diff --git a/src/dehacked.c b/src/dehacked.c index 08b19a55..4c04a8d5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6410,6 +6410,24 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FIREDITEM3", "S_FIREDITEM4", + "S_PLAYERARROW", // Above player arrow + "S_PLAYERARROW_MUSHROOM", + "S_PLAYERARROW_GREENSHELL", + "S_PLAYERARROW_BANANA", + "S_PLAYERARROW_FAKEITEM", + "S_PLAYERARROW_BOO", + "S_PLAYERARROW_FEATHER", + "S_PLAYERARROW_REDSHELL", + "S_PLAYERARROW_BOBOMB", + "S_PLAYERARROW_FIREFLOWER", + "S_PLAYERARROW_TRIPLEGREENSHELL", + "S_PLAYERARROW_TRIPLEBANANA", + "S_PLAYERARROW_TRIPLEREDSHELL", + "S_PLAYERARROW_STAR", + "S_PLAYERARROW_MEGASHROOM", + "S_PLAYERARROW_KITCHENSINK", + "S_PLAYERARROW_EMPTY", + #ifdef SEENAMES "S_NAMECHECK", #endif @@ -6986,6 +7004,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FIREDITEM", + "MT_PLAYERARROW", + #ifdef SEENAMES "MT_NAMECHECK", #endif diff --git a/src/info.c b/src/info.c index 3c1fb681..b72a5eae 100644 --- a/src/info.c +++ b/src/info.c @@ -58,7 +58,7 @@ char sprnames[NUMSPRITES + 1][5] = "SPRG","BSPR","RNDM","RPOP","KFRE","DRIF","DSMO","FITM","DFAK","BANA", "DBAN","GSHE","DGSH","RSHE","DRSH","BOMB","BLIG","LIGH","SINK","SITR", "KBLN","LAKI","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB", - "CHOM","SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW" + "CHOM","SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW","ARRO" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2865,6 +2865,25 @@ state_t states[NUMSTATES] = {SPR_PSHW, 2, 3, {NULL}, 0, 0, S_FIREDITEM4}, // S_FIREDITEM3 {SPR_PSHW, 3, 3, {NULL}, 0, 0, S_NULL}, // S_FIREDITEM4 + // Above player arrow + {SPR_ARRO, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW + {SPR_ARRO, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_MUSHROOM + {SPR_ARRO, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_GREENSHELL + {SPR_ARRO, FF_FULLBRIGHT|3, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BANANA + {SPR_ARRO, FF_FULLBRIGHT|4, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_FAKEITEM + {SPR_ARRO, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOO + {SPR_ARRO, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_FEATHER + {SPR_ARRO, FF_FULLBRIGHT|7, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_REDSHELL + {SPR_ARRO, FF_FULLBRIGHT|8, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOBOMB + {SPR_ARRO, FF_FULLBRIGHT|9, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_FIREFLOWER + {SPR_ARRO, FF_FULLBRIGHT|10, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_TRIPLEGREENSHELL + {SPR_ARRO, FF_FULLBRIGHT|11, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_TRIPLEBANANA + {SPR_ARRO, FF_FULLBRIGHT|12, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_TRIPLEREDSHELL + {SPR_ARRO, FF_FULLBRIGHT|13, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_STAR + {SPR_ARRO, FF_FULLBRIGHT|14, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_MEGASHROOM + {SPR_ARRO, FF_FULLBRIGHT|15, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_KITCHENSINK + {SPR_ARRO, FF_FULLBRIGHT|16, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_EMPTY + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif @@ -16739,6 +16758,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, + + { // MT_PLAYERARROW + -1, // doomednum + S_PLAYERARROW, // 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 + 8, // speed + 36*FRACUNIT, // radius + 37*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + // ============================================================================================================================// #ifdef SEENAMES diff --git a/src/info.h b/src/info.h index 37babceb..55cc83a9 100644 --- a/src/info.h +++ b/src/info.h @@ -621,6 +621,8 @@ typedef enum sprite SPR_CLAS, // items clash SPR_PSHW, // thrown indicator + SPR_ARRO, // player arrows + SPR_FIRSTFREESLOT, SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, NUMSPRITES @@ -3383,6 +3385,24 @@ typedef enum state S_FIREDITEM3, S_FIREDITEM4, + S_PLAYERARROW, // Above player arrow + S_PLAYERARROW_MUSHROOM, + S_PLAYERARROW_GREENSHELL, + S_PLAYERARROW_BANANA, + S_PLAYERARROW_FAKEITEM, + S_PLAYERARROW_BOO, + S_PLAYERARROW_FEATHER, + S_PLAYERARROW_REDSHELL, + S_PLAYERARROW_BOBOMB, + S_PLAYERARROW_FIREFLOWER, + S_PLAYERARROW_TRIPLEGREENSHELL, + S_PLAYERARROW_TRIPLEBANANA, + S_PLAYERARROW_TRIPLEREDSHELL, + S_PLAYERARROW_STAR, + S_PLAYERARROW_MEGASHROOM, + S_PLAYERARROW_KITCHENSINK, + S_PLAYERARROW_EMPTY, + #ifdef SEENAMES S_NAMECHECK, #endif @@ -4033,6 +4053,8 @@ typedef enum mobj_type MT_FIREDITEM, + MT_PLAYERARROW, + #ifdef SEENAMES MT_NAMECHECK, #endif diff --git a/src/k_kart.c b/src/k_kart.c index 29936b4b..b3b78465 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -681,7 +681,7 @@ static INT32 K_KartItemOddsPosition_Retro[MAXPLAYERS][NUMKARTITEMS][MAXPLAYERS] static INT32 K_KartItemOddsDistance_Retro[NUMKARTITEMS][10] = { //P-Odds 0 1 2 3 4 5 6 7 8 9 - /*Magnet*/ { 2, 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Magnet + /*Magnet*/ { 0, 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Magnet /*Boo*/ { 0, 0, 0, 2, 2, 1, 0, 0, 0, 0 }, // Boo /*Mushroom*/ { 0, 1, 0, 0, 3, 7, 5, 0, 0, 0 }, // Mushroom /*Triple Mushroom*/ { 0, 0, 0, 0, 0, 3,10, 6, 4, 0 }, // Triple Mushroom @@ -980,7 +980,9 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) player->kartstuff[k_itemclose] = 0; // Reset the item window closer. - if (gametype == GT_MATCH) useodds = 0; // Battle Mode + if (gametype == GT_MATCH + || gametype == GT_TEAMMATCH + || gametype == GT_CTF) useodds = 0; // Battle Mode else if (pingame == 1) useodds = 1; // Record Attack, or just alone else if (pdis <= distvar * 0) useodds = 2; // (64*14) * 0 = 0 else if (pdis <= distvar * 1) useodds = 3; // (64*14) * 1 = 896 @@ -1637,7 +1639,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source) else if (player->kartstuff[k_balloon] & 1) { player->kartstuff[k_balloon] &= ~1; - CONS_Printf(M_GetText("%s lost all of their balloons!"), player_names[players-player]); + CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); //P_DamageMobj(player->mo, NULL, NULL, 10000); //return; } @@ -1702,7 +1704,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source) else if (player->kartstuff[k_balloon] & 1) { player->kartstuff[k_balloon] &= ~1; - CONS_Printf(M_GetText("%s lost all of their balloons!"), player_names[players-player]); + CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); //P_DamageMobj(player->mo, NULL, NULL, 10000); //return; } @@ -1756,7 +1758,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju else if (player->kartstuff[k_balloon] & 1) { player->kartstuff[k_balloon] &= ~1; - CONS_Printf(M_GetText("%s lost all of their balloons!"), player_names[players-player]); + CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); //P_DamageMobj(player->mo, NULL, NULL, 10000); //return; } diff --git a/src/p_inter.c b/src/p_inter.c index d1115563..5658a131 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2092,10 +2092,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) source->player->numboxes++; if ((cv_itemrespawn.value && gametype != GT_COOP && (modifiedgame || netgame || multiplayer))) { - if (gametype == GT_RACE) - target->fuse = TICRATE + 2; - else - target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation + target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation } } diff --git a/src/p_mobj.c b/src/p_mobj.c index f5df3010..ffce0300 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6696,6 +6696,77 @@ void P_MobjThinker(mobj_t *mobj) return; } break; + case MT_PLAYERARROW: + if (mobj->target && mobj->target->health + && mobj->target->player && mobj->target->player->mo + && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD + && !(gametype != GT_RACE && mobj->target->player->kartstuff[k_balloon] <= 0)) + { + fixed_t scale = mobj->target->scale; + mobj->color = mobj->target->color; + + if (mobj->target->player == &players[displayplayer]) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + + if ((splitscreen || !netgame) + || (gametype == GT_RACE) + || (mobj->target->player->kartstuff[k_bootaketimer] > 0)) + mobj->flags2 |= MF2_DONTDRAW; + + P_UnsetThingPosition(mobj); + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + + if (!(mobj->target->eflags & MFE_VERTICALFLIP)) + { + mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT; + mobj->eflags &= ~MFE_VERTICALFLIP; + } + else + { + mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT; + mobj->eflags |= MFE_VERTICALFLIP; + } + P_SetThingPosition(mobj); + + // Set it to use the correct states for its condition + if (mobj->target->player->kartstuff[k_kitchensink]) P_SetMobjState(mobj, S_PLAYERARROW_KITCHENSINK); + else if (mobj->target->player->kartstuff[k_megashroom] == 1 + || (mobj->target->player->kartstuff[k_growshrinktimer] > 1 + && (leveltime & 1))) P_SetMobjState(mobj, S_PLAYERARROW_MEGASHROOM); + else if (mobj->target->player->kartstuff[k_growshrinktimer] > 1 + && !(leveltime & 1)) P_SetMobjState(mobj, S_PLAYERARROW_EMPTY); // S_INVISIBLE + else if (mobj->target->player->kartstuff[k_star] == 1) P_SetMobjState(mobj, S_PLAYERARROW_STAR); + else if (mobj->target->player->kartstuff[k_tripleredshell]) P_SetMobjState(mobj, S_PLAYERARROW_TRIPLEREDSHELL); + else if (mobj->target->player->kartstuff[k_triplebanana]) P_SetMobjState(mobj, S_PLAYERARROW_TRIPLEBANANA); + else if (mobj->target->player->kartstuff[k_triplegreenshell]) P_SetMobjState(mobj, S_PLAYERARROW_TRIPLEGREENSHELL); + else if (mobj->target->player->kartstuff[k_fireflower]) P_SetMobjState(mobj, S_PLAYERARROW_FIREFLOWER); + else if (mobj->target->player->kartstuff[k_bobomb]) P_SetMobjState(mobj, S_PLAYERARROW_BOBOMB); + else if (mobj->target->player->kartstuff[k_redshell]) P_SetMobjState(mobj, S_PLAYERARROW_REDSHELL); + //else if (mobj->target->player->kartstuff[k_feather]) P_SetMobjState(mobj, S_PLAYERARROW_FEATHER); + else if (mobj->target->player->kartstuff[k_boo] == 1) P_SetMobjState(mobj, S_PLAYERARROW_BOO); + else if (mobj->target->player->kartstuff[k_fakeitem] & 2) P_SetMobjState(mobj, S_PLAYERARROW_FAKEITEM); + else if (mobj->target->player->kartstuff[k_banana]) P_SetMobjState(mobj, S_PLAYERARROW_BANANA); + else if (mobj->target->player->kartstuff[k_greenshell]) P_SetMobjState(mobj, S_PLAYERARROW_GREENSHELL); + else if (mobj->target->player->kartstuff[k_mushroom]) P_SetMobjState(mobj, S_PLAYERARROW_MUSHROOM); + else P_SetMobjState(mobj, S_PLAYERARROW); // S_INVISIBLE + + scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x, + players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); + if (scale > 16*FRACUNIT) + { + scale = 16*FRACUNIT; + } + mobj->destscale = scale; + } + else if (mobj->health > 0) + { + P_KillMobj(mobj, NULL, NULL); + return; + } + break; //} case MT_WATERDROP: P_SceneryCheckWater(mobj); @@ -8849,7 +8920,7 @@ void P_RemoveSavegameMobj(mobj_t *mobj) } static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}}; -consvar_t cv_itemrespawntime = {"respawnitemtime", "3", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_itemrespawntime = {"respawnitemtime", "1", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_itemrespawn = {"respawnitem", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t flagtime_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}}; consvar_t cv_flagtime = {"flagtime", "30", CV_NETVAR|CV_CHEAT, flagtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -9167,7 +9238,7 @@ void P_RespawnBattleSpecials(void) return; // wait a teeeensy bit after collecting everything - if (leveltime - itemrespawntime[iquehead-1] < (tic_t)cv_itemrespawntime.value*TICRATE) + if (leveltime - itemrespawntime[iquehead-1] < (tic_t)cv_itemrespawntime.value*(5*TICRATE)) return; while (iquehead != iquetail) // respawn EVERYTHING in que! @@ -9248,6 +9319,7 @@ void P_SpawnPlayer(INT32 playernum) { player_t *p = &players[playernum]; mobj_t *mobj; + mobj_t *overheadarrow; if (p->playerstate == PST_REBORN) G_PlayerReborn(playernum); @@ -9335,7 +9407,12 @@ void P_SpawnPlayer(INT32 playernum) // Spawn with a pity shield if necessary. //P_DoPityCheck(p); - if (gametype == GT_MATCH && (leveltime < 1 || p->kartstuff[k_balloon] > 0)) // srb2kart + overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW); + P_SetTarget(&overheadarrow->target, mobj); + overheadarrow->flags2 |= MF2_DONTDRAW; + P_SetScale(overheadarrow, mobj->destscale); + + if (gametype != GT_RACE && (leveltime < 1 || p->kartstuff[k_balloon] > 0)) // srb2kart { angle_t newangle, diff; fixed_t newx; diff --git a/src/p_user.c b/src/p_user.c index c11bf8d1..fa9daa01 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7974,10 +7974,6 @@ static void P_DeathThink(player_t *player) if (player->deadtimer > TICRATE) player->playerstate = PST_REBORN; - // SRB2kart - spawn after 1 second & Button press - if ((cmd->buttons & BT_JUMP || cmd->buttons & BT_ACCELERATE) && player->deadtimer > TICRATE) - player->playerstate = PST_REBORN; - // Single player auto respawn if (!(netgame || multiplayer) && player->deadtimer > 5*TICRATE) player->playerstate = PST_REBORN;