- scriptified the pipe bomb and RR's dynamite, which is mostly the same thing.

The mortars were split off because they made the code too convoluted.
This commit is contained in:
Christoph Oelckers 2022-12-01 10:19:37 +01:00
parent b9caa23357
commit 0bc9023e17
18 changed files with 326 additions and 223 deletions

View file

@ -1178,18 +1178,6 @@ static void heavyhbomb(DDukeActor *actor)
int l;
double xx;
if ((actor->spr.cstat & CSTAT_SPRITE_INVISIBLE))
{
actor->temp_data[2]--;
if (actor->temp_data[2] <= 0)
{
S_PlayActorSound(TELEPORTER, actor);
spawn(actor, TRANSPORTERSTAR);
actor->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
}
return;
}
int p = findplayer(actor, &xx);
if (xx < 1220 / 16.) actor->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
@ -1278,16 +1266,7 @@ static void heavyhbomb(DDukeActor *actor)
DETONATEB:
bool bBoom = false;
if ((l >= 0 && ps[l].hbomb_on == 0) || actor->temp_data[3] == 1)
bBoom = true;
if (isNamWW2GI() && actor->spr.picnum == HEAVYHBOMB)
{
actor->spr.extra--;
if (actor->spr.extra <= 0)
bBoom = true;
}
if (bBoom)
if (actor->temp_data[3] == 1)
{
actor->temp_data[4]++;
@ -1297,7 +1276,6 @@ DETONATEB:
int m = 0;
switch (actor->spr.picnum)
{
case HEAVYHBOMB: m = gs.pipebombblastradius; break;
case MORTER: m = gs.morterblastradius; break;
case BOUNCEMINE: m = gs.bouncemineblastradius; break;
}
@ -1318,61 +1296,10 @@ DETONATEB:
if (actor->temp_data[4] > 20)
{
if (Owner != actor || ud.respawn_items == 0)
{
actor->Destroy();
return;
}
else
{
actor->temp_data[2] = gs.respawnitemtime;
spawn(actor, PClass::FindActor("DukeRespawnMarker"));
actor->spr.cstat = CSTAT_SPRITE_INVISIBLE;
actor->spr.scale.Y = (0.140625);
return;
}
actor->Destroy();
return;
}
}
else if (actor->spr.picnum == HEAVYHBOMB && xx < 788 / 16. && actor->temp_data[0] > 7 && actor->vel.X == 0)
if (cansee(actor->spr.pos.plusZ(-8), actor->sector(), ps[p].GetActor()->getPosWithOffsetZ(), ps[p].cursector))
if (ps[p].ammo_amount[HANDBOMB_WEAPON] < gs.max_ammo_amount[HANDBOMB_WEAPON])
{
if (ud.coop >= 1 && Owner == actor)
{
for (int j = 0; j < ps[p].weapreccnt; j++)
if (ps[p].weaprecs[j] == actor->spr.picnum)
continue;
if (ps[p].weapreccnt < 255) // DukeGDX has 16 here.
ps[p].weaprecs[ps[p].weapreccnt++] = actor->spr.picnum;
}
addammo(HANDBOMB_WEAPON, &ps[p], 1);
S_PlayActorSound(DUKE_GET, ps[p].GetActor());
if (ps[p].gotweapon[HANDBOMB_WEAPON] == 0 || Owner == ps[p].GetActor())
fi.addweapon(&ps[p], HANDBOMB_WEAPON, true);
if (!Owner || !Owner->isPlayer())
{
SetPlayerPal(&ps[p], PalEntry(32, 0, 32, 0));
}
if (Owner != actor || ud.respawn_items == 0)
{
if (Owner == actor && ud.coop >= 1)
return;
actor->Destroy();
return;
}
else
{
actor->temp_data[2] = gs.respawnitemtime;
spawn(actor, PClass::FindActor("DukeRespawnMarker"));
actor->spr.cstat = CSTAT_SPRITE_INVISIBLE;
}
}
if (actor->temp_data[0] < 8) actor->temp_data[0]++;
}
@ -1417,13 +1344,9 @@ void moveactors_d(void)
case BOUNCEMINE:
case MORTER:
spawn(act, FRAMEEFFECT1)->temp_data[0] = 3;
[[fallthrough]];
case HEAVYHBOMB:
heavyhbomb(act);
continue;
}
if (monsterCheatCheck(act) && badguy(act))
{
continue;

View file

@ -1275,22 +1275,6 @@ static void heavyhbomb(DDukeActor *actor)
int p = findplayer(actor, &xx);
if (xx < 1220 / 16.) actor->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
else actor->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
if (actor->temp_data[3] == 0)
{
int j = fi.ifhitbyweapon(actor);
if (j >= 0)
{
actor->temp_data[3] = 1;
actor->temp_data[4] = 0;
l = 0;
actor->vel.X = 0;
goto DETONATEB;
}
}
makeitfall(actor);
if (sectp->lotag != 1 && (!isRRRA() || sectp->lotag != ST_160_FLOOR_TELEPORT) && actor->spr.pos.Z >= actor->floorz - FOURSLEIGHT_F && actor->spr.yint < 3)
@ -1387,22 +1371,14 @@ static void heavyhbomb(DDukeActor *actor)
DETONATEB:
if ((l >= 0 && ps[l].hbomb_on == 0) || actor->temp_data[3] == 1)
if (actor->temp_data[3] == 1)
{
actor->temp_data[4]++;
if (actor->temp_data[4] == 2)
{
int x = actor->spr.extra;
int m = 0;
switch (actor->spr.picnum)
{
case POWDERKEG: m = gs.tripbombblastradius; break; // powder keg
case DYNAMITE: m = gs.pipebombblastradius; break;
case HBOMBAMMO: m = gs.pipebombblastradius; break;
case MORTER: m = gs.morterblastradius; break;
case CHEERBOMB: m = gs.morterblastradius; break;
}
int m = gs.morterblastradius;
if (actor->sector()->lotag != 800)
{
@ -1434,48 +1410,6 @@ DETONATEB:
return;
}
}
else if (actor->spr.picnum == DYNAMITE && xx < 788 / 16. && actor->temp_data[0] > 7 && actor->vel.X == 0)
if (cansee(actor->spr.pos.plusZ(-8), actor->sector(), ps[p].GetActor()->getPosWithOffsetZ(), ps[p].cursector))
if (ps[p].ammo_amount[DYNAMITE_WEAPON] < gs.max_ammo_amount[DYNAMITE_WEAPON])
if (actor->spr.pal == 0)
{
if (ud.coop >= 1)
{
for (int j = 0; j < ps[p].weapreccnt; j++)
if (ps[p].weaprecs[j] == actor->spr.picnum)
return;
if (ps[p].weapreccnt < 255)
ps[p].weaprecs[ps[p].weapreccnt++] = actor->spr.picnum;
}
addammo(DYNAMITE_WEAPON, &ps[p], 1);
addammo(CROSSBOW_WEAPON, &ps[p], 1);
S_PlayActorSound(DUKE_GET, ps[p].GetActor());
if (ps[p].gotweapon[DYNAMITE_WEAPON] == 0 || Owner == ps[p].GetActor())
fi.addweapon(&ps[p], DYNAMITE_WEAPON, true);
if (!Owner || !Owner->isPlayer())
{
SetPlayerPal(&ps[p], PalEntry(32, 0, 32, 0));
}
if (Owner && (Owner->attackertype != DYNAMITE || ud.respawn_items == 0 || Owner->isPlayer()))
{
if (actor->spr.picnum == DYNAMITE && !Owner->isPlayer() && ud.coop)
return;
actor->Destroy();
return;
}
else
{
actor->temp_data[2] = gs.respawnitemtime;
spawn(actor, PClass::FindActor("RedneckRespawnMarker"));
actor->spr.cstat = CSTAT_SPRITE_INVISIBLE;
}
}
if (actor->temp_data[0] < 8) actor->temp_data[0]++;
}
@ -1661,7 +1595,6 @@ void moveactors_r(void)
if (!isRRRA()) break;
[[fallthrough]];
case MORTER:
case DYNAMITE:
heavyhbomb(act);
continue;
}

