- scriptified several of Duke's destructible items.

This commit is contained in:
Christoph Oelckers 2022-12-02 19:55:28 +01:00
parent 066c4c88b2
commit e6c466fcba
14 changed files with 229 additions and 104 deletions

View file

@ -473,6 +473,36 @@ DEFINE_ACTION_FUNCTION_NATIVE(_sectortype, nextsectorneighborz, nextsectorneighb
ACTION_RETURN_POINTER(nextsectorneighborzptr(self, z, find));
}
int sector_checktexture(sectortype* sec, int place, int intname)
{
if (!sec) ThrowAbortException(X_READ_NIL, nullptr);
int tilenum = TileFiles.tileForName(FName(ENamedName(intname)).GetChars());
return tilenum == place ? sec->ceilingpicnum : sec->floorpicnum;
}
DEFINE_ACTION_FUNCTION_NATIVE(_sectortype, checktexture, sector_checktexture)
{
PARAM_SELF_STRUCT_PROLOGUE(sectortype);
PARAM_INT(place);
PARAM_INT(name);
ACTION_RETURN_BOOL(sector_checktexture(self, place, name));
}
void sector_settexture(sectortype* sec, int place, int intname)
{
if (!sec) ThrowAbortException(X_READ_NIL, nullptr);
int tilenum = TileFiles.tileForName(FName(ENamedName(intname)).GetChars());
(place ? sec->ceilingpicnum : sec->floorpicnum) = tilenum;
}
DEFINE_ACTION_FUNCTION_NATIVE(_sectortype, settexture, sector_settexture)
{
PARAM_SELF_STRUCT_PROLOGUE(sectortype);
PARAM_INT(place);
PARAM_INT(name);
sector_settexture(self, place, name);
return 0;
}
//=============================================================================

View file

