diff --git a/source/core/vmexports.cpp b/source/core/vmexports.cpp index faf7346d6..3198205e1 100644 --- a/source/core/vmexports.cpp +++ b/source/core/vmexports.cpp @@ -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; +} + //============================================================================= diff --git a/source/games/duke/src/ccmds.cpp b/source/games/duke/src/ccmds.cpp index 27397e335..43637b98b 100644 --- a/source/games/duke/src/ccmds.cpp +++ b/source/games/duke/src/ccmds.cpp @@ -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"); diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index fd2983140..d4d2d76a9 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -398,6 +398,7 @@ enum sflags3_t SFLAG3_DONTDIVEALIVE = 0x00000001, SFLAG3_BLOODY = 0x00000002, SFLAG3_BROWNBLOOD = 0x00000004, + SFLAG3_LIGHTDAMAGE = 0x00000008, }; diff --git a/source/games/duke/src/flags_d.cpp b/source/games/duke/src/flags_d.cpp index 4117a3073..67a15c53b 100644 --- a/source/games/duke/src/flags_d.cpp +++ b/source/games/duke/src/flags_d.cpp @@ -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()) { diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 56bacaa6a..f2fd07e41 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -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; diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 60f5f7367..65a4bc756 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -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: diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index 50e080052..678d3ac5e 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -186,17 +186,10 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* 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: diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index 03b52c4ce..18c64eb5b 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -93,12 +93,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* 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: diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index 1c49bc927..2cd8f5da0 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -31,6 +31,7 @@ int PicForName(int intname) {"DukeSmallSmoke", "SMALLSMOKE"}, {"DukeBurning", "BURNING"}, {"RedneckBowlingBallSprite", "BOWLINGBALLSPRITE"}, + {"DukeBloodSplat1", "BLOODSPLAT1"}, }; for (auto& p : classes) diff --git a/wadsrc/static/filter/dukelike/engine/engine.def b/wadsrc/static/filter/dukelike/engine/engine.def index 197dbcfd2..e29ec04b6 100644 --- a/wadsrc/static/filter/dukelike/engine/engine.def +++ b/wadsrc/static/filter/dukelike/engine/engine.def @@ -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 diff --git a/wadsrc/static/filter/redneck/engine/engine.def b/wadsrc/static/filter/redneck/engine/engine.def index 181d79abb..9f611fc87 100644 --- a/wadsrc/static/filter/redneck/engine/engine.def +++ b/wadsrc/static/filter/redneck/engine/engine.def @@ -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 diff --git a/wadsrc/static/zscript/games/duke/actors/destructibles.zs b/wadsrc/static/zscript/games/duke/actors/destructibles.zs index e352f55ab..d9b5f3003 100644 --- a/wadsrc/static/zscript/games/duke/actors/destructibles.zs +++ b/wadsrc/static/zscript/games/duke/actors/destructibles.zs @@ -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; + } +} diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index 5f7b5ebc5..65779870b 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -416,4 +416,5 @@ enum sflags3_t SFLAG3_DONTDIVEALIVE = 0x00000001, SFLAG3_BLOODY = 0x00000002, SFLAG3_BROWNBLOOD = 0x00000004, + SFLAG3_LIGHTDAMAGE = 0x00000008, }; diff --git a/wadsrc/static/zscript/maptypes.zs b/wadsrc/static/zscript/maptypes.zs index bc80ec8b7..2bee29735 100644 --- a/wadsrc/static/zscript/maptypes.zs +++ b/wadsrc/static/zscript/maptypes.zs @@ -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); }