View file

@ -177,7 +177,6 @@ void spawntransporter(DDukeActor* actj, DDukeActor* acti, bool beam);
int spawnbloodpoolpart1(DDukeActor* acti);
void initfootprint(DDukeActor* actj, DDukeActor* acti);
void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell);
int initreactor(DDukeActor* actj, DDukeActor* acti, bool isrecon);
void spawneffector(DDukeActor* actor, TArray<DDukeActor*>* actors);
int startrts(int lumpNum, int localPlayer);

View file

@ -1345,6 +1345,31 @@ void DoActor(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor,
return;
}
//---------------------------------------------------------------------------
//
// what a lousy hack job... :(
//
//---------------------------------------------------------------------------
int CheckWeapRec(player_struct* p, DDukeActor* g_ac, int testonly)
{
int j;
for (j = 0; j < p->weapreccnt; j++)
if (p->weaprecs[j] == g_ac->spr.picnum)
break;
if (testonly)
{
return (j < p->weapreccnt && g_ac->GetOwner() == g_ac);
}
else if (p->weapreccnt < 32)
{
p->weaprecs[p->weapreccnt++] = g_ac->spr.picnum;
return (g_ac->GetOwner() == g_ac);
}
return false;
}
//---------------------------------------------------------------------------
//
//
@ -1665,19 +1690,7 @@ int ParseState::parse(void)
if (ud.coop >= 1 && ud.multimode > 1)
{
if (*insptr == 0)
{
for (j = 0; j < ps[g_p].weapreccnt; j++)
if (ps[g_p].weaprecs[j] == g_ac->spr.picnum)
break;
parseifelse(j < ps[g_p].weapreccnt&& g_ac->GetOwner() == g_ac);
}
else if (ps[g_p].weapreccnt < 16)
{
ps[g_p].weaprecs[ps[g_p].weapreccnt++] = g_ac->spr.picnum;
parseifelse(g_ac->GetOwner() == g_ac);
}
parseifelse(CheckWeapRec(&ps[g_p], g_ac, !*insptr));
}
else parseifelse(0);
break;

