mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-26 05:51:00 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
159c316ebb
36 changed files with 426 additions and 477 deletions
|
@ -91,7 +91,7 @@ void initSkyInfo(HWDrawInfo *di, HWSkyInfo* sky, sectortype* sector, int plane)
|
|||
pe.a = 230;
|
||||
|
||||
sky->fadecolor = pe;
|
||||
sky->shade = clamp<int>(plane == plane_ceiling ? sector->ceilingshade : sector->floorshade, 0, numshades - 1);
|
||||
sky->shade = 0;// clamp(plane == plane_ceiling ? sector->ceilingshade : sector->floorshade, 0, numshades - 1);
|
||||
sky->texture = skytex;
|
||||
}
|
||||
|
||||
|
|
|
@ -822,6 +822,7 @@ DEFINE_FIELD_NAMED(DCoreActor, spr.Angles.Yaw, angle)
|
|||
DEFINE_FIELD_NAMED(DCoreActor, spr.Angles.Pitch, pitch)
|
||||
DEFINE_FIELD(DCoreActor, vel)
|
||||
DEFINE_FIELD(DCoreActor, viewzoffset)
|
||||
DEFINE_FIELD(DCoreActor, oviewzoffset)
|
||||
DEFINE_FIELD(DCoreActor, opos)
|
||||
|
||||
void coreactor_setpos(DCoreActor* self, double x, double y, double z, int relink)
|
||||
|
|
|
@ -96,7 +96,7 @@ void cerberusBurnSeqCallback(int, DBloodActor* actor)
|
|||
if (nDist == 0 || nDist > 0x280)
|
||||
continue;
|
||||
|
||||
pos += actor2->vel * nDist * (65536. / 0x1aaaaa);
|
||||
pos2 += actor->vel * nDist * (65536. / 0x1aaaaa);
|
||||
|
||||
DVector3 tvec = pos;
|
||||
tvec.XY() += actor->spr.Angles.Yaw.ToVector() * nDist;
|
||||
|
@ -161,7 +161,7 @@ void cerberusBurnSeqCallback2(int, DBloodActor* actor)
|
|||
if (nDist == 0 || nDist > 0x280)
|
||||
continue;
|
||||
|
||||
pos += actor2->vel * nDist * (65536. / 0x1aaaaa);
|
||||
pos2 += actor->vel * nDist * (65536. / 0x1aaaaa);
|
||||
|
||||
DVector3 tvec = pos;
|
||||
tvec.XY() += actor->spr.Angles.Yaw.ToVector() * nDist;
|
||||
|
|
|
@ -121,7 +121,7 @@ void BlastSSeqCallback(int, DBloodActor* actor)
|
|||
if (nDist == 0 || nDist > 0x280)
|
||||
continue;
|
||||
|
||||
pos += actor2->vel * nDist * (65536. / 0x1aaaaa);
|
||||
pos2 += actor->vel * nDist * (65536. / 0x1aaaaa);
|
||||
|
||||
DVector3 tvec = pos;
|
||||
tvec.XY() += actor->spr.Angles.Yaw.ToVector() * nDist;
|
||||
|
|
|
@ -108,7 +108,7 @@ void ghostBlastSeqCallback(int, DBloodActor* actor)
|
|||
if (nDist == 0 || nDist > 0x280)
|
||||
continue;
|
||||
|
||||
pos += actor2->vel * nDist * (65536. / 0x1aaaaa);
|
||||
pos2 += actor->vel * nDist * (65536. / 0x1aaaaa);
|
||||
|
||||
DVector3 tvec = pos;
|
||||
tvec.XY() += actor->spr.Angles.Yaw.ToVector() * nDist;
|
||||
|
|
|
@ -79,7 +79,7 @@ void tchernobogBurnSeqCallback(int, DBloodActor* actor)
|
|||
if (nDist == 0 || nDist > 0x280)
|
||||
continue;
|
||||
|
||||
pos += actor2->vel * nDist * (65536. / 0x1aaaaa);
|
||||
pos2 += actor->vel * nDist * (65536. / 0x1aaaaa);
|
||||
|
||||
DVector3 tvec = pos;
|
||||
tvec.XY() += actor->spr.Angles.Yaw.ToVector() * nDist;
|
||||
|
@ -135,7 +135,7 @@ void tchernobogBurnSeqCallback2(int, DBloodActor* actor)
|
|||
if (nDist == 0 || nDist > 0x280)
|
||||
continue;
|
||||
|
||||
pos += actor2->vel * nDist * (65536. / 0x1aaaaa);
|
||||
pos2 += actor->vel * nDist * (65536. / 0x1aaaaa);
|
||||
|
||||
DVector3 tvec = pos;
|
||||
tvec.XY() += actor->spr.Angles.Yaw.ToVector() * nDist;
|
||||
|
|
|
@ -800,7 +800,6 @@ void nnExtInitModernStuff(TArray<DBloodActor*>& actors)
|
|||
{
|
||||
if (iactor->xspr.busyTime <= 0 || iactor->xspr.isTriggered) continue;
|
||||
|
||||
int count = 0;
|
||||
TRCONDITION* pCond = &gConditions[gConditions.Reserve(1)];
|
||||
|
||||
for (auto iactor2 : actors)
|
||||
|
@ -818,18 +817,18 @@ void nnExtInitModernStuff(TArray<DBloodActor*>& actors)
|
|||
if (iactor2->spr.type == kModernCondition || iactor2->spr.type == kModernConditionFalse)
|
||||
condError(iactor, "Tracking condition always must be first in condition sequence!");
|
||||
|
||||
pCond->objects.Reserve(2);
|
||||
pCond->objects[count].obj = EventObject(iactor2);
|
||||
pCond->objects[count++].cmd = (uint8_t)iactor2->xspr.command;
|
||||
pCond->objects.Reserve(1);
|
||||
pCond->objects.Last().obj = EventObject(iactor2);
|
||||
pCond->objects.Last().cmd = (uint8_t)iactor2->xspr.command;
|
||||
}
|
||||
|
||||
for (auto& sect : sector)
|
||||
{
|
||||
if (!sect.hasX() || sect.xs().txID != iactor->xspr.rxID) continue;
|
||||
|
||||
pCond->objects.Reserve(2);
|
||||
pCond->objects[count].obj = EventObject(§);
|
||||
pCond->objects[count++].cmd = sect.xs().command;
|
||||
pCond->objects.Reserve(1);
|
||||
pCond->objects.Last().obj = EventObject(§);
|
||||
pCond->objects.Last().cmd = sect.xs().command;
|
||||
}
|
||||
|
||||
for (auto& wal : wall)
|
||||
|
@ -843,12 +842,12 @@ void nnExtInitModernStuff(TArray<DBloodActor*>& actors)
|
|||
continue;
|
||||
}
|
||||
|
||||
pCond->objects.Reserve(2);
|
||||
pCond->objects[count].obj = EventObject(&wal);
|
||||
pCond->objects[count++].cmd = wal.xw().command;
|
||||
pCond->objects.Reserve(1);
|
||||
pCond->objects.Last().obj = EventObject(&wal);
|
||||
pCond->objects.Last().cmd = wal.xw().command;
|
||||
}
|
||||
|
||||
if (iactor->xspr.data1 > kCondGameMax && count == 0)
|
||||
if (iactor->xspr.data1 > kCondGameMax && pCond->objects.Size() == 0)
|
||||
Printf(PRINT_HIGH, "No objects to track found for condition #%d, RXID: %d!", iactor->GetIndex(), iactor->xspr.rxID);
|
||||
|
||||
pCond->actor = iactor;
|
||||
|
|
|
@ -239,12 +239,12 @@ struct TRPLAYERCTRL { // this one for controlling the player using triggers (mov
|
|||
};
|
||||
|
||||
struct OBJECTS_TO_TRACK {
|
||||
uint8_t cmd;
|
||||
EventObject obj;
|
||||
uint8_t cmd = 0;
|
||||
EventObject obj = EventObject(nullptr);
|
||||
};
|
||||
|
||||
struct TRCONDITION {
|
||||
DBloodActor* actor;
|
||||
DBloodActor* actor = nullptr;
|
||||
TArray<OBJECTS_TO_TRACK> objects;
|
||||
};
|
||||
|
||||
|
|
|
@ -1452,7 +1452,7 @@ int ActionScan(PLAYER* pPlayer, HitInfo* out)
|
|||
int nMass = getDudeInfo(hitactor->spr.type)->mass;
|
||||
if (nMass)
|
||||
{
|
||||
hitactor->spr.pos += pos * (FixedToFloat<8>(0xccccc) / nMass);
|
||||
hitactor->vel += pos * (FixedToFloat<10>(0xccccc) / nMass);
|
||||
}
|
||||
if (hitactor->xspr.Push && !hitactor->xspr.state && !hitactor->xspr.isTriggered)
|
||||
trTriggerSprite(hitactor, kCmdSpritePush);
|
||||
|
|
|
@ -577,9 +577,11 @@ void tickstat(int stat, bool deleteinvalid)
|
|||
if (actorflag(act, SFLAG2_DIENOW) || act->sector() == nullptr || (deleteinvalid && act->spr.scale.X == 0))
|
||||
{
|
||||
act->Destroy();
|
||||
continue;
|
||||
}
|
||||
CallTick(act);
|
||||
else if (stat != STAT_ACTOR || !badguy(act) || !monsterCheatCheck(act))
|
||||
{
|
||||
CallTick(act);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2964,6 +2966,8 @@ void getglobalz(DDukeActor* actor)
|
|||
|
||||
void makeitfall(DDukeActor* actor)
|
||||
{
|
||||
if (actorflag(actor, SFLAG3_NOGRAVITY)) return;
|
||||
|
||||
double grav;
|
||||
|
||||
if( floorspace(actor->sector()) )
|
||||
|
@ -2993,7 +2997,7 @@ void makeitfall(DDukeActor* actor)
|
|||
|
||||
if( actor->spr.pos.Z < actor->floorz - FOURSLEIGHT_F)
|
||||
{
|
||||
if( actor->sector()->lotag == 2 && actor->vel.Z > 3122/256.)
|
||||
if( actor->sector()->lotag == ST_2_UNDERWATER && actor->vel.Z > 3122/256.)
|
||||
actor->vel.Z = 3144 / 256.;
|
||||
if (actor->vel.Z < 24)
|
||||
actor->vel.Z += grav;
|
||||
|
|
|
@ -991,201 +991,6 @@ void movetransports_d(void)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void flamethrowerflame(DDukeActor *actor)
|
||||
{
|
||||
auto sectp = actor->sector();
|
||||
double xx;
|
||||
int p = findplayer(actor, &xx);
|
||||
execute(actor, p, xx);
|
||||
if (actor->ObjectFlags & OF_EuthanizeMe) return; // killed by script.
|
||||
actor->temp_data[0]++;
|
||||
if (sectp->lotag == 2)
|
||||
{
|
||||
spawn(actor, DTILE_EXPLOSION2)->spr.shade = 127;
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
auto dapos = actor->spr.pos;
|
||||
|
||||
getglobalz(actor);
|
||||
|
||||
int ds = actor->temp_data[0] / 6;
|
||||
if (actor->spr.scale.X < 0.1250)
|
||||
{
|
||||
actor->spr.scale.X += (ds * REPEAT_SCALE);
|
||||
actor->spr.scale.Y = (actor->spr.scale.X);
|
||||
}
|
||||
actor->clipdist += ds * 0.25;
|
||||
if (actor->temp_data[0] <= 2)
|
||||
actor->temp_data[3] = krand() % 10;
|
||||
if (actor->temp_data[0] > 30)
|
||||
{
|
||||
spawn(actor, DTILE_EXPLOSION2)->spr.shade = 127;
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
Collision coll;
|
||||
movesprite_ex(actor, DVector3(actor->spr.Angles.Yaw.ToVector() * actor->vel.X, actor->vel.Z), CLIPMASK1, coll);
|
||||
|
||||
if (!actor->insector())
|
||||
{
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (coll.type != kHitSprite)
|
||||
{
|
||||
if (actor->spr.pos.Z < actor->ceilingz)
|
||||
{
|
||||
coll.setSector(actor->sector());
|
||||
actor->vel.Z -= 1/256.;
|
||||
}
|
||||
else if ((actor->spr.pos.Z > actor->floorz && actor->sector()->lotag != 1)
|
||||
|| (actor->spr.pos.Z > actor->floorz + 16 && actor->sector()->lotag == 1))
|
||||
{
|
||||
coll.setSector(actor->sector());
|
||||
if (actor->sector()->lotag != 1)
|
||||
actor->vel.Z += 1/256.;
|
||||
}
|
||||
}
|
||||
|
||||
if (coll.type != 0) {
|
||||
actor->vel.XY().Zero();
|
||||
actor->vel.Z = 0;
|
||||
if (coll.type == kHitSprite)
|
||||
{
|
||||
fi.checkhitsprite(coll.actor(), actor);
|
||||
if (coll.actor()->isPlayer())
|
||||
S_PlayActorSound(PISTOL_BODYHIT, coll.actor());
|
||||
}
|
||||
else if (coll.type == kHitWall)
|
||||
{
|
||||
SetActor(actor, dapos);
|
||||
checkhitwall(actor, coll.hitWall, actor->spr.pos);
|
||||
}
|
||||
else if (coll.type == kHitSector)
|
||||
{
|
||||
SetActor(actor, dapos);
|
||||
if (actor->vel.Z < 0)
|
||||
checkhitceiling(actor->sector());
|
||||
}
|
||||
|
||||
if (actor->spr.scale.X >= 0.15625)
|
||||
{
|
||||
int x = actor->spr.extra;
|
||||
fi.hitradius(actor, gs.rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = actor->spr.extra + (global_random & 3);
|
||||
fi.hitradius(actor, (gs.rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void moveactors_d(void)
|
||||
{
|
||||
DukeStatIterator it(STAT_ACTOR);
|
||||
while (auto act = it.Next())
|
||||
{
|
||||
if (act->spr.scale.X == 0 || act->spr.sectp == nullptr || actorflag(act, SFLAG2_DIENOW))
|
||||
{
|
||||
act->Destroy();
|
||||
}
|
||||
else if (monsterCheatCheck(act) && badguy(act))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (isWorldTour() && act->spr.picnum == DTILE_FLAMETHROWERFLAME)
|
||||
{
|
||||
flamethrowerflame(act);
|
||||
}
|
||||
else
|
||||
{
|
||||
CallTick(act);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void fireflyflyingeffect(DDukeActor *actor)
|
||||
{
|
||||
double xx;
|
||||
int p = findplayer(actor, &xx);
|
||||
execute(actor, p, xx);
|
||||
if (actor->ObjectFlags & OF_EuthanizeMe) return; // killed by script.
|
||||
|
||||
auto Owner = actor->GetOwner();
|
||||
if (!Owner || Owner->spr.picnum != DTILE_FIREFLY)
|
||||
{
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Owner->spr.scale.X >= 0.375 || Owner->spr.pal == 1)
|
||||
actor->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
|
||||
else
|
||||
actor->spr.cstat &= ~CSTAT_SPRITE_INVISIBLE;
|
||||
|
||||
auto dvec = Owner->spr.pos.XY() - ps[p].GetActor()->spr.pos.XY();
|
||||
double dist = dvec.Length();
|
||||
|
||||
if (dist != 0.0) dvec /= dist;
|
||||
actor->spr.pos = Owner->spr.pos + DVector3(dvec.X * -0.625, dvec.Y * -0.625, 8);
|
||||
|
||||
if (Owner->spr.extra <= 0)
|
||||
{
|
||||
actor->Destroy();
|
||||
}
|
||||
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void moveexplosions_d(void) // STATNUM 5
|
||||
{
|
||||
DukeStatIterator it(STAT_MISC);
|
||||
while (auto act = it.Next())
|
||||
{
|
||||
if (act->spr.scale.X == 0 || act->spr.sectp == nullptr || actorflag(act, SFLAG2_DIENOW))
|
||||
{
|
||||
act->Destroy();
|
||||
}
|
||||
else if (isWorldTour() && act->spr.picnum == DTILE_FIREFLYFLYINGEFFECT)
|
||||
{
|
||||
fireflyflyingeffect(act);
|
||||
}
|
||||
else
|
||||
{
|
||||
CallTick(act);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void handle_se06_d(DDukeActor* actor)
|
||||
{
|
||||
auto sc = actor->sector();
|
||||
|
@ -1741,11 +1546,11 @@ void think_d(void)
|
|||
tickstat(STAT_PROJECTILE); //ST 4
|
||||
moveplayers(); //ST 10
|
||||
movefallers_d(); //ST 12
|
||||
moveexplosions_d(); //ST 5
|
||||
tickstat(STAT_MISC, true); //ST 5
|
||||
|
||||
actortime.Reset();
|
||||
actortime.Clock();
|
||||
moveactors_d(); //ST 1
|
||||
tickstat(STAT_ACTOR); //ST 1
|
||||
actortime.Unclock();
|
||||
|
||||
moveeffectors_d(); //ST 3
|
||||
|
|
|
@ -1018,10 +1018,6 @@ static void rrra_specialstats()
|
|||
|
||||
void moveactors_r(void)
|
||||
{
|
||||
double xx;
|
||||
int p;
|
||||
Collision coll;
|
||||
|
||||
dojaildoor();
|
||||
moveminecart();
|
||||
|
||||
|
@ -1033,46 +1029,7 @@ void moveactors_r(void)
|
|||
if (ud.chickenplant) tickstat(STAT_CHICKENPLANT);
|
||||
tickstat(STAT_BOWLING);
|
||||
tickstat(STAT_TELEPORT);
|
||||
|
||||
DukeStatIterator it(STAT_ACTOR);
|
||||
while (auto act = it.Next())
|
||||
{
|
||||
if( act->spr.scale.X == 0 || !act->insector() || actorflag(act, SFLAG2_DIENOW))
|
||||
{
|
||||
act->Destroy();
|
||||
continue;
|
||||
}
|
||||
if (monsterCheatCheck(act) && badguy(act))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto sectp = act->sector();
|
||||
|
||||
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
|
||||
{
|
||||
CallTick(act);
|
||||
continue;
|
||||
}
|
||||
else switch(act->spr.picnum)
|
||||
{
|
||||
case RTILE_POWDERKEG:
|
||||
if (!isRRRA() || (sectp->lotag != ST_1_ABOVE_WATER && sectp->lotag != ST_160_FLOOR_TELEPORT))
|
||||
if (act->vel.X != 0)
|
||||
{
|
||||
movesprite_ex(act, DVector3(act->spr.Angles.Yaw.ToVector()* act->vel.X, act->vel.Z), CLIPMASK0, coll);
|
||||
act->vel.X -= 1. / 16.;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
p = findplayer(act, &xx);
|
||||
|
||||
execute(act,p,xx);
|
||||
}
|
||||
|
||||
tickstat(STAT_ACTOR);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -126,8 +126,6 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
|
|||
if (h->spr.extra > 0)
|
||||
t->pos.Z += 6;
|
||||
break;
|
||||
case RTILE_POWDERKEG:
|
||||
continue;
|
||||
case RTILE_BURNING:
|
||||
if (OwnerAc && OwnerAc->spr.statnum == STAT_PLAYER)
|
||||
{
|
||||
|
|
|
@ -404,6 +404,7 @@ enum sflags3_t
|
|||
SFLAG3_BROWNBLOOD = 0x00000004,
|
||||
SFLAG3_LIGHTDAMAGE = 0x00000008,
|
||||
SFLAG3_FORCERUNCON = 0x00000010, // by default only STAT_ACTOR runs CON - this enables it for other statnums as well, provided they run Tick()
|
||||
SFLAG3_NOGRAVITY = 0x00000020, // disables makeitfall.
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ BEGIN_DUKE_NS
|
|||
|
||||
void initactorflags_d()
|
||||
{
|
||||
setflag(SFLAG3_NOGRAVITY, { DTILE_RECON }); // not ported!!!
|
||||
|
||||
gs.actorinfo[DTILE_COMMANDER].gutsoffset = -24;
|
||||
|
||||
|
|
|
@ -232,6 +232,7 @@ void initactorflags_r()
|
|||
RTILE_SHITBALL,
|
||||
RTILE_RPG,
|
||||
RTILE_RECON,
|
||||
RTILE_POWDERKEG
|
||||
});
|
||||
// Animals were not supposed to have this, but due to a coding bug the logic was unconditional for everything in the game.
|
||||
for (auto& ainf : gs.actorinfo)
|
||||
|
|
|
@ -175,7 +175,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
|||
void addspritetodelete(int spnum=0);
|
||||
void checkavailinven(player_struct* p);
|
||||
bool initspriteforspawn(DDukeActor* spn);
|
||||
bool spawninitdefault(DDukeActor* actj, DDukeActor* act);
|
||||
bool commonEnemySetup(DDukeActor* self, DDukeActor* owner);
|
||||
void spawntransporter(DDukeActor* actj, DDukeActor* acti, bool beam);
|
||||
int spawnbloodpoolpart1(DDukeActor* acti);
|
||||
void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell);
|
||||
|
|
|
@ -142,91 +142,6 @@ static void shootfireball(DDukeActor *actor, int p, DVector3 pos, DAngle ang)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void shootflamethrowerflame(DDukeActor* actor, int p, DVector3 spos, DAngle sang)
|
||||
{
|
||||
double vel, zvel = 0;
|
||||
|
||||
if (actor->spr.extra >= 0)
|
||||
actor->spr.shade = -96;
|
||||
vel = 25;
|
||||
|
||||
DDukeActor* spawned = nullptr;
|
||||
if (p < 0)
|
||||
{
|
||||
double x;
|
||||
int j = findplayer(actor, &x);
|
||||
sang = (ps[j].GetActor()->opos.XY() - spos.XY()).Angle();
|
||||
|
||||
if (actor->spr.picnum == DTILE_BOSS5)
|
||||
{
|
||||
vel = 33;
|
||||
spos.Z += 24;
|
||||
}
|
||||
else if (actor->spr.picnum == DTILE_BOSS3)
|
||||
spos.Z -= 32;
|
||||
|
||||
double dist = (ps[j].GetActor()->spr.pos.XY() - actor->spr.pos.XY()).Length();
|
||||
if (dist != 0)
|
||||
zvel = (((ps[j].GetActor()->getPrevOffsetZ() - spos.Z) * vel) / dist);
|
||||
|
||||
if (badguy(actor) && (actor->spr.hitag & face_player_smart) != 0)
|
||||
sang = actor->spr.Angles.Yaw + mapangle((krand() & 31) - 16);
|
||||
|
||||
if (actor->sector()->lotag == 2 && (krand() % 5) == 0)
|
||||
spawned = spawn(actor, DTILE_WATERBUBBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 40.5);
|
||||
|
||||
// WTF???
|
||||
DAngle myang = DAngle90 - (DAngle180 - abs(abs((spos.XY() - ps[p].GetActor()->spr.pos.XY()).Angle() - sang) - DAngle180));
|
||||
if (ps[p].GetActor()->vel.X != 0)
|
||||
vel = ((myang / DAngle90) * ps[p].GetActor()->vel.X) + 25;
|
||||
if (actor->sector()->lotag == 2 && (krand() % 5) == 0)
|
||||
spawned = spawn(actor, DTILE_WATERBUBBLE);
|
||||
}
|
||||
|
||||
if (spawned == nullptr)
|
||||
{
|
||||
spawned = spawn(actor, DTILE_FLAMETHROWERFLAME);
|
||||
if (!spawned) return;
|
||||
spawned->vel.X = vel;
|
||||
spawned->vel.Z = zvel;
|
||||
}
|
||||
|
||||
|
||||
DVector3 offset;
|
||||
offset.X = (sang + DAngle::fromBuild(118)).Cos() * (1024 / 448.); // Yes, these angles are really different!
|
||||
offset.Y = (sang + DAngle::fromBuild(112)).Sin() * (1024 / 448.);
|
||||
offset.Z = -1;
|
||||
|
||||
spawned->spr.pos = spos + offset;
|
||||
spawned->spr.pos.Z--;
|
||||
spawned->setsector(actor->sector());
|
||||
spawned->spr.cstat = CSTAT_SPRITE_YCENTER;
|
||||
spawned->spr.Angles.Yaw = sang;
|
||||
spawned->spr.scale = DVector2(0.03125, 0.03125);
|
||||
spawned->clipdist = 10;
|
||||
spawned->spr.yint = p;
|
||||
spawned->SetOwner(actor);
|
||||
|
||||
if (p == -1)
|
||||
{
|
||||
if (actor->spr.picnum == DTILE_BOSS5)
|
||||
{
|
||||
spawned->spr.pos += sang.ToVector() * (128. / 7);
|
||||
spawned->spr.scale = DVector2(0.15625, 0.15625);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void shootknee(DDukeActor* actor, int p, DVector3 pos, DAngle ang)
|
||||
{
|
||||
auto sectp = actor->sector();
|
||||
|
@ -1105,10 +1020,6 @@ void shoot_d(DDukeActor* actor, int atwith, PClass *cls)
|
|||
shootfireball(actor, p, spos, sang);
|
||||
return;
|
||||
|
||||
case DTILE_FLAMETHROWERFLAME:
|
||||
shootflamethrowerflame(actor, p, spos, sang);
|
||||
return;
|
||||
|
||||
case DTILE_FIREFLY: // DTILE_BOSS5 shot
|
||||
{
|
||||
auto k = spawn(actor, atwith);
|
||||
|
|
|
@ -845,17 +845,6 @@ void shoot_r(DDukeActor* actor, int atwith, PClass* cls)
|
|||
shootweapon(actor, p, spos, sang, atwith);
|
||||
return;
|
||||
|
||||
case RTILE_POWDERKEG:
|
||||
{
|
||||
auto j = spawn(actor, atwith);
|
||||
if (j)
|
||||
{
|
||||
j->vel.X = 2;
|
||||
j->spr.Angles.Yaw = actor->spr.Angles.Yaw;
|
||||
j->spr.pos.Z -= 5;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RTILE_OWHIP:
|
||||
case RTILE_UWHIP:
|
||||
shootwhip(actor, p, spos, sang, atwith);
|
||||
|
|
|
@ -298,63 +298,48 @@ DDukeActor* spawn(DDukeActor* actj, PClassActor * cls)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool spawninitdefault(DDukeActor* actj, DDukeActor *act)
|
||||
bool commonEnemySetup(DDukeActor* self, DDukeActor* owner)
|
||||
{
|
||||
if (gs.actorinfo[act->spr.picnum].scriptaddress)
|
||||
if (!self->mapSpawned) self->spr.lotag = 0;
|
||||
|
||||
// Init the size. This is different for internal and user enemies.
|
||||
if (actorflag(self, SFLAG_INTERNAL_BADGUY))
|
||||
{
|
||||
if (actj == nullptr && act->spr.lotag > ud.player_skill)
|
||||
{
|
||||
// make it go away...
|
||||
act->spr.scale = DVector2(0, 0);
|
||||
ChangeActorStat(act, STAT_MISC);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Init the size
|
||||
if (act->spr.scale.X == 0 || act->spr.scale.Y == 0)
|
||||
act->spr.scale = DVector2(REPEAT_SCALE, REPEAT_SCALE);
|
||||
|
||||
if (actorflag(act, SFLAG_BADGUY))
|
||||
{
|
||||
if (ud.monsters_off == 1)
|
||||
{
|
||||
act->spr.scale = DVector2(0, 0);
|
||||
ChangeActorStat(act, STAT_MISC);
|
||||
return false;
|
||||
}
|
||||
|
||||
makeitfall(act);
|
||||
|
||||
if (actorflag(act, SFLAG_BADGUYSTAYPUT))
|
||||
act->actorstayput = act->sector();
|
||||
|
||||
if (!isRR() || actorflag(act, SFLAG_KILLCOUNT)) // Duke is just like Doom - Bad guys always count as kill.
|
||||
ps[myconnectindex].max_actors_killed++;
|
||||
|
||||
act->clipdist = 20;
|
||||
if (actj)
|
||||
{
|
||||
if (isrespawncontroller(actj))
|
||||
act->tempval = act->spr.pal = actj->spr.pal;
|
||||
ChangeActorStat(act, STAT_ACTOR);
|
||||
}
|
||||
else ChangeActorStat(act, STAT_ZOMBIEACTOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
act->clipdist = 10;
|
||||
act->SetOwner(act);
|
||||
ChangeActorStat(act, STAT_ACTOR);
|
||||
}
|
||||
|
||||
act->timetosleep = 0;
|
||||
|
||||
if (actj)
|
||||
act->spr.Angles.Yaw = actj->spr.Angles.Yaw;
|
||||
self->spr.scale = DVector2(0.625, 0.625);
|
||||
}
|
||||
else if (self->spr.scale.X == 0 || self->spr.scale.Y == 0)
|
||||
{
|
||||
self->spr.scale = DVector2(REPEAT_SCALE, REPEAT_SCALE);
|
||||
}
|
||||
|
||||
if ((self->spr.lotag > ud.player_skill) || ud.monsters_off == 1)
|
||||
{
|
||||
self->spr.scale.Zero();
|
||||
ChangeActorStat(self, STAT_MISC);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
makeitfall(self);
|
||||
|
||||
self->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
|
||||
|
||||
if (!isRR() && actorflag(self, SFLAG_KILLCOUNT))
|
||||
ps[myconnectindex].max_actors_killed++;
|
||||
|
||||
self->timetosleep = 0;
|
||||
if (!self->mapSpawned)
|
||||
{
|
||||
CallPlayFTASound(self);
|
||||
ChangeActorStat(self, STAT_ACTOR);
|
||||
if (owner && !actorflag(self, SFLAG_INTERNAL_BADGUY)) self->spr.Angles.Yaw = owner->spr.Angles.Yaw;
|
||||
}
|
||||
else ChangeActorStat(self, STAT_ZOMBIEACTOR);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
|
|
@ -59,7 +59,7 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
|||
|
||||
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
|
||||
{
|
||||
if (spawninitdefault(actj, act))
|
||||
if (!badguy(act) || commonEnemySetup(act, actj))
|
||||
CallInitialize(act);
|
||||
return act;
|
||||
}
|
||||
|
@ -123,11 +123,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
|||
ChangeActorStat(act, STAT_ZOMBIEACTOR);
|
||||
}
|
||||
return act;
|
||||
case DTILE_FIREFLYFLYINGEFFECT:
|
||||
act->SetOwner(actj);
|
||||
ChangeActorStat(act, STAT_MISC);
|
||||
act->spr.scale = DVector2(0.25, 0.25);
|
||||
return act;
|
||||
case DTILE_LAVAPOOLBUBBLE:
|
||||
if (actj->spr.scale.X < 0.46875)
|
||||
return act;
|
||||
|
@ -154,7 +149,7 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
|||
switch (act->spr.picnum)
|
||||
{
|
||||
default:
|
||||
spawninitdefault(actj, act);
|
||||
CallInitialize(act);
|
||||
break;
|
||||
case FOF:
|
||||
act->spr.scale = DVector2(0, 0);
|
||||
|
|
|
@ -51,7 +51,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
|||
|
||||
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
|
||||
{
|
||||
if (spawninitdefault(actj, act))
|
||||
if (!badguy(act) || commonEnemySetup(act, actj))
|
||||
CallInitialize(act);
|
||||
return act;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
|||
{
|
||||
default:
|
||||
default_case:
|
||||
spawninitdefault(actj, act);
|
||||
CallInitialize(act);
|
||||
break;
|
||||
case RTILE_RRTILE7936:
|
||||
if (!isRRRA()) goto default_case;
|
||||
|
|
|
@ -212,6 +212,20 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Duke, StopCommentary, StopCommentary)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int getPlayerIndex(player_struct* p)
|
||||
{
|
||||
if (!p) return -1;
|
||||
return int(p - ps);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Duke, getPlayerIndex, getPlayerIndex)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_POINTER(p, player_struct);
|
||||
ACTION_RETURN_INT(getPlayerIndex(p));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_GLOBAL_UNSIZED(dlevel)
|
||||
DEFINE_GLOBAL(camsprite)
|
||||
|
||||
|
@ -609,6 +623,17 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, badguy, badguy)
|
|||
ACTION_RETURN_INT(badguy(self));
|
||||
}
|
||||
|
||||
int duke_scripted(DDukeActor* act)
|
||||
{
|
||||
return gs.actorinfo[act->spr.picnum].scriptaddress > 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, scripted, duke_scripted)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DDukeActor);
|
||||
ACTION_RETURN_INT(duke_scripted(self));
|
||||
}
|
||||
|
||||
int duke_isplayer(DDukeActor* act)
|
||||
{
|
||||
return act->isPlayer();
|
||||
|
|
|
@ -110,7 +110,7 @@ static void analyzesprites(tspriteArray& tsprites, const DVector3& view, double
|
|||
pTSprite->pos.Z -= nTileY;
|
||||
}
|
||||
|
||||
if (pTSprite->pal == 4 && pTSprite->shade >= numshades) pTSprite->shade = numshades - 1;
|
||||
if (pTSprite->pal == 4 && pTSprite->shade >= numshades && !hw_int_useindexedcolortextures) pTSprite->shade = numshades - 1;
|
||||
|
||||
if (pActor->spr.statnum > 0)
|
||||
{
|
||||
|
|
|
@ -5,4 +5,6 @@ spawnclasses
|
|||
5736 = DukeGenericDestructible, "WTGLASS1", "", "GLASS_BREAKING", spawnglass
|
||||
5737 = DukeGenericDestructible, "WTGLASS2", "", "GLASS_BREAKING", spawnglass
|
||||
5294 = DeveloperCommentary
|
||||
1891 = DukeFlamethrowerFlame
|
||||
5296 = DukeFireflyFlyingEffect
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ spawnclasses
|
|||
1083 = DukeCameraPole
|
||||
|
||||
26 = RedneckDynamite
|
||||
27 = RedneckPowderKeg
|
||||
1416 = RedneckMortar
|
||||
285 = RedneckChickenSpawner1
|
||||
286 = RedneckChickenSpawner2
|
||||
|
|
|
@ -102,7 +102,10 @@ version "4.10"
|
|||
#include "zscript/games/duke/actors/bloodpool.zs"
|
||||
#include "zscript/games/duke/actors/toilet.zs"
|
||||
|
||||
#include "zscript/games/duke/actors/flamethrowerflame.zs"
|
||||
#include "zscript/games/duke/actors/firefly.zs"
|
||||
|
||||
#include "zscript/games/duke/actors/powderkeg.zs"
|
||||
#include "zscript/games/duke/actors/redneckmisc.zs"
|
||||
#include "zscript/games/duke/actors/emptybike.zs"
|
||||
#include "zscript/games/duke/actors/rrteleport.zs"
|
||||
|
|
|
@ -57,6 +57,7 @@ class CoreActor native
|
|||
native double pitch;
|
||||
native Vector3 vel;
|
||||
native double viewzoffset;
|
||||
native double oviewzoffset;
|
||||
|
||||
native readonly int16 spritesetindex;
|
||||
native readonly int spawnindex;
|
||||
|
|
47
wadsrc/static/zscript/games/duke/actors/firefly.zs
Normal file
47
wadsrc/static/zscript/games/duke/actors/firefly.zs
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
// for now only the effect is scriptified.
|
||||
|
||||
class DukeFireflyFlyingEffect : DukeActor
|
||||
{
|
||||
default
|
||||
{
|
||||
pic "FIREFLYFLYINGEFFECT";
|
||||
}
|
||||
|
||||
override void Initialize()
|
||||
{
|
||||
self.scale = (0.25, 0.25);
|
||||
self.ChangeStat(STAT_MISC);
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if (bDestroyed) return; // killed by script.
|
||||
|
||||
|
||||
let Owner = self.ownerActor;
|
||||
if (!Owner || !Owner.checkType("FIREFLY"))
|
||||
{
|
||||
self.Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Owner.scale.X >= 0.375 || Owner.pal == 1)
|
||||
self.cstat |= CSTAT_SPRITE_INVISIBLE;
|
||||
else
|
||||
self.cstat &= ~CSTAT_SPRITE_INVISIBLE;
|
||||
|
||||
let p = self.findplayer();
|
||||
let dvec = Owner.pos.XY - p.actor.pos.XY;
|
||||
double dist = dvec.Length();
|
||||
|
||||
if (dist != 0.0) dvec /= dist;
|
||||
self.pos = Owner.pos + (dvec.X * -0.625, dvec.Y * -0.625, 8);
|
||||
|
||||
if (Owner.extra <= 0)
|
||||
{
|
||||
self.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
192
wadsrc/static/zscript/games/duke/actors/flamethrowerflame.zs
Normal file
192
wadsrc/static/zscript/games/duke/actors/flamethrowerflame.zs
Normal file
|
@ -0,0 +1,192 @@
|
|||
class DukeFlamethrowerFlame : DukeActor
|
||||
{
|
||||
default
|
||||
{
|
||||
pic "FLAMETHROWERFLAME";
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Console.Printf("ticky");
|
||||
let sectp = self.sector;
|
||||
double xx;
|
||||
Super.Tick(); // Run CON or its replacement.
|
||||
if (self.bDestroyed) return; // killed by script.
|
||||
self.temp_data[0]++;
|
||||
if (sectp.lotag == ST_2_UNDERWATER)
|
||||
{
|
||||
let spawned = self.spawn("DukeExplosion2");
|
||||
if (spawned) spawned.shade = 127;
|
||||
self.Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
let dapos = self.pos;
|
||||
|
||||
self.getglobalz();
|
||||
|
||||
int ds = self.temp_data[0] / 6;
|
||||
if (self.scale.X < 0.1250)
|
||||
{
|
||||
self.scale.X += (ds * REPEAT_SCALE);
|
||||
self.scale.Y = (self.scale.X);
|
||||
}
|
||||
self.clipdist += ds * 0.25;
|
||||
if (self.temp_data[0] <= 2)
|
||||
self.temp_data[3] = random(0, 9);
|
||||
if (self.temp_data[0] > 30)
|
||||
{
|
||||
let spawned = self.spawn("DukeExplosion2");
|
||||
if (spawned) spawned.shade = 127;
|
||||
self.Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
CollisionData coll;
|
||||
self.movesprite_ex((self.angle.ToVector() * self.vel.X, self.vel.Z), CLIPMASK1, coll);
|
||||
|
||||
if (self.sector == null)
|
||||
{
|
||||
self.Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (coll.type != kHitSprite)
|
||||
{
|
||||
if (self.pos.Z < self.ceilingz)
|
||||
{
|
||||
coll.setSector(self.sector);
|
||||
self.vel.Z -= 1/256.;
|
||||
}
|
||||
else if ((self.pos.Z > self.floorz && self.sector.lotag != ST_1_ABOVE_WATER)
|
||||
|| (self.pos.Z > self.floorz + 16 && self.sector.lotag == ST_1_ABOVE_WATER))
|
||||
{
|
||||
coll.setSector(self.sector);
|
||||
if (self.sector.lotag != 1)
|
||||
self.vel.Z += 1/256.;
|
||||
}
|
||||
}
|
||||
|
||||
if (coll.type != 0)
|
||||
{
|
||||
self.vel.XY = (0, 0);
|
||||
self.vel.Z = 0;
|
||||
if (coll.type == kHitSprite)
|
||||
{
|
||||
let hitact = DukeActor(coll.hitActor());
|
||||
hitact.checkhitsprite(self);
|
||||
if (hitact.isPlayer())
|
||||
hitact.PlayActorSound("PISTOL_BODYHIT");
|
||||
}
|
||||
else if (coll.type == kHitWall)
|
||||
{
|
||||
self.SetPosition(dapos);
|
||||
dlevel.checkhitwall(coll.hitWall(), self, self.pos);
|
||||
}
|
||||
else if (coll.type == kHitSector)
|
||||
{
|
||||
self.SetPosition(dapos);
|
||||
if (self.vel.Z < 0)
|
||||
dlevel.checkhitceiling(self.sector, self);
|
||||
}
|
||||
|
||||
if (self.scale.X >= 0.15625)
|
||||
{
|
||||
int x = self.extra;
|
||||
self.hitradius(gs.rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = self.extra + (Duke.global_random() & 3);
|
||||
self.hitradius((gs.rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
override bool shootthis(DukeActor actor, DukePlayer p, Vector3 spos, double sang) const
|
||||
{
|
||||
Console.Printf("launching");
|
||||
double vel, zvel = 0;
|
||||
|
||||
if (actor.extra >= 0)
|
||||
actor.shade = -96;
|
||||
vel = 25;
|
||||
|
||||
DukeActor spawned = nullptr;
|
||||
if (p == null)
|
||||
{
|
||||
double x;
|
||||
DukePlayer j;
|
||||
[j, x] = actor.findplayer();
|
||||
sang = (j.Actor.opos.XY - spos.XY).Angle();
|
||||
|
||||
if (actor.checktype("BOSS5"))
|
||||
{
|
||||
vel = 33;
|
||||
spos.Z += 24;
|
||||
}
|
||||
else if (actor.checktype("BOSS3"))
|
||||
spos.Z -= 32;
|
||||
|
||||
double dist = (j.actor.pos.XY - actor.pos.XY).Length();
|
||||
if (dist != 0)
|
||||
zvel = (((j.actor.opos.Z + j.actor.oviewzoffset - spos.Z) * vel) / dist);
|
||||
|
||||
if (actor.badguy() && (actor.hitag & face_player_smart) != 0)
|
||||
sang = actor.Angle + Raze.BAngToDegree * random(-16, 15);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
[vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 40.5);
|
||||
|
||||
// WTF???
|
||||
double myang = 90. - (180. - abs(abs((spos.XY - p.actor.pos.XY).Angle() - sang) - 180.));
|
||||
if (p.actor.vel.X != 0)
|
||||
vel = ((myang / 90.) * p.actor.vel.X) + 25;
|
||||
}
|
||||
|
||||
if (actor.sector.lotag == ST_2_UNDERWATER && (random(0, 4)) == 0)
|
||||
spawned = actor.spawn("DukeWaterBubble");
|
||||
|
||||
if (spawned == nullptr)
|
||||
{
|
||||
spawned = actor.spawn("DukeFlamethrowerFlame");
|
||||
if (!spawned) return true;
|
||||
spawned.vel.X = vel;
|
||||
spawned.vel.Z = zvel;
|
||||
}
|
||||
|
||||
|
||||
Vector3 offset;
|
||||
offset.X = cos(sang + Raze.BAngToDegree * 118) * (1024 / 448.); // Yes, these angles are really different!
|
||||
offset.Y = sin(sang + Raze.BAngToDegree * 112) * (1024 / 448.);
|
||||
offset.Z = -1;
|
||||
|
||||
spawned.pos = spos + offset;
|
||||
spawned.pos.Z--;
|
||||
spawned.sector = actor.sector;
|
||||
spawned.cstat = CSTAT_SPRITE_YCENTER;
|
||||
spawned.Angle = sang;
|
||||
spawned.scale = (0.03125, 0.03125);
|
||||
spawned.clipdist = 10;
|
||||
spawned.yint = Duke.GetPlayerIndex(p);
|
||||
spawned.ownerActor = actor;
|
||||
|
||||
if (p == null)
|
||||
{
|
||||
if (actor.checktype("BOSS5"))
|
||||
{
|
||||
spawned.pos += sang.ToVector() * (128. / 7);
|
||||
spawned.scale = (0.15625, 0.15625);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -7,7 +7,6 @@ class DukeGreenSlime : DukeActor
|
|||
|
||||
override void Initialize()
|
||||
{
|
||||
commonEnemySetup();
|
||||
self.scale = (0.625, 0.625);
|
||||
self.clipdist = 20;
|
||||
self.extra = 1;
|
||||
|
|
34
wadsrc/static/zscript/games/duke/actors/powderkeg.zs
Normal file
34
wadsrc/static/zscript/games/duke/actors/powderkeg.zs
Normal file
|
@ -0,0 +1,34 @@
|
|||
|
||||
class RedneckPowderKeg : DukeActor
|
||||
{
|
||||
default
|
||||
{
|
||||
pic "POWDERKEG";
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
let sectp = self.sector;
|
||||
if (sectp.lotag != ST_1_ABOVE_WATER && sectp.lotag != ST_160_FLOOR_TELEPORT)
|
||||
if (self.vel.X != 0)
|
||||
{
|
||||
movesprite((self.Angle.ToVector()* self.vel.X, self.vel.Z), CLIPMASK0);
|
||||
self.vel.X -= 1. / 16.;
|
||||
}
|
||||
Super.Tick();
|
||||
}
|
||||
|
||||
|
||||
override bool shootthis(DukeActor actor, DukePlayer p, Vector3 spos, double sang)
|
||||
{
|
||||
let j = actor.spawn("RedneckPowderKeg");
|
||||
if (j)
|
||||
{
|
||||
j.vel.X = 2;
|
||||
j.Angle = actor.Angle;
|
||||
j.pos.Z -= 5;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -13,36 +13,12 @@ class DukeRecon : DukeActor
|
|||
|
||||
override void initialize()
|
||||
{
|
||||
if (self.lotag > ud.player_skill)
|
||||
{
|
||||
self.scale = (0, 0);
|
||||
self.ChangeStat(STAT_MISC);
|
||||
return;
|
||||
}
|
||||
if (!Raze.isRR() || self.actorflag1(SFLAG_KILLCOUNT)) // in Duke bad guys always count as kill. RR uses a flag. Needs to be cleaned up.
|
||||
Duke.GetLocalPlayer().max_actors_killed++;
|
||||
self.temp_data[5] = 0;
|
||||
if (ud.monsters_off == 1)
|
||||
{
|
||||
self.scale = (0, 0);
|
||||
self.ChangeStat(STAT_MISC);
|
||||
return;
|
||||
}
|
||||
self.extra = 130;
|
||||
|
||||
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.pal = 0;
|
||||
self.shade = -17;
|
||||
|
||||
self.ChangeStat(STAT_ZOMBIEACTOR);
|
||||
|
||||
|
||||
AttackSnd = "RECO_ATTACK";
|
||||
PainSnd = "RECO_PAIN";
|
||||
RoamSnd = "RECO_ROAM";
|
||||
|
|
|
@ -115,6 +115,28 @@ class DukeActor : CoreActor native
|
|||
STAT_REMOVED = MAXSTATUS-2,
|
||||
|
||||
};
|
||||
|
||||
enum amoveflags_t
|
||||
{
|
||||
face_player = 1,
|
||||
geth = 2,
|
||||
getv = 4,
|
||||
random_angle = 8,
|
||||
face_player_slow = 16,
|
||||
spin = 32,
|
||||
face_player_smart = 64,
|
||||
fleeenemy = 128,
|
||||
jumptoplayer_only = 256,
|
||||
justjump1 = 256,
|
||||
jumptoplayer = 257,
|
||||
seekplayer = 512,
|
||||
furthestdir = 1024,
|
||||
dodgebullet = 4096,
|
||||
justjump2 = 8192,
|
||||
windang = 16384,
|
||||
antifaceplayerslow = 32768
|
||||
};
|
||||
|
||||
|
||||
native void SetSpritesetImage(int index);
|
||||
native int GetSpritesetSize();
|
||||
|
@ -187,7 +209,6 @@ class DukeActor : CoreActor native
|
|||
|
||||
virtual void BeginPlay() {}
|
||||
virtual void StaticSetup() {}
|
||||
virtual void Initialize() {}
|
||||
virtual void onHit(DukeActor hitter) { checkhitdefault(hitter); }
|
||||
virtual void onHurt(DukePlayer p) {}
|
||||
virtual bool onUse(DukePlayer user) { return false; }
|
||||
|
@ -208,6 +229,7 @@ class DukeActor : CoreActor native
|
|||
native void hitradius(int r, int hp1, int hp2, int hp3, int hp4);
|
||||
native double, DukeActor hitasprite();
|
||||
native int badguy();
|
||||
native int scripted();
|
||||
native int isplayer();
|
||||
native void lotsofstuff(Name type, int count);
|
||||
native double gutsoffset();
|
||||
|
@ -229,33 +251,26 @@ class DukeActor : CoreActor native
|
|||
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)
|
||||
|
||||
virtual void Initialize()
|
||||
{
|
||||
if (!self.mapSpawned) self.lotag = 0;
|
||||
|
||||
if ((self.lotag > ud.player_skill) || ud.monsters_off == 1)
|
||||
if (!self.badguy() && self.scripted())
|
||||
{
|
||||
self.scale = (0, 0);
|
||||
self.ChangeStat(STAT_MISC);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.makeitfall();
|
||||
if (!self.mapSpawned) self.lotag = 0;
|
||||
|
||||
self.cstat |= CSTAT_SPRITE_BLOCK_ALL;
|
||||
if (countkill)
|
||||
Duke.GetLocalPlayer().max_actors_killed++;
|
||||
|
||||
if (!self.mapSpawned)
|
||||
if (self.lotag > ud.player_skill)
|
||||
{
|
||||
self.timetosleep = 0;
|
||||
self.PlayFTASound();
|
||||
self.ChangeStat(STAT_ACTOR);
|
||||
self.scale = (0, 0);
|
||||
self.ChangeStat(STAT_MISC);
|
||||
}
|
||||
else self.ChangeStat(STAT_ZOMBIEACTOR);
|
||||
self.clipdist = 10;
|
||||
self.ownerActor = self;
|
||||
self.ChangeStat(STAT_ACTOR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int checkLocationForFloorSprite(double radius)
|
||||
{
|
||||
bool away = self.isAwayFromWall(radius);
|
||||
|
|
|
@ -170,6 +170,7 @@ struct Duke native
|
|||
native static void updatepindisplay(int tag, int pinmask);
|
||||
native static bool StartCommentary(int tag, DukeActor act);
|
||||
native static void StopCommentary();
|
||||
static native int getPlayerIndex(DukePlayer p);
|
||||
static int rnd(int val)
|
||||
{
|
||||
return (random(0, 255) >= (255 - (val)));
|
||||
|
@ -216,6 +217,7 @@ struct Duke native
|
|||
if (align != -1) x -= myfont.StringWidth(t) * (align == 0 ? 0.5 : 1);
|
||||
Screen.DrawText(myfont, Font.CR_NATIVEPAL, x, y + 2, t, DTA_FullscreenScale, fsmode, DTA_TranslationIndex, Translation.MakeID(Translation_Remap, trans), DTA_Color, Raze.shadeToLight(shade));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct DukePlayer native
|
||||
|
|
|
@ -264,6 +264,11 @@ struct Raze
|
|||
// Right now, with no MP support there is no need, though.
|
||||
}
|
||||
|
||||
static double, double setFreeAimVelocity(double vel, double zvel, double pitch, double zvspeed)
|
||||
{
|
||||
return vel * cos(pitch), sin(pitch) * zvspeed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue