note
	description: "[
		p_doors.c
		
		Door animation code (opening/closing)
	]"
	license: "[
				Copyright (C) 1993-1996 by id Software, Inc.
				Copyright (C) 2005-2014 Simon Howard
				Copyright (C) 2021 Ilgiz Mustafin
		
				This program is free software; you can redistribute it and/or modify
				it under the terms of the GNU General Public License as published by
				the Free Software Foundation; either version 2 of the License, or
				(at your option) any later version.
		
				This program is distributed in the hope that it will be useful,
				but WITHOUT ANY WARRANTY; without even the implied warranty of
				MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
				GNU General Public License for more details.
		
				You should have received a copy of the GNU General Public License along
				with this program; if not, write to the Free Software Foundation, Inc.,
				51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
	]"

class 
	P_DOORS

inherit
	VLDOOR_E

create 
	make

feature 

	i_main: I_MAIN

	make (a_i_main: like i_main)
		do
			i_main := a_i_main
		end
	
feature 

	ev_verticaldoor (line: LINE_T; thing: MOBJ_T)
			-- open a door manually, no tag value
		local
			player: PLAYER_T
			sec: SECTOR_T
			door: VLDOOR_T
			side: INTEGER_32
			returned: BOOLEAN
		do
			side := 0
			player := thing.player
			if line.special = 26 or line.special = 32 then
				if attached player then
					if not player.cards [{CARD_T}.it_bluecard] and not player.cards [{CARD_T}.it_blueskull] then
						player.message := {D_ENGLSH}.pd_bluek
						i_main.S_sound.s_startsound (Void, {SFXENUM_T}.sfx_oof)
						returned := True
					end
				else
					returned := True
				end
			end
			if not returned and (line.special = 27 or line.special = 34) then
				if attached player then
					if not player.cards [{CARD_T}.it_yellowcard] and not player.cards [{CARD_T}.it_yellowskull] then
						player.message := {D_ENGLSH}.pd_yellowk
						i_main.S_sound.s_startsound (Void, {SFXENUM_T}.sfx_oof)
						returned := True
					end
				else
					returned := True
				end
			end
			if not returned and (line.special = 28 or line.special = 33) then
				if attached player then
					if not player.cards [{CARD_T}.it_redcard] and not player.cards [{CARD_T}.it_redskull] then
						player.message := {D_ENGLSH}.pd_redk
						i_main.S_sound.s_startsound (Void, {SFXENUM_T}.sfx_oof)
						returned := True
					end
				else
					returned := True
				end
			end
			if not returned then
				sec := i_main.P_setup.sides [line.sidenum [side.bit_xor (1)].to_integer_32].sector
				check
						attached sec as s
				then
					if attached s.specialdata as sd then
						check
								attached {VLDOOR_T} s.specialdata as ddd
						then
							door := ddd
						end
						if line.special = 1 or line.special = 26 or line.special = 27 or line.special = 28 or line.special = 117 then
							if door.direction = -1 then
								door.direction := 1
							else
								if thing.player = Void then
									returned := True
								else
									door.direction := -1
								end
							end
							returned := True
						end
					end
				end
			end
			if not returned then
				check
						attached sec as s
				then
					if line.special = 117 or line.special = 118 then
						i_main.S_sound.s_startsound (s.soundorg, {SFXENUM_T}.sfx_bdopn)
					elseif line.special = 1 or line.special = 31 then
						i_main.S_sound.s_startsound (s.soundorg, {SFXENUM_T}.sfx_doropn)
					else
						i_main.S_sound.s_startsound (s.soundorg, {SFXENUM_T}.sfx_doropn)
					end
				end
			end
			if not returned then
				check
						attached sec
				then
					create door.make (sec)
					i_main.P_tick.p_addthinker (door)
					sec.specialdata := door
					door.thinker.function := agent t_verticaldoor (door)
					door.direction := 1
					door.speed := create {FIXED_T}.from_integer ({P_SPEC}.vdoorspeed)
					door.topwait := {P_SPEC}.vdoorwait
					if line.special = 1 or line.special = 26 or line.special = 27 or line.special = 28 then
						door.type := Normal
					elseif line.special = 31 or line.special = 32 or line.special = 33 or line.special = 34 then
						door.type := Open
						line.special := 0
					elseif line.special = 117 then
						door.type := Blazeraise
						door.speed := create {FIXED_T}.from_integer ({P_SPEC}.vdoorspeed * 4)
					elseif line.special = 118 then
						door.type := Blazeopen
						line.special := 0
						door.speed := create {FIXED_T}.from_integer ({P_SPEC}.vdoorspeed * 4)
					end
					door.topheight := i_main.P_spec.p_findlowestceilingsurrounding (sec)
					door.topheight := door.topheight - create {FIXED_T}.from_integer ((4 * {M_FIXED}.fracunit))
				end
			end
		end

	ev_dodoor (line: LINE_T; type: INTEGER_32): BOOLEAN
		do
			{NOT_IMPLEMENTED}.not_implemented ("EV_DoDoor", True)
		ensure
			instance_free: class
		end

	ev_dolockeddoor (line: LINE_T; type: INTEGER_32; thing: MOBJ_T): BOOLEAN
			-- Move a locked door up/down
		do
			{NOT_IMPLEMENTED}.not_implemented ("EV_DoLockedDoor", True)
		ensure
			instance_free: class
		end

	t_verticaldoor (door: VLDOOR_T)
		local
			res: RESULT_E
		do
			if door.direction = 0 then
				door.topcountdown := door.topcountdown - 1
				if door.topcountdown /= 0 then
					if door.type = Blazeraise then
						door.direction := -1
						i_main.S_sound.s_startsound (door.sector.soundorg, {SFXENUM_T}.sfx_bdcls)
					elseif door.type = Normal then
						door.direction := -1
						i_main.S_sound.s_startsound (door.sector.soundorg, {SFXENUM_T}.sfx_dorcls)
					elseif door.type = Close30thenopen then
						door.direction := 1
						i_main.S_sound.s_startsound (door.sector.soundorg, {SFXENUM_T}.sfx_doropn)
					end
				end
			elseif door.direction = 2 then
				door.topcountdown := door.topcountdown - 1
				if door.topcountdown /= 0 then
					if door.type = Raisein5mins then
						door.direction := 1
						door.type := Normal
						i_main.S_sound.s_startsound (door.sector.soundorg, {SFXENUM_T}.sfx_doropn)
					end
				end
			elseif door.direction = -1 then
				res := i_main.P_floor.t_moveplane (door.sector, door.speed, door.sector.floorheight, False, 1, door.direction)
				if res = {RESULT_E}.pastdest then
					if door.type = Blazeraise or door.type = Blazeclose then
						door.sector.specialdata := Void
						i_main.P_tick.p_removethinker (door)
						i_main.S_sound.s_startsound (door.sector.soundorg, {SFXENUM_T}.sfx_bdcls)
					elseif door.type = Normal or door.type = Close then
						door.sector.specialdata := Void
						i_main.P_tick.p_removethinker (door)
					elseif door.type = Close30thenopen then
						door.direction := 0
						door.topcountdown := 35 * 30
					end
				elseif res = {RESULT_E}.crushed then
					if door.type = Blazeclose or door.type = Close then
					else
						door.direction := 1
						i_main.S_sound.s_startsound (door.sector.soundorg, {SFXENUM_T}.sfx_doropn)
					end
				end
			elseif door.direction = 1 then
				res := i_main.P_floor.t_moveplane (door.sector, door.speed, door.topheight, False, 1, door.direction)
				if res = {RESULT_E}.pastdest then
					if door.type = Blazeraise or door.type = Normal then
						door.direction := 0
						door.topcountdown := door.topwait
					elseif door.type = Close30thenopen or door.type = Blazeopen or door.type = Open then
						door.sector.specialdata := Void
						i_main.P_tick.p_removethinker (door)
					end
				end
			end
		end
	
end -- class P_DOORS

Generated by ISE EiffelStudio