- refactored Duke's cactus.

This commit is contained in:
Christoph Oelckers 2022-11-15 10:17:23 +01:00
parent ad7cf290d2
commit a2683559ce
15 changed files with 120 additions and 78 deletions

View file

@ -355,7 +355,7 @@ DCoreActor* InsertActor(PClass* type, sectortype* sector, int stat, bool tail)
#define setter(flag, var) if (actorinfo->DefaultFlags & flag) actor->spr.var = actorinfo->defsprite.var;
if (actorinfo->DefaultFlags & DEFF_STATNUM) stat = actorinfo->defsprite.statnum;
if (stat < 0 && (actorinfo->DefaultFlags & DEFF_STATNUM)) stat = actorinfo->defsprite.statnum;
setter(DEFF_PICNUM, picnum);
setter(DEFF_ANG, angle);
setter(DEFF_XVEL, xint);

View file

@ -117,6 +117,7 @@ void CallInitialize(DDukeActor* actor);
void CallTick(DDukeActor* actor);
void CallAction(DDukeActor* actor);
void CallOnHit(DDukeActor* actor, DDukeActor* hitter);
void CallOnHurt(DDukeActor* actor, player_struct* hitter);
void CallOnUse(DDukeActor* actor, player_struct* user);
bool CallAnimate(DDukeActor* actor, tspritetype* hitter);

View file

@ -172,6 +172,7 @@ void OnEvent(int id, int pnum = -1, DDukeActor* snum = nullptr, int dist = -1);
DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, int s_pn, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat);
DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor* cls, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat);
DDukeActor* SpawnActor(sectortype* whatsectp, const DVector3& pos, PClassActor* cls, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat = -1);
void ceilingglass(DDukeActor* snum, sectortype* sectnum, int cnt);
void spriteglass(DDukeActor* snum, int cnt);

View file

@ -435,6 +435,17 @@ void CallOnHit(DDukeActor* actor, DDukeActor* hitter)
}
}
void CallOnHurt(DDukeActor* actor, player_struct* hitter)
{
IFVIRTUALPTR(actor, DDukeActor, onHurt)
{
VMValue val[2] = { actor, hitter };
VMCall(func, val, 2, nullptr, 0);
}
}
void CallOnUse(DDukeActor* actor, player_struct* user)
{
IFVIRTUALPTR(actor, DDukeActor, onUse)

View file

@ -885,18 +885,7 @@ void checkplayerhurt_d(player_struct* p, const Collision& coll)
{
if (coll.type == kHitSprite)
{
switch (coll.actor()->spr.picnum)
{
case CACTUS:
if (p->hurt_delay < 8)
{
p->GetActor()->spr.extra -= 5;
p->hurt_delay = 16;
SetPlayerPal(p, PalEntry(32, 32, 0, 0));
S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor());
}
break;
}
CallOnHurt(coll.actor(), p);
return;
}
@ -1064,30 +1053,6 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj)
}
}
break;
case CACTUS:
// case CACTUSBROKE:
if (actorflag(proj, SFLAG_INFLAME))
{
for (k = 0; k < 64; k++)
{
auto a = randomAngle();
auto vel = krandf(4) + 4;
auto zvel = -krandf(16) - targ->vel.Z * 0.25;
auto spawned = CreateActor(targ->sector(), targ->spr.pos.plusZ(-48), PClass::FindActor("DukeScrap"), -8, DVector2(0.75, 0.75), a, vel, zvel, targ, STAT_MISC);
if (spawned)
{
if (spawned) spawned->spriteextra = Scrap3 + krand() & 3;
spawned->spr.pal = 6;
}
}
if (targ->spr.picnum == CACTUS)
targ->spr.picnum = CACTUSBROKE;
targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
}
break;
case HANGLIGHT:
case GENERICPOLE2:
for (k = 0; k < 6; k++)

View file