@ -78,10 +78,10 @@ static int ccmd_spawn(CCmdFuncPtr parm)
}
else
{
picnum = getlabelvalue(parm->parms[0]);
picnum = TileFiles.tileForName(parm->parms[0]);
if (picnum < 0)
{
picnum = TileFiles.tileForName(parm->parms[0]);
picnum = getlabelvalue(parm->parms[0]);
if (picnum < 0)
{
Printf("spawn: Invalid tile label given\n");

View file

@ -398,6 +398,7 @@ enum sflags3_t
SFLAG3_DONTDIVEALIVE = 0x00000001,
SFLAG3_BLOODY = 0x00000002,
SFLAG3_BROWNBLOOD = 0x00000004,
SFLAG3_LIGHTDAMAGE = 0x00000008,
};

View file

@ -126,6 +126,8 @@ void initactorflags_d()
setflag(SFLAG2_MIRRORREFLECT, { SHRINKSPARK, FIRELASER, COOLEXPLOSION1 });
setflag(SFLAG2_UNDERWATERSLOWDOWN, { RPG });
setflag(SFLAG3_BROWNBLOOD, { FECES });
setflag(SFLAG3_DONTDIVEALIVE, { OCTABRAIN, SHARK, GREENSLIME });
setflag(SFLAG3_LIGHTDAMAGE, { SHOTSPARK1 });
if (isWorldTour())
{

View file

@ -1060,69 +1060,6 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj)
switch (targ->spr.picnum)
{
case FANSPRITE:
targ->spr.picnum = FANSPRITEBROKE;
targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
if (targ->sector()->floorpicnum == FANSHADOW)
targ->sector()->floorpicnum = FANSHADOWBROKE;
S_PlayActorSound(GLASS_HEAVYBREAK, targ);
for (j = 0; j < 16; j++) RANDOMSCRAP(targ);
break;
case SATELITE:
case FUELPOD:
case SOLARPANNEL:
case ANTENNA:
if (gs.actorinfo[SHOTSPARK1].scriptaddress && proj->spr.extra != ScriptCode[gs.actorinfo[SHOTSPARK1].scriptaddress])
{
for (j = 0; j < 15; j++)
{
auto a = randomAngle();
auto vel = krandf(8) + 4;
auto zvel = -krandf(2) - 1;
auto spawned = CreateActor(targ->sector(), DVector3(targ->spr.pos.XY(), targ->sector()->floorz - 12 - j * 2), PClass::FindActor("DukeScrap"), -8, DVector2(1, 1), a, vel, zvel, targ, 5);
if (spawned) spawned->spriteextra = Scrap1 + (krand() & 15);
}
spawn(targ, EXPLOSION2);
targ->Destroy();
}
break;
case FETUS:
targ->spr.picnum = FETUSBROKE;
S_PlayActorSound(GLASS_BREAKING, targ);
lotsofglass(targ, nullptr, 10);
break;
case FETUSBROKE:
for (j = 0; j < 48; j++)
{
fi.shoot(targ, -1, PClass::FindActor("DukeBloodSplat1"));
targ->spr.Angles.Yaw += DAngle1 * 58.5; // Was 333, which really makes no sense.
}
S_PlayActorSound(GLASS_HEAVYBREAK, targ);
S_PlayActorSound(SQUISHED, targ);
S_PlayActorSound(GLASS_BREAKING, targ);
lotsofglass(targ, nullptr, 10);
targ->Destroy();
break;
case HYDROPLANT:
targ->spr.picnum = BROKEHYDROPLANT;
S_PlayActorSound(GLASS_BREAKING, targ);
lotsofglass(targ, nullptr, 10);
break;
case BROKEHYDROPLANT:
if (targ->spr.cstat & CSTAT_SPRITE_BLOCK)
{
S_PlayActorSound(GLASS_BREAKING, targ);
targ->spr.pos.Z += 16;
targ->spr.cstat = 0;
lotsofglass(targ, nullptr, 5);
}
break;
case TOILET:
targ->spr.picnum = TOILETBROKE;
if (krand() & 1) targ->spr.cstat |= CSTAT_SPRITE_XFLIP;

View file

@ -1434,33 +1434,6 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj)
if (spawned) spawned->spriteextra = Scrap6 + (krand() & 15);
}
break;
case FANSPRITE:
targ->spr.picnum = FANSPRITEBROKE;
targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
S_PlayActorSound(GLASS_HEAVYBREAK, targ);
for (j = 0; j < 16; j++) RANDOMSCRAP(targ);
break;
case SATELITE:
case FUELPOD:
case SOLARPANNEL:
case ANTENNA:
if (gs.actorinfo[SHOTSPARK1].scriptaddress && proj->spr.extra != ScriptCode[gs.actorinfo[SHOTSPARK1].scriptaddress])
{
for (j = 0; j < 15; j++)
{
auto a = randomAngle();
auto vel = krandf(8) + 4;
auto zvel = -krandf(2) - 1;
auto spawned = CreateActor(targ->sector(), DVector3(targ->spr.pos.XY(), targ->sector()->floorz - 12 - j * 2), PClass::FindActor("DukeScrap"), -8, DVector2(1, 1),
a, vel, zvel, targ, 5);
if (spawned) spawned->spriteextra = Scrap1 + (krand() & 15);
}
spawn(targ, EXPLOSION2);
targ->Destroy();
}
break;
case RRTILE2654:
case RRTILE2656:
case RRTILE3172:

View file

@ -186,17 +186,10 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
break;
case HYDRENT:
case SATELITE:
case FUELPOD:
case SOLARPANNEL:
case ANTENNA:
case MONK:
case INDY:
case LUKE:
case JURYGUY:
case FANSPRITE:
case FETUS:
case FETUSBROKE:
case PIPE1:
case PIPE2:
case PIPE3:

View file

@ -93,12 +93,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
ChangeActorStat(act, STAT_MISC);
break;
case HYDRENT:
case SATELITE:
case FUELPOD:
case SOLARPANNEL:
case ANTENNA:
case GRATE1:
case FANSPRITE:
case PIPE1:
case PIPE2:
case PIPE3:

View file

@ -31,6 +31,7 @@ int PicForName(int intname)
{"DukeSmallSmoke", "SMALLSMOKE"},
{"DukeBurning", "BURNING"},
{"RedneckBowlingBallSprite", "BOWLINGBALLSPRITE"},
{"DukeBloodSplat1", "BLOODSPLAT1"},
};
for (auto& p : classes)

View file

@ -98,6 +98,16 @@ spawnclasses
2533 = DukeShell
2535 = DukeShotgunShell
1226 = DukeBloodPool
407 = DukeFanSprite
516 = DukeSatellite
517 = DukeFuelPod
602 = DukeSolarPanel
607 = DukeAntenna
1358 = DukeFetus
1359 = DukeFetusBroke
969 = DukeHydroplant
1003 = DukeHydroplantBroke
1272 = DukeTrash
634 = DukeBolt1

View file

@ -89,6 +89,13 @@ spawnclasses
1702 = DukeShell
1704 = DukeShotgunShell
1303 = DukeBloodPool
210 = DukeFanSprite
1066 = DukeSatellite
1067 = DukeFuelPod
1114 = DukeSolarPanel
1117 = DukeAntenna
1349 = DukeFetus
1360 = DukeFetusBroke
26 = RedneckDynamite
1416 = RedneckMortar

View file

