diff --git a/source/core/actorinfo.cpp b/source/core/actorinfo.cpp index 231d24210..8ab37c5bb 100644 --- a/source/core/actorinfo.cpp +++ b/source/core/actorinfo.cpp @@ -258,14 +258,6 @@ void FActorInfo::ResolveTextures(const char* clsname, DCoreActor* defaults) if (defaults->spritesetindex < 0 || defaults->spritesetindex >= (int)SpriteSet.Size()) defaults->spritesetindex = 0; defaults->spr.picnum = SpriteSet[defaults->spritesetindex]; // Unless picnum is specified it will be set to the given image of the sprite set. } - if (PicName.IsNotEmpty()) - { - defaults->spr.picnum = TileFiles.tileForName(PicName); -#ifdef _DEBUG - if (defaults->spr.picnum == -1) Printf(TEXTCOLOR_RED "Unknown texture '%s' in pic for class %s\n", PicName.GetChars(), clsname); -#endif - } SpriteSetNames.Reset(); - PicName = ""; } diff --git a/source/core/actorinfo.h b/source/core/actorinfo.h index 5eb6ac4c2..98568bb92 100644 --- a/source/core/actorinfo.h +++ b/source/core/actorinfo.h @@ -47,7 +47,6 @@ struct FActorInfo int Health = 0; // not used yet - this will stand in if no CON defines a health value for Duke. // these are temporary. Due to how Build games handle their tiles, we cannot look up the textures when scripts are being parsed. - FString PicName; TArray SpriteSetNames; FActorInfo() = default; @@ -57,7 +56,6 @@ struct FActorInfo TypeNum = other.TypeNum; DefaultFlags = other.DefaultFlags; DefaultCstat = other.DefaultCstat; - PicName = other.PicName; SpriteSetNames = other.SpriteSetNames; } diff --git a/source/core/thingdef_properties.cpp b/source/core/thingdef_properties.cpp index 569cd8d99..17104f508 100644 --- a/source/core/thingdef_properties.cpp +++ b/source/core/thingdef_properties.cpp @@ -305,15 +305,13 @@ static bool PointerCheck(PType *symtype, PType *checktype) //========================================================================== // -// Default spritetype fields cannot be set directly -// they need to be combined with the data from the map, so they need to be -// stored outside the actual actor until the spawn code can init it. // //========================================================================== DEFINE_PROPERTY(pic, S, CoreActor) { PROP_STRING_PARM(str, 0); - bag.Info->ActorInfo()->PicName = str; + info->ActorInfo()->SpriteSetNames.Clear(); + info->ActorInfo()->SpriteSetNames.Push(str); bag.Info->ActorInfo()->DefaultFlags |= DEFF_PICNUM; } diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index f9482e9f3..2c872fec6 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -2581,8 +2581,6 @@ void moveexplosions_r(void) // STATNUM 5 break; - case RRTILE2460: - case RRTILE2465: case BIKEJIBA: case BIKEJIBB: case BIKEJIBC: @@ -2624,8 +2622,7 @@ void moveexplosions_r(void) // STATNUM 5 case DUKETORSO: case DUKEGUN: case DUKELEG: - if (!jibs(act, JIBS6, false, true, true, act->spr.picnum == DUKELEG || act->spr.picnum == DUKETORSO || act->spr.picnum == DUKEGUN, - isRRRA() && (act->spr.picnum == RRTILE2465 || act->spr.picnum == RRTILE2560))) continue; + if (!jibs(act, JIBS6, false, true, true, act->spr.picnum == DUKELEG || act->spr.picnum == DUKETORSO || act->spr.picnum == DUKEGUN, false)) continue; if (act->sector()->lotag == 800) if (act->spr.pos.Z >= act->sector()->floorz - 8) diff --git a/source/games/duke/src/animatesprites_r.cpp b/source/games/duke/src/animatesprites_r.cpp index 8afa2cfba..34ee12ed2 100644 --- a/source/games/duke/src/animatesprites_r.cpp +++ b/source/games/duke/src/animatesprites_r.cpp @@ -526,8 +526,6 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi break; - case RRTILE2460: - case RRTILE2465: case BIKEJIBA: case BIKEJIBB: case BIKEJIBC: diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index deed404b3..dbd4aa30b 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -123,6 +123,7 @@ void CallOnHit(DDukeActor* actor, DDukeActor* hitter); void CallOnHurt(DDukeActor* actor, player_struct* hitter); void CallOnTouch(DDukeActor* actor, player_struct* hitter); bool CallOnUse(DDukeActor* actor, player_struct* user); +void CallOnMotoSmash(DDukeActor* actor, player_struct* hitter); void CallOnRespawn(DDukeActor* actor, int low); bool CallAnimate(DDukeActor* actor, tspritetype* hitter); void CallStaticSetup(DDukeActor* actor); diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index 338a4ed1b..be4aa6721 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -466,6 +466,16 @@ bool CallOnUse(DDukeActor* actor, player_struct* user) return nval; } +void CallOnMotoSmash(DDukeActor* actor, player_struct* hitter) +{ + IFVIRTUALPTR(actor, DDukeActor, onMotoSmash) + { + VMValue val[2] = { actor, hitter }; + VMCall(func, val, 2, nullptr, 0); + } +} + + void CallOnRespawn(DDukeActor* actor, int low) { IFVIRTUALPTR(actor, DDukeActor, onRespawn) diff --git a/source/games/duke/src/namelist_r.h b/source/games/duke/src/namelist_r.h index 11b06f02d..b08adc951 100644 --- a/source/games/duke/src/namelist_r.h +++ b/source/games/duke/src/namelist_r.h @@ -689,18 +689,18 @@ y(RRTILE2326, 2326) y(RRTILE2329, 2329) y(RRTILE2357, 2357) y(RRTILE2382, 2382) -y(RRTILE2430, 2430) -y(RRTILE2431, 2431) -y(RRTILE2432, 2432) +x(CACTUSLARGEYELLOW, 2430) +x(CACTUSLARGEGREEN, 2431) +x(CACTUSLARGEBROWN, 2432) y(RRTILE2437, 2437) -y(RRTILE2443, 2443) +x(CACTUSDRUG, 2443) y(RRTILE2445, 2445) -y(RRTILE2446, 2446) +x(CACTUSLARGEGREEN2, 2446) y(RRTILE2450, 2450) -y(RRTILE2451, 2451) -y(RRTILE2455, 2455) -y(RRTILE2460, 2460) -y(RRTILE2465, 2465) +x(CACTUSWITHHOLES, 2451) +x(CACTUSSMALL, 2455) +x(CACTUSDEBRIS1, 2460) +x(CACTUSDEBRIS2, 2465) x(BONUSSCREEN, 2510) x(VIEWBORDER, 2520) x(VICTORY1, 2530) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 7896c229e..3fc28bd66 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -2445,33 +2445,9 @@ void onMotorcycleHit(int snum, DDukeActor* victim) p->MotoSpeed -= p->MotoSpeed / 4.; p->TurbCount = 6; } - else if ((victim->spr.picnum == RRTILE2431 || victim->spr.picnum == RRTILE2443 || victim->spr.picnum == RRTILE2451 || victim->spr.picnum == RRTILE2455) - && !islockedactivator(victim) && p->MotoSpeed > 45) + else if (p->MotoSpeed > 45) { - S_PlayActorSound(SQUISHED, victim); - if (victim->spr.picnum == RRTILE2431 || victim->spr.picnum == RRTILE2451) - { - if (victim->spr.lotag != 0) - { - DukeSpriteIterator it; - while (auto act2 = it.Next()) - { - if ((act2->spr.picnum == RRTILE2431 || act2->spr.picnum == RRTILE2451) && act2->spr.pal == 4) - { - if (victim->spr.lotag == act2->spr.lotag) - { - act2->spr.scale = DVector2(0, 0); - } - } - } - } - fi.guts(victim, RRTILE2460, 12, myconnectindex); - fi.guts(victim, RRTILE2465, 3, myconnectindex); - } - else - fi.guts(victim, RRTILE2465, 3, myconnectindex); - fi.guts(victim, RRTILE2465, 3, myconnectindex); - victim->spr.scale = DVector2(0, 0); + CallOnMotoSmash(victim, p); } } @@ -3802,15 +3778,6 @@ HORIZONLY: } } CallOnTouch(clip.actor(), p); - if (isRRRA()) - { - if (clip.actor()->spr.picnum == RRTILE2443 && clip.actor()->spr.pal == 19) - { - clip.actor()->spr.pal = 0; - p->DrugMode = 5; - ps[snum].GetActor()->spr.extra = gs.max_player_health; - } - } } if (p->jetpack_on == 0) diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index fc4e3d19c..4385330f5 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -1326,42 +1326,23 @@ void checkplayerhurt_r(player_struct* p, const Collision &coll) { if (coll.type == kHitSprite) { - switch (coll.actor()->spr.picnum) - { - case RRTILE2430: - case RRTILE2431: - case RRTILE2432: - case RRTILE2443: - case RRTILE2446: - case RRTILE2451: - case RRTILE2455: - if (isRRRA() && p->hurt_delay2 < 8) - { - p->GetActor()->spr.extra -= 2; - p->hurt_delay2 = 16; - SetPlayerPal(p, PalEntry(32, 32, 0, 0)); - S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor()); - } - return; - - default: - CallOnHurt(coll.actor(), p); - return; - } - + CallOnHurt(coll.actor(), p); + return; } - if (coll.type != kHitWall) return; - auto wal = coll.hitWall; - - if (p->hurt_delay > 0) p->hurt_delay--; - else if (wal->cstat & (CSTAT_WALL_BLOCK | CSTAT_WALL_ALIGN_BOTTOM | CSTAT_WALL_MASKED | CSTAT_WALL_BLOCK_HITSCAN)) switch (wal->overpicnum) + if (coll.type == kHitWall) { - case BIGFORCE: - p->hurt_delay = 26; - fi.checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->angle.ang.ToVector() * 2, -1); - break; + auto wal = coll.hitWall; + if (p->hurt_delay > 0) p->hurt_delay--; + else if (wal->cstat & (CSTAT_WALL_BLOCK | CSTAT_WALL_ALIGN_BOTTOM | CSTAT_WALL_MASKED | CSTAT_WALL_BLOCK_HITSCAN)) switch (wal->overpicnum) + { + case BIGFORCE: + p->hurt_delay = 26; + fi.checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->angle.ang.ToVector() * 2, -1); + break; + + } } } @@ -1976,62 +1957,6 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) } } break; - case RRTILE2431: - if (targ->spr.pal != 4) - { - targ->spr.picnum = RRTILE2451; - if (targ->spr.lotag != 0) - { - DukeSpriteIterator it; - while (auto act = it.Next()) - { - if (act->spr.picnum == RRTILE2431 && act->spr.pal == 4) - { - if (targ->spr.lotag == act->spr.lotag) - act->spr.picnum = RRTILE2451; - } - } - } - } - break; - case RRTILE2443: - if (targ->spr.pal != 19) - targ->spr.picnum = RRTILE2455; - break; - case RRTILE2455: - S_PlayActorSound(SQUISHED, targ); - fi.guts(targ, RRTILE2465, 3, myconnectindex); - targ->Destroy(); - break; - case RRTILE2451: - if (targ->spr.pal != 4) - { - S_PlayActorSound(SQUISHED, targ); - if (targ->spr.lotag != 0) - { - DukeSpriteIterator it; - while (auto act = it.Next()) - { - if (act->spr.picnum == RRTILE2451 && act->spr.pal == 4) - { - if (targ->spr.lotag == act->spr.lotag) - { - fi.guts(targ, RRTILE2460, 12, myconnectindex); - fi.guts(targ, RRTILE2465, 3, myconnectindex); - act->spr.scale = DVector2(0, 0); - targ->spr.scale = DVector2(0, 0); - } - } - } - } - else - { - fi.guts(targ, RRTILE2460, 12, myconnectindex); - fi.guts(targ, RRTILE2465, 3, myconnectindex); - targ->spr.scale = DVector2(0, 0); - } - } - break; case RRTILE2437: S_PlayActorSound(439, targ); break; diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index cebd933bd..5f31bc9db 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -142,8 +142,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* ChangeActorStat(act, 122); break; - case RRTILE2460: - case RRTILE2465: case BIKEJIBA: case BIKEJIBB: case BIKEJIBC: diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index e18830d6f..11a073998 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -51,6 +51,15 @@ int PicForName(int intname) { picnum = TileFiles.tileForName("FEATHER"); } + else if (FName(ENamedName(intname)) == FName("RedneckCactusDebris1")) + { + picnum = TileFiles.tileForName("CACTUSDEBRIS1"); + } + else if (FName(ENamedName(intname)) == FName("RedneckCactusDebris2")) + { + picnum = TileFiles.tileForName("CACTUSDEBRIS2"); + } + return picnum; } @@ -341,7 +350,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, lotsofstuff, DukeActor_Lotsofstuff) return 0; } -void DukeActor_spawnguts(DDukeActor* actor, int count, int intname) +void DukeActor_spawnguts(DDukeActor* actor, int intname, int count) { int picnum = PicForName(intname); fi.guts(actor, picnum, count, myconnectindex); @@ -352,7 +361,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, spawnguts, DukeActor_spawnguts) PARAM_SELF_PROLOGUE(DDukeActor); PARAM_INT(type); PARAM_INT(count); - DukeActor_spawnguts(self, count, type); + DukeActor_spawnguts(self, type, count); return 0; } @@ -372,6 +381,24 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, movesprite, DukeActor_movesprite) ACTION_RETURN_INT(DukeActor_movesprite(self, velx, vely, velz, clipmask)); } +int DukeActor_jibs(DDukeActor* actor, int jib6mode, int timeout, int callsetsprite, int floorcheck, int zcheck1, int zcheck2) +{ + + return jibs(actor, -1 /* fixme*/, timeout, callsetsprite, floorcheck, zcheck1, zcheck2); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, jibs, DukeActor_jibs) +{ + PARAM_SELF_PROLOGUE(DDukeActor); + PARAM_INT(jib6mode); + PARAM_INT(timeout); + PARAM_INT(callsetsprite); + PARAM_INT(floorcheck); + PARAM_INT(zcheck1); + PARAM_INT(zcheck2); + ACTION_RETURN_INT(DukeActor_jibs(self, jib6mode, timeout, callsetsprite, floorcheck, zcheck1, zcheck2)); +} + DDukeActor* DukeActor_Spawnsprite(DDukeActor* origin, int picnum) { if (picnum >= 0 && picnum < MAXTILES) diff --git a/wadsrc/static/filter/redneck.ridesagain/engine/engine.def b/wadsrc/static/filter/redneck.ridesagain/engine/engine.def index cff689dbe..98ad8506f 100644 --- a/wadsrc/static/filter/redneck.ridesagain/engine/engine.def +++ b/wadsrc/static/filter/redneck.ridesagain/engine/engine.def @@ -1,4 +1,13 @@ spawnclasses { + 2430 = RedneckCactusLargeYellow + 2431 = RedneckCactusLargeGreen + 2432 = RedneckCactusLargeBrown + 2443 = RedneckCactusDrug + 2451 = RedneckCactusWithHoles + 2455 = RedneckCactusSmall + 2446 = RedneckCactusLargeGreen2 + 2460 = RedneckCactusDebris1 + 2465 = RedneckCactusDebris2 7424 = RedneckRabbitSpawner } diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 3c7e2c326..271687aff 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -76,6 +76,7 @@ version "4.10" #include "zscript/games/duke/actors/rabbitspawner.zs" #include "zscript/games/duke/actors/chickenplant.zs" #include "zscript/games/duke/actors/lumberblade.zs" +#include "zscript/games/duke/actors/rrcactus.zs" #include "zscript/games/blood/bloodgame.zs" #include "zscript/games/blood/ui/menu.zs" diff --git a/wadsrc/static/zscript/games/duke/actors/rrcactus.zs b/wadsrc/static/zscript/games/duke/actors/rrcactus.zs new file mode 100644 index 000000000..ad4642db8 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/rrcactus.zs @@ -0,0 +1,212 @@ + +class RedneckCactusLargeYellow : DukeActor +{ + default + { + statnum STAT_ACTOR; + SpriteSet "CACTUSLARGEYELLOW"; + } + + override void onHurt(DukePlayer p) + { + if (p.hurt_delay2 < 8) + { + p.actor.extra -= 2; + p.hurt_delay2 = 16; + p.pals = Color(32, 32, 0, 0); + p.actor.PlayActorSound(RRSnd.LN_PAIN8); + } + } + +} + +class RedneckCactusLargeBrown : RedneckCactusLargeYellow +{ + default + { + SpriteSet "CACTUSLARGEBROWN"; + } +} + +class RedneckCactusLargeGreen2 : RedneckCactusLargeYellow +{ + default + { + SpriteSet "CACTUSLARGEGREEN2"; + } +} + +class RedneckCactusLargeGreen : RedneckCactusLargeYellow +{ + default + { + SpriteSet "CACTUSLARGEGREEN", "CACTUSWITHHOLES"; + } + + override void onHit(DukeActor hitter) + { + if (self.SpriteSetIndex == 0) + { + if (self.pal != 4) + { + self.setSpriteSetImage(1); + if (self.lotag != 0) + { + DukeSpriteIterator it; + for(let act = it.First(); act; act = it.Next()) + { + if (act is 'RedneckCactusLargeGreen' && act.spriteSetIndex == 0 && act.pal == 4) + { + if (self.lotag == act.lotag) + act.setSpriteSetImage(1); + } + } + } + } + } + else + { + if (self.pal != 4) + { + self.PlayActorSound(DukeSnd.SQUISHED); + if (self.lotag != 0) + { + DukeSpriteIterator it; + for(let act = it.First(); act; act = it.Next()) + { + if (act is 'RedneckCactusLargeGreen' && act.spriteSetIndex == 1 && act.pal == 4) + { + if (self.lotag == act.lotag) + { + self.spawnguts('RedneckCactusDebris1', 12); + self.spawnguts('RedneckCactusDebris2', 3); + act.scale = (0, 0); + self.scale = (0, 0); + } + } + } + } + else + { + self.spawnguts('RedneckCactusDebris1', 12); + self.spawnguts('RedneckCactusDebris2', 3); + self.scale = (0, 0); + } + } + } + } + + override void OnMotoSmash(DukePlayer hitter) + { + self.PlayActorSound(DukeSnd.SQUISHED); + if (self.lotag != 0) + { + DukeSpriteIterator it; + for(let act = it.First(); act; act = it.Next()) + { + if (act is 'RedneckCactusLargeGreen' && act.pal == 4) + { + if (self.lotag == act.lotag) + { + act.scale = (0, 0); + } + } + } + } + + self.spawnguts('RedneckCactusDebris1', 12); + self.spawnguts('RedneckCactusDebris2', 3); + self.scale = (0, 0); + } +} + +class RedneckCactusWithHoles : RedneckCactusLargeGreen +{ + default + { + SpriteSetIndex 1; + } +} + +class RedneckCactusDrug : RedneckCactusLargeYellow +{ + default + { + SpriteSet "CACTUSDRUG", "CACTUSSMALL"; + } + + override void onHit(DukeActor hitter) + { + if (self.spritesetIndex == 0 && self.pal != 19) + { + self.setSpriteSetImage(1); + } + else if (self.spritesetIndex == 1) + { + self.PlayActorSound(DukeSnd.SQUISHED); + self.spawnguts('RedneckCactusDebris2', 3); + self.Destroy(); + } + } + + override void onTouch(DukePlayer toucher) + { + if (self.spritesetindex == 0 && self.pal == 19) + { + self.pal = 0; + toucher.DrugMode = 5; + toucher.actor.extra = gs.max_player_health; + } + } + + override void OnMotoSmash(DukePlayer hitter) + { + self.spawnguts('RedneckCactusDebris2', 3); + self.scale = (0, 0); + } + +} + +class RedneckCactusSmall : RedneckCactusDrug +{ + default + { + SpriteSetIndex 1; + } +} + +// --------------------------------- + +class RedneckCactusDebris1 : DukeActor +{ + default + { + statnum STAT_MISC; + pic "CACTUSDEBRIS1"; + } + + override void Tick() + { + if (!self.jibs(false, false, true, true, false, true)) return; // very poor API... Change this when jibs can be scriptified. + if (self.sector.lotag == 800 && self.pos.Z >= self.sector.floorz - 8) + self.Destroy(); + } + + override bool animate(tspritetype tspr) + { + if (tspr.pal == 6) tspr.shade = -120; + + if (self.sector.shadedsector == 1) + tspr.shade = 16; + + return true; + } +} + +class RedneckCactusDebris2 : RedneckCactusDebris1 +{ + default + { + pic "CACTUSDEBRIS2"; + } +} diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index 7ebd15443..d098f1406 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -178,6 +178,7 @@ class DukeActor : CoreActor native virtual void onHurt(DukePlayer p) {} virtual bool onUse(DukePlayer user) { return false; } virtual void onTouch(DukePlayer toucher) {} + virtual void onMotoSmash(DukePlayer toucher) {} virtual void onRespawn(int tag) { } virtual bool animate(tspritetype tspr) { return false; } virtual void RunState() {} // this is the CON function. @@ -192,6 +193,7 @@ class DukeActor : CoreActor native native void lotsofstuff(Name type, int count); native void spawnguts(Name type, int count); native int movesprite(Vector3 move, int clipmask); + native bool jibs(bool jib6mode, bool timeout, bool callsetsprite, bool floorcheck, bool zcheck1, bool zcheck2); // temporary flag accessors - need to be eliminated once we can have true actor flags