- chickenplant scriptified.

This commit is contained in:
Christoph Oelckers 2022-11-21 08:15:41 +01:00
parent 397acfa242
commit 76fabcd1c7
18 changed files with 559 additions and 286 deletions

View file

@ -432,7 +432,7 @@ int movesprite_ex_r(DDukeActor* actor, const DVector3& change, unsigned int clip
void lotsoffeathers_r(DDukeActor *actor, int n)
{
lotsofstuff(actor, n, MONEY);
lotsofstuff(actor, n, FEATHER);
}
@ -715,7 +715,7 @@ static void chickenarrow(DDukeActor* actor)
if (spawned) spawned->spr.pos.Z += 1;
if ((krand() & 15) == 2)
{
spawn(actor, MONEY);
spawn(actor, FEATHER);
}
}
DDukeActor* ts = actor->seek_actor;
@ -1917,91 +1917,9 @@ void rr_specialstats()
}
}
if (chickenplant)
if (ud.chickenplant)
{
it.Reset(STAT_CHICKENPLANT);
while (auto act = it.Next())
{
switch (act->spr.picnum)
{
case CHICKENASPAWN:
act->spr.lotag--;
if (act->spr.lotag < 0)
{
spawn(act, CHICKENA)->spr.angle = act->spr.angle;
act->spr.lotag = 128;
}
break;
case CHICKENCSPAWN:
act->spr.lotag--;
if (act->spr.lotag < 0)
{
spawn(act, CHICKENC)->spr.angle = act->spr.angle;
act->spr.lotag = 256;
}
break;
case FEATHERSPAWN:
act->spr.lotag--;
if (act->spr.lotag < 0)
{
lotsoffeathers_r(act, (krand() & 3) + 4);
act->spr.lotag = 84;
}
break;
case CHICKENHEADSPAWN:
act->spr.lotag--;
if (act->spr.lotag < 0)
{
auto j = spawn(act, CHICKENHEAD);
act->spr.lotag = 96;
if (j && !isRRRA()) S_PlayActorSound(472, j);
}
break;
case LOAFSPAWN:
act->spr.lotag--;
if (act->spr.lotag < 0)
{
spawn(act, CHICKENLOAF)->spr.angle = act->spr.angle;
act->spr.lotag = 448;
}
break;
case NUGGETSPAWN:
act->spr.lotag--;
if (act->spr.lotag < 0)
{
spawn(act, CHICKENNUGGET)->spr.angle = act->spr.angle;
act->spr.lotag = 64;
}
break;
case ROASTSPAWN:
act->spr.lotag--;
if (act->spr.lotag < 0)
{
spawn(act, ROASTEDCHICKEN)->spr.angle = act->spr.angle;
act->spr.lotag = 512;
}
break;
case BONELESSSPAWN:
act->spr.lotag--;
if (act->spr.lotag < 0)
{
spawn(act, BONELESSCHICKEN)->spr.angle = act->spr.angle;
act->spr.lotag = 224;
}
break;
case JIBSSPAWN:
act->spr.lotag--;
if (act->spr.lotag < 0)
{
fi.guts(act, JIBS1, 1, myconnectindex);
fi.guts(act, JIBS2, 1, myconnectindex);
fi.guts(act, JIBS3, 1, myconnectindex);
fi.guts(act, JIBS4, 1, myconnectindex);
act->spr.lotag = 256;
}
break;
}
}
tickstat(STAT_CHICKENPLANT);
}
it.Reset(STAT_BOWLING);
@ -2425,94 +2343,6 @@ void moveactors_r(void)
case RAT:
if (!rat(act, !isRRRA())) continue;
break;
case CHICKENA:
case CHICKENB:
case CHICKENC:
if (!chickenplant)
{
act->Destroy();
continue;
}
if (sectp->lotag == 903)
makeitfall(act);
movesprite_ex(act, DVector3(act->spr.angle.ToVector() * act->vel.X, act->vel.Z), CLIPMASK0, coll);
switch (sectp->lotag)
{
case 901:
act->spr.picnum = CHICKENB;
break;
case 902:
act->spr.picnum = CHICKENC;
break;
case 903:
if (act->spr.pos.Z >= sectp->floorz - 8)
{
act->Destroy();
continue;
}
break;
case 904:
act->Destroy();
continue;
break;
}
if (coll.type > kHitSector)
{
act->Destroy();
continue;
}
break;
case CHICKENLOAF:
case CHICKENNUGGET:
case ROASTEDCHICKEN:
case BONELESSCHICKEN:
if (!chickenplant)
{
act->Destroy();
continue;
}
makeitfall(act);
movesprite_ex(act, DVector3(act->spr.angle.ToVector() * act->vel.X, act->vel.Z), CLIPMASK0, coll);
if (coll.type > kHitSector)
{
act->Destroy();
continue;
}
if (sectp->lotag == 903)
{
if (act->spr.pos.Z >= sectp->floorz - 4)
{
act->Destroy();
continue;
}
}
else if (sectp->lotag == 904)
{
act->Destroy();
continue;
}
break;
case CHICKENHEAD:
if (!chickenplant)
{
act->Destroy();
continue;
}
makeitfall(act);
movesprite_ex(act, DVector3(act->spr.angle.ToVector() * act->vel.X, act->vel.Z), CLIPMASK0, coll);
if (act->spr.pos.Z >= sectp->floorz - 8)
{
if (sectp->lotag == 1)
{
auto j = spawn(act, WATERSPLASH2);
if (j) j->spr.pos.Z = j->sector()->floorz;
}
act->Destroy();
continue;
}
break;
case BOWLINGBALL:
if (act->vel.X != 0)
{

View file

@ -201,8 +201,8 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
case FOOTPRINTS4:
if (t->pal == 6)
t->shade = -127;
case MONEY:
case MONEY + 1:
case FEATHER:
case FEATHER + 1:
break;
case POWDERKEG:
continue;

View file

@ -75,8 +75,8 @@ void initactorflags_r()
TECHSWITCH + 1,
DIPSWITCH3,
DIPSWITCH3 + 1,
NUKEBUTTON,
NUKEBUTTON + 1 });
CHICKENPLANTBUTTON,
CHICKENPLANTBUTTON + 1 });
if (isRRRA()) settileflag(TFLAG_WALLSWITCH, {
MULTISWITCH2,
MULTISWITCH2 + 1,

View file

@ -60,7 +60,6 @@ int earthquaketime;
int global_random; // readonly - one single global per-frame random value. Ugh...
// Redneck Rampage
int chickenplant; // readonly - used to trigger some special behavior if a special item is found in a map.
int thunderon; // readonly - enables thunder effect in RR if true.
int ufospawn; // UFO spawn flag
int ufocnt; // UFO spawn count

View file

@ -68,7 +68,7 @@ x(LIGHTSWITCH, 86)
x(SPACEDOORSWITCH, 88)
x(SPACELIGHTSWITCH, 90)
x(FRANKENSTINESWITCH, 92)
x(NUKEBUTTON, 94)
x(CHICKENPLANTBUTTON, 94)
x(MULTISWITCH, 98)
x(DOORTILE1, 102)
x(DOORTILE2, 103)
@ -171,8 +171,8 @@ x(ROASTSPAWN, 291)
x(BONELESSSPAWN, 292)
x(JIBSSPAWN, 293)
x(KEGHOLDER, 295) // that's what the text on the sprite says. It doesn't seem to do anything.
y(RRTELEPORT, 296)
y(RRTELEPORTDEST, 297)
x(RRTELEPORT, 296)
x(RRTELEPORTDEST, 297)
x(CDPLAYER, 370)
y(RRTILE380, 380)
x(BONUSPIC01, 403)
@ -406,7 +406,6 @@ x(NUKEBARREL, 1304)
x(NUKEBARRELDENTED, 1305)
x(NUKEBARRELLEAKED, 1306)
x(CANWITHSOMETHING, 1309)
x(MONEY, 1310)
x(FEATHER, 1310)
x(BANNER, 1313)
x(EXPLODINGBARREL, 1315)
@ -884,7 +883,6 @@ y(RRTILE3115, 3115)
y(RRTILE3116, 3116)
y(RRTILE3117, 3117)
x(CHICKENLOAF, 3120)
y(RRTILE3121, 3121)
x(CHICKENNUGGET, 3122)
x(ROASTEDCHICKEN, 3123)
x(BONELESSCHICKEN, 3124)

View file

@ -660,7 +660,7 @@ void prelevel_common(int g)
geocnt = 0;
ambienttags.Clear();
thunderon = 0;
chickenplant = 0;
ud.chickenplant = 0;
WindTime = 0;
WindDir = nullAngle;
fakebubba_spawn = 0;

View file

@ -534,6 +534,10 @@ void prelevel_r(int g, TArray<DDukeActor*>& actors)
{
ps[0].Exit = ac->spr.pos.XY();
}
else if (ac->spr.picnum == CHICKENPLANTBUTTON)
{
ud.chickenplant = 1;
}
else
{
premapcontroller(ac);
@ -624,8 +628,8 @@ void prelevel_r(int g, TArray<DDukeActor*>& actors)
case POWERSWITCH1 + 1:
case LOCKSWITCH1 + 1:
case POWERSWITCH2 + 1:
case NUKEBUTTON:
case NUKEBUTTON + 1:
case CHICKENPLANTBUTTON:
case CHICKENPLANTBUTTON + 1:
for (j = 0; j < lotaglist; j++)
if (ac->spr.lotag == lotags[j])

View file

@ -380,6 +380,7 @@ void GameInterface::SerializeGameState(FSerializer& arc)
("numplayersprites", numplayersprites)
("spriteqloc", spriteqloc)
("animates", animates)
("chickenplant", ud.chickenplant)
("numclouds", numclouds)
("cloudx", cloudx)
@ -393,7 +394,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
.Array("mirrorsector", mirrorsector, mirrorcnt)
.Array("mirrorwall", mirrorwall, mirrorcnt)
("wupass", wupass)
("chickenplant", chickenplant)
("thunderon", thunderon)
("ufospawn", ufospawn)
("ufocnt", ufocnt)

View file

@ -437,8 +437,8 @@ bool checkhitswitch_r(int snum, walltype* wwal, DDukeActor* act)
case LOCKSWITCH1 + 1:
case POWERSWITCH2:
case POWERSWITCH2 + 1:
case NUKEBUTTON:
case NUKEBUTTON + 1:
case CHICKENPLANTBUTTON:
case CHICKENPLANTBUTTON + 1:
case RRTILE2214:
case RRTILE2697:
case RRTILE2697 + 1:
@ -510,7 +510,7 @@ bool checkhitswitch_r(int snum, walltype* wwal, DDukeActor* act)
case PULLSWITCH:
case DIPSWITCH2:
case DIPSWITCH3:
case NUKEBUTTON:
case CHICKENPLANTBUTTON:
case RRTILE2697:
case RRTILE2707:
if (other->spr.picnum == DIPSWITCH3)
@ -532,8 +532,8 @@ bool checkhitswitch_r(int snum, walltype* wwal, DDukeActor* act)
other->spr.picnum++;
break;
}
if (other->spr.picnum == NUKEBUTTON)
chickenplant = 0;
if (other->spr.picnum == CHICKENPLANTBUTTON)
ud.chickenplant = 0;
if (other->spr.picnum == RRTILE8660)
{
BellTime = 132;
@ -554,11 +554,11 @@ bool checkhitswitch_r(int snum, walltype* wwal, DDukeActor* act)
case FRANKENSTINESWITCH + 1:
case DIPSWITCH2 + 1:
case DIPSWITCH3 + 1:
case NUKEBUTTON + 1:
case CHICKENPLANTBUTTON + 1:
case RRTILE2697 + 1:
case RRTILE2707 + 1:
if (other->spr.picnum == NUKEBUTTON + 1)
chickenplant = 1;
if (other->spr.picnum == CHICKENPLANTBUTTON + 1)
ud.chickenplant = 1;
if (other->spr.hitag != 999)
other->spr.picnum--;
break;

View file

@ -145,22 +145,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
act->spr.extra = 0;
ChangeActorStat(act, 122);
break;
case CHICKENASPAWN:
case CHICKENCSPAWN:
case FEATHERSPAWN:
case CHICKENHEADSPAWN:
case LOAFSPAWN:
case NUGGETSPAWN:
case ROASTSPAWN:
case BONELESSSPAWN:
case JIBSSPAWN:
act->spr.cstat = 0;
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
act->spr.scale = DVector2(0, 0);
act->clipdist = 0;
act->spr.lotag = 0;
ChangeActorStat(act, STAT_CHICKENPLANT);
break;
case RRTILE2460:
case RRTILE2465:
@ -461,50 +445,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
act->clipdist = 16;
ChangeActorStat(act, STAT_TELEPORT);
break;
case CHICKENA:
case CHICKENB:
case CHICKENC:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.5, 0.40625);
act->vel.X = 2;
ChangeActorStat(act, STAT_ACTOR);
break;
case CHICKENLOAF:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.1875, 0.15625);
act->vel.X = 2;
ChangeActorStat(act, STAT_ACTOR);
break;
case CHICKENNUGGET:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 0.5;
act->spr.scale = DVector2(0.125, 0.09375);
act->vel.X = 1;
ChangeActorStat(act, STAT_ACTOR);
break;
case ROASTEDCHICKEN:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.203125, 0.203125);
act->vel.X = 1;
ChangeActorStat(act, STAT_ACTOR);
break;
case BONELESSCHICKEN:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.265625, 0.1875);
act->vel.X = 2;
ChangeActorStat(act, STAT_ACTOR);
break;
case CHICKENHEAD:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.203125, 0.15625);
act->vel.X = 0;
ChangeActorStat(act, STAT_ACTOR);
break;
case BOWLINGPIN:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 12;
@ -548,8 +488,8 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
act->spr.cstat = CSTAT_SPRITE_ALIGNMENT_WALL | randomFlip();
insertspriteq(act);
[[fallthrough]];
case MONEY:
if (act->spr.picnum == MONEY)
case FEATHER:
if (act->spr.picnum == FEATHER)
{
act->temp_data[0] = krand() & 2047;
act->spr.cstat = randomFlip();

View file

@ -161,6 +161,7 @@ struct user_defs
int m_respawn_items, m_respawn_monsters, m_respawn_inventory, m_recstat, m_monsters_off;
int m_ffire, ffire, m_player_skill, multimode;
int player_skill, marker;
int chickenplant; // readonly - used to trigger some special behavior if a special item is found in a map.
TObjPtr<DDukeActor*> cameraactor;

View file

@ -1,5 +1,58 @@
BEGIN_DUKE_NS
// Workaround so that the script code can be written in its final form. This must go away later.
int PicForName(int intname)
{
int picnum = -1;
// this is still a hack so it can spawn actors which haven't been scriptified yet. This will go away later.
if (FName(ENamedName(intname)) == FName("DukeToiletWater"))
{
picnum = TileFiles.tileForName("TOILETWATER");
}
else if (FName(ENamedName(intname)) == FName("DukeBurning"))
{
picnum = TileFiles.tileForName("BURNIMG");
}
else if (FName(ENamedName(intname)) == FName("DukeBloodPool"))
{
picnum = TileFiles.tileForName("BLOODPOOL");
}
else if (FName(ENamedName(intname)) == FName("DukeExplosion2"))
{
picnum = TileFiles.tileForName("EXPLOSION2");
}
else if (FName(ENamedName(intname)) == FName("DukeTransporterStar"))
{
picnum = TileFiles.tileForName("TRANSPORTERSTAR");
}
else if (FName(ENamedName(intname)) == FName("RedneckRabbit"))
{
picnum = TileFiles.tileForName("RABBIT");
}
else if (FName(ENamedName(intname)) == FName("DukeJibs1"))
{
picnum = TileFiles.tileForName("JIBS1");
}
else if (FName(ENamedName(intname)) == FName("DukeJibs2"))
{
picnum = TileFiles.tileForName("JIBS2");
}
else if (FName(ENamedName(intname)) == FName("DukeJibs3"))
{
picnum = TileFiles.tileForName("JIBS3");
}
else if (FName(ENamedName(intname)) == FName("DukeJibs4"))
{
picnum = TileFiles.tileForName("JIBS4");
}
else if (FName(ENamedName(intname)) == FName("RedneckFeather"))
{
picnum = TileFiles.tileForName("FEATHER");
}
return picnum;
}
//---------------------------------------------------------------------------
//
// global exports
@ -249,33 +302,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, StopSound, DukeActor_StopSound)
DDukeActor* DukeActor_Spawn(DDukeActor* origin, int intname)
{
int picnum = -1;
// this is still a hack so it can spawn actors which haven't been scriptified yet. This will go away later.
if (FName(ENamedName(intname)) == FName("DukeToiletWater"))
{
picnum = TileFiles.tileForName("TOILETWATER");
}
else if (FName(ENamedName(intname)) == FName("DukeBurning"))
{
picnum = TileFiles.tileForName("BURNIMG");
}
else if (FName(ENamedName(intname)) == FName("DukeBloodPool"))
{
picnum = TileFiles.tileForName("BLOODPOOL");
}
else if (FName(ENamedName(intname)) == FName("DukeExplosion2"))
{
picnum = TileFiles.tileForName("EXPLOSION2");
}
else if (FName(ENamedName(intname)) == FName("DukeTransporterStar"))
{
picnum = TileFiles.tileForName("TRANSPORTERSTAR");
}
else if (FName(ENamedName(intname)) == FName("RedneckRabbit"))
{
picnum = TileFiles.tileForName("RABBIT");
}
int picnum = PicForName(intname);
if (picnum == -1)
{
@ -296,6 +323,53 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, spawn, DukeActor_Spawn)
ACTION_RETURN_POINTER(DukeActor_Spawn(self, type));
}
void DukeActor_Lotsofstuff(DDukeActor* actor, int count, int intname)
{
int picnum = PicForName(intname);
// Todo: make this class aware.
lotsofstuff(actor, count, picnum);
}
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, lotsofstuff, DukeActor_Lotsofstuff)
{
PARAM_SELF_PROLOGUE(DDukeActor);
PARAM_INT(type);
PARAM_INT(count);
DukeActor_Lotsofstuff(self, count, type);
return 0;
}
void DukeActor_spawnguts(DDukeActor* actor, int count, int intname)
{
int picnum = PicForName(intname);
fi.guts(actor, picnum, count, myconnectindex);
}
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, spawnguts, DukeActor_spawnguts)
{
PARAM_SELF_PROLOGUE(DDukeActor);
PARAM_INT(type);
PARAM_INT(count);
DukeActor_spawnguts(self, count, type);
return 0;
}
int DukeActor_movesprite(DDukeActor* actor, double velx, double vely, double velz, int clipmask)
{
Collision coll;
return movesprite_ex(actor, DVector3(velx, vely, velz), clipmask, coll);
}
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, movesprite, DukeActor_movesprite)
{
PARAM_SELF_PROLOGUE(DDukeActor);
PARAM_FLOAT(velx);
PARAM_FLOAT(vely);
PARAM_FLOAT(velz);
PARAM_INT(clipmask);
ACTION_RETURN_INT(DukeActor_movesprite(self, velx, vely, velz, clipmask));
}
DDukeActor* DukeActor_Spawnsprite(DDukeActor* origin, int picnum)
{
if (picnum >= 0 && picnum < MAXTILES)
@ -980,6 +1054,7 @@ DEFINE_FIELD_X(DukeUserDefs, user_defs, player_skill);
DEFINE_FIELD_X(DukeUserDefs, user_defs, marker);
DEFINE_FIELD_X(DukeUserDefs, user_defs, bomb_tag);
DEFINE_FIELD_X(DukeUserDefs, user_defs, cameraactor);
DEFINE_FIELD_X(DukeUserDefs, user_defs, chickenplant);
DEFINE_GLOBAL_UNSIZED(ud)

View file

@ -47,5 +47,24 @@ spawnclasses
1439 = DukeInnerJaw
1440 = DukeInnerJaw1
285 = RedneckChickenSpawner1
286 = RedneckChickenSpawner2
287 = RedneckFeatherSpawner
288 = RedneckChickenHeadSpawner
289 = RedneckChickenLoafSpawner
290 = RedneckChickenNuggetSpawner
291 = RedneckChickenRoastSpawner
292 = RedneckBonelessSpawner
293 = RedneckJibsSpawner
7525 = RedneckRabbitSpawner
3190 = RedneckChickenA
3191 = RedneckChickenB
3192 = RedneckChickenC
3120 = RedneckChickenLoaf
3122 = RedneckChickenNugget
3123 = RedneckRoastedChicken
3124 = RedneckBonelessChicken
3132 = RedneckChickenHead
}

