note description: "[ p_enemy.c Enemy thinking, AI. Action Pointer Functions that are associated with states/frames ]" 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_ENEMY inherit SFXENUM_T MOBJTYPE_T MOBJFLAG_T create make feature i_main: I_MAIN make (a_i_main: I_MAIN) do i_main := a_i_main end feature -- dirtype_t Di_east: INTEGER_32 = 0 Di_northeast: INTEGER_32 = 1 Di_north: INTEGER_32 = 2 Di_northwest: INTEGER_32 = 3 Di_west: INTEGER_32 = 4 Di_southwest: INTEGER_32 = 5 Di_south: INTEGER_32 = 6 Di_southeast: INTEGER_32 = 7 Di_nodir: INTEGER_32 = 8 Numdirs: INTEGER_32 = 9 Opposite: ARRAY [INTEGER_32] once Result := <<Di_west, Di_southwest, Di_south, Di_southeast, Di_east, Di_northeast, Di_north, Di_northwest, Di_nodir>> Result.rebase (0) end Diags: ARRAY [INTEGER_32] once Result := <<Di_northwest, Di_northeast, Di_southwest, Di_southeast>> Result.rebase (0) end feature soundtarget: detachable MOBJ_T p_noisealert (target, emitter: MOBJ_T) -- If a monster yells at a player, -- it will alert other monsters to the player. do soundtarget := target i_main.R_main.validcount := i_main.R_main.validcount + 1 check attached emitter.subsector as sub and then attached sub.sector as s then p_recursivesound (s, 0) end end p_recursivesound (sec: SECTOR_T; soundblocks: INTEGER_32) -- Called by P_NoiseAlert -- Recursively traverse adjacent sectors, -- sound blocking lines cut off traversal. local i: INTEGER_32 c: LINE_T other: SECTOR_T do if sec.validcount = i_main.R_main.validcount and sec.soundtraversed <= soundblocks + 1 then else sec.validcount := i_main.R_main.validcount sec.soundtraversed := soundblocks + 1 sec.soundtarget := soundtarget from i := sec.lines.Lower until i > sec.lines.upper loop c := sec.lines [i] if c.flags.to_integer_32 & {DOOMDATA_H}.ml_twosided = 0 then else i_main.P_maputl.p_lineopening (c) if i_main.P_maputl.openrange <= create {FIXED_T}.from_integer (0) then else if i_main.P_setup.sides [c.sidenum [0].to_integer_32].sector = sec then other := i_main.P_setup.sides [c.sidenum [1].to_integer_32].sector else other := i_main.P_setup.sides [c.sidenum [0].to_integer_32].sector end if c.flags.to_integer_32 & {DOOMDATA_H}.ml_soundblock /= 0 then check attached other then if soundblocks = 0 then p_recursivesound (other, 1) else p_recursivesound (other, soundblocks) end end end end end i := i + 1 end end end feature a_openshotgun2 (player: PLAYER_T; psp: PSPDEF_T) do {NOT_IMPLEMENTED}.not_implemented ("A_OpenShotgun2", False) end a_loadshotgun2 (player: PLAYER_T; psp: PSPDEF_T) do {NOT_IMPLEMENTED}.not_implemented ("A_LoadShotgun2", False) end a_closeshotgun2 (player: PLAYER_T; psp: PSPDEF_T) do {NOT_IMPLEMENTED}.not_implemented ("A_CloseShotgun2", False) end a_explode (thingy: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_Explode", False) end a_pain (actor: MOBJ_T) do check attached actor.info as info then if info.painsound /= 0 then i_main.S_sound.s_startsound (actor, info.painsound) end end end a_playerscream (mo: MOBJ_T) local sound: INTEGER_32 do sound := Sfx_pldeth if i_main.Doomstat_h.gamemode = {GAME_MODE_T}.commercial and mo.health < -50 then sound := Sfx_pdiehi end i_main.S_sound.s_startsound (mo, sound) end a_fall (actor: MOBJ_T) do actor.flags := actor.flags & {P_MOBJ}.mf_solid.bit_not end a_xscream (actor: MOBJ_T) do i_main.S_sound.s_startsound (actor, Sfx_slop) end a_look (actor: MOBJ_T) -- Stay in state until a player is sighted local targ: MOBJ_T seeyou: BOOLEAN returned: BOOLEAN sound: INTEGER_32 do actor.threshold := 0 check attached actor.subsector as sub and then attached sub.sector as sec then targ := sec.soundtarget end if attached targ and then targ.flags & Mf_shootable /= 0 then actor.target := targ if actor.flags & Mf_ambush /= 0 then if i_main.P_sight.p_checksight (actor, targ) then seeyou := True end else seeyou := True end end if not seeyou then if not p_lookforplayers (actor, False) then returned := True end end if not returned then check attached actor.info as i then if i.seesound /= 0 then if i.seesound = Sfx_posit1 or i.seesound = Sfx_posit2 or i.seesound = Sfx_posit3 then sound := Sfx_posit1 + i_main.M_random.p_random \\ 3 elseif i.seesound = Sfx_bgsit1 or i.seesound = Sfx_bgsit2 then sound := Sfx_bgsit1 + i_main.M_random.p_random \\ 2 else sound := i.seesound end if actor.type = Mt_spider or actor.type = Mt_cyborg then i_main.S_sound.s_startsound (Void, sound) else i_main.S_sound.s_startsound (actor, sound) end end i_main.P_mobj.p_setmobjstate (actor, i.seestate).do_nothing end end end p_lookforplayers (actor: MOBJ_T; allaround: BOOLEAN): BOOLEAN -- If allaround is false, only look 180 degrees in front. -- Returns true if a player is targeted. local c: INTEGER_32 stop: INTEGER_32 player: PLAYER_T an: ANGLE_T dist: FIXED_T returned: BOOLEAN continue: BOOLEAN do c := 0 stop := (actor.lastlook - 1) & 3 from until returned loop continue := False if not i_main.G_game.Playeringame [actor.lastlook] then else c := c + 1 if c = 3 or actor.lastlook = stop then Result := False returned := True else player := i_main.G_game.Players [actor.lastlook] if player.health <= 0 then else check attached player.mo as mo then if not i_main.P_sight.p_checksight (actor, mo) then else if not allaround then an := i_main.R_main.r_pointtoangle2 (actor.x, actor.y, mo.x, mo.y) - actor.angle if an > {R_MAIN}.ang90 and an < {R_MAIN}.ang270 then dist := i_main.P_maputl.p_aproxdistance (mo.x - actor.x, mo.y - actor.y) if dist > create {FIXED_T}.from_integer ({P_LOCAL}.meleerange) then continue := True end end end if not continue then actor.target := player.mo Result := True returned := True end end end end end end if not returned then actor.lastlook := (actor.lastlook + 1) & 3 end end if not returned then Result := False end end a_chase (actor: MOBJ_T) -- Actor has a melee attack, -- so it tries to close as fast as possible local delta: INTEGER_32 returned: BOOLEAN do check attached actor.info as ainfo then if actor.reactiontime /= 0 then actor.reactiontime := actor.reactiontime - 1 end if actor.threshold /= 0 then if actor.target = Void or (attached actor.target as t and then t.health <= 0) then actor.threshold := 0 else actor.threshold := actor.threshold - 1 end end if actor.movedir < 8 then actor.angle := actor.angle & create {ANGLE_T}.from_natural (((7).to_natural_32 |<< 29)) delta := actor.angle.as_integer_32 - (actor.movedir |<< 29) if delta > 0 then actor.angle := actor.angle - {R_MAIN}.ang90 // create {ANGLE_T}.from_natural ((2).to_natural_32) elseif delta < 0 then actor.angle := actor.angle + {R_MAIN}.ang90 // create {ANGLE_T}.from_natural ((2).to_natural_32) end end if actor.target = Void or else (attached actor.target as t and then t.flags & Mf_shootable = 0) then if p_lookforplayers (actor, True) then else i_main.P_mobj.p_setmobjstate (actor, ainfo.spawnstate).do_nothing end else if actor.flags & Mf_justattacked /= 0 then actor.flags := actor.flags & Mf_justattacked.bit_not if i_main.G_game.gameskill /= {DOOMDEF_H}.sk_nightmare and not i_main.D_main.fastparm then p_newchasedir (actor) end else if ainfo.meleestate /= 0 and p_checkmeleerange (actor) then if ainfo.attacksound /= 0 then i_main.S_sound.s_startsound (actor, ainfo.attacksound) end i_main.P_mobj.p_setmobjstate (actor, ainfo.meleestate).do_nothing else if ainfo.missilestate /= 0 then if i_main.G_game.gameskill < {DOOMDEF_H}.sk_nightmare and not i_main.D_main.fastparm and actor.movecount /= 0 then elseif not p_checkmissilerange (actor) then else i_main.P_mobj.p_setmobjstate (actor, ainfo.missilestate).do_nothing actor.flags := actor.flags | Mf_justattacked returned := True end if not returned then check attached actor.target as t then if i_main.G_game.netgame and actor.threshold = 0 and not i_main.P_sight.p_checksight (actor, t) then if p_lookforplayers (actor, True) then returned := True end end end end if not returned then actor.movecount := actor.movecount - 1 if actor.movecount < 0 or else not p_move (actor) then p_newchasedir (actor) end if ainfo.activesound /= 0 and i_main.M_random.p_random < 3 then i_main.S_sound.s_startsound (actor, ainfo.activesound) end end end end end end end end p_newchasedir (actor: MOBJ_T) require attached actor.target local deltax, deltay: FIXED_T d: ARRAY [INTEGER_32] tdir: INTEGER_32 olddir: INTEGER_32 turnaround: INTEGER_32 returned: BOOLEAN do create d.make_filled (0, 0, 2) check attached actor.target as t then olddir := actor.movedir turnaround := Opposite [olddir] deltax := t.x - actor.x deltay := t.y - actor.y if deltax > create {FIXED_T}.from_integer (10 * {M_FIXED}.fracunit) then d [1] := Di_east elseif deltax < create {FIXED_T}.from_integer (-10 * {M_FIXED}.fracunit) then d [1] := Di_west else d [1] := Di_nodir end if deltay < create {FIXED_T}.from_integer (-10 * {M_FIXED}.fracunit) then d [2] := Di_south elseif deltay > create {FIXED_T}.from_integer (10 * {M_FIXED}.fracunit) then d [2] := Di_north else d [2] := Di_nodir end if d [1] /= Di_nodir and d [2] /= Di_nodir then actor.movedir := Diags [((deltay < create {FIXED_T}.from_integer (0)).to_integer |<< 1) + (deltax > create {FIXED_T}.from_integer (0)).to_integer] if actor.movedir /= turnaround and then p_trywalk (actor) then returned := True end end if not returned then if i_main.M_random.p_random > 200 or deltay.abs > deltax.abs then tdir := d [1] d [1] := d [2] d [2] := tdir end if d [1] = turnaround then d [1] := Di_nodir end if d [2] = turnaround then d [2] := Di_nodir end if d [1] /= Di_nodir then actor.movedir := d [1] if p_trywalk (actor) then returned := True end end end if not returned then if d [2] /= Di_nodir then actor.movedir := d [2] if p_trywalk (actor) then returned := True end end end if not returned then if olddir /= Di_nodir then actor.movedir := olddir if p_trywalk (actor) then returned := True end end end if not returned then if (i_main.M_random.p_random & 1) /= 0 then from tdir := Di_east until returned or tdir > Di_southeast loop if tdir /= turnaround then actor.movedir := tdir if p_trywalk (actor) then returned := True end end tdir := tdir + 1 end else from tdir := Di_southeast until returned or tdir <= Di_east - 1 loop if tdir /= turnaround then actor.movedir := tdir if p_trywalk (actor) then returned := True end end tdir := tdir - 1 end end end if not returned then if turnaround /= Di_nodir then actor.movedir := turnaround if p_trywalk (actor) then returned := True end end end if not returned then actor.movedir := Di_nodir end end end p_trywalk (actor: MOBJ_T): BOOLEAN -- Attempts to move actor on -- in its current (ob->moveangle) direction. -- If blocked by either a wall or an actor -- returns FALSE -- If move is either clear or blocked only by a door, -- returns TRUE and sets... -- If a door is in the way, -- an OpenDoor call is made to start it opening do if not p_move (actor) then Result := False else actor.movecount := i_main.M_random.p_random & 15 Result := True end end p_checkmeleerange (actor: MOBJ_T): BOOLEAN local dist: FIXED_T do if attached actor.target as pl then dist := i_main.P_maputl.p_aproxdistance (pl.x - actor.x, pl.y - actor.y) check attached pl.info as i then if dist >= create {FIXED_T}.from_integer ({P_LOCAL}.meleerange - 20 * {M_FIXED}.fracunit + i.radius) then Result := False else if not i_main.P_sight.p_checksight (actor, pl) then Result := False else Result := True end end end else Result := False end end p_checkmissilerange (actor: MOBJ_T): BOOLEAN local dist: FIXED_T returned: BOOLEAN do check attached actor.target as t and then attached actor.info as i then if not i_main.P_sight.p_checksight (actor, t) then Result := False elseif actor.flags & Mf_justhit /= 0 then actor.flags := actor.flags & Mf_justhit.bit_not Result := True elseif actor.reactiontime /= 0 then Result := False else dist := i_main.P_maputl.p_aproxdistance (actor.x - t.x, actor.y - t.y) - create {FIXED_T}.from_integer (64 * {M_FIXED}.fracunit) if i.meleestate = 0 then dist := dist - create {FIXED_T}.from_integer (128 * {M_FIXED}.fracunit) end dist := dist |>> 16 if actor.type = Mt_vile then if dist > create {FIXED_T}.from_integer (14 * 64) then Result := False returned := True end elseif actor.type = Mt_undead then if dist < create {FIXED_T}.from_integer (196) then Result := False else dist := dist |>> 1 end elseif actor.type = Mt_cyborg or actor.type = Mt_spider or actor.type = Mt_skull then dist := dist |>> 1 end if not returned then if dist > create {FIXED_T}.from_integer (200) then dist := create {FIXED_T}.from_integer (200) end if actor.type = Mt_cyborg and dist > create {FIXED_T}.from_integer (160) then dist := create {FIXED_T}.from_integer (160) end if i_main.M_random.p_random < dist.as_integer_32 then Result := False else Result := True end end end end end feature -- P_Move Xspeed: ARRAY [FIXED_T] once Result := ARRAY [FIXED_T] <<create {FIXED_T}.from_integer ({M_FIXED}.fracunit), create {FIXED_T}.from_integer (47000), create {FIXED_T}.from_integer (0), create {FIXED_T}.from_integer (-47000), create {FIXED_T}.from_integer (- {M_FIXED}.fracunit), create {FIXED_T}.from_integer (-47000), create {FIXED_T}.from_integer (0), create {FIXED_T}.from_integer (47000)>> Result.rebase (0) end Yspeed: ARRAY [FIXED_T] once Result := ARRAY [FIXED_T] <<create {FIXED_T}.from_integer (0), create {FIXED_T}.from_integer (47000), create {FIXED_T}.from_integer ({M_FIXED}.fracunit), create {FIXED_T}.from_integer (47000), create {FIXED_T}.from_integer (0), create {FIXED_T}.from_integer (-47000), create {FIXED_T}.from_integer (- {M_FIXED}.fracunit), create {FIXED_T}.from_integer (-47000)>> Result.rebase (0) end p_move (actor: MOBJ_T): BOOLEAN require actor.movedir < 8 local tryx, tryy: FIXED_T ld: LINE_T try_ok: BOOLEAN good: BOOLEAN returned: BOOLEAN do if actor.movedir = Di_nodir then Result := False else check attached actor.info as i then tryx := actor.x + create {FIXED_T}.from_integer (i.speed * Xspeed [actor.movedir].as_integer_32) tryy := actor.y + create {FIXED_T}.from_integer (i.speed * Yspeed [actor.movedir].as_integer_32) try_ok := i_main.P_map.p_trymove (actor, tryx, tryy) if not try_ok then if actor.flags & Mf_float /= 0 and i_main.P_map.floatok then if actor.z < i_main.P_map.tmfloorz then actor.z := actor.z + create {FIXED_T}.from_integer ({P_LOCAL}.floatspeed) else actor.z := actor.z - create {FIXED_T}.from_integer ({P_LOCAL}.floatspeed) end actor.flags := actor.flags | Mf_infloat Result := True returned := True end if not returned then if i_main.P_map.numspechit = 0 then Result := False returned := True end end if not returned then actor.movedir := Di_nodir good := False from until i_main.P_map.numspechit = 0 loop i_main.P_map.numspechit := i_main.P_map.numspechit - 1 ld := i_main.P_map.spechit [i_main.P_map.numspechit] check attached ld then if i_main.P_switch.p_usespecialline (actor, ld, 0) then good := True end end end Result := good returned := True end else actor.flags := actor.flags & Mf_infloat.bit_not end if not returned then if actor.flags & Mf_float = 0 then actor.z := actor.floorz end Result := True end end end end feature a_facetarget (actor: MOBJ_T) do if attached actor.target as t then actor.flags := actor.flags & Mf_ambush.bit_not actor.angle := i_main.R_main.r_pointtoangle2 (actor.x, actor.y, t.x, t.y) if t.flags & Mf_shadow /= 0 then actor.angle := actor.angle + create {ANGLE_T}.from_natural (((i_main.M_random.p_random - i_main.M_random.p_random) |<< 21).to_natural_32) end end end a_posattack (actor: MOBJ_T) local angle: ANGLE_T damage: INTEGER_32 slope: INTEGER_32 do if attached actor.target as t then a_facetarget (actor) angle := actor.angle slope := i_main.P_map.p_aimlineattack (actor, angle, create {FIXED_T}.from_integer ({P_LOCAL}.missilerange)).as_integer_32 i_main.S_sound.s_startsound (actor, Sfx_pistol) angle := angle + create {ANGLE_T}.from_natural (((i_main.M_random.p_random - i_main.M_random.p_random) |<< 20).to_natural_32) damage := ((i_main.M_random.p_random \\ 5) + 1) * 3 i_main.P_map.p_lineattack (actor, angle, create {FIXED_T}.from_integer ({P_LOCAL}.missilerange), create {FIXED_T}.from_integer (slope), damage) end end a_scream (actor: MOBJ_T) local sound: INTEGER_32 returned: BOOLEAN do check attached actor.info as i then if i.deathsound = 0 then returned := True elseif i.deathsound = Sfx_podth1 or i.deathsound = Sfx_podth2 or i.deathsound = Sfx_podth3 then sound := Sfx_podth1 + i_main.M_random.p_random \\ 3 elseif i.deathsound = Sfx_bgdth1 or i.deathsound = Sfx_bgdth2 then sound := Sfx_bgdth1 + i_main.M_random.p_random \\ 2 else sound := i.deathsound end end if not returned then if actor.type = Mt_spider or actor.type = Mt_cyborg then i_main.S_sound.s_startsound (Void, sound) else i_main.S_sound.s_startsound (actor, sound) end end end a_sposattack (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_SPosAttack", False) end a_vilechase (actor: MOBJ_T) -- Check for resurrecting a body do {NOT_IMPLEMENTED}.not_implemented ("A_VileChase", False) end a_vilestart (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_VileStart", False) end a_viletarget (actor: MOBJ_T) -- Spawn the hellfire do {NOT_IMPLEMENTED}.not_implemented ("A_VileTarget", False) end a_vileattack (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_VileAttack", False) end a_startfire (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_StartFire", False) end a_fire (actor: MOBJ_T) -- Keep fire in front of player unless out of sight do {NOT_IMPLEMENTED}.not_implemented ("A_Fire", False) end a_firecrackle (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_FireCrackle", False) end a_tracer (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_Tracer", False) end a_skelwhoosh (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_SkelWhoosh", False) end a_skelfist (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_SkelFist", False) end a_skelmissile (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_SkelMissile", False) end a_fatraise (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_FatRaise", False) end a_fatattack1 (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_FatAttack1", False) end a_fatattack2 (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_FatAttack2", False) end a_fatattack3 (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_FatAttack3", False) end a_bossdeath (mo: MOBJ_T) -- Possibly trigger special effects -- if on first boss level do {NOT_IMPLEMENTED}.not_implemented ("A_BossDeath", False) end a_cposattack (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_CPosAttack", False) end a_cposrefire (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_CPosRefire", False) end a_troopattack (actor: MOBJ_T) local damage: INTEGER_32 do if attached actor.target as t then a_facetarget (actor) if p_checkmeleerange (actor) then i_main.S_sound.s_startsound (actor, Sfx_claw) damage := (i_main.M_random.p_random \\ 8 + 1) * 3 i_main.P_inter.p_damagemobj (t, actor, actor, damage) else i_main.P_mobj.p_spawnmissile (actor, t, Mt_troopshot).do_nothing end end end a_sargattack (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_SargAttack", False) end a_headattack (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_HeadAttack", False) end a_bruisattack (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_BruisAttack", False) end a_skullattack (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_SkullAttack", False) end a_metal (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_Metal", False) end a_spidrefire (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_SpidRefire", False) end a_babymetal (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_BabyMetal", False) end a_bspiattack (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_BspiAttack", False) end a_hoof (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_Hoof", False) end a_cyberattack (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_CyberAttack", False) end a_painattack (actor: MOBJ_T) -- Spawn a lost soul and launch it at the target do {NOT_IMPLEMENTED}.not_implemented ("A_PainAttack", False) end a_paindie (actor: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_PainDie", False) end a_keendie (mo: MOBJ_T) -- DOOM II special, map 32. -- Uses special tag 666. do {NOT_IMPLEMENTED}.not_implemented ("A_KeenDie", False) end a_brainpain (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_BrainPain", False) end a_brainscream (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_BrainScream", False) end a_braindie (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_BrainDie", False) end a_brainawake (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_BrainAwake", False) end a_brainspit (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_BrainSpit", False) end a_spawnsound (mo: MOBJ_T) -- Travelling cube sound do {NOT_IMPLEMENTED}.not_implemented ("A_SpawnSound", False) end a_spawnfly (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_SpawnFly", False) end a_brainexplode (mo: MOBJ_T) do {NOT_IMPLEMENTED}.not_implemented ("A_BrainExplode", False) end end -- class P_ENEMY
Generated by ISE EiffelStudio