View file

@ -1390,6 +1390,9 @@ x(BOULDER, 256)
x(BOULDER1, 264)
x(TORNADO, 1930)
x(CHEERBOMB, 3464)
x(CHEERBOMB1, 3465)
x(CHEERBOMB2, 3466)
x(CHEERBOMB3, 3467)
x(CHEERBLADE, 3460)
x(CHEERBLADE2, 3461)
x(CHEERBLADE3, 3462)

View file

@ -2185,7 +2185,7 @@ static void operateweapon(int snum, ESyncBits actions)
}
auto spawned = CreateActor(p->cursector, p->GetActor()->getPosWithOffsetZ() + p->GetActor()->spr.Angles.Yaw.ToVector() * 16, HEAVYHBOMB, -16, DVector2(0.140625, 0.140625),
p->GetActor()->spr.Angles.Yaw, vel + p->hbomb_hold_delay * 2, zvel, pact, 1);
p->GetActor()->spr.Angles.Yaw, vel + p->hbomb_hold_delay * 2, zvel, pact, STAT_ACTOR);
if (isNam())
{

View file

@ -865,10 +865,6 @@ void shoot_r(DDukeActor* actor, int atwith, PClass* cls)
if (isRRRA()) goto rrra_rpg2;
else break;
case FREEZEBLAST:
spos.Z += 3;
[[fallthrough]];
case RPG:
case SAWBLADE:
rrra_rpg2:

View file

@ -485,31 +485,6 @@ void initshell(DDukeActor* actj, DDukeActor* act, bool isshell)
//
//---------------------------------------------------------------------------
int initreactor(DDukeActor* actj, DDukeActor* actor, bool isrecon)
{
actor->spr.extra = gs.impact_damage;
actor->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; // Make it hitable
if (ud.multimode < 2 && actor->spr.pal != 0)
{
actor->spr.scale = DVector2(0, 0);
ChangeActorStat(actor, STAT_MISC);
return false;
}
actor->spr.pal = 0;
actor->spr.shade = -17;
ChangeActorStat(actor, 2);
return false;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void spawneffector(DDukeActor* actor, TArray<DDukeActor*>* actors)
{
auto sectp = actor->sector();

View file

@ -621,15 +621,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
break;
case HEAVYHBOMB:
if (actj) act->SetOwner(actj);
else act->SetOwner(act);
act->spr.scale = DVector2(0.140625, 0.140625);
act->spr.yint = 4;
if (initreactor(actj, act, false)) return act;
break;
case FLAMETHROWERSPRITE:
case FLAMETHROWERAMMO: // Twentieth Anniversary World Tour
if (!isWorldTour())
@ -724,15 +715,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
ChangeActorStat(act, STAT_STANDABLE);
break;
case BOUNCEMINE:
act->SetOwner(act);
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; //Make it hitable
act->spr.scale = DVector2(0.375, 0.375);
act->spr.shade = -127;
act->spr.extra = gs.impact_damage << 2;
ChangeActorStat(act, STAT_ZOMBIEACTOR);
break;
case CAMERAPOLE:
act->spr.extra = 1;

View file

@ -659,13 +659,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
break;
case DYNAMITE:
act->SetOwner(act);
act->spr.scale = DVector2(0.140625, 0.140625);
act->spr.yint = 4;
if (initreactor(actj, act, false)) return act;
break;
case RPG2SPRITE:
case MOTOAMMO:
case BOATAMMO:

View file

@ -240,7 +240,7 @@ struct player_struct
short extra_extra8, quick_kick, last_quick_kick;
short heat_amount, timebeforeexit, customexitsound;
short weaprecs[256], weapreccnt;
short weaprecs[32], weapreccnt;
unsigned int interface_toggle_flag;
short dead_flag, show_empty_weapon;

View file

@ -23,7 +23,6 @@ int PicForName(int intname)
{"RedneckRabbit","RABBIT"},
{"RedneckFeather","FEATHER"},
{"DukeBatteryAmmo", "BATTERYAMMO"},
{"RedneckDynamite", "DYNAMITE"},
{"DukeSixpak", "SIXPAK"},
{"DukeAtomicHealth", "ATOMICHEALTH"},
{"DukeShrinkerExplosion", "SHRINKEREXPLOSION" },
@ -800,8 +799,6 @@ DEFINE_FIELD_X(DukePlayer, player_struct, last_quick_kick)
DEFINE_FIELD_X(DukePlayer, player_struct, heat_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, timebeforeexit)
DEFINE_FIELD_X(DukePlayer, player_struct, customexitsound)
DEFINE_FIELD_X(DukePlayer, player_struct, weaprecs)
DEFINE_FIELD_X(DukePlayer, player_struct, weapreccnt)
DEFINE_FIELD_X(DukePlayer, player_struct, interface_toggle_flag)
DEFINE_FIELD_X(DukePlayer, player_struct, dead_flag)
DEFINE_FIELD_X(DukePlayer, player_struct, show_empty_weapon)
@ -1045,6 +1042,45 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, quickkill, quickkill)
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, CheckWeapRec, CheckWeapRec)
{
PARAM_SELF_STRUCT_PROLOGUE(player_struct);
PARAM_POINTER(ac, DDukeActor);
PARAM_BOOL(test);
ACTION_RETURN_INT(CheckWeapRec(self, ac, test));
}
void DukePlayer_addammo(player_struct* p, int ammo, int amount)
{
if ((unsigned)ammo >= MAX_WEAPONS) ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Ammo number out of range");
addammo(ammo, p, amount);
}
DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, addammo, DukePlayer_addammo)
{
PARAM_SELF_STRUCT_PROLOGUE(player_struct);
PARAM_INT(type);
PARAM_INT(amount);
DukePlayer_addammo(self, type, amount);
return 0;
}
void DukePlayer_addweapon(player_struct* p, int wpn, int switchit)
{
if ((unsigned)wpn >= MAX_WEAPONS) ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Weapon number out of range");
fi.addweapon(p, wpn, switchit);
}
DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, addweapon, DukePlayer_addweapon)
{
PARAM_SELF_STRUCT_PROLOGUE(player_struct);
PARAM_INT(type);
PARAM_INT(switchit);
DukePlayer_addweapon(self, type, switchit);
return 0;
}
static DDukeActor* duke_firstStat(DukeStatIterator* it, int statnum)
{
it->Reset(statnum);
@ -1290,6 +1326,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, LocateTheLocator, LocateTheLocator)
}
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, max_ammo_amount);
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, playerfriction);
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, gravity);
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, respawnactortime);