View file

@ -74,6 +74,7 @@ version "4.10"
#include "zscript/games/duke/actors/tongue.zs"
#include "zscript/games/duke/actors/rabbitspawner.zs"
#include "zscript/games/duke/actors/chickenplant.zs"
#include "zscript/games/blood/bloodgame.zs"
#include "zscript/games/blood/ui/menu.zs"

View file

@ -5,6 +5,15 @@ enum EClipMask
CLIPMASK1 = (256 << 16) + 64
};
enum EHitBits
{
kHitNone = 0,
kHitSector = 0x4000,
kHitWall = 0x8000,
kHitSprite = 0xC000,
kHitVoid = 0x10000, // SW only
};
const MAXPLAYERS = 8;
const MAXSTATUS = 1024;
const zmaptoworld = (1. / 256.);

View file

@ -0,0 +1,391 @@
class RedneckChickenSpawner1 : DukeActor
{
default
{
scaleX 0;
scaleY 0;
clipdist 0;
lotag 0;
statnum STAT_CHICKENPLANT;
pic "CHICKENASPAWN";
}
override void Initialize()
{
self.cstat = CSTAT_SPRITE_INVISIBLE;
}
override void Tick()
{
self.lotag--;
if (self.lotag < 0)
{
let spawned = self.spawn('RedneckChickenA');
if (spawned) spawned.angle = self.angle;
self.lotag = 128;
}
}
}
class RedneckChickenSpawner2 : RedneckChickenSpawner1
{
default
{
pic "CHICKENCSPAWN";
}
override void Tick()
{
self.lotag--;
if (self.lotag < 0)
{
let spawned = self.spawn('RedneckChickenC');
if (spawned) spawned.angle = self.angle;
self.lotag = 256;
}
}
}
class RedneckFeatherSpawner : RedneckChickenSpawner1
{
default
{
pic "FEATHERSPAWN";
}
override void Tick()
{
self.lotag--;
if (self.lotag < 0)
{
self.lotsofstuff('RedneckFeather', random(4, 7));
self.lotag = 84;
}
}
}
class RedneckChickenHeadSpawner : RedneckChickenSpawner1
{
default
{
pic "CHICKENHEADSPAWN";
}
override void Tick()
{
self.lotag--;
if (self.lotag < 0)
{
let spawned = self.spawn('RedneckChickenHead');
self.lotag = 96;
if (spawned && !Raze.isRRRA()) self.PlayActorSound(RRSnd.POOLBUD);
}
}
}
class RedneckChickenLoafSpawner : RedneckChickenSpawner1
{
default
{
pic "LOAFSPAWN";
}
override void Tick()
{
self.lotag--;
if (self.lotag < 0)
{
let spawned = self.spawn('RedneckChickenLoaf');
if (spawned) spawned.angle = self.angle;
self.lotag = 448;
}
}
}
class RedneckChickenNuggetSpawner : RedneckChickenSpawner1
{
default
{
pic "NUGGETSPAWN";
}
override void Tick()
{
self.lotag--;
if (self.lotag < 0)
{
let spawned = self.spawn('RedneckChickenNugget');
if (spawned) spawned.angle = self.angle;
self.lotag = 64;
}
}
}
class RedneckChickenRoastSpawner : RedneckChickenSpawner1
{
default
{
pic "ROASTSPAWN";
}
override void Tick()
{
self.lotag--;
if (self.lotag < 0)
{
let spawned = self.spawn('RedneckChickenRoast');
if (spawned) spawned.angle = self.angle;
self.lotag = 512;
}
}
}
class RedneckBonelessSpawner : RedneckChickenSpawner1
{
default
{
pic "BONELESSSPAWN";
}
override void Tick()
{
self.lotag--;
if (self.lotag < 0)
{
let spawned = self.spawn('RedneckBonelessChicken');
if (spawned) spawned.angle = self.angle;
self.lotag = 224;
}
}
}
class RedneckJibsSpawner : RedneckChickenSpawner1
{
default
{
pic "JIBSSPAWN";
}
override void Tick()
{
self.lotag--;
if (self.lotag < 0)
{
self.spawnguts('DukeJibs1', 1);
self.spawnguts('DukeJibs2', 1);
self.spawnguts('DukeJibs3', 1);
self.spawnguts('DukeJibs4', 1);
self.lotag = 256;
}
}
}
//----------------------------------
class RedneckChickenA : DukeActor
{
default
{
clipdist 2;
scaleX 0.5;
scaleY 0.40625;
statnum STAT_ACTOR;
spriteset "CHICKENA", "CHICKENB", "CHICKENC";
}
override void Initialize()
{
self.cstat = CSTAT_SPRITE_BLOCK_ALL;
self.vel.X = 2;
}
override void Tick()
{
if (!ud.chickenplant)
{
self.Destroy();
return;
}
let sectp = self.sector;
if (sectp.lotag == 903)
self.makeitfall();
int collision = self.movesprite((self.angle.ToVector() * self.vel.X, self.vel.Z), CLIPMASK0);
switch (sectp.lotag)
{
case 901:
self.SetSpritesetImage(1);
break;
case 902:
self.SetSpritesetImage(2);
break;
case 903:
if (self.pos.Z >= sectp.floorz - 8)
{
self.Destroy();
return;
}
break;
case 904:
self.Destroy();
break;
}
if (collision > kHitSector)
{
self.Destroy();
}
}
}
class RedneckChickenB : RedneckChickenA
{
default
{
spritesetindex 1;
}
}
class RedneckChickenC : RedneckChickenA
{
default
{
spritesetindex 2;
}
}
//----------------------------------
class RedneckChickenLoaf : DukeActor
{
default
{
statnum STAT_ACTOR;
clipdist 2;
scaleX 0.1875;
scaleY 0.15625;
pic "CHICKENLOAF";
}
override void Initialize()
{
self.cstat = CSTAT_SPRITE_BLOCK_ALL;
self.vel.X = 2;
}
override void Tick()
{
if (!ud.chickenplant)
{
self.Destroy();
return;
}
self.makeitfall();
let collision = self.movesprite((self.angle.ToVector() * self.vel.X, self.vel.Z), CLIPMASK0);
if (collision > kHitSector)
{
self.Destroy();
return;
}
let sectp = self.sector;
if (sectp.lotag == 903)
{
if (self.pos.Z >= sectp.floorz - 4)
{
self.Destroy();
return;
}
}
else if (sectp.lotag == 904)
{
self.Destroy();
return;
}
}
}
class RedneckRoastedChicken : RedneckChickenLoaf
{
default
{
scaleX 0.203125;
scaleY 0.203125;
clipdist 2;
pic "ROASTEDCHICKEN";
}
override void Initialize()
{
self.vel.X = 1;
}
}
class RedneckChickenNugget : RedneckChickenLoaf
{
default
{
scaleX 0.125;
scaleY 0.09375;
clipdist 0.5;
pic "CHICKENNUGGET";
}
override void Initialize()
{
self.vel.X = 1;
}
}
class RedneckBonelessChicken : RedneckChickenLoaf
{
default
{
scaleX 0.265625;
scaleY 0.1875;
clipdist 2;
pic "BONELESSCHICKEN";
}
override void Initialize()
{
self.vel.X = 2;
}
}
class RedneckChickenHead : DukeActor
{
default
{
statnum STAT_ACTOR;
scaleX 0.203125;
scaleY 0.15625;
clipdist 2;
pic "CHICKENHEAD";
}
override void Initialize()
{
self.vel.X = 0;
}
override void Tick()
{
if (!ud.chickenplant)
{
self.Destroy();
return;
}
self.makeitfall();
self.movesprite((self.angle.ToVector() * self.vel.X, self.vel.Z), CLIPMASK0);
if (self.pos.Z >= self.sector.floorz - 8)
{
if (self.sector.lotag == 1)
{
let j = self.spawn('DukeWaterSplash2');
if (j) j.pos.Z = j.sector.floorz;
}
self.Destroy();
}
}
}

View file

@ -102,6 +102,9 @@ class DukeActor : CoreActor native
STAT_DESTRUCT = 100,
STAT_BOWLING = 105,
STAT_CHICKENPLANT = 106,
STAT_LUMBERMILL = 107,
STAT_TELEPORT = 108,
STAT_RABBITSPAWN = 119,
STAT_REMOVED = MAXSTATUS-2,
@ -185,6 +188,9 @@ class DukeActor : CoreActor native
native void ChangeStat(int s, bool forcetail = false);
native int badguy();
native int isplayer();
native void lotsofstuff(Name type, int count);
native void spawnguts(Name type, int count);
native int movesprite(Vector3 move, int clipmask);
// temporary flag accessors - need to be eliminated once we can have true actor flags

View file

@ -1307,7 +1307,7 @@ struct DukeUserDefs native
native readonly int coop;
native readonly int respawn_monsters, respawn_items, respawn_inventory, recstat, monsters_off, brightness;
native readonly int ffire, multimode;
native readonly int player_skill, marker;
native readonly int player_skill, marker, chickenplant;
native int16 bomb_tag;
native DukeActor cameraactor;