@ -108,3 +108,171 @@ class DukeVase : DukeActor
}
}
class DukeFanSprite : DukeActor
{
Default
{
spriteset "FANSPRITE", "FANSPRITEBROKE";
clipdist 8;
statnum STAT_DEFAULT;
}
override void Initialize()
{
self.cstat |= CSTAT_SPRITE_BLOCK_ALL;
}
override void OnHit(DukeActor proj)
{
if (self.spritesetindex == 0)
{
self.setSpriteSetImage(1);
self.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
if (self.sector.CheckTexture(sectortype.floor, "FANSHADOW"))
self.sector.SetTexture(sectortype.floor, "FANSHADOWBROKE");
self.PlayActorSound("GLASS_HEAVYBREAK");
for (int j = 0; j < 16; j++) self.RANDOMSCRAP();
}
}
}
class DukeSatellite : DukeActor
{
Default
{
pic "SATELITE";
clipdist 8;
statnum STAT_DEFAULT;
}
override void Initialize()
{
self.cstat |= CSTAT_SPRITE_BLOCK_ALL;
}
override void OnHit(DukeActor proj)
{
if (!proj.actorflag3(SFLAG3_LIGHTDAMAGE))
{
for (int j = 0; j < 15; j++)
{
let a = frandom(0, 360);
let vel = frandom(4, 12);
let zvel = -frandom(-1, 1);
let spawned = dlevel.SpawnActor(self.sector, (self.pos.XY, self.sector.floorz - 12 - j * 2), 'DukeScrap', -8, (1, 1), a, vel, zvel, self, STAT_MISC);
if (spawned) spawned.spriteextra = DukeScrap.Scrap1 + random(0, 15);
}
self.spawn("DukeExplosion2");
self.Destroy();
}
}
}
class DukeFuelPod : DukeSatellite
{
Default
{
pic "FUELPOD";
}
}
class DukeSolarPanel : DukeSatellite
{
Default
{
pic "SOLARPANNEL";
}
}
class DukeAntenna : DukeSatellite
{
Default
{
pic "ANTENNA";
}
}
class DukeFetus : DukeActor
{
Default
{
spriteset "FETUS", "FETUSBROKE";
clipdist 8;
statnum STAT_DEFAULT;
}
override void Initialize()
{
self.cstat |= CSTAT_SPRITE_BLOCK_ALL;
}
override void OnHit(DukeActor proj)
{
Console.printf("a%d", self.spritesetindex);
if (self.spritesetindex == 0)
{
Console.printf("a%d", proj.spawnindex);
self.setSpriteSetImage(1);
self.PlayActorSound("GLASS_BREAKING");
self.lotsofglass(10);
}
else
{
Console.printf("b%d", proj.spawnindex);
for (int j = 0; j < 48; j++)
{
self.shoot("DukeBloodSplat1");
self.angle += 58.5; // Was 333, which really makes no sense.
}
self.PlayActorSound("GLASS_HEAVYBREAK");
self.PlayActorSound("SQUISHED");
self.PlayActorSound("GLASS_BREAKING");
self.lotsofglass(10);
self.Destroy();
}
}
}
class DukeFetusBroke : DukeFetus
{
Default
{
spritesetindex 1;
}
}
// This one had no init code.
class DukeHydroplant : DukeActor
{
Default
{
spriteset "HYDROPLANT", "BROKEHYDROPLANT";
}
override void OnHit(DukeActor proj)
{
if (self.spritesetindex == 0)
{
self.setSpriteSetImage(1);
self.PlayActorSound("GLASS_BREAKING");
self.lotsofglass(10);
}
else if (self.cstat & CSTAT_SPRITE_BLOCK)
{
self.PlayActorSound("GLASS_BREAKING");
self.pos.Z += 16;
self.cstat = 0;
self.lotsofglass(5);
}
}
}
class DukeHydroplantBroke : DukeHydroplant
{
Default
{
spritesetindex 1;
}
}

View file

@ -416,4 +416,5 @@ enum sflags3_t
SFLAG3_DONTDIVEALIVE = 0x00000001,
SFLAG3_BLOODY = 0x00000002,
SFLAG3_BROWNBLOOD = 0x00000004,
SFLAG3_LIGHTDAMAGE = 0x00000008,
};

View file

@ -118,6 +118,11 @@ enum ESectorExBits
struct sectortype native
{
enum EPlane
{
ceiling = 0,
floor = 1,
}
enum EFindNextSector
{
Find_Floor = 0,
@ -235,6 +240,8 @@ struct sectortype native
native int floorslope();
native double, double getslopes(Vector2 pos);
native sectortype nextsectorneighborz(double refz, int find);
native bool CheckTexture(int place, Name tex);
native void SetTexture(int place, Name tex);
}