From 39d24f2319ca4c6d461b727ed6c80c5a64023286 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Sat, 20 Oct 2018 21:17:13 +0200 Subject: [PATCH] Mementos hardcode --- src/dehacked.c | 2 + src/info.c | 116 +++++++++++++++++++++++++- src/info.h | 16 ++++ src/p_enemy.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++++- src/p_inter.c | 10 +++ src/sounds.c | 1 + src/sounds.h | 1 + 7 files changed, 366 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 9b4ddc71..30def251 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1840,6 +1840,8 @@ static actionpointer_t actionpointers[] = {{A_LightningFollowPlayer},"A_LIGHTNINGFOLLOWPLAYER"}, //SRB2kart {{A_RandomShadowFrame}, "A_RANDOMSHADOWFRAME"}, //SRB2kart {{A_RoamingShadowThinker}, "A_ROAMINGSHADOWTHINKER"}, //SRB2kart + {{A_ReaperThinker}, "A_REAPERTHINKER"}, //SRB2kart + {{A_MementosTPParticles}, "A_MEMENTOSTPPARTICLES"}, //SRB2kart {{A_OrbitNights}, "A_ORBITNIGHTS"}, {{A_GhostMe}, "A_GHOSTME"}, {{A_SetObjectState}, "A_SETOBJECTSTATE"}, diff --git a/src/info.c b/src/info.c index e0a55a8a..231f672a 100644 --- a/src/info.c +++ b/src/info.c @@ -61,7 +61,7 @@ char sprnames[NUMSPRITES + 1][5] = "DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM", "SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB", "ARRO","ITEM","ITMO","ITMI","ITMN","WANT","PBOM","RETI","AIDU","KSPK", - "LZI1","LZI2","KLIT", "SPTL", "ENM1", "GARU", "MARR", "VIEW" + "LZI1","LZI2","KLIT", "SPTL", "ENM1", "GARU", "MARR", "REAP", "VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -3082,6 +3082,11 @@ state_t states[NUMSTATES] = {SPR_ENM1, 2, 1, {A_RoamingShadowThinker}, 0, 0, S_ROAMINGSHADOW}, //S_ROAMINGSHADOW {SPR_MARR, 0, 1, {A_MayonakaArrow}, 0, 0, S_MAYONAKAARROW}, //S_MAYONAKAARROW + + //Mementos stuff + {SPR_NULL, 0, TICRATE*130, {NULL}, 0, 0, S_REAPER}, //S_REAPER_INVIS + {SPR_REAP, 0, 1, {A_ReaperThinker}, 0, 0, S_REAPER}, //S_REAPER + {SPR_NULL, 0, 1, {A_MementosTPParticles}, 0, 0, S_MEMENTOSTP}, //S_MEMENTOSTP #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -17337,6 +17342,115 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags S_NULL // raisestate }, + + // Mementos stuff + { // MT_REAPERWAYPOINT + 3199, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 64*FRACUNIT, // radius + 128*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_REAPER + 3202, // doomednum + S_REAPER_INVIS, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 64*FRACUNIT, // radius + 128*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_MEMENTOSTP + 3201, // doomednum + S_MEMENTOSTP, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 512*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_SPECIAL, // flags + S_NULL // raisestate + }, + + { // MT_MEMENTOSPARTICLE + -1, // doomednum + S_THOK, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 32<extravalue1 = ((actor->extravalue1) ? (actor->extravalue1+1) : (P_RandomRange(0, TICRATE*3))); flip = ((actor->spawnpoint->options & 1) ? (3) : (0)); // flip adds 3 frames, which is the flipped version of the sign. @@ -8556,6 +8558,224 @@ void A_MayonakaArrow(mobj_t *actor) actor->momz = 0; return; } + +// A_MementosTPParticles +// Mementos teleporters particles effects. Short and simple. + +void A_MementosTPParticles(mobj_t *actor) +{ + mobj_t *particle; + mobj_t *mo2; + int i = 0; + thinker_t *th; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_MementosTPParticles", (actor))) + return; +#endif + + for (; i<4; i++) + { + particle = P_SpawnMobj(actor->x + (P_RandomRange(-256, 256)<y + (P_RandomRange(-256, 256)<z + (P_RandomRange(48, 256)<frame = 0; + particle->color = ((i%2) ? (SKINCOLOR_RED) : (SKINCOLOR_BLACK)); + particle->destscale = 1; + P_HomingAttack(particle, actor); + } + + // Although this is mostly used to spawn particles, we will also save the OTHER teleport inside actor->target. That way teleporting doesn't require a thinker iteration. + // Doesn't seem like much given the small amount of mobjs this map has but heh. + if (!actor->target) + { + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo2 = (mobj_t *)th; + if (mo2->type == MT_MEMENTOSTP && mo2 != actor) + { + P_SetTarget(&actor->target, mo2); // The main target we're pursing. + break; + } + } + } +} + +// A_ReaperThinker +// Mementos's Reaper's thinker. A huge pain in the Derek Bum to translate from Lua to this shite if you ask me. + +void A_ReaperThinker(mobj_t *actor) +{ + mobj_t *particle; // particles to spawn + int i = 0; // for loops + angle_t an = ANGLE_22h; // Reminder that angle constants suck. + + //Waypoint stuff: + mobj_t *mo2; + thinker_t *th; + + //Player targetting stuff: + INT32 maxscore = 0; // we target the player with the highest score so yeah there you go. + player_t *player; // used as a shortcut in a loop. + mobj_t *targetplayermo; // the player mo we can eventually target, or whatever. + + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_ReaperThinker", (actor))) + return; +#endif + + // We don't have custom variables or whatever so we'll do with whatever the fuck we have left. + + if (actor->health == 1000) // if health is 1000, set it to a small scale and have it start growing with destscale. Then set the health to uh, not 1000. + { + actor->scale = 1; + actor->destscale = 2<scalespeed = FRACUNIT/24; // Should take a bit less than 2 seconds to fully grow. + S_StartSound(NULL, sfx_chain); + actor->health--; // now we have 999 health, so that above won't happen again. Awesome. + } + + if (actor->scale < 2<x + (P_RandomRange(-60, 60)<y + (P_RandomRange(-60, 60)<z, MT_THOK); + particle->momz = 20<color = ((i%2 !=0) ? (SKINCOLOR_RED) : (SKINCOLOR_BLACK)); + particle->frame = 0; + P_SetScale(particle, FRACUNIT/2); + } + + // Spawn particles in some edgy circle or w/e. + + if (leveltime%5 != 0) // spawn the thing under that every tic. + return; + + i=0; + for (; i<15; i++) // spawn in a circle formation or w/e. + { + particle = P_SpawnMobj(actor->x, actor->y, actor->z, MT_THOK); + particle->momz = 20<color = ((i%2 !=0) ? (SKINCOLOR_RED) : (SKINCOLOR_BLACK)); + particle->frame = 0; + P_SetScale(particle, FRACUNIT/2); + P_InstaThrust(particle, an*i, 30<flags = MF_NOGRAVITY|MF_PAIN|MF_SPECIAL|MF_NOCLIP|MF_NOCLIPHEIGHT; // set our flags to be a damaging thing. + + if (!actor->target) + { + if (actor->hnext) + { + P_SetTarget(&actor->target, actor->hnext); // Default back to last waypoint. + return; + } + + // We have no target and oughta find one, so let's scan through thinkers for a waypoint of angle 0, or something. + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type == MT_REAPERWAYPOINT && mo2->spawnpoint->angle == 0) + { + P_SetTarget(&actor->target, mo2); // The main target we're pursing. + P_SetTarget(&actor->hnext, mo2); // The last waypoint we hit. We will default back to that if a player goes out of our range! + actor->extravalue1 = 0; // This will store the angle of the last waypoint we touched. This will essentially be useful later on. + if (!actor->tracer) // If we already have a tracer (Waypoint #0), don't do anything. + P_SetTarget(&actor->tracer, mo2); // Because our target might be a player OR a waypoint, we need some sort of fallback option. This will always be waypoint 0. + + break; + } + } + } + else // Awesome, we now have a target. + { + // Follow target: + P_InstaThrust(actor, R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y), 20<angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); + + // The player we should target if it's near us: + i = 0; + for (; ilastlook]; + if (player && player->mo && player->kartstuff[k_bumper] && player->score >= maxscore) + { + targetplayermo = player->mo; + maxscore = player->score; + } + } + + // Try to target that player: + if (targetplayermo) + { + if (P_LookForPlayers(actor, false, false, 1024<target == targetplayermo && actor->target && !actor->target->player->powers[pw_flashing] + && !actor->target->player->kartstuff[k_invincibilitytimer] + && !actor->target->player->kartstuff[k_growshrinktimer] + && !actor->target->player->kartstuff[k_spinouttimer])) + P_SetTarget(&actor->target, actor->hnext); + // if the above isn't correct, then we should go back to targetting waypoints or something. + } + } + + // Waypoint behavior. + if (actor->target->type == MT_REAPERWAYPOINT) + { + + if (R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y) < 22<target, NULL); // remove target so we can default back to first waypoint if things go ham. + + // If we reach close to a waypoint, then we should go to the NEXT one. + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type == MT_REAPERWAYPOINT && mo2->spawnpoint->angle == actor->extravalue1+1) + { + P_SetTarget(&actor->target, mo2); // The main target we're pursing. + P_SetTarget(&actor->hnext, mo2); // The last waypoint we hit. We will default back to that if a player goes out of our range! + actor->extravalue1++; // This will store the angle of the last waypoint we touched. This will essentially be useful later on. + break; + } + } + } + + + if (!actor->target) // If we have no target, revert back to waypoint 0. + { + actor->extravalue1 = 0; + P_SetTarget(&actor->target, actor->tracer); + } + } + else // if our target ISN'T a waypoint, then it can only be a player. + { + if (!P_CheckSight(actor, actor->target) || R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y) > 1024<target, actor->hnext); + } + } +} + //} // Function: A_OrbitNights diff --git a/src/p_inter.c b/src/p_inter.c index 5e532c61..fc0fc53b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -378,6 +378,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // We now identify by object type, not sprite! Tails 04-11-2001 switch (special->type) { + case MT_MEMENTOSTP: // Mementos teleport + // Teleport player to the other teleporter (special->target). We'll assume there's always only ever 2. + if (!special->target) + return; // foolproof crash prevention check!!!!! + + P_TeleportMove(player->mo, special->target->x, special->target->y, special->target->z + (48<mo->angle = special->target->angle; + P_SetObjectMomZ(player->mo, 12<mo, player->mo->angle, 20<kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) return; diff --git a/src/sounds.c b/src/sounds.c index 625522be..e1bf870b 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -815,6 +815,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"zio3", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"wind1", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"fire2", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, + {"chain", false, 128, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"mcitm1", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"chaooo", false, 110, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, diff --git a/src/sounds.h b/src/sounds.h index ccd99e99..eedc7f38 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -890,6 +890,7 @@ typedef enum sfx_zio3, sfx_wind1, sfx_fire2, + sfx_chain, sfx_mcitm1, sfx_chaooo, sfx_itfree,