@ -1383,18 +1383,13 @@ void checkplayerhurt_r(player_struct* p, const Collision &coll)
SetPlayerPal(p, PalEntry(32, 32, 0, 0));
S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor());
}
break;
case CACTUS:
if (!isRRRA() && p->hurt_delay < 8)
{
p->GetActor()->spr.extra -= 5;
p->hurt_delay = 16;
SetPlayerPal(p, PalEntry(32, 32, 0, 0));
S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor());
}
break;
return;
default:
CallOnHurt(coll.actor(), p);
return;
}
return;
}
if (coll.type != kHitWall) return;
@ -2061,7 +2056,8 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj)
auto vel = krandf(4) + 4;
auto zvel = -krandf(16) - targ->vel.Z * 0.25;
CreateActor(targ->sector(), targ->spr.pos.plusZ(-8), SCRAP6 + (krand() & 15), -8, DVector2(0.75, 0.75), a, vel, zvel, targ, 5);
auto spawned = CreateActor(targ->sector(), targ->spr.pos.plusZ(-8), PClass::FindActor("DukeScrap"), -8, DVector2(0.75, 0.75), a, vel, zvel, targ, 5);
if (spawned) spawned->spriteextra = Scrap6 + (krand() & 15);
}
break;
case BOWLINGBALL:
@ -2108,28 +2104,6 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj)
}
break;
case CACTUS:
// case CACTUSBROKE:
if (actorflag(proj, SFLAG_INFLAME))
{
for (k = 0; k < 64; k++)
{
auto a = randomAngle();
auto vel = krandf(4) + 4;
auto zvel = -krandf(16) - targ->vel.Z * 0.25;
auto spawned = CreateActor(targ->sector(), targ->spr.pos.plusZ(-krandf(48)), SCRAP6 + (krand() & 3), -8, DVector2(0.75, 0.75), a, vel, zvel, targ, 5);
if (spawned) spawned->spr.pal = 8;
}
if (targ->spr.picnum == CACTUS)
targ->spr.picnum = CACTUSBROKE;
targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
// else deletesprite(i);
}
break;
case FANSPRITE:
targ->spr.picnum = FANSPRITEBROKE;
targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;

View file

@ -77,7 +77,7 @@ DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor*
act->spr.pos = pos;
if (s_pn != -1) act->spr.picnum = s_pn; // if -1 use the class default.
act->spr.shade = s_shd;
act->spr.scale = DVector2(scale.X, scale.Y);
if (!scale.isZero()) act->spr.scale = DVector2(scale.X, scale.Y);
act->spr.angle = s_ang;
act->vel.X = s_vel;
@ -134,9 +134,9 @@ DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor*
return CreateActor(whatsectp, pos, cls, -1, s_shd, scale, s_ang, s_vel, s_zvel, s_ow, s_stat);
}
DDukeActor* SpawnActor(sectortype* whatsectp, const DVector3& pos, int s_pn, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat)
DDukeActor* SpawnActor(sectortype* whatsectp, const DVector3& pos, PClassActor* cls, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat)
{
auto actor = CreateActor(whatsectp, pos, s_pn, s_shd, scale, s_ang, s_vel, s_zvel, s_ow, s_stat);
auto actor = CreateActor(whatsectp, pos, cls, s_shd, scale, s_ang, s_vel, s_zvel, s_ow, s_stat);
if (actor) fi.spawninit(s_ow, actor, nullptr);
return actor;
}

View file

@ -390,8 +390,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
case SCALE:
case VACUUM:
case FANSPRITE:
case CACTUS:
case CACTUSBROKE:
case HANGLIGHT:
case FETUS:
case FETUSBROKE:

View file

@ -384,8 +384,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
case SCALE:
case VACUUM:
case FANSPRITE:
case CACTUS:
case CACTUSBROKE:
case CAMERALIGHT:
case MOVIECAMERA:
case IVUNIT:

View file

