diff --git a/src/g_heretic/a_hereticmisc.cpp b/src/g_heretic/a_hereticmisc.cpp index 17cd4df09..64de3ef84 100644 --- a/src/g_heretic/a_hereticmisc.cpp +++ b/src/g_heretic/a_hereticmisc.cpp @@ -25,191 +25,3 @@ #include "a_hereticweaps.cpp" #include "a_ironlich.cpp" - -static FRandom pr_podpain ("PodPain"); -static FRandom pr_makepod ("MakePod"); -static FRandom pr_teleg ("TeleGlitter"); -static FRandom pr_teleg2 ("TeleGlitter2"); -static FRandom pr_volcano ("VolcanoSet"); -static FRandom pr_blast ("VolcanoBlast"); -static FRandom pr_volcimpact ("VolcBallImpact"); - -//---------------------------------------------------------------------------- -// -// PROC A_PodPain -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_PodPain) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_CLASS_DEF (gootype, AActor) - - int count; - int chance; - AActor *goo; - - chance = pr_podpain (); - if (chance < 128) - { - return 0; - } - for (count = chance > 240 ? 2 : 1; count; count--) - { - goo = Spawn(gootype, self->PosPlusZ(48.), ALLOW_REPLACE); - goo->target = self; - goo->Vel.X = pr_podpain.Random2() / 128.; - goo->Vel.Y = pr_podpain.Random2() / 128.; - goo->Vel.Z = 0.5 + pr_podpain() / 128.; - } - return 0; -} - -//---------------------------------------------------------------------------- -// -// PROC A_RemovePod -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_RemovePod) -{ - PARAM_SELF_PROLOGUE(AActor); - - AActor *mo; - - if ( (mo = self->master) ) - { - if (mo->special1 > 0) - { - mo->special1--; - } - } - return 0; -} - -//---------------------------------------------------------------------------- -// -// PROC A_MakePod -// -//---------------------------------------------------------------------------- - -#define MAX_GEN_PODS 16 - -DEFINE_ACTION_FUNCTION(AActor, A_MakePod) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_CLASS_DEF(podtype, AActor) - - AActor *mo; - - if (self->special1 == MAX_GEN_PODS) - { // Too many generated pods - return 0; - } - mo = Spawn(podtype, self->PosAtZ(ONFLOORZ), ALLOW_REPLACE); - if (!P_CheckPosition (mo, mo->Pos())) - { // Didn't fit - mo->Destroy (); - return 0; - } - mo->SetState (mo->FindState("Grow")); - mo->Thrust(pr_makepod() * (360. / 256), 4.5); - S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE); - self->special1++; // Increment generated pod count - mo->master = self; // Link the generator to the pod - return 0; -} - -//---------------------------------------------------------------------------- -// -// PROC A_AccTeleGlitter -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter) -{ - PARAM_SELF_PROLOGUE(AActor); - - if (++self->health > 35) - { - self->Vel.Z *= 1.5; - } - return 0; -} - - -//---------------------------------------------------------------------------- -// -// PROC A_VolcanoSet -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_VolcanoSet) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->tics = 105 + (pr_volcano() & 127); - return 0; -} - -//---------------------------------------------------------------------------- -// -// PROC A_VolcanoBlast -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast) -{ - PARAM_SELF_PROLOGUE(AActor); - - int i; - int count; - AActor *blast; - - count = 1 + (pr_blast() % 3); - for (i = 0; i < count; i++) - { - blast = Spawn("VolcanoBlast", self->PosPlusZ(44.), ALLOW_REPLACE); - blast->target = self; - blast->Angles.Yaw = pr_blast() * (360 / 256.); - blast->VelFromAngle(1.); - blast->Vel.Z = 2.5 + pr_blast() / 64.; - S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM); - P_CheckMissileSpawn (blast, self->radius); - } - return 0; -} - -//---------------------------------------------------------------------------- -// -// PROC A_VolcBallImpact -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact) -{ - PARAM_SELF_PROLOGUE(AActor); - - unsigned int i; - AActor *tiny; - - if (self->Z() <= self->floorz) - { - self->flags |= MF_NOGRAVITY; - self->Gravity = 1; - self->AddZ(28); - //self->Vel.Z = 3; - } - P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, RADF_HURTSOURCE); - for (i = 0; i < 4; i++) - { - tiny = Spawn("VolcanoTBlast", self->Pos(), ALLOW_REPLACE); - tiny->target = self; - tiny->Angles.Yaw = 90.*i; - tiny->VelFromAngle(0.7); - tiny->Vel.Z = 1. + pr_volcimpact() / 128.; - P_CheckMissileSpawn (tiny, self->radius); - } - return 0; -} - diff --git a/src/p_map.cpp b/src/p_map.cpp index 3f0edc8d7..26dc3d473 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1738,6 +1738,15 @@ bool P_CheckPosition(AActor *thing, const DVector2 &pos, bool actorsonly) return P_CheckPosition(thing, pos, tm, actorsonly); } +DEFINE_ACTION_FUNCTION(AActor, CheckPosition) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_BOOL_DEF(actorsonly); + ACTION_RETURN_BOOL(P_CheckPosition(self, DVector2(x, y), actorsonly)); +} + //---------------------------------------------------------------------------- // // FUNC P_TestMobjLocation diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 59b4c43e9..c998bcf91 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6022,6 +6022,13 @@ bool P_CheckMissileSpawn (AActor* th, double maxdist) return true; } +DEFINE_ACTION_FUNCTION(AActor, CheckMissileSpawn) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_FLOAT(add); + ACTION_RETURN_BOOL(P_CheckMissileSpawn(self, add)); +} + //--------------------------------------------------------------------------- // diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 043ab3ed4..137fedbec 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -1,7 +1,10 @@ class Actor : Thinker native { const DEFAULT_HEALTH = 1000; - + const ONFLOORZ = -2147483648.0; + const ONCEILINGZ = 2147483647.0; + const FLOATRANDZ = ONCEILINGZ-1; + Default { Scale 1; @@ -76,6 +79,8 @@ class Actor : Thinker native native Actor GetPointer(int aaptr); native void FaceMovementDirection(); native Actor AimTarget(); + native bool CheckMissileSpawn(double maxdist); + native bool CheckPosition(Vector2 pos, bool actorsonly = false); native static Actor Spawn(class type, vector3 pos = (0,0,0), int replace = NO_REPLACE); native Actor SpawnMissile(Actor dest, class type, Actor owner = null); native Actor SpawnMissileZ (double z, Actor dest, class type); diff --git a/wadsrc/static/zscript/heretic/hereticmisc.txt b/wadsrc/static/zscript/heretic/hereticmisc.txt index f858a6fa2..4cb094d06 100644 --- a/wadsrc/static/zscript/heretic/hereticmisc.txt +++ b/wadsrc/static/zscript/heretic/hereticmisc.txt @@ -16,9 +16,7 @@ class Pod : Actor DeathSound "world/podexplode"; PushFactor 0.5; } - native void A_PodPain (class podtype = "PodGoo"); - native void A_RemovePod (); - + States { Spawn: @@ -37,6 +35,44 @@ class Pod : Actor PPOD IJKLMNOP 3; Goto Spawn; } + + //---------------------------------------------------------------------------- + // + // PROC A_PodPain + // + //---------------------------------------------------------------------------- + + void A_PodPain (class gootype = "PodGoo") + { + int chance = Random[PodPain](); + if (chance < 128) + { + return; + } + for (int count = chance > 240 ? 2 : 1; count; count--) + { + Actor goo = Spawn(gootype, pos + (0, 0, 48), ALLOW_REPLACE); + goo.target = self; + goo.Vel.X = Random2[PodPain]() / 128.; + goo.Vel.Y = Random2[PodPain]() / 128.; + goo.Vel.Z = 0.5 + random[PodPain]() / 128.; + } + } + + //---------------------------------------------------------------------------- + // + // PROC A_RemovePod + // + //---------------------------------------------------------------------------- + + void A_RemovePod () + { + if (master && master.special1 > 0) + { + master.special1--; + } + } + } @@ -75,7 +111,6 @@ class PodGenerator : Actor AttackSound "world/podgrow"; } - native void A_MakePod (class podtype = "Pod"); States { @@ -83,6 +118,34 @@ class PodGenerator : Actor TNT1 A 35 A_MakePod; Loop; } + + //---------------------------------------------------------------------------- + // + // PROC A_MakePod + // + //---------------------------------------------------------------------------- + + const MAX_GEN_PODS = 16; + + void A_MakePod (class podtype = "Pod") + { + if (special1 >= MAX_GEN_PODS) + { // Too many generated pods + return; + } + Actor mo = Spawn(podtype, (pos.xy, ONFLOORZ), ALLOW_REPLACE); + if (!mo) return; + if (!mo.CheckPosition (mo.Pos.xy)) + { // Didn't fit + mo.Destroy (); + return; + } + mo.SetStateLabel("Grow"); + mo.Thrust(4.5, random[MakePod]() * (360. / 256)); + A_PlaySound (AttackSound, CHAN_BODY); + special1++; // Increment generated pod count + mo.master = self; // Link the generator to the pod + } } @@ -136,7 +199,6 @@ class TeleGlitter1 : Actor Damage 0; } - native void A_AccTeleGlitter (); States { @@ -148,6 +210,20 @@ class TeleGlitter1 : Actor TGLT E 2 BRIGHT; Loop; } + + //---------------------------------------------------------------------------- + // + // PROC A_AccTeleGlitter + // + //---------------------------------------------------------------------------- + + void A_AccTeleGlitter () + { + if (++health > 35) + { + Vel.Z *= 1.5; + } + } } // Teleglitter 2 ------------------------------------------------------------ @@ -178,9 +254,6 @@ class Volcano : Actor +SOLID } - native void A_VolcanoSet (); - native void A_VolcanoBlast (); - States { Spawn: @@ -190,7 +263,38 @@ class Volcano : Actor VLCO E 10 A_VolcanoBlast; Goto Spawn+1; } + + //---------------------------------------------------------------------------- + // + // PROC A_VolcanoSet + // + //---------------------------------------------------------------------------- + void A_VolcanoSet () + { + tics = 105 + (random[VolcanoSet]() & 127); + } + + //---------------------------------------------------------------------------- + // + // PROC A_VolcanoBlast + // + //---------------------------------------------------------------------------- + + void A_VolcanoBlast () + { + int count = random[VolcanoBlast](1,3); + for (int i = 0; i < count; i++) + { + Actor blast = Spawn("VolcanoBlast", pos + (0, 0, 44), ALLOW_REPLACE); + blast.target = self; + blast.Angle = random[VolcanoBlast]() * (360 / 256.); + blast.VelFromAngle(1.); + blast.Vel.Z = 2.5 + random[VolcanoBlast]() / 64.; + blast.A_PlaySound ("world/volcano/shoot", CHAN_BODY); + blast.CheckMissileSpawn (radius); + } + } } // Volcano blast ------------------------------------------------------------ @@ -210,8 +314,6 @@ class VolcanoBlast : Actor DeathSound "world/volcano/blast"; } - native void A_VolcBallImpact (); - States { Spawn: @@ -224,6 +326,35 @@ class VolcanoBlast : Actor XPL1 BCDEF 4 BRIGHT; Stop; } + + //---------------------------------------------------------------------------- + // + // PROC A_VolcBallImpact + // + //---------------------------------------------------------------------------- + + void A_VolcBallImpact () + { + if (pos.Z <= floorz) + { + bNoGravity = true; + Gravity = 1; + AddZ(28); + } + A_Explode(25, 25, XF_NOSPLASH|XF_HURTSOURCE, false, 0, 0, 0, "BulletPuff", 'Fire'); + for (int i = 0; i < 4; i++) + { + Actor tiny = Spawn("VolcanoTBlast", Pos, ALLOW_REPLACE); + if (tiny) + { + tiny.target = self; + tiny.Angle = 90.*i; + tiny.VelFromAngle(0.7); + tiny.Vel.Z = 1. + random[VolcBallImpact]() / 128.; + tiny.CheckMissileSpawn (radius); + } + } + } } // Volcano T Blast ---------------------------------------------------------- @@ -252,4 +383,3 @@ class VolcanoTBlast : Actor } } -