View file

@ -76,6 +76,7 @@ spawnclasses
4359 = DukeTarget
1346 = DukeHelicopter
2491 = DukeCar
26 = DukePipeBomb
1272 = DukeTrash
634 = DukeBolt1

View file

@ -74,6 +74,7 @@ spawnclasses
1280 = DukeBottle10
1172 = DukeVase
26 = RedneckDynamite
285 = RedneckChickenSpawner1
286 = RedneckChickenSpawner2
287 = RedneckFeatherSpawner

View file

@ -88,6 +88,7 @@ version "4.10"
#include "zscript/games/duke/actors/ducktarget.zs"
#include "zscript/games/duke/actors/helicopt.zs"
#include "zscript/games/duke/actors/greenslime.zs"
#include "zscript/games/duke/actors/heavyhbomb.zs"
#include "zscript/games/duke/actors/redneckmisc.zs"
#include "zscript/games/duke/actors/rabbitspawner.zs"

View file

@ -0,0 +1,239 @@
class DukePipeBomb : DukeActor
{
default
{
pic "HEAVYHBOMB";
detail 3; // ceiling distance
// do not add anything here!
}
override void Initialize()
{
// This is only for placed items, not for armed weapons!
if (self.ownerActor == self)
{
self.extra = gs.impact_damage;
self.cstat |= CSTAT_SPRITE_BLOCK_ALL; // Make it hitable
if (ud.multimode < 2 && self.pal != 0)
{
self.scale = (0, 0);
self.ChangeStat(STAT_MISC);
return;
}
self.ChangeStat(STAT_ZOMBIEACTOR);
self.yint = 4;
self.pal = 0;
self.shade = -17;
self.Scale = (0.140625, 0.140625);
}
}
override void Tick()
{
if (self.statnum != STAT_ACTOR) return;
let Owner = self.ownerActor;
let sectp = self.sector;
DukePlayer p;
double xx;
if ((self.cstat & CSTAT_SPRITE_INVISIBLE))
{
self.temp_data[2]--;
if (self.temp_data[2] <= 0)
{
self.PlayActorSound("TELEPORTER");
self.spawn("DukeTransporterStar");
self.cstat = CSTAT_SPRITE_BLOCK_ALL;
}
return;
}
[p, xx] = self.findplayer();
if (xx < 1220 / 16.) self.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
else self.cstat |= CSTAT_SPRITE_BLOCK_ALL;
if (self.temp_data[3] == 0)
{
int j = self.ifhitbyweapon();
if (j >= 0)
{
self.temp_data[4] = 0;
self.vel.X = 0;
self.DetonateIt();
return;
}
}
self.makeitfall();
// Feature check later needs to be map controlled, not game controlled.
if (sectp.lotag != ST_1_ABOVE_WATER && (!Raze.isRRRA() || sectp.lotag != ST_160_FLOOR_TELEPORT) && self.pos.Z >= self.floorz - 1 && self.yint < 3)
{
if (self.yint > 0 || (self.yint == 0 && self.floorz == sectp.floorz))
{
self.PlayActorSound("PIPEBOMB_BOUNCE");
}
self.vel.Z = -(4 - self.yint);
if (sectp.lotag == 2)
self.vel.Z *= 0.25;
self.yint++;
}
if (self.pos.Z < self.ceilingz + 16 && (!Raze.isRR() || sectp.lotag != ST_2_UNDERWATER)) // underwater check only for RR
{
self.pos.Z = self.ceilingz + self.detail;
self.vel.Z = 0;
}
CollisionData coll;
self.movesprite_ex((self.angle.ToVector() * self.vel.X, self.vel.Z), CLIPMASK0, coll);
if (sectp.lotag == ST_1_ABOVE_WATER && self.vel.Z == 0)
{
self.pos.Z += 32;
if (self.temp_data[5] == 0)
{
self.temp_data[5] = 1;
self.spawn("DukeWaterSplash2");
}
}
else self.temp_data[5] = 0;
if(self.vel.X > 0)
{
self.vel.X -= 5. / 16;
if (sectp.lotag == ST_2_UNDERWATER)
self.vel.X -= 10. / 16;
if(self.vel.X < 0)
self.vel.X = 0;
if (int(self.vel.X * 16) & 8) self.cstat ^= CSTAT_SPRITE_XFLIP;
}
if (coll.type == kHitWall)
{
let wal = coll.hitWall();
dlevel.checkhitwall(wal, self, self.pos);
let k = wal.delta().Angle();
self.angle = k * 2 - self.angle;
self.vel.X *= 0.5;
}
bool bBoom = false;
if (Owner && Owner.isPlayer())
{
if (Raze.isNamWW2GI())
{
self.extra--;
if (self.extra <= 0)
bBoom = true;
}
else bBoom = Owner.GetPlayer().hbomb_on == 0;
}
if (bBoom) self.DetonateIt();
else self.pickupCheck(p);
if (self.temp_data[0] < 8) self.temp_data[0]++;
}
void DetonateIt()
{
self.temp_data[4]++;
if (self.temp_data[4] == 2)
{
int x = self.extra;
int m = gs.pipebombblastradius;
if (self.sector.lotag != 800 || !Raze.isRR()) // this line is RR only
{
self.hitradius(m, x >> 2, x >> 1, x - (x >> 2), x);
self.spawn("DukeExplosion2");
if (self.vel.Z == 0 && !Raze.isRR()) self.spawn("DukeExplosion2Bot"); // this line is Duke only
self.PlayActorSound("PIPEBOMB_EXPLODE");
for (x = 0; x < 8; x++)
self.RANDOMSCRAP();
}
}
if (self.scale.Y)
{
self.scale.Y = 0;
return;
}
if (self.temp_data[4] > 20)
{
self.Destroy();
}
}
protected bool doPickupCheck(DukePlayer p, int weapon1, int weapon2)
{
let xx = (p.actor.pos - self.pos).Sum();
let Owner = self.ownerActor;
// Duke
if (xx < 788 / 16. && self.temp_data[0] > 7 && self.vel.X == 0)
if (Raze.cansee(self.pos.plusZ(-8), self.sector, p.actor.pos.plusZ(p.actor.viewzoffset), p.cursector))
if (p.ammo_amount[weapon1] < gs.max_ammo_amount[weapon1])
{
if (ud.coop >= 1 && Owner == self)
{
p.CheckWeapRec(self, false);
}
p.addammo(weapon1, 1);
if (weapon2 >= 0) p.addammo(weapon2, 1);
p.actor.PlayActorSound("PLAYER_GET");
if (p.gotweapon[weapon1] == 0 || Owner == p.actor)
p.addweapon(weapon1, true);
if (!Owner || !Owner.isPlayer())
{
p.pals = Color(32, 0, 32, 0);
}
if (Owner != self || ud.respawn_items == 0)
{
if (Owner == self && ud.coop >= 1)
return false;
self.Destroy();
return false;
}
else
{
self.temp_data[2] = gs.respawnitemtime;
self.cstat = CSTAT_SPRITE_INVISIBLE;
return true;
}
}
return false;
}
virtual void pickupCheck(DukePlayer p)
{
if (doPickupCheck(p, DukeWpn.HANDBOMB_WEAPON, -1))
self.spawn("DukeRespawnMarker");
}
}
class RedneckDynamite : DukePipeBomb
{
default
{
pic "DYNAMITE";
detail 16;
}
override void pickupCheck(DukePlayer p)
{
if (doPickupCheck(p, RRWpn.DYNAMITE_WEAPON, RRWpn.CROSSBOW_WEAPON))
self.spawn("RedneckRespawnMarker");
}
}

