aboutsummaryrefslogtreecommitdiff
path: root/trainhud.lua
blob: 601b28fed7d514f4dd41d2028a62aef3d5e4d20e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 
advtrains.hud = {}

minetest.register_on_leaveplayer(function(player)
advtrains.hud[player:get_player_name()] = nil
end)

function advtrains.set_trainhud(name, text)
	local hud = advtrains.hud[name]
	local player=minetest.get_player_by_name(name)
	if not hud then
		hud = {}
		advtrains.hud[name] = hud
		hud.id = player:hud_add({
			hud_elem_type = "text",
			name = "ADVTRAINS",
			number = 0xFFFFFF,
			position = {x=0.5, y=0.7},
			offset = {x=0, y=0},
			text = text,
			scale = {x=200, y=60},
			alignment = {x=0, y=0},
		})
		hud.oldText=text
		return
	elseif hud.oldText ~= text then
		player:hud_change(hud.id, "text", text)
		hud.oldText=text
	end
end
function advtrains.hud_train_format(train, flip)
	local fct=1
	if flip then fct=-1 end
	if not train then return "" end
	local max=advtrains.all_traintypes[train.traintype].max_speed or 10
	local vel=advtrains.abs_ceil(train.velocity)*fct
	local tvel=advtrains.abs_ceil(train.tarvelocity)*fct
	local firstLine, secondLine
	if vel<0 then
		firstLine="Speed: <"..string.rep("_", vel+max)..string.rep("+", -vel).."|"..string.rep("_", max)..">"
	else
		firstLine="Speed: <"..string.rep("_", max).."|"..string.rep("+", vel)..string.rep("_", max-vel)..">"
	end
	if tvel<0 then
		secondLine="Target: <"..string.rep("_", tvel+max)..string.rep("+", -tvel).."|"..string.rep("_", max)..">"
	else
		secondLine="Target: <"..string.rep("_", max).."|"..string.rep("+", tvel)..string.rep("_", max-tvel)..">"
	end
	if vel==0 then
		return firstLine.."\n"..secondLine.."\nup for forward, down for backward, use to get off train.  "
	elseif vel<0 then
		return firstLine.."\n"..secondLine.."\nPress up to decelerate, down to accelerate, sneak to stop."
	elseif vel>0 then
		return firstLine.."\n"..secondLine.."\nPress up to accelerate, down to decelerate, sneak to stop."
	end
end
401'>401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
--atan2 counts angles clockwise, minetest does counterclockwise
local print=function(t) minetest.log("action", t) minetest.chat_send_all(t) end

local wagon={
	collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
	--physical = true,
	visual = "mesh",
	mesh = "wagon.b3d",
	visual_size = {x=3, y=3},
	textures = {"black.png"},
	is_wagon=true,
	wagon_span=1,--how many index units of space does this wagon consume
	attach_offset={x=0, y=0, z=0},
	view_offset={x=0, y=0, z=0},
}



function wagon:on_rightclick(clicker)
	--print("[advtrains] wagon rightclick")
	if not clicker or not clicker:is_player() then
		return
	end
	if not self.initialized then
		print("[advtrains] not initiaalized")
		return
	end
	if clicker:get_player_control().aux1 then
		--advtrains.dumppath(self:train().path)
		--minetest.chat_send_all("at index "..(self:train().index or "nil"))
		--advtrains.invert_train(self.train_id)
		minetest.chat_send_all(dump(self:train()))
		return
	end	
	local no=self:get_seatno(clicker:get_player_name())
	if no then
		self:get_off(no)
	else
		self:show_get_on_form(clicker:get_player_name())
	end
end

function wagon:train()
	return advtrains.trains[self.train_id]
end

function wagon:on_activate(staticdata, dtime_s)
	--print("[advtrains][wagon "..(self.unique_id or "no-id").."] activated")
	self.object:set_armor_groups({immortal=1})
	if staticdata then
		local tmp = minetest.deserialize(staticdata)
		if tmp then
			self.unique_id=tmp.unique_id
			self.train_id=tmp.train_id
			self.wagon_flipped=tmp.wagon_flipped
			self.owner=tmp.owner
			self.seatp=tmp.seatp
		end

	end
	self.old_pos = self.object:getpos()
	self.old_velocity = self.velocity
	self.initialized_pre=true
	self.entity_name=self.name
	
	--same code is in on_step
	--does this object already have an ID?
	if not self.unique_id then
		self.unique_id=os.time()..os.clock()--should be random enough.
	else
		for _,wagon in pairs(minetest.luaentities) do
			if wagon.is_wagon and wagon.initialized and wagon.unique_id==self.unique_id then--i am a duplicate!
				self.object:remove()
				return
			end
		end
	end
	--is my train still here
	if not self.train_id or not self:train() then
		if self.initialized then
			print("[advtrains][wagon "..self.unique_id.."] missing train_id, destroying")
			self.object:remove()
			return
		end
		print("[advtrains][wagon "..self.unique_id.."] missing train_id, but not yet initialized, returning")
		return
	elseif not self.initialized then
		self.initialized=true
	end
	advtrains.update_trainpart_properties(self.train_id)
	minetest.after(1, function() self:reattach_all() end)
	
	if self.custom_on_activate then
		self:custom_on_activate(staticdata_table, dtime_s)
	end
end

function wagon:get_staticdata()
	--save to table before being unloaded
	advtrains.wagon_save[self.unique_id]=advtrains.merge_tables(self)
	return minetest.serialize({
		unique_id=self.unique_id,
		train_id=self.train_id,
		wagon_flipped=self.wagon_flipped,
		owner=self.owner,
		seatp=self.seatp,
	})
end

-- Remove the wagon
function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
	if not puncher or not puncher:is_player() then
		return
	end
	if self.owner and puncher:get_player_name()~=self.owner then
		minetest.chat_send_player(puncher:get_player_name(), "This wagon is owned by "..self.owner..", you can't destroy it.")
		return
	end
	
	if minetest.setting_getbool("creative_mode") then
		if not self:destroy() then return end
		
		local inv = puncher:get_inventory()
		if not inv:contains_item("main", self.name) then
			inv:add_item("main", self.name)
		end
	else
		local pc=puncher:get_player_control()
		if not pc.sneak then
			minetest.chat_send_player(puncher:get_player_name(), "Warning: If you destroy this wagon, you only get some steel back! If you are sure, shift-leftclick the wagon.")
			return
		end

		if not self:destroy() then return end

		local inv = puncher:get_inventory()
		for _,item in ipairs(self.drops or {self.name}) do
			inv:add_item("main", item)
		end
	end
end
function wagon:destroy()
	--some rules:
	-- you get only some items back
	-- single left-click shows warning
	-- shift leftclick destroys
	-- not when a driver is inside
	
	for _,_ in pairs(self.seatp) do
		return
	end
	
	if self.custom_may_destroy then
		if not self.custom_may_destroy(self, puncher, time_from_last_punch, tool_capabilities, direction) then