mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-19 07:01:09 +00:00
- scriptified RR's bowling stuff.
This commit is contained in:
parent
9ad8f67ce9
commit
5a155730b4
17 changed files with 456 additions and 499 deletions
|
@ -24,6 +24,7 @@ xx(DukeGlassPieces)
|
||||||
xx(DukeGlassPieces1)
|
xx(DukeGlassPieces1)
|
||||||
xx(DukeGlassPieces2)
|
xx(DukeGlassPieces2)
|
||||||
xx(DukeNaturalLightning)
|
xx(DukeNaturalLightning)
|
||||||
|
xx(RedneckBowlingPin)
|
||||||
|
|
||||||
xx(spawnstate)
|
xx(spawnstate)
|
||||||
xx(brokenstate)
|
xx(brokenstate)
|
||||||
|
|
|
@ -465,6 +465,15 @@ DEFINE_ACTION_FUNCTION_NATIVE(_sectortype, getslopes, sector_getslopes)
|
||||||
return min(numret, 2);
|
return min(numret, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_sectortype, nextsectorneighborz, nextsectorneighborzptr)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(sectortype);
|
||||||
|
PARAM_FLOAT(z);
|
||||||
|
PARAM_INT(find);
|
||||||
|
ACTION_RETURN_POINTER(nextsectorneighborzptr(self, z, find));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void wall_setxpan(walltype* wal, double val)
|
void wall_setxpan(walltype* wal, double val)
|
||||||
|
|
|
@ -37,14 +37,6 @@ BEGIN_DUKE_NS
|
||||||
void dojaildoor();
|
void dojaildoor();
|
||||||
void moveminecart();
|
void moveminecart();
|
||||||
|
|
||||||
void ballreturn(DDukeActor* spr);
|
|
||||||
void pinsectorresetdown(sectortype* sect);
|
|
||||||
int pinsectorresetup(sectortype* sect);
|
|
||||||
int checkpins(sectortype* sect);
|
|
||||||
void resetpins(sectortype* sect);
|
|
||||||
void resetlanepics(void);
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -1191,34 +1183,9 @@ void rr_specialstats()
|
||||||
tickstat(STAT_CHICKENPLANT);
|
tickstat(STAT_CHICKENPLANT);
|
||||||
}
|
}
|
||||||
|
|
||||||
DukeStatIterator it(STAT_BOWLING);
|
tickstat(STAT_BOWLING);
|
||||||
while (auto act = it.Next())
|
|
||||||
{
|
|
||||||
if (act->spr.picnum == BOWLINGPINSPOT)
|
|
||||||
if (act->spr.lotag == 100)
|
|
||||||
{
|
|
||||||
auto pst = pinsectorresetup(act->sector());
|
|
||||||
if (pst)
|
|
||||||
{
|
|
||||||
act->spr.lotag = 0;
|
|
||||||
if (act->spr.extra == 1)
|
|
||||||
{
|
|
||||||
pst = checkpins(act->sector());
|
|
||||||
if (!pst)
|
|
||||||
{
|
|
||||||
act->spr.extra = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (act->spr.extra == 2)
|
|
||||||
{
|
|
||||||
act->spr.extra = 0;
|
|
||||||
resetpins(act->sector());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
it.Reset(STAT_TELEPORT);
|
DukeStatIterator it(STAT_TELEPORT);
|
||||||
while (auto act = it.Next())
|
while (auto act = it.Next())
|
||||||
{
|
{
|
||||||
if (act->spr.picnum == RRTELEPORT)
|
if (act->spr.picnum == RRTELEPORT)
|
||||||
|
@ -1254,91 +1221,6 @@ void rr_specialstats()
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
static int henstand(DDukeActor *actor)
|
|
||||||
{
|
|
||||||
if (actor->spr.picnum == HENSTAND || actor->spr.picnum == HENSTAND + 1)
|
|
||||||
{
|
|
||||||
actor->spr.lotag--;
|
|
||||||
if (actor->spr.lotag == 0)
|
|
||||||
{
|
|
||||||
spawn(actor, HEN);
|
|
||||||
actor->spr.scale.Zero();
|
|
||||||
ChangeActorStat(actor, STAT_MISC);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (actor->sector()->lotag == 900)
|
|
||||||
actor->vel.X = 0;
|
|
||||||
if(actor->vel.X != 0)
|
|
||||||
{
|
|
||||||
makeitfall(actor);
|
|
||||||
Collision coll;
|
|
||||||
movesprite_ex(actor, DVector3(actor->spr.Angles.Yaw.ToVector() * actor->vel.X, actor->vel.Z), CLIPMASK0, coll);
|
|
||||||
if (coll.type)
|
|
||||||
{
|
|
||||||
if (coll.type == kHitWall)
|
|
||||||
{
|
|
||||||
DAngle k = coll.hitWall->delta().Angle();
|
|
||||||
actor->spr.Angles.Yaw = k * 2 - actor->spr.Angles.Yaw;
|
|
||||||
}
|
|
||||||
else if (coll.type == kHitSprite)
|
|
||||||
{
|
|
||||||
auto hitact = coll.actor();
|
|
||||||
fi.checkhitsprite(actor, hitact);
|
|
||||||
if (hitact->spr.picnum == HEN)
|
|
||||||
{
|
|
||||||
auto ns = spawn(hitact, HENSTAND);
|
|
||||||
hitact->spr.scale.Zero();
|
|
||||||
ChangeActorStat(hitact, STAT_MISC);
|
|
||||||
if (ns)
|
|
||||||
{
|
|
||||||
ns->vel.X = 2;
|
|
||||||
ns->spr.lotag = 40;
|
|
||||||
ns->spr.Angles.Yaw = actor->spr.Angles.Yaw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
actor->vel.X -= 1/16.;
|
|
||||||
if(actor->vel.X < 0) actor->vel.X = 0;
|
|
||||||
actor->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
|
|
||||||
if (actor->spr.picnum == BOWLINGPIN)
|
|
||||||
{
|
|
||||||
actor->spr.cstat |= CSTAT_SPRITE_XFLIP & ESpriteFlags::FromInt(int(actor->vel.X * 16));
|
|
||||||
actor->spr.cstat |= CSTAT_SPRITE_YFLIP & ESpriteFlags::FromInt(int(actor->vel.X * 16));
|
|
||||||
if (krand() & 1)
|
|
||||||
actor->spr.picnum = BOWLINGPIN + 1;
|
|
||||||
}
|
|
||||||
else if (actor->spr.picnum == HENSTAND)
|
|
||||||
{
|
|
||||||
actor->spr.cstat |= CSTAT_SPRITE_XFLIP & ESpriteFlags::FromInt(int(actor->vel.X * 16));
|
|
||||||
actor->spr.cstat |= CSTAT_SPRITE_YFLIP & ESpriteFlags::FromInt(int(actor->vel.X * 16));
|
|
||||||
if (krand() & 1)
|
|
||||||
actor->spr.picnum = HENSTAND + 1;
|
|
||||||
if (actor->vel.X == 0)
|
|
||||||
return 2;//actor->Destroy(); still needs to run a script but should not do on a deleted object
|
|
||||||
}
|
|
||||||
if (actor->spr.picnum == BOWLINGPIN || (actor->spr.picnum == BOWLINGPIN + 1 && actor->vel.X == 0))
|
|
||||||
{
|
|
||||||
return 2;//actor->Destroy(); still needs to run a script but should not do on a deleted object
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (actor->sector()->lotag == 900)
|
|
||||||
{
|
|
||||||
if (actor->spr.picnum == BOWLINGBALL)
|
|
||||||
ballreturn(actor);
|
|
||||||
actor->Destroy();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void moveactors_r(void)
|
void moveactors_r(void)
|
||||||
{
|
{
|
||||||
double xx;
|
double xx;
|
||||||
|
@ -1374,34 +1256,6 @@ void moveactors_r(void)
|
||||||
}
|
}
|
||||||
else switch(act->spr.picnum)
|
else switch(act->spr.picnum)
|
||||||
{
|
{
|
||||||
case BOWLINGBALL:
|
|
||||||
if (act->vel.X != 0)
|
|
||||||
{
|
|
||||||
if(!S_CheckSoundPlaying(356))
|
|
||||||
S_PlayActorSound(356,act);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spawn(act,BOWLINGBALLSPRITE);
|
|
||||||
act->Destroy();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (act->sector()->lotag == 900)
|
|
||||||
{
|
|
||||||
S_StopSound(356, nullptr);
|
|
||||||
}
|
|
||||||
[[fallthrough]];
|
|
||||||
case BOWLINGPIN:
|
|
||||||
case BOWLINGPIN+1:
|
|
||||||
case HENSTAND:
|
|
||||||
case HENSTAND+1:
|
|
||||||
{
|
|
||||||
int todo = henstand(act);
|
|
||||||
if (todo == 2) deleteafterexecute = true;
|
|
||||||
if (todo == 1) continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EMPTYBIKE:
|
case EMPTYBIKE:
|
||||||
if (!isRRRA()) break;
|
if (!isRRRA()) break;
|
||||||
makeitfall(act);
|
makeitfall(act);
|
||||||
|
@ -2175,7 +2029,7 @@ static int fallspecial(DDukeActor *actor, int playernum)
|
||||||
}
|
}
|
||||||
if (actor->sector()->lotag == 800)
|
if (actor->sector()->lotag == 800)
|
||||||
{
|
{
|
||||||
if (actor->spr.picnum == 40)
|
if (actor->spr.picnum == AMMO)
|
||||||
{
|
{
|
||||||
addspritetodelete();
|
addspritetodelete();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -34,275 +34,29 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
|
||||||
|
|
||||||
BEGIN_DUKE_NS
|
BEGIN_DUKE_NS
|
||||||
|
|
||||||
void ballreturn(DDukeActor *ball)
|
void updatepindisplay(int tag, int pins)
|
||||||
{
|
{
|
||||||
DukeStatIterator it(STAT_BOWLING);
|
static const uint8_t pinx[] = { 64, 56, 72, 48, 64, 80, 40, 56, 72, 88 };
|
||||||
while (auto act = it.Next())
|
static const uint8_t piny[] = { 48, 40, 40, 32, 32, 32, 24, 24, 24, 24 };
|
||||||
|
|
||||||
|
if (tag < 1 || tag > 4) return;
|
||||||
|
tag += BOWLINGLANE1 - 1;
|
||||||
|
if (TileFiles.tileMakeWritable(tag))
|
||||||
{
|
{
|
||||||
if (act->spr.picnum == RRTILE281 && ball->sector() == act->sector())
|
tileCopySection(LANEPICBG, 0, 0, 128, 64, tag, 0, 0);
|
||||||
{
|
for (int i = 0; i < 10; i++) if (pins & (1 << i))
|
||||||
DukeStatIterator it2(STAT_BOWLING);
|
tileCopySection(LANEPICS, 0, 0, 8, 8, tag, pinx[i] - 4, piny[i] - 10);
|
||||||
while (auto act2 = it2.Next())
|
|
||||||
{
|
|
||||||
if (act2->spr.picnum == BOWLINGBALLSPOT && act->spr.hitag == act2->spr.hitag)
|
|
||||||
spawn(act2, BOWLINGBALLSPRITE);
|
|
||||||
if (act2->spr.picnum == BOWLINGPINSPOT && act->spr.hitag == act2->spr.hitag && act2->spr.lotag == 0)
|
|
||||||
{
|
|
||||||
act2->spr.lotag = 100;
|
|
||||||
act2->spr.extra++;
|
|
||||||
pinsectorresetdown(act2->sector());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void pinsectorresetdown(sectortype* sec)
|
|
||||||
{
|
|
||||||
int j = getanimationindex(anim_ceilingz, sec);
|
|
||||||
|
|
||||||
if (j == -1)
|
|
||||||
{
|
|
||||||
setanimation(sec, anim_ceilingz, sec, sec->floorz, 0.25);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int pinsectorresetup(sectortype* sec)
|
|
||||||
{
|
|
||||||
int j = getanimationindex(anim_ceilingz, sec);
|
|
||||||
|
|
||||||
if (j == -1)
|
|
||||||
{
|
|
||||||
double z = nextsectorneighborzptr(sec, sec->ceilingz, Find_CeilingUp | Find_Safe)->ceilingz;
|
|
||||||
setanimation(sec, anim_ceilingz, sec, z, 0.25);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int checkpins(sectortype* sect)
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
bool pins[10] = {};
|
|
||||||
int tag = 0;
|
|
||||||
int pin = 0;
|
|
||||||
|
|
||||||
DukeSectIterator it(sect);
|
|
||||||
while (auto a2 = it.Next())
|
|
||||||
{
|
|
||||||
if (a2->spr.picnum == BOWLINGPIN)
|
|
||||||
{
|
|
||||||
pin++;
|
|
||||||
pins[a2->spr.lotag] = true;
|
|
||||||
}
|
|
||||||
if (a2->spr.picnum == BOWLINGPINSPOT)
|
|
||||||
{
|
|
||||||
tag = a2->spr.hitag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag)
|
|
||||||
{
|
|
||||||
tag += LANEPICS + 1;
|
|
||||||
TileFiles.tileMakeWritable(tag);
|
|
||||||
tileCopySection(LANEPICS + 1, 0, 0, 128, 64, tag, 0, 0);
|
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
if (pins[i])
|
|
||||||
{
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0:
|
|
||||||
x = 64;
|
|
||||||
y = 48;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
x = 56;
|
|
||||||
y = 40;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
x = 72;
|
|
||||||
y = 40;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
x = 48;
|
|
||||||
y = 32;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
x = 64;
|
|
||||||
y = 32;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
x = 80;
|
|
||||||
y = 32;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
x = 40;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
x = 56;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
x = 72;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
x = 88;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tileCopySection(LANEPICS, 0, 0, 8, 8, tag, x - 4, y - 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetpins(sectortype* sect)
|
|
||||||
{
|
|
||||||
int i, tag = 0;
|
|
||||||
int x, y;
|
|
||||||
DukeSectIterator it(sect);
|
|
||||||
while (auto a2 = it.Next())
|
|
||||||
{
|
|
||||||
if (a2->spr.picnum == BOWLINGPIN)
|
|
||||||
a2->Destroy();
|
|
||||||
}
|
|
||||||
it.Reset(sect);
|
|
||||||
while (auto a2 = it.Next())
|
|
||||||
{
|
|
||||||
if (a2->spr.picnum == 283)
|
|
||||||
{
|
|
||||||
auto spawned = spawn(a2, BOWLINGPIN);
|
|
||||||
if (spawned)
|
|
||||||
{
|
|
||||||
spawned->spr.lotag = a2->spr.lotag;
|
|
||||||
spawned->clipdist = 12; // random formula here was bogus and always produced 48.
|
|
||||||
spawned->spr.Angles.Yaw -= DAngle22_5 * 0.125 * (((krand() & 32) - (krand() & 64)) >> 5); // weird formula to preserve number of krand calls.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (a2->spr.picnum == 280)
|
|
||||||
tag = a2->spr.hitag;
|
|
||||||
}
|
|
||||||
if (tag)
|
|
||||||
{
|
|
||||||
tag += LANEPICS + 1;
|
|
||||||
TileFiles.tileMakeWritable(tag);
|
|
||||||
tileCopySection(LANEPICS + 1, 0, 0, 128, 64, tag, 0, 0);
|
|
||||||
for (i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0:
|
|
||||||
x = 64;
|
|
||||||
y = 48;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
x = 56;
|
|
||||||
y = 40;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
x = 72;
|
|
||||||
y = 40;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
x = 48;
|
|
||||||
y = 32;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
x = 64;
|
|
||||||
y = 32;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
x = 80;
|
|
||||||
y = 32;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
x = 40;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
x = 56;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
x = 72;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
x = 88;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tileCopySection(LANEPICS, 0, 0, 8, 8, tag, x - 4, y - 10);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetlanepics(void)
|
void resetlanepics(void)
|
||||||
{
|
{
|
||||||
if (!isRR()) return;
|
if (!isRR()) return;
|
||||||
int x, y;
|
|
||||||
for (int tag = 0; tag < 4; tag++)
|
for (int tag = 0; tag < 4; tag++)
|
||||||
{
|
{
|
||||||
int pic = tag + 1;
|
int pic = tag + 1;
|
||||||
if (pic == 0) continue;
|
if (pic == 0) continue;
|
||||||
pic += LANEPICS + 1;
|
updatepindisplay(pic, 0xffff);
|
||||||
TileFiles.tileMakeWritable(pic);
|
|
||||||
tileCopySection(LANEPICS + 1, 0, 0, 128, 64, pic, 0, 0);
|
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0:
|
|
||||||
x = 64;
|
|
||||||
y = 48;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
x = 56;
|
|
||||||
y = 40;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
x = 72;
|
|
||||||
y = 40;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
x = 48;
|
|
||||||
y = 32;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
x = 64;
|
|
||||||
y = 32;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
x = 80;
|
|
||||||
y = 32;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
x = 40;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
x = 56;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
x = 72;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
x = 88;
|
|
||||||
y = 24;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tileCopySection(LANEPICS, 0, 0, 8, 8, pic, x - 4, y - 10);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,7 @@ void displayweapon_r(int snum, double interpfrac)
|
||||||
if (p->ammo_amount[BOWLING_WEAPON])
|
if (p->ammo_amount[BOWLING_WEAPON])
|
||||||
{
|
{
|
||||||
hud_drawpal(weapon_xoffset + 162 - look_anghalf,
|
hud_drawpal(weapon_xoffset + 162 - look_anghalf,
|
||||||
looking_arc + 214 - gun_pos + (*kb << 3), BOWLINGBALLH, shade, o, pal);
|
looking_arc + 214 - gun_pos + (*kb << 3), BOWLINGBALLHUD, shade, o, pal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -173,10 +173,10 @@ x(WALLLIGHTBUST2, 249)
|
||||||
x(LIGHTSWITCH2, 250)
|
x(LIGHTSWITCH2, 250)
|
||||||
x(LIGHTSWITCH2ON, 251)
|
x(LIGHTSWITCH2ON, 251)
|
||||||
x(UFOBEAM, 252)
|
x(UFOBEAM, 252)
|
||||||
y(BOWLINGPINSPOT, 280)
|
y(BOWLINGPINCTRL, 280)
|
||||||
y(RRTILE281, 281)
|
y(BOWLINGSECTORLINK, 281)
|
||||||
y(BOWLINGBALLSPOT, 282)
|
y(BOWLINGBALLSPOT, 282)
|
||||||
y(RRTILE283, 283)
|
y(BOWLINGPINSPOT, 283)
|
||||||
x(CHICKENASPAWN, 285)
|
x(CHICKENASPAWN, 285)
|
||||||
x(CHICKENCSPAWN, 286)
|
x(CHICKENCSPAWN, 286)
|
||||||
x(FEATHERSPAWN, 287)
|
x(FEATHERSPAWN, 287)
|
||||||
|
@ -664,10 +664,11 @@ y(RRTILE2005, 2005)
|
||||||
x(POPCORN, 2021)
|
x(POPCORN, 2021)
|
||||||
y(RRTILE2022, 2022)
|
y(RRTILE2022, 2022)
|
||||||
x(LANEPICS, 2023)
|
x(LANEPICS, 2023)
|
||||||
y(RRTILE2025, 2025)
|
x(LANEPICBG, 2024)
|
||||||
y(RRTILE2026, 2026)
|
x(BOWLINGLANE1, 2025)
|
||||||
y(RRTILE2027, 2027)
|
x(BOWLINGLANE2, 2026)
|
||||||
y(RRTILE2028, 2028)
|
x(BOWLINGLANE3, 2027)
|
||||||
|
x(BOWLINGLANE4, 2028)
|
||||||
y(RRTILE2034, 2034)
|
y(RRTILE2034, 2034)
|
||||||
y(RRTILE2050, 2050)
|
y(RRTILE2050, 2050)
|
||||||
y(RRTILE2052, 2052)
|
y(RRTILE2052, 2052)
|
||||||
|
@ -1014,11 +1015,12 @@ x(FIRELASER3, 3422)
|
||||||
x(FIRELASER4, 3423)
|
x(FIRELASER4, 3423)
|
||||||
x(FIRELASER5, 3424)
|
x(FIRELASER5, 3424)
|
||||||
x(FIRELASER6, 3425)
|
x(FIRELASER6, 3425)
|
||||||
x(BOWLINGBALLH, 3428)
|
x(BOWLINGBALLHUD, 3428)
|
||||||
x(BOWLINGBALL, 3430)
|
x(BOWLINGBALL, 3430)
|
||||||
x(BOWLINGBALLSPRITE, 3437)
|
x(BOWLINGBALLSPRITE, 3437)
|
||||||
x(POWDERH, 3438)
|
x(POWDERH, 3438)
|
||||||
x(BOWLINGPIN, 3440)
|
x(BOWLINGPIN, 3440)
|
||||||
|
x(BOWLINGPIN1, 3441)
|
||||||
x(DEVISTATOR, 3445)
|
x(DEVISTATOR, 3445)
|
||||||
x(RPGGUN, 3452)
|
x(RPGGUN, 3452)
|
||||||
y(RRTILE3462, 3462)
|
y(RRTILE3462, 3462)
|
||||||
|
@ -1452,6 +1454,7 @@ x(SBDIE, 4820)
|
||||||
x(HEN, 4861)
|
x(HEN, 4861)
|
||||||
x(HENSTAYPUT, 4862)
|
x(HENSTAYPUT, 4862)
|
||||||
x(HENSTAND, 4897)
|
x(HENSTAND, 4897)
|
||||||
|
x(HENSTAND1, 4898)
|
||||||
x(PIG, 4945)
|
x(PIG, 4945)
|
||||||
x(PIGSTAYPUT, 4946)
|
x(PIGSTAYPUT, 4946)
|
||||||
x(PIGEAT, 4983)
|
x(PIGEAT, 4983)
|
||||||
|
|
|
@ -838,17 +838,6 @@ void shoot_r(DDukeActor* actor, int atwith, PClass* cls)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BOWLINGBALL:
|
|
||||||
{
|
|
||||||
auto j = spawn(actor, atwith);
|
|
||||||
if (j)
|
|
||||||
{
|
|
||||||
j->vel.X = 250 / 16.;
|
|
||||||
j->spr.Angles.Yaw = actor->spr.Angles.Yaw;
|
|
||||||
j->spr.pos.Z -= 15;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OWHIP:
|
case OWHIP:
|
||||||
case UWHIP:
|
case UWHIP:
|
||||||
shootwhip(actor, p, spos, sang, atwith);
|
shootwhip(actor, p, spos, sang, atwith);
|
||||||
|
|
|
@ -1448,40 +1448,6 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj)
|
||||||
if (spawned) spawned->spriteextra = Scrap6 + (krand() & 15);
|
if (spawned) spawned->spriteextra = Scrap6 + (krand() & 15);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BOWLINGBALL:
|
|
||||||
proj->vel.X = targ->vel.X * 0.75;
|
|
||||||
if (krand() & 16) proj->spr.Angles.Yaw -= DAngle22_5 / 8;
|
|
||||||
S_PlayActorSound(355, targ);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BOWLINGPIN:
|
|
||||||
case BOWLINGPIN + 1:
|
|
||||||
case HENSTAND:
|
|
||||||
case HENSTAND + 1:
|
|
||||||
if (proj->spr.picnum == BOWLINGPIN || proj->spr.picnum == BOWLINGPIN + 1)
|
|
||||||
{
|
|
||||||
proj->vel.X *= 0.75;
|
|
||||||
proj->spr.Angles.Yaw -= targ->spr.Angles.Yaw * 2 + randomAngle(11.25);
|
|
||||||
targ->spr.Angles.Yaw += randomAngle(22.5 / 8);
|
|
||||||
S_PlayActorSound(355, targ);
|
|
||||||
}
|
|
||||||
else if (proj->spr.picnum == HENSTAND || proj->spr.picnum == HENSTAND + 1)
|
|
||||||
{
|
|
||||||
proj->vel.X *= 0.75;
|
|
||||||
proj->spr.Angles.Yaw -= targ->spr.Angles.Yaw * 2 + randomAngle(22.5 / 8);
|
|
||||||
targ->spr.Angles.Yaw += randomAngle(22.5 / 8);
|
|
||||||
S_PlayActorSound(355, targ);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (krand() & 3)
|
|
||||||
{
|
|
||||||
targ->vel.X = 10.25;
|
|
||||||
targ->spr.Angles.Yaw = proj->spr.Angles.Yaw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FANSPRITE:
|
case FANSPRITE:
|
||||||
targ->spr.picnum = FANSPRITEBROKE;
|
targ->spr.picnum = FANSPRITEBROKE;
|
||||||
targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
|
targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
|
||||||
|
|
|
@ -56,21 +56,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
||||||
default_case:
|
default_case:
|
||||||
spawninitdefault(actj, act);
|
spawninitdefault(actj, act);
|
||||||
break;
|
break;
|
||||||
case BOWLINGPINSPOT:
|
|
||||||
case RRTILE281:
|
|
||||||
case BOWLINGBALLSPOT:
|
|
||||||
case RRTILE283:
|
|
||||||
case RRTILE2025:
|
|
||||||
case RRTILE2026:
|
|
||||||
case RRTILE2027:
|
|
||||||
case RRTILE2028:
|
|
||||||
act->spr.cstat = 0;
|
|
||||||
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
|
|
||||||
act->spr.scale = DVector2(0, 0);
|
|
||||||
act->clipdist = 0;
|
|
||||||
act->spr.extra = 0;
|
|
||||||
ChangeActorStat(act, STAT_BOWLING);
|
|
||||||
break;
|
|
||||||
case RRTILE8450:
|
case RRTILE8450:
|
||||||
if (!isRRRA()) goto default_case;
|
if (!isRRRA()) goto default_case;
|
||||||
act->spr.scale = DVector2(1, 1);
|
act->spr.scale = DVector2(1, 1);
|
||||||
|
@ -172,30 +157,12 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
||||||
act->clipdist = 8;
|
act->clipdist = 8;
|
||||||
ChangeActorStat(act, STAT_ZOMBIEACTOR);
|
ChangeActorStat(act, STAT_ZOMBIEACTOR);
|
||||||
break;
|
break;
|
||||||
case BOWLINGBALL:
|
|
||||||
act->spr.cstat = CSTAT_SPRITE_BLOCK_HITSCAN;
|
|
||||||
act->clipdist = 16;
|
|
||||||
act->spr.scale = DVector2(0.171875, 0.140625);
|
|
||||||
ChangeActorStat(act, STAT_ZOMBIEACTOR);
|
|
||||||
break;
|
|
||||||
case HENSTAND:
|
|
||||||
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
|
|
||||||
act->clipdist = 12;
|
|
||||||
act->spr.scale = DVector2(0.328125, 0.234375);
|
|
||||||
ChangeActorStat(act, STAT_ZOMBIEACTOR);
|
|
||||||
break;
|
|
||||||
case RRTELEPORT:
|
case RRTELEPORT:
|
||||||
case RRTELEPORTDEST:
|
case RRTELEPORTDEST:
|
||||||
act->spr.scale = DVector2(1, 1);
|
act->spr.scale = DVector2(1, 1);
|
||||||
act->clipdist = 16;
|
act->clipdist = 16;
|
||||||
ChangeActorStat(act, STAT_TELEPORT);
|
ChangeActorStat(act, STAT_TELEPORT);
|
||||||
break;
|
break;
|
||||||
case BOWLINGPIN:
|
|
||||||
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
|
|
||||||
act->clipdist = 12;
|
|
||||||
act->spr.scale = DVector2(0.359375, 0.359375);
|
|
||||||
ChangeActorStat(act, STAT_ZOMBIEACTOR);
|
|
||||||
break;
|
|
||||||
case DUKELYINGDEAD:
|
case DUKELYINGDEAD:
|
||||||
if (actj && actj->isPlayer())
|
if (actj && actj->isPlayer())
|
||||||
{
|
{
|
||||||
|
@ -420,7 +387,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
||||||
break;
|
break;
|
||||||
case HEN:
|
case HEN:
|
||||||
case HENSTAYPUT:
|
case HENSTAYPUT:
|
||||||
case HENSTAND:
|
|
||||||
if (act->spr.pal == 35)
|
if (act->spr.pal == 35)
|
||||||
{
|
{
|
||||||
act->spr.scale = DVector2(0.65625, 0.46875);
|
act->spr.scale = DVector2(0.65625, 0.46875);
|
||||||
|
|
|
@ -30,6 +30,7 @@ int PicForName(int intname)
|
||||||
{"DukePigCop", "PIGCOP"},
|
{"DukePigCop", "PIGCOP"},
|
||||||
{"DukeSmallSmoke", "SMALLSMOKE"},
|
{"DukeSmallSmoke", "SMALLSMOKE"},
|
||||||
{"DukeBurning", "BURNING"},
|
{"DukeBurning", "BURNING"},
|
||||||
|
{"RedneckBowlingBallSprite", "BOWLINGBALLSPRITE"},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto& p : classes)
|
for (auto& p : classes)
|
||||||
|
@ -176,6 +177,16 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Duke, badguyID, badguypic)
|
||||||
ACTION_RETURN_INT(badguypic(p));
|
ACTION_RETURN_INT(badguypic(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updatepindisplay(int tag, int pins);
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_Duke, updatepindisplay, updatepindisplay)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_INT(tag);
|
||||||
|
PARAM_INT(mask);
|
||||||
|
updatepindisplay(tag, mask);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_GLOBAL_UNSIZED(dlevel)
|
DEFINE_GLOBAL_UNSIZED(dlevel)
|
||||||
DEFINE_GLOBAL(camsprite)
|
DEFINE_GLOBAL(camsprite)
|
||||||
|
@ -728,6 +739,13 @@ DEFINE_ACTION_FUNCTION(DDukeActor, attackerflag2)
|
||||||
ACTION_RETURN_BOOL(!!attackerflag(self, EDukeFlags2::FromInt(mask)));
|
ACTION_RETURN_BOOL(!!attackerflag(self, EDukeFlags2::FromInt(mask)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DDukeActor, checktype) // for temporary checking of types that haven't been ported yet.
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DDukeActor);
|
||||||
|
PARAM_STRING(name);
|
||||||
|
ACTION_RETURN_BOOL(self->spr.picnum == TileFiles.tileForName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -1363,6 +1381,24 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, LocateTheLocator, LocateTheLocator)
|
||||||
ACTION_RETURN_POINTER(LocateTheLocator(tag, sect));
|
ACTION_RETURN_POINTER(LocateTheLocator(tag, sect));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, getanimationindex, getanimationindex)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_INT(tag);
|
||||||
|
PARAM_POINTER(sect, sectortype);
|
||||||
|
ACTION_RETURN_INT(getanimationindex(tag, sect));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, setanimation, static_cast<int(*)(sectortype*, int, sectortype*, double, double)>(setanimation))
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_POINTER(asect, sectortype);
|
||||||
|
PARAM_INT(tag);
|
||||||
|
PARAM_POINTER(sect, sectortype);
|
||||||
|
PARAM_FLOAT(dest);
|
||||||
|
PARAM_FLOAT(vel);
|
||||||
|
ACTION_RETURN_INT(setanimation(asect, tag, sect, dest, vel));
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, max_ammo_amount);
|
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, max_ammo_amount);
|
||||||
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, playerfriction);
|
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, playerfriction);
|
||||||
|
|
|
@ -132,6 +132,13 @@ spawnclasses
|
||||||
5602 = RedneckCootJibA
|
5602 = RedneckCootJibA
|
||||||
5607 = RedneckCootJibB
|
5607 = RedneckCootJibB
|
||||||
5616 = RedneckCootJibB
|
5616 = RedneckCootJibB
|
||||||
|
280 = RedneckBowlingPinController
|
||||||
|
281 = RedneckBowlingSectorLink
|
||||||
|
282 = RedneckBowlingBallSpot
|
||||||
|
283 = RedneckBowlingPinSpot
|
||||||
|
3440 = RedneckBowlingPin
|
||||||
|
3430 = RedneckBowlingBall
|
||||||
|
4897 = RedneckHenstand
|
||||||
|
|
||||||
3114 = DukeGenericDestructible, "RRTILE3114", "RRTILE3117", "GLASS_BREAKING", spawnglass
|
3114 = DukeGenericDestructible, "RRTILE3114", "RRTILE3117", "GLASS_BREAKING", spawnglass
|
||||||
2876 = DukeGenericDestructible, "RRTILE2876", "RRTILE2990", "GLASS_BREAKING", spawnglass
|
2876 = DukeGenericDestructible, "RRTILE2876", "RRTILE2990", "GLASS_BREAKING", spawnglass
|
||||||
|
|
|
@ -101,6 +101,7 @@ version "4.10"
|
||||||
|
|
||||||
|
|
||||||
#include "zscript/games/duke/actors/redneckmisc.zs"
|
#include "zscript/games/duke/actors/redneckmisc.zs"
|
||||||
|
#include "zscript/games/duke/actors/bowling.zs"
|
||||||
#include "zscript/games/duke/actors/rabbitspawner.zs"
|
#include "zscript/games/duke/actors/rabbitspawner.zs"
|
||||||
#include "zscript/games/duke/actors/chickenplant.zs"
|
#include "zscript/games/duke/actors/chickenplant.zs"
|
||||||
#include "zscript/games/duke/actors/lumberblade.zs"
|
#include "zscript/games/duke/actors/lumberblade.zs"
|
||||||
|
|
338
wadsrc/static/zscript/games/duke/actors/bowling.zs
Normal file
338
wadsrc/static/zscript/games/duke/actors/bowling.zs
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
class RedneckBowlingPin : DukeActor
|
||||||
|
{
|
||||||
|
default
|
||||||
|
{
|
||||||
|
statnum STAT_ZOMBIEACTOR;
|
||||||
|
clipdist 12;
|
||||||
|
scaleX 0.359375;
|
||||||
|
scaleY 0.359375;
|
||||||
|
detail 0;
|
||||||
|
spriteset "BOWLINGPIN", "BOWLINGPIN1";
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Initialize()
|
||||||
|
{
|
||||||
|
self.cstat |= CSTAT_SPRITE_BLOCK_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void DoTick(int type)
|
||||||
|
{
|
||||||
|
if (self.sector.lotag == 900)
|
||||||
|
self.vel.X = 0;
|
||||||
|
|
||||||
|
if(self.vel.X != 0)
|
||||||
|
{
|
||||||
|
self.makeitfall();
|
||||||
|
CollisionData coll;
|
||||||
|
self.movesprite_ex((self.angle.ToVector() * self.vel.X, self.vel.Z), CLIPMASK0, coll);
|
||||||
|
if (coll.type)
|
||||||
|
{
|
||||||
|
if (coll.type == kHitWall)
|
||||||
|
{
|
||||||
|
double k = coll.hitWall().delta().Angle();
|
||||||
|
self.angle = k * 2 - self.angle;
|
||||||
|
}
|
||||||
|
else if (coll.type == kHitSprite)
|
||||||
|
{
|
||||||
|
let hitact = DukeActor(coll.hitActor());
|
||||||
|
// avoid checkhitsprite here. The way this was handled was just wrong on all accounts
|
||||||
|
self.collide(hitact);
|
||||||
|
//if (hitact is "RedneckHen") // does not work yet - Hen is not scriptified.
|
||||||
|
if (hitact.checkType("HEN")) // Temporary workaround
|
||||||
|
{
|
||||||
|
let ns = hitact.spawn("RedneckHenstand");
|
||||||
|
hitact.scale = (0,0);
|
||||||
|
hitact.ChangeStat(STAT_MISC);
|
||||||
|
if (ns)
|
||||||
|
{
|
||||||
|
ns.vel.X = 2;
|
||||||
|
ns.lotag = 40;
|
||||||
|
ns.angle = self.angle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.vel.X -= 1/16.;
|
||||||
|
if(self.vel.X < 0) self.vel.X = 0;
|
||||||
|
self.cstat = CSTAT_SPRITE_BLOCK_ALL;
|
||||||
|
if (type < 2 && self.vel.X > 0)
|
||||||
|
{
|
||||||
|
self.cstat |= CSTAT_SPRITE_XFLIP & int(self.vel.X * 16);
|
||||||
|
self.cstat |= CSTAT_SPRITE_YFLIP & int(self.vel.X * 16);
|
||||||
|
if (random(0, 1)) self.setSpritesetImage(1);
|
||||||
|
}
|
||||||
|
if (type < 2 && self.vel.X == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (self.sector.lotag == 900 && type != 2)
|
||||||
|
{
|
||||||
|
self.Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Tick()
|
||||||
|
{
|
||||||
|
DoTick(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
virtual void collide(DukeActor targa)
|
||||||
|
{
|
||||||
|
let targ = RedneckBowlingPin(targa);
|
||||||
|
if (!targ) return;
|
||||||
|
|
||||||
|
if (targ.detail == 0)
|
||||||
|
{
|
||||||
|
self.vel.X *= 0.75;
|
||||||
|
self.angle -= targ.angle * 2 + frandom(0, 11.25);
|
||||||
|
targ.angle += frandom(0, 22.5 / 8);
|
||||||
|
targ.PlayActorSound("BOWLPIN");
|
||||||
|
}
|
||||||
|
else if (targ.detail == 1)
|
||||||
|
{
|
||||||
|
self.vel.X *= 0.75;
|
||||||
|
self.angle -= targ.angle * 2 + frandom(0, 22.5 / 8);
|
||||||
|
targ.angle += frandom(0, 22.5 / 8);
|
||||||
|
targ.PlayActorSound("BOWLPIN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override void onHit(DukeActor hitter)
|
||||||
|
{
|
||||||
|
if (random(0, 3))
|
||||||
|
{
|
||||||
|
self.vel.X = 10.25;
|
||||||
|
self.angle = hitter.angle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// chickens on the bowling lane...
|
||||||
|
class RedneckHenstand : RedneckBowlingPin
|
||||||
|
{
|
||||||
|
default
|
||||||
|
{
|
||||||
|
scaleY 0.234375;
|
||||||
|
spriteset "HENSTAND", "HENSTAND1";
|
||||||
|
detail 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Tick()
|
||||||
|
{
|
||||||
|
self.lotag--;
|
||||||
|
if (self.lotag == 0)
|
||||||
|
{
|
||||||
|
self.spawn("RedneckHen");
|
||||||
|
self.scale = (0,0);
|
||||||
|
self.ChangeStat(STAT_MISC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DoTick(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RedneckBowlingBall : RedneckBowlingPin
|
||||||
|
{
|
||||||
|
default
|
||||||
|
{
|
||||||
|
clipdist 17;
|
||||||
|
scaleX 0.171875;
|
||||||
|
scaleY 0.140625;
|
||||||
|
statnum STAT_ACTOR;
|
||||||
|
pic "BOWLINGBALL";
|
||||||
|
detail 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Tick()
|
||||||
|
{
|
||||||
|
if (self.vel.X != 0)
|
||||||
|
{
|
||||||
|
if(!Duke.CheckSoundPlaying("BOWLLOOP"))
|
||||||
|
self.PlayActorSound("BOWLLOOP");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.spawn("RedneckBowlingBallSprite");
|
||||||
|
self.Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (self.sector.lotag == 900)
|
||||||
|
{
|
||||||
|
self.StopSound("BOWLLOOP");
|
||||||
|
}
|
||||||
|
DoTick(2);
|
||||||
|
if (self.sector.lotag == 900)
|
||||||
|
{
|
||||||
|
self.ballreturn();
|
||||||
|
self.Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ballreturn()
|
||||||
|
{
|
||||||
|
DukeStatIterator it;
|
||||||
|
for (let act1 = it.First(STAT_BOWLING); act1; act1 = it.Next())
|
||||||
|
{
|
||||||
|
if (act1.getClassName() == 'RedneckBowlingSectorLink' && self.sector == act1.sector)
|
||||||
|
{
|
||||||
|
DukeStatIterator it2;
|
||||||
|
for (let act2 = it2.First(STAT_BOWLING); act2; act2 = it2.Next())
|
||||||
|
{
|
||||||
|
if (act2.getClassName() == 'RedneckBowlingBallSpot' && act1.hitag == act2.hitag)
|
||||||
|
{
|
||||||
|
act2.spawn("RedneckBowlingBallSprite");
|
||||||
|
}
|
||||||
|
if (act2.getClassName() == 'RedneckBowlingPinController' && act1.hitag == act2.hitag && act2.lotag == 0)
|
||||||
|
{
|
||||||
|
let sec = act2.sector;
|
||||||
|
act2.lotag = 100;
|
||||||
|
act2.extra++;
|
||||||
|
int j = dlevel.getanimationindex(dlevel.anim_ceilingz, sec);
|
||||||
|
if (j == -1)
|
||||||
|
dlevel.setanimation(sec, dlevel.anim_ceilingz, sec, sec.floorz, 0.25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override void onHit(DukeActor hitter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
override void collide(DukeActor targ)
|
||||||
|
{
|
||||||
|
targ.vel.X = self.vel.X * 0.75;
|
||||||
|
if (random(0, 32767) & 16) targ.angle -= 22.5 / 8;
|
||||||
|
targ.PlayActorSound("BOWLPIN");
|
||||||
|
}
|
||||||
|
|
||||||
|
override bool ShootThis(DukeActor actor, DukePlayer plr, Vector3 spos, double sang)
|
||||||
|
{
|
||||||
|
let j = actor.spawn(self.GetClassName());
|
||||||
|
if (j)
|
||||||
|
{
|
||||||
|
j.vel.X = 250 / 16.;
|
||||||
|
j.angle = self.angle;
|
||||||
|
j.pos.Z -= 15;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RedneckBowlingController : DukeActor
|
||||||
|
{
|
||||||
|
default
|
||||||
|
{
|
||||||
|
statnum STAT_BOWLING;
|
||||||
|
scaleX 0;
|
||||||
|
scaleY 0;
|
||||||
|
clipdist 0;
|
||||||
|
extra 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Initialize()
|
||||||
|
{
|
||||||
|
self.cstat = CSTAT_SPRITE_INVISIBLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RedneckBowlingPinController : RedneckBowlingController
|
||||||
|
{
|
||||||
|
override void Tick()
|
||||||
|
{
|
||||||
|
if (self.lotag == 100)
|
||||||
|
{
|
||||||
|
let pst = pinsectorresetup();
|
||||||
|
if (pst)
|
||||||
|
{
|
||||||
|
self.lotag = 0;
|
||||||
|
if (self.extra == 1)
|
||||||
|
{
|
||||||
|
pst = checkpins();
|
||||||
|
if (!pst)
|
||||||
|
{
|
||||||
|
self.extra = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self.extra == 2)
|
||||||
|
{
|
||||||
|
self.extra = 0;
|
||||||
|
resetpins();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pinsectorresetup()
|
||||||
|
{
|
||||||
|
let sec = self.sector;
|
||||||
|
int j = dlevel.getanimationindex(dlevel.anim_ceilingz, sec);
|
||||||
|
|
||||||
|
if (j == -1)
|
||||||
|
{
|
||||||
|
double z = sec.nextsectorneighborz(sec.ceilingz, sectortype.Find_CeilingUp | sectortype.Find_Safe).ceilingz;
|
||||||
|
dlevel.setanimation(sec, dlevel.anim_ceilingz, sec, z, 0.25);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int checkpins()
|
||||||
|
{
|
||||||
|
int pins = 0;
|
||||||
|
int pin = 0;
|
||||||
|
|
||||||
|
DukeSectIterator it;
|
||||||
|
for (let a2 = it.First(self.sector); a2; a2 = it.Next())
|
||||||
|
{
|
||||||
|
if (a2.GetClassName() == 'RedneckBowlingPin' && a2.spritesetindex == 0)
|
||||||
|
{
|
||||||
|
pin++;
|
||||||
|
pins |= 1 << a2.lotag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Duke.updatepindisplay(self.hitag, pins);
|
||||||
|
return pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetpins()
|
||||||
|
{
|
||||||
|
int i, tag = 0;
|
||||||
|
DukeSectIterator it;
|
||||||
|
for (let a2 = it.First(self.sector); a2; a2 = it.Next())
|
||||||
|
{
|
||||||
|
if (a2.GetClassName() == 'RedneckBowlingPin')
|
||||||
|
a2.Destroy();
|
||||||
|
}
|
||||||
|
for (let a2 = it.First(self.sector); a2; a2 = it.Next())
|
||||||
|
{
|
||||||
|
if (a2.GetClassName() == 'RedneckBowlingPinSpot')
|
||||||
|
{
|
||||||
|
let spawned = a2.spawn('RedneckBowlingPin');
|
||||||
|
if (spawned)
|
||||||
|
{
|
||||||
|
spawned.lotag = a2.lotag;
|
||||||
|
spawned.clipdist = 12; // random formula here was bogus and always produced 48.
|
||||||
|
spawned.angle -= 22.5 * 0.125 * (((random(0, 32767) & 32) - (random(0, 32767) & 64)) >> 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Duke.updatepindisplay(self.hitag, 0xffff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RedneckBowlingSectorLink : RedneckBowlingController
|
||||||
|
{ }
|
||||||
|
|
||||||
|
class RedneckBowlingBallSpot : RedneckBowlingController
|
||||||
|
{ }
|
||||||
|
|
||||||
|
class RedneckBowlingPinSpot : RedneckBowlingController
|
||||||
|
{ }
|
||||||
|
|
|
@ -44,7 +44,10 @@ class DukeQueball : DukeActor
|
||||||
}
|
}
|
||||||
else if (j == kHitSprite)
|
else if (j == kHitSprite)
|
||||||
{
|
{
|
||||||
self.checkhitsprite(DukeActor(colli.hitactor()));
|
// the logic here was inverted, so to set things right the type check had to be added.
|
||||||
|
let targ = DukeActor(colli.hitactor());
|
||||||
|
if (targ is 'DukeQueball')
|
||||||
|
targ.checkhitsprite(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.vel.X -= 1/16.;
|
self.vel.X -= 1/16.;
|
||||||
|
@ -108,10 +111,10 @@ class DukeQueball : DukeActor
|
||||||
{
|
{
|
||||||
if (hitter is 'DukeQueball')
|
if (hitter is 'DukeQueball')
|
||||||
{
|
{
|
||||||
hitter.vel.X = self.vel.X * 0.75;
|
self.vel.X = hitter.vel.X * 0.75;
|
||||||
hitter.angle -= Normalize180(self.angle) * 2 + 180;
|
self.angle -= Normalize180(hitter.angle) * 2 + 180;
|
||||||
self.angle = (self.pos.XY - hitter.pos.XY).Angle() - 90;
|
hitter.angle = (hitter.pos.XY - self.pos.XY).Angle() - 90;
|
||||||
self.PlayActorSound("POOLBALLHIT");
|
hitter.PlayActorSound("POOLBALLHIT");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -225,6 +225,7 @@ class DukeActor : CoreActor native
|
||||||
native int actorflag3(int mask);
|
native int actorflag3(int mask);
|
||||||
native int attackerflag1(int mask);
|
native int attackerflag1(int mask);
|
||||||
native int attackerflag2(int mask);
|
native int attackerflag2(int mask);
|
||||||
|
deprecated("4.9") native bool checktype(String name); // this must not stay in the code, so mark it deprecated to keep the annoying warning at startup.
|
||||||
|
|
||||||
|
|
||||||
void commonEnemySetup(bool countkill = true)
|
void commonEnemySetup(bool countkill = true)
|
||||||
|
@ -288,6 +289,14 @@ extend struct _
|
||||||
// On the script side we do not really want scattered global data that is publicly accessible.
|
// On the script side we do not really want scattered global data that is publicly accessible.
|
||||||
struct DukeLevel
|
struct DukeLevel
|
||||||
{
|
{
|
||||||
|
enum animtype_t
|
||||||
|
{
|
||||||
|
anim_floorz,
|
||||||
|
anim_ceilingz,
|
||||||
|
anim_vertexx,
|
||||||
|
anim_vertexy,
|
||||||
|
};
|
||||||
|
|
||||||
native DukeActor SpawnActor(sectortype sect, Vector3 pos, class<DukeActor> type, int shade, Vector2 scale, double angle, double vel, double zvel, DukeActor owner, int stat = -1);
|
native DukeActor SpawnActor(sectortype sect, Vector3 pos, class<DukeActor> type, int shade, Vector2 scale, double angle, double vel, double zvel, DukeActor owner, int stat = -1);
|
||||||
native static int check_activator_motion(int lotag);
|
native static int check_activator_motion(int lotag);
|
||||||
native static void operatemasterswitches(int lotag);
|
native static void operatemasterswitches(int lotag);
|
||||||
|
@ -304,6 +313,8 @@ struct DukeLevel
|
||||||
native static void checkhitwall(walltype wal, DukeActor hitter, Vector3 hitpos);
|
native static void checkhitwall(walltype wal, DukeActor hitter, Vector3 hitpos);
|
||||||
native static void checkhitceiling(sectortype wal, DukeActor hitter);
|
native static void checkhitceiling(sectortype wal, DukeActor hitter);
|
||||||
native static DukeActor LocateTheLocator(int n, sectortype sect);
|
native static DukeActor LocateTheLocator(int n, sectortype sect);
|
||||||
|
native static int getanimationindex(int type, sectortype sec);
|
||||||
|
native static int setanimation(sectortype animsect, int type, sectortype sec, double target, double vel);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DukeStatIterator
|
struct DukeStatIterator
|
||||||
|
|
|
@ -153,6 +153,7 @@ struct Duke native
|
||||||
native static int global_random();
|
native static int global_random();
|
||||||
native static int GetSoundFlags(Sound snd);
|
native static int GetSoundFlags(Sound snd);
|
||||||
native static int badguyID(int id);
|
native static int badguyID(int id);
|
||||||
|
native static void updatepindisplay(int tag, int pinmask);
|
||||||
static int rnd(int val)
|
static int rnd(int val)
|
||||||
{
|
{
|
||||||
return (random(0, 255) >= (255 - (val)));
|
return (random(0, 255) >= (255 - (val)));
|
||||||
|
|
|
@ -118,6 +118,22 @@ enum ESectorExBits
|
||||||
|
|
||||||
struct sectortype native
|
struct sectortype native
|
||||||
{
|
{
|
||||||
|
enum EFindNextSector
|
||||||
|
{
|
||||||
|
Find_Floor = 0,
|
||||||
|
Find_Ceiling = 1,
|
||||||
|
|
||||||
|
Find_Down = 0,
|
||||||
|
Find_Up = 2,
|
||||||
|
|
||||||
|
Find_Safe = 4,
|
||||||
|
|
||||||
|
Find_CeilingUp = Find_Ceiling | Find_Up,
|
||||||
|
Find_CeilingDown = Find_Ceiling | Find_Down,
|
||||||
|
Find_FloorUp = Find_Floor | Find_Up,
|
||||||
|
Find_FloorDown = Find_Floor | Find_Down,
|
||||||
|
};
|
||||||
|
|
||||||
// panning byte fields were promoted to full floats to enable panning interpolation.
|
// panning byte fields were promoted to full floats to enable panning interpolation.
|
||||||
native readonly float ceilingxpan;
|
native readonly float ceilingxpan;
|
||||||
native readonly float ceilingypan;
|
native readonly float ceilingypan;
|
||||||
|
@ -218,6 +234,8 @@ struct sectortype native
|
||||||
native int ceilingslope();
|
native int ceilingslope();
|
||||||
native int floorslope();
|
native int floorslope();
|
||||||
native double, double getslopes(Vector2 pos);
|
native double, double getslopes(Vector2 pos);
|
||||||
|
native sectortype nextsectorneighborz(double refz, int find);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
Loading…
Reference in a new issue