View file

@ -76,6 +76,10 @@ enum ESectorTriggers
ST_41_JAILDOOR = 41,
ST_42_MINECART = 42,
ST_160_FLOOR_TELEPORT = 160,
ST_161_CEILING_TELEPORT = 161,
// left: ST 32767, 65534, 65535
};

View file

@ -258,7 +258,6 @@ struct DukePlayer native
native DukeActor actor, actorsqu, wackedbyactor, on_crane, somethingonplayer, access_spritenum, dummyplayersprite, newOwner, holoduke_on;
native sectortype cursector;
native int16 weaprecs[256], weapreccnt;
native uint interface_toggle_flag;
native int16 dead_flag, show_empty_weapon; // JBF 20031220: added orotscrnang
@ -352,6 +351,9 @@ struct DukePlayer native
native void addPitch(double p);
native void centerView();
native int playerinput(int bit);
native int CheckWeapRec(DukeActor item, bool checkonly);
native void addammo(int type, int amount);
native void addweapon(int type, bool switchit);
}
@ -414,6 +416,7 @@ struct DukeGameInfo native
// Static constant global state
readonly native double playerfriction;
readonly native double gravity;
readonly native int16 max_ammo_amount[RRWpn.MAX_WEAPONS];
readonly native int respawnactortime;
readonly native int bouncemineblastradius;