-- j2b2's Deton Demon Challenge mod freeslot( "A_DemonChase", "S_GREEN_DEMON_WAIT", "S_GREEN_DEMON_SEE", "S_GREEN_DEMON_ACTIVATE", "S_GREEN_DEMON_FOLLOW1", "S_GREEN_DEMON_FOLLOW2", "S_GREEN_DEMON_FOLLOW3", "S_GREEN_DEMON_FOLLOW4", "S_GREEN_DEMON_FOLLOW5", "S_GREEN_DEMON_FOLLOW6", "S_GREEN_DEMON_FOLLOW7", "S_GREEN_DEMON_FOLLOW8", "S_GREEN_DEMON_FOLLOW9", "S_GREEN_DEMON_FOLLOW10", "S_GREEN_DEMON_FOLLOW11", "S_GREEN_DEMON_FOLLOW12", "S_GREEN_DEMON_FOLLOW13", "S_GREEN_DEMON_FOLLOW14", "MT_GREEN_DEMON" ) local function IsValid(a) if a ~= nil then return a.valid end return false end local function DD_DelayChanged(var) states[S_GREEN_DEMON_WAIT].tics = var.value*TICRATE end local cvDDMinSpeed = CV_RegisterVar({name="dd_minspeed",defaultvalue=10,flags=CV_NETVAR|CV_SHOWMODIF,PossibleValue=CV_Unsigned}) local cvDDMaxSpeed = CV_RegisterVar({name="dd_maxspeed",defaultvalue=30,flags=CV_NETVAR|CV_SHOWMODIF,PossibleValue=CV_Unsigned}) local cvDDDelay = CV_RegisterVar({name="dd_delay",defaultvalue=7,flags=CV_CALL|CV_NETVAR|CV_SHOWMODIF,PossibleValue=CV_Unsigned,func=DD_DelayChanged}) local cvDDCatchupFactor = CV_RegisterVar({name="dd_catchupfactor",defaultvalue=40,flags=CV_NETVAR|CV_SHOWMODIF,PossibleValue=CV_Natural}) local cvDDDamageOthers = CV_RegisterVar({name="dd_damageothers",defaultvalue="No",flags=CV_NETVAR|CV_SHOWMODIF,PossibleValue=CV_YesNo}) function A_DemonChase(mobj) if IsValid(mobj.target) then local distance = R_PointToDist2(mobj.target.x,0,mobj.x,R_PointToDist2(mobj.target.y,mobj.target.z,mobj.y,mobj.z)) local speedMin = cvDDMinSpeed.value*FRACUNIT local speedMax = cvDDMaxSpeed.value*FRACUNIT local speed = distance/cvDDCatchupFactor.value if speed < speedMin then speed = speedMin elseif speed > speedMax then speed = speedMax end A_HomingChase(mobj,speed,0) if mobj.target.player.exiting > 0 or mobj.target.player.pflags & PF_FINISHED > 0 then P_KillMobj(mobj) return false end local beep = distance>>(FRACBITS+6) if beep < 1 then beep = 1 end if (leveltime % beep) == 0 then A_PlayAttackSound(mobj) end else P_KillMobj(mobj) return false end end states[S_GREEN_DEMON_WAIT] = { sprite = SPR_DETN, frame = A, tics = cvDDDelay.value*TICRATE, action = A_FaceTarget, nextstate = S_SEESTATE } states[S_GREEN_DEMON_SEE] = { sprite = SPR_DETN, frame = A, tics = 5, action = A_PlaySeeSound, nextstate = S_GREEN_DEMON_ACTIVATE } states[S_GREEN_DEMON_ACTIVATE] = { sprite = SPR_DETN, frame = A, tics = 0, action = A_SetObjectFlags, var1 = MF_PAIN, var2 = 2, nextstate = S_GREEN_DEMON_FOLLOW1 } states[S_GREEN_DEMON_FOLLOW1] = {SPR_DETN,A,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW2} states[S_GREEN_DEMON_FOLLOW2] = {SPR_DETN,B,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW3} states[S_GREEN_DEMON_FOLLOW3] = {SPR_DETN,C,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW4} states[S_GREEN_DEMON_FOLLOW4] = {SPR_DETN,D,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW5} states[S_GREEN_DEMON_FOLLOW5] = {SPR_DETN,E,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW6} states[S_GREEN_DEMON_FOLLOW6] = {SPR_DETN,F,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW7} states[S_GREEN_DEMON_FOLLOW7] = {SPR_DETN,G,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW8} states[S_GREEN_DEMON_FOLLOW8] = {SPR_DETN,H,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW9} states[S_GREEN_DEMON_FOLLOW9] = {SPR_DETN,G,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW10} states[S_GREEN_DEMON_FOLLOW10] = {SPR_DETN,F,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW11} states[S_GREEN_DEMON_FOLLOW11] = {SPR_DETN,E,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW12} states[S_GREEN_DEMON_FOLLOW12] = {SPR_DETN,D,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW13} states[S_GREEN_DEMON_FOLLOW13] = {SPR_DETN,C,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW14} states[S_GREEN_DEMON_FOLLOW14] = {SPR_DETN,B,1,A_DemonChase,0,0,S_GREEN_DEMON_FOLLOW1} mobjinfo[MT_GREEN_DEMON] = { spawnstate = S_GREEN_DEMON_WAIT, seestate = S_GREEN_DEMON_SEE, seesound = sfx_s3k86, attacksound = sfx_deton, deathstate = S_XPLD_FLICKY, deathsound = sfx_pop, radius = 20*FRACUNIT, height = 32*FRACUNIT, mass = DMG_INSTAKILL, flags = MF_NOCLIP | MF_NOCLIPHEIGHT | MF_NOGRAVITY } addHook("PlayerSpawn",function(player) if IsValid(player.mo) and player.exiting == 0 and (player.pflags & PF_FINISHED) == 0 then local obj = P_SpawnMobj(player.mo.x,player.mo.y,player.mo.z+100*FRACUNIT,MT_GREEN_DEMON) if multiplayer == true then obj.color = player.skincolor else obj.color = SKINCOLOR_GREEN end obj.colorized = true obj.target = player.mo player.mo.greenDemon = obj end end) addHook("PlayerQuit",function(player) if IsValid(player.mo) then if IsValid(player.mo.greenDemon) then P_KillMobj(player.mo.greenDemon) player.mo.greenDemon = nil end end end) addHook("MobjDeath",function(target,inflictor,source,damagetype) if IsValid(target.greenDemon) then P_KillMobj(target.greenDemon) target.greenDemon = nil end end,MT_PLAYER) addHook("ShouldDamage",function(target,inflictor) if IsValid(inflictor) and IsValid(target) then if inflictor.type == MT_GREEN_DEMON then if inflictor.target ~= target and cvDDDamageOthers.value == 0 then return false end end end end,MT_PLAYER) -- j2b2's Deton Demon Challenge mod