@ -611,6 +611,30 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukeSpriteIterator, Next, duke_nextSprite)
ACTION_RETURN_POINTER(duke_nextSprite(self));
}
DDukeActor* DukeLevel_SpawnActor(DukeLevel* self, sectortype* sect, double x, double y, double z, PClassActor* type, int shade, double scalex, double scaley, double angle, double vel, double zvel, DDukeActor* owner, int stat)
{
return SpawnActor(sect, DVector3(x, y, z), type, shade, DVector2(scalex, scaley), DAngle::fromDeg(angle), vel, zvel, owner, stat);
}
DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, SpawnActor, DukeLevel_SpawnActor)
{
PARAM_SELF_STRUCT_PROLOGUE(DukeLevel);
PARAM_POINTER(sect, sectortype);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
PARAM_CLASS(type, DDukeActor);
PARAM_INT(shade);
PARAM_FLOAT(scalex);
PARAM_FLOAT(scaley);
PARAM_FLOAT(angle);
PARAM_FLOAT(vel);
PARAM_FLOAT(zvel);
PARAM_OBJECT(owner, DDukeActor);
PARAM_INT(stat);
ACTION_RETURN_POINTER(DukeLevel_SpawnActor(self, sect, x, y, z, static_cast<PClassActor*>(type), shade, scalex, scaley, angle, vel, zvel, owner, stat));
}
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, playerfriction);
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, gravity);
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, respawnactortime);

View file

@ -12,4 +12,6 @@ spawnclasses
908 = DukeTree1
910 = DukeTree2
990 = DukeTire
911 = DukeCactus
939 = DukeCactusBroke
}

View file

@ -11,5 +11,7 @@ spawnclasses
1191 = DukeTree1
1193 = DukeTree2
1230 = DukeTire
1194 = DukeCactus
1203 = DukeCactusBroke
}

View file

@ -54,6 +54,7 @@ version "4.9"
#include "zscript/games/duke/actors/waterfountain.zs"
#include "zscript/games/duke/actors/flammables.zs"
#include "zscript/games/duke/actors/scrap.zs"
#include "zscript/games/duke/actors/cactus.zs"
#include "zscript/games/blood/bloodgame.zs"
#include "zscript/games/blood/ui/menu.zs"

View file

@ -0,0 +1,63 @@
class DukeCactusBroke : DukeActor
{
default
{
clipdist 8;
statnum STAT_ACTOR;
pic "CACTUSBROKE";
}
override void Initialize()
{
self.cstat |= CSTAT_SPRITE_BLOCK_ALL;
}
}
class DukeCactus : DukeCactusBroke
{
default
{
clipdist 8;
statnum STAT_ACTOR;
spriteset "CACTUS", "CACTUSBROKE";
}
override void onHit(DukeActor hitter)
{
if (self.spritesetindex == 0 && hitter.actorflag1(SFLAG_INFLAME))
{
let scrap = Raze.isRR()? DukeScrap.Scrap6 : DukeScrap.Scrap3;
for (int k = 0; k < 64; k++)
{
double ang = frandom(0, 360);
double vel = frandom(4, 8);
double zvel = -frandom(0, 16) - self.vel.Z * 0.25;
let spawned = dlevel.SpawnActor(self.sector, self.pos.plusZ(-48), "DukeScrap", -8, (0.75, 0.75), ang, vel, zvel, self);
if (spawned)
{
spawned.spriteextra = DukeScrap.Scrap3 + random(0, 3);
spawned.pal = 6;
}
}
setSpritePic(1);
self.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
}
}
override void onHurt(DukePlayer p)
{
if (self.spritesetindex == 0 && p.hurt_delay < 8)
{
p.actor.extra -= 5;
p.hurt_delay = 16;
p.pals = Color(32, 32, 0, 0);
p.actor.PlayActorSound(DukeSnd.DUKE_LONGTERM_PAIN);
}
}
}

View file

@ -78,6 +78,7 @@ class DukeActor : CoreActor native
virtual void Initialize() {}
virtual void Tick() {}
virtual void onHit(DukeActor hitter) {}
virtual void onHurt(DukePlayer p) {}
virtual void onUse(DukePlayer user) {}
virtual bool animate(tspritetype tspr) { return false; }
virtual void RunState() {} // this is the CON function.
@ -101,6 +102,7 @@ extend struct _
// On the script side we do not really want scattered global data that is publicly accessible.
struct DukeLevel
{
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);
}
struct DukeStatIterator