diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 11b12331..3566ed30 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -118,6 +118,9 @@ static UINT8 resynch_local_inprogress = false; // WE are desynched and getting p static UINT8 player_joining = false; UINT8 hu_resynching = 0; +// kart, true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks +UINT8 hu_stopped = 0; + // Client specific static ticcmd_t localcmds; static ticcmd_t localcmds2; @@ -4737,8 +4740,16 @@ void TryRunTics(tic_t realtics) } #endif + if (neededtic > gametic) + { + hu_stopped = false; + } + if (player_joining) + { + hu_stopped = true; return; + } if (neededtic > gametic) { @@ -4756,6 +4767,10 @@ void TryRunTics(tic_t realtics) consistancy[gametic%BACKUPTICS] = Consistancy(); } } + else + { + hu_stopped = true; + } } #ifdef NEWPING diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 2d49bd61..12ff0a96 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -553,4 +553,5 @@ tic_t GetLag(INT32 node); UINT8 GetFreeXCmdSize(void); extern UINT8 hu_resynching; +extern UINT8 hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player #endif diff --git a/src/d_main.c b/src/d_main.c index cc8934e6..8548ac49 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -702,6 +702,7 @@ void D_SRB2Loop(void) else if (rendertimeout < entertic) // in case the server hang or netsplit { // Lagless camera! Yay! + /* if (gamestate == GS_LEVEL && netgame) { if (camera.chase) @@ -713,6 +714,7 @@ void D_SRB2Loop(void) if (splitscreen > 2 && camera4.chase) P_MoveChaseCamera(&players[fourthdisplayplayer], &camera4, false); } + */ D_Display(); if (moviemode) diff --git a/src/dehacked.c b/src/dehacked.c index abbe835a..1240a4a9 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6360,6 +6360,31 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BOMBITEM", "S_BOMBAIR", "S_BOMBEXPLODE", + "S_BOMBEXPLOSION1", + "S_BOMBEXPLOSION2", + + // New explosion + "S_QUICKBOOM1", + "S_QUICKBOOM2", + "S_QUICKBOOM3", + "S_QUICKBOOM4", + "S_QUICKBOOM5", + "S_QUICKBOOM6", + "S_QUICKBOOM7", + "S_QUICKBOOM8", + "S_QUICKBOOM9", + "S_QUICKBOOM10", + + "S_SLOWBOOM1", + "S_SLOWBOOM2", + "S_SLOWBOOM3", + "S_SLOWBOOM4", + "S_SLOWBOOM5", + "S_SLOWBOOM6", + "S_SLOWBOOM7", + "S_SLOWBOOM8", + "S_SLOWBOOM9", + "S_SLOWBOOM10", // Blue Shell - Blue Lightning for now... "S_BLUELIGHTNING1", @@ -6991,6 +7016,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BOMBEXPLOSION", "MT_BOMBEXPLOSIONSOUND", + "MT_SMOLDERING", // New explosion + "MT_BOOMPARTICLE", + "MT_BLUELIGHTNING", // Lightning stuff "MT_BLUEEXPLOSION", "MT_LIGHTNING", diff --git a/src/g_game.c b/src/g_game.c index 4104d35a..a685e951 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1252,7 +1252,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // why build a ticcmd if we're paused? // Or, for that matter, if we're being reborn. - if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN)) + // Kart, don't build a ticcmd if someone is resynching or the server is stopped too so we don't fly off course in bad conditions + if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN) || hu_resynching) { cmd->angleturn = (INT16)(lang >> 16); cmd->aiming = G_ClipAimingPitch(&laim); @@ -1578,8 +1579,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(lang >> 16); } - switch (ssplayer) + if (!hu_stopped) { + switch (ssplayer) + { case 2: localangle2 = lang; localaiming2 = laim; @@ -1609,6 +1612,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) turnheld = th; camspin = InputDown(gc_lookback, ssplayer); break; + } } //Reset away view if a command is given. diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 094a5212..57783da8 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5276,7 +5276,7 @@ static void HWR_ProjectSprite(mobj_t *thing) // New colormap stuff for skins Tails 06-07-2002 if (thing->skin && thing->sprite == SPR_PLAY) // This thing is a player! { - if (thing->player && thing->player->kartstuff[k_startimer]) + if (thing->colorized) vis->colormap = R_GetTranslationColormap(TC_STARMAN, thing->color, GTC_CACHE); else { @@ -5285,7 +5285,12 @@ static void HWR_ProjectSprite(mobj_t *thing) } } else - vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE); + { + if (vis->mobj && vis->mobj->colorized) + vis->colormap = R_GetTranslationColormap(TC_STARMAN, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE); + else + vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE); + } } else vis->colormap = colormaps; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index d7e2ed66..8bb4c959 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -39,6 +39,8 @@ #include "../w_wad.h" #include "../z_zone.h" #include "../r_things.h" +#include "../r_draw.h" +#include "../p_tick.h" #include "hw_main.h" #include "../v_video.h" @@ -934,7 +936,7 @@ spritemd2found: fclose(f); } -static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, skincolors_t color) +static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) { UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; @@ -1205,45 +1207,83 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, break; } - while (size--) + // starman support, could theoretically support boss ones too + if (skinnum == TC_STARMAN) { - if (blendimage->s.alpha == 0) + while (size--) { - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 - cur->rgba = image->rgba; + if (image->s.alpha == 0 && blendimage->s.alpha == 0) + { + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 + cur->rgba = image->rgba; + } + else + { + UINT32 tempcolor; + UINT16 imagebright, blendbright, finalbright, colorbright; + imagebright = (image->s.red+image->s.green+image->s.blue)/3; + blendbright = (blendimage->s.red+blendimage->s.green+blendimage->s.blue)/3; + // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway + finalbright = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; + colorbright = (blendcolor.s.red+blendcolor.s.green+blendcolor.s.blue)/3; + + tempcolor = (finalbright*blendcolor.s.red)/colorbright; + tempcolor = min(255, max(0, tempcolor)); + cur->s.red = (UINT8)tempcolor; + tempcolor = (finalbright*blendcolor.s.green)/colorbright; + tempcolor = min(255, max(0, tempcolor)); + cur->s.green = (UINT8)tempcolor; + tempcolor = (finalbright*blendcolor.s.blue)/colorbright; + tempcolor = min(255, max(0, tempcolor)); + cur->s.blue = (UINT8)tempcolor; + cur->s.alpha = image->s.alpha; + } + + cur++; image++; blendimage++; } - else + } + else + { + while (size--) { - INT32 tempcolor; - INT16 tempmult, tempalpha; - tempalpha = -(abs(blendimage->s.red-127)-127)*2; - if (tempalpha > 255) - tempalpha = 255; - else if (tempalpha < 0) - tempalpha = 0; + if (blendimage->s.alpha == 0) + { + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 + cur->rgba = image->rgba; + } + else + { + INT32 tempcolor; + INT16 tempmult, tempalpha; + tempalpha = -(abs(blendimage->s.red-127)-127)*2; + if (tempalpha > 255) + tempalpha = 255; + else if (tempalpha < 0) + tempalpha = 0; - tempmult = (blendimage->s.red-127)*2; - if (tempmult > 255) - tempmult = 255; - else if (tempmult < 0) - tempmult = 0; + tempmult = (blendimage->s.red-127)*2; + if (tempmult > 255) + tempmult = 255; + else if (tempmult < 0) + tempmult = 0; - tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; - cur->s.red = (UINT8)tempcolor; - tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255; - cur->s.green = (UINT8)tempcolor; - tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255; - cur->s.blue = (UINT8)tempcolor; - cur->s.alpha = image->s.alpha; + tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; + cur->s.red = (UINT8)tempcolor; + tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255; + cur->s.green = (UINT8)tempcolor; + tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255; + cur->s.blue = (UINT8)tempcolor; + cur->s.alpha = image->s.alpha; + } + + cur++; image++; blendimage++; } - - cur++; image++; blendimage++; } return; } -static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, const UINT8 *colormap, skincolors_t color) +static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolors_t color) { // mostly copied from HWR_GetMappedPatch, hence the similarities and comment GLMipmap_t *grmip, *newmip; @@ -1284,7 +1324,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, con grmip->nextcolormap = newmip; newmip->colormap = colormap; - HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, color); + HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color); HWD.pfnSetTexture(newmip); Z_ChangeTag(newmip->grInfo.data, PU_HWRCACHE_UNLOCKED); @@ -1435,7 +1475,30 @@ void HWR_DrawMD2(gr_vissprite_t *spr) md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) { - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, spr->colormap, (skincolors_t)spr->mobj->color); + INT32 skinnum; + if ((spr->mobj->flags & MF_BOSS) && (spr->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" + { + if (spr->mobj->type == MT_CYBRAKDEMON) + skinnum = TC_ALLWHITE; + else if (spr->mobj->type == MT_METALSONIC_BATTLE) + skinnum = TC_METALSONIC; + else + skinnum = TC_BOSS; + } + else if (spr->mobj->color) + { + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + { + if (spr->mobj->colorized) + skinnum = TC_STARMAN; + else + { + skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); + } + } + else skinnum = TC_DEFAULT; + } + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); } else { diff --git a/src/info.c b/src/info.c index ee8853ef..2b38bada 100644 --- a/src/info.c +++ b/src/info.c @@ -56,9 +56,10 @@ char sprnames[NUMSPRITES + 1][5] = "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", //SRB2kart Sprites "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","ARRO","PBOM" + "DBAN","GSHE","DGSH","RSHE","DRSH","BOMB","KRBM","BLIG","LIGH","SINK", + "SITR","KBLN","LAKI","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS", + "BUZB","CHOM","SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW","ARRO", + "PBOM" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2687,6 +2688,30 @@ state_t states[NUMSTATES] = {SPR_BOMB, 0, 1, {A_GrenadeRing}, 0, 0, S_BOMBITEM}, // S_BOMBITEM {SPR_BOMB, 0, 1, {NULL}, 0, 0, S_BOMBAIR}, // S_BOMBAIR {SPR_BOMB, 0, 1, {A_BobombExplode}, MT_BOMBEXPLOSION, 0, S_NULL}, // S_BOMBEXPLODE + {SPR_NULL, 0, 6, {NULL}, 0, 0, S_BOMBEXPLOSION2}, // S_BOMBEXPLOSION1 + {SPR_NULL, 1, 22, {A_ForceStop}, 0, 0, S_NULL}, // S_BOMBEXPLOSION2 + + {SPR_KRBM, 0, 1, {NULL}, 0, 0, S_QUICKBOOM2}, // S_QUICKBOOM1 + {SPR_KRBM, 1, 1, {NULL}, 0, 0, S_QUICKBOOM3}, // S_QUICKBOOM2 + {SPR_KRBM, 2, 1, {NULL}, 0, 0, S_QUICKBOOM4}, // S_QUICKBOOM3 + {SPR_KRBM, 3, 1, {NULL}, 0, 0, S_QUICKBOOM5}, // S_QUICKBOOM4 + {SPR_KRBM, 4, 1, {NULL}, 0, 0, S_QUICKBOOM6}, // S_QUICKBOOM5 + {SPR_KRBM, 5, 1, {NULL}, 0, 0, S_QUICKBOOM7}, // S_QUICKBOOM6 + {SPR_KRBM, 6, 1, {NULL}, 0, 0, S_QUICKBOOM8}, // S_QUICKBOOM7 + {SPR_KRBM, 7, 2, {NULL}, 0, 0, S_QUICKBOOM9}, // S_QUICKBOOM8 + {SPR_KRBM, 8, 2, {NULL}, 0, 0, S_QUICKBOOM10}, // S_QUICKBOOM9 + {SPR_KRBM, 9, 2, {NULL}, 0, 0, S_NULL}, // S_QUICKBOOM10 + + {SPR_KRBM, 0, 3, {NULL}, 0, 0, S_SLOWBOOM2}, // S_SLOWBOOM1 + {SPR_KRBM, 1, 3, {NULL}, 0, 0, S_SLOWBOOM3}, // S_SLOWBOOM2 + {SPR_KRBM, 2, 3, {NULL}, 0, 0, S_SLOWBOOM4}, // S_SLOWKBOOM3 + {SPR_KRBM, 3, 3, {NULL}, 0, 0, S_SLOWBOOM5}, // S_SLOWBOOM4 + {SPR_KRBM, 4, 3, {NULL}, 0, 0, S_SLOWBOOM6}, // S_SLOWBOOM5 + {SPR_KRBM, 5, 3, {NULL}, 0, 0, S_SLOWBOOM7}, // S_SLOWBOOM6 + {SPR_KRBM, 6, 3, {NULL}, 0, 0, S_SLOWBOOM8}, // S_SLOWBOOM7 + {SPR_KRBM, 7, 5, {NULL}, 0, 0, S_SLOWBOOM9}, // S_SLOWBOOM8 + {SPR_KRBM, 8, 5, {NULL}, 0, 0, S_SLOWBOOM10}, // S_SLOWBOOM9 + {SPR_KRBM, 9, 5, {NULL}, 0, 0, S_NULL}, // S_SLOWBOOM10 {SPR_BLIG, 0, 2, {NULL}, 0, 0, S_BLUELIGHTNING2}, // S_BLUELIGHTNING1 {SPR_BLIG, 1, 2, {NULL}, 0, 0, S_BLUELIGHTNING3}, // S_BLUELIGHTNING2 @@ -14932,7 +14957,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 256*FRACUNIT, // painchance + 288*FRACUNIT, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -14946,13 +14971,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 1, // damage sfx_bomb, // activesound - MF_BOUNCE|MF_FLOAT|MF_NOCLIPTHING|MF_MISSILE|MF_SHOOTABLE, // flags + MF_BOUNCE|MF_NOCLIPTHING|MF_MISSILE|MF_SHOOTABLE, // flags S_NULL // raisestate }, { // MT_BOMBEXPLOSION -1, // doomednum - S_BPLD1, // spawnstate + S_BOMBEXPLOSION1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -15004,6 +15029,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SMOLDERING + -1, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // 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 + 35*FRACUNIT, // radius + 70*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_BOOMPARTICLE + -1, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // 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 + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_BOUNCE|MF_SCENERY, // flags + S_NULL // raisestate + }, + { // MT_BLUELIGHTNING -1, // doomednum S_BLUELIGHTNING1, // spawnstate diff --git a/src/info.h b/src/info.h index e50e9bf0..fa751c7a 100644 --- a/src/info.h +++ b/src/info.h @@ -594,6 +594,7 @@ typedef enum sprite SPR_RSHE, // Red Shell SPR_DRSH, // Dead Red Shell SPR_BOMB, // Bob-omb + SPR_KRBM, SPR_BLIG, // Blue Lightning SPR_LIGH, // Lightning SPR_SINK, // Kitchen Sink @@ -3197,6 +3198,31 @@ typedef enum state S_BOMBITEM, S_BOMBAIR, S_BOMBEXPLODE, + S_BOMBEXPLOSION1, + S_BOMBEXPLOSION2, + + // New explosion + S_QUICKBOOM1, + S_QUICKBOOM2, + S_QUICKBOOM3, + S_QUICKBOOM4, + S_QUICKBOOM5, + S_QUICKBOOM6, + S_QUICKBOOM7, + S_QUICKBOOM8, + S_QUICKBOOM9, + S_QUICKBOOM10, + + S_SLOWBOOM1, + S_SLOWBOOM2, + S_SLOWBOOM3, + S_SLOWBOOM4, + S_SLOWBOOM5, + S_SLOWBOOM6, + S_SLOWBOOM7, + S_SLOWBOOM8, + S_SLOWBOOM9, + S_SLOWBOOM10, // Blue Shell - Blue Lightning for now... S_BLUELIGHTNING1, @@ -3972,6 +3998,9 @@ typedef enum mobj_type MT_BOMBEXPLOSION, MT_BOMBEXPLOSIONSOUND, + MT_SMOLDERING, // New explosion + MT_BOOMPARTICLE, + MT_BLUELIGHTNING, // Lightning stuff MT_BLUEEXPLOSION, MT_LIGHTNING, diff --git a/src/k_kart.c b/src/k_kart.c index e06bc6fd..44ec8b0f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -197,6 +197,11 @@ void K_StarmanColormap(UINT8 *dest_colormap, UINT8 skincolor) // next, for every colour in the palette, choose the transcolor that has the closest brightness for (i = 0; i < NUM_PALETTE_ENTRIES; i++) { + if (i == 0 || i == 31 || i == 120) // pure black and pure white don't change + { + dest_colormap[i] = (UINT8)i; + continue; + } color = V_GetColor(i); brightness = (UINT8)(((UINT16)color.s.red + (UINT16)color.s.green + (UINT16)color.s.blue)/3); brightdif = 256; @@ -1454,6 +1459,20 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { K_UpdateOffroad(player); + // setting players to use the star colormap and spawning afterimages + if (player->kartstuff[k_startimer]) + { + mobj_t *ghost; + player->mo->colorized = true; + ghost = P_SpawnGhostMobj(player->mo); + ghost->fuse = 4; + ghost->frame |= FF_FULLBRIGHT; + } + else + { + player->mo->colorized = false; + } + if (player->kartstuff[k_itemclose]) player->kartstuff[k_itemclose]--; @@ -1616,6 +1635,19 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) S_ChangeMusicInternal(mapmusname, true); } +void K_KartPlayerAfterThink(player_t *player) +{ + if (player->kartstuff[k_startimer]) + { + player->mo->frame |= FF_FULLBRIGHT; + } + else + { + if (!(player->mo->state->frame & FF_FULLBRIGHT)) + player->mo->frame &= ~FF_FULLBRIGHT; + } +} + static void K_PlayTauntSound(mobj_t *source) { switch (P_RandomFixed() % 4) @@ -2056,6 +2088,7 @@ void K_StealBalloon(player_t *player, player_t *victim, boolean force) } // source is the mobj that originally threw the bomb that exploded etc. +// Spawns the sphere around the explosion that handles spinout void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source) { mobj_t *mobj; @@ -2076,8 +2109,6 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 degrees = FINEANGLES/number; - radius = FixedDiv(radius,5*(FRACUNIT/4)); - closestangle = 0; // Create the hoop! @@ -2122,10 +2153,6 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 mobj = ghost; } - mobj->momx = FixedMul(FixedDiv(mobjx - x, dist), 2*FRACUNIT); - mobj->momy = FixedMul(FixedDiv(mobjy - y, dist), 2*FRACUNIT); - mobj->momz = FixedMul(FixedDiv(mobjz - z, dist), 2*FRACUNIT); - if (spawncenter) { mobj->x = x; @@ -2133,6 +2160,10 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 mobj->z = z; } + mobj->momx = FixedMul(FixedDiv(mobjx - x, dist), FixedDiv(dist, 6*FRACUNIT)); + mobj->momy = FixedMul(FixedDiv(mobjy - y, dist), FixedDiv(dist, 6*FRACUNIT)); + mobj->momz = FixedMul(FixedDiv(mobjz - z, dist), FixedDiv(dist, 6*FRACUNIT)); + mobj->flags |= MF_NOCLIPTHING; mobj->flags &= ~MF_SPECIAL; @@ -2140,6 +2171,67 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 } } +// Spawns the purely visual explosion +void K_SpawnBobombExplosion(mobj_t *source) +{ + INT32 i, radius, height; + mobj_t *smoldering = P_SpawnMobj(source->x, source->y, source->z, MT_SMOLDERING); + mobj_t *dust; + mobj_t *truc; + smoldering->tics = TICRATE*3; + INT32 speed, speed2; + + radius = source->radius>>FRACBITS; + height = source->height>>FRACBITS; + + for (i = 0; i < 32; i++) + { + dust = P_SpawnMobj(source->x, source->y, source->z, MT_SMOKE); + dust->angle = (ANGLE_180/16) * i; + dust->scale = source->scale; + dust->destscale = source->scale*10; + P_InstaThrust(dust, dust->angle, FixedMul(20*FRACUNIT, source->scale)); + + truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT, + source->y + P_RandomRange(-radius, radius)*FRACUNIT, + source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOSSEXPLODE); + truc->scale = source->scale*2; + truc->destscale = source->scale*6; + P_SetMobjState(truc, S_SLOWBOOM1); + speed = FixedMul(10*FRACUNIT, source->scale)>>FRACBITS; + truc->momx = P_RandomRange(-speed, speed)*FRACUNIT; + truc->momy = P_RandomRange(-speed, speed)*FRACUNIT; + speed = FixedMul(20*FRACUNIT, source->scale)>>FRACBITS; + truc->momz = P_RandomRange(-speed, speed)*FRACUNIT; + } + + for (i = 0; i < 16; i++) + { + dust = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT, + source->y + P_RandomRange(-radius, radius)*FRACUNIT, + source->z + P_RandomRange(0, height)*FRACUNIT, MT_SMOKE); + dust->scale = source->scale; + dust->destscale = source->scale*10; + dust->tics = 30; + dust->momz = P_RandomRange(FixedMul(3*FRACUNIT, source->scale)>>FRACBITS, FixedMul(7*FRACUNIT, source->scale)>>FRACBITS)*FRACUNIT; + + truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT, + source->y + P_RandomRange(-radius, radius)*FRACUNIT, + source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMPARTICLE); + truc->scale = source->scale; + truc->destscale = source->scale*5; + speed = FixedMul(20*FRACUNIT, source->scale)>>FRACBITS; + truc->momx = P_RandomRange(-speed, speed)*FRACUNIT; + truc->momy = P_RandomRange(-speed, speed)*FRACUNIT; + speed = FixedMul(15*FRACUNIT, source->scale)>>FRACBITS; + speed2 = FixedMul(45*FRACUNIT, source->scale)>>FRACBITS; + truc->momz = P_RandomRange(speed, speed2)*FRACUNIT; + if (P_RandomChance(FRACUNIT/2)) + truc->momz = -truc->momz; + truc->tics = TICRATE*2; + } +} + static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle, INT32 flags2, fixed_t speed) { mobj_t *th; @@ -4154,7 +4246,7 @@ static void K_initKartHUD(void) // CHECK graphic CHEK_Y = BASEVIDHEIGHT; // 200 // Minimap - MINI_X = BASEVIDWIDTH - 58; // 262 + MINI_X = BASEVIDWIDTH - 50; // 270 MINI_Y = BASEVIDHEIGHT/2; // 100 if (splitscreen) // Splitscreen @@ -4740,6 +4832,15 @@ static void K_drawKartPositionFaces(void) else { colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE); + if (players[rankplayer[i]].mo->colorized) + { + colormap = R_GetTranslationColormap(TC_STARMAN, players[rankplayer[i]].mo->color, GTC_CACHE); + } + else + { + colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE); + } + if (rankplayer[i] != myplayer) { V_DrawSmallTranslucentMappedPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin], colormap); @@ -5019,16 +5120,16 @@ static void K_drawKartMinimap(void) else return; // no pic, just get outta here - x = MINI_X - (AutomapPic->width/4); - y = MINI_Y - (AutomapPic->height/4); + x = MINI_X - (AutomapPic->width/2); + y = MINI_Y - (AutomapPic->height/2); if (splitscreen == 2) splitflags = 0; if (mirrormode) - V_DrawSmallScaledPatch(x+(AutomapPic->width/2), y, splitflags|V_FLIP, AutomapPic); + V_DrawScaledPatch(x+(AutomapPic->width), y, splitflags|V_FLIP, AutomapPic); else - V_DrawSmallScaledPatch(x, y, splitflags, AutomapPic); + V_DrawScaledPatch(x, y, splitflags, AutomapPic); splitflags &= ~V_HUDTRANSHALF; // Head icons won't be transparent @@ -5065,41 +5166,67 @@ static void K_drawKartMinimap(void) if (bsp->bbox[1][BOXTOP] > maxy) maxy = bsp->bbox[1][BOXTOP]; + // You might be wondering why these are being bitshift here + // it's because mapwidth and height would otherwise overflow for maps larger than half the size possible... + // map boundaries and sizes will ALWAYS be whole numbers thankfully + // later calculations take into consideration that these are actually not in terms of FRACUNIT though + minx >>= FRACBITS; + maxx >>= FRACBITS; + miny >>= FRACBITS; + maxy >>= FRACBITS; + fixed_t mapwidth = maxx - minx; fixed_t mapheight = maxy - miny; - fixed_t xoffset = minx + mapwidth/2; - fixed_t yoffset = miny + mapheight/2; + // These should always be small enough to be bitshift back right now + fixed_t xoffset = (minx + mapwidth/2)<width<height<width, mapwidth); + fixed_t yscale = FixedDiv(AutomapPic->height, mapheight); fixed_t zoom = FixedMul(min(xscale, yscale), FRACUNIT-FRACUNIT/20); amnumxpos = (FixedMul(players[i].mo->x, zoom) - FixedMul(xoffset, zoom)); amnumypos = -(FixedMul(players[i].mo->y, zoom) - FixedMul(yoffset, zoom)); - amxpos = amnumxpos + ((x + AutomapPic->width/4 - (iconprefix[players[i].skin]->width/4))<height/4 - (iconprefix[players[i].skin]->height/4))<width/2 - (iconprefix[players[i].skin]->width/2))<height/2 - (iconprefix[players[i].skin]->height/2))<width/4 + (iconprefix[players[i].skin]->width/4))<width/2 + (iconprefix[players[i].skin]->width/2))<colorized) + { + colormap = R_GetTranslationColormap(TC_STARMAN, players[i].mo->color, 0); + } + else + { + colormap = R_GetTranslationColormap(players[i].skin, players[i].mo->color, 0); + } + V_DrawFixedPatch(amxpos, amypos, FRACUNIT, splitflags|V_FLIP, iconprefix[players[i].skin], colormap); } } else { if (!players[i].skincolor) // 'default' color - V_DrawSciencePatch(amxpos, amypos, splitflags, iconprefix[players[i].skin], FRACUNIT/2); + V_DrawSciencePatch(amxpos, amypos, splitflags, iconprefix[players[i].skin], FRACUNIT); else { - UINT8 *colormap = R_GetTranslationColormap(players[i].skin, players[i].skincolor, 0); //transtables[players[i].skin] - 256 + (players[i].skincolor<<8); - V_DrawFixedPatch(amxpos, amypos, FRACUNIT/2, splitflags, iconprefix[players[i].skin], colormap); + UINT8 *colormap; + if (players[i].mo->colorized) + { + colormap = R_GetTranslationColormap(TC_STARMAN, players[i].mo->color, 0); + } + else + { + colormap = R_GetTranslationColormap(players[i].skin, players[i].mo->color, 0); + } + V_DrawFixedPatch(amxpos, amypos, FRACUNIT, splitflags, iconprefix[players[i].skin], colormap); } } } diff --git a/src/k_kart.h b/src/k_kart.h index 9a6c62bb..11ec63c6 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -21,11 +21,13 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) void K_LakituChecker(player_t *player); void K_KartMoveAnimation(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); +void K_KartPlayerAfterThink(player_t *player); void K_SpinPlayer(player_t *player, mobj_t *source); void K_SquishPlayer(player_t *player, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *source); void K_StealBalloon(player_t *player, player_t *victim, boolean force); void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); +void K_SpawnBobombExplosion(mobj_t *source); void K_SpawnDriftTrail(player_t *player); void K_DoMushroom(player_t *player, boolean doPFlag, boolean startboost); void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index ec19261a..2dbb58c8 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -80,7 +80,8 @@ enum mobj_e { mobj_extravalue1, mobj_extravalue2, mobj_cusval, - mobj_cvmem + mobj_cvmem, + mobj_colorized }; static const char *const mobj_opt[] = { @@ -140,6 +141,7 @@ static const char *const mobj_opt[] = { "extravalue2", "cusval", "cvmem", + "colorized", NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) @@ -343,6 +345,9 @@ static int mobj_get(lua_State *L) case mobj_cvmem: lua_pushinteger(L, mo->cvmem); break; + case mobj_colorized: + lua_pushboolean(L, mo->colorized); + break; default: // extra custom variables in Lua memory lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -638,6 +643,9 @@ static int mobj_set(lua_State *L) case mobj_cvmem: mo->cvmem = luaL_checkinteger(L, 3); break; + case mobj_colorized: + mo->colorized = luaL_checkboolean(L, 3); + break; default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); diff --git a/src/p_enemy.c b/src/p_enemy.c index 59a4a076..e2c027d3 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3922,11 +3922,11 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing) if (thing->type != MT_PLAYER) // Don't explode for anything but an actual player. return true; - if (thing == grenade->target && !(grenade->threshold == 0)) // Don't blow up at your owner. + if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner. return true; if (thing->player && (thing->player->kartstuff[k_bootimer] - || (thing->player->kartstuff[k_balloon] <= 0 && thing->player->kartstuff[k_comebacktimer]))) + || (gametype == GT_MATCH && thing->player && thing->player->kartstuff[k_balloon] <= 0 && thing->player->kartstuff[k_comebacktimer]))) return true; if ((gametype == GT_CTF || gametype == GT_TEAMMATCH) @@ -8268,7 +8268,9 @@ void A_BobombExplode(mobj_t *actor) type = (mobjtype_t)locvar1; for (d = 0; d < 16; d++) - K_SpawnKartExplosion(actor->x, actor->y, actor->z, actor->info->painchance + 32*FRACUNIT, 32, type, d*(ANGLE_45/4), false, false, actor->target); // 32 <-> 64 + K_SpawnKartExplosion(actor->x, actor->y, actor->z, actor->info->painchance + 32*FRACUNIT, 32, type, d*(ANGLE_45/4), true, false, actor->target); // 32 <-> 64 + + K_SpawnBobombExplosion(actor); P_SpawnMobj(actor->x, actor->y, actor->z, MT_BOMBEXPLOSIONSOUND); @@ -8284,7 +8286,7 @@ void A_BobombExplode(mobj_t *actor) if (mo2 == actor || mo2->type == MT_BOMBEXPLOSIONSOUND) // Don't explode yourself! Endless loop! continue; - if (actor->target && actor->target->player && actor->target->player->kartstuff[k_balloon] <= 0 && mo2 == actor->target) + if (gametype == GT_MATCH && actor->target && actor->target->player && actor->target->player->kartstuff[k_balloon] <= 0 && mo2 == actor->target) continue; if (P_AproxDistance(P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y), mo2->z - actor->z) > actor->info->painchance) diff --git a/src/p_map.c b/src/p_map.c index 0a52d6fb..6674e0b1 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -848,9 +848,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->player && thing->player->powers[pw_flashing]) return true; - if (thing->type == MT_PLAYER) + if (thing->type == MT_PLAYER && thing->player) { - K_SpinPlayer(thing->player, tmthing->target); + if (tmthing->state == &states[S_BOMBEXPLOSION1]) + K_ExplodePlayer(thing->player, tmthing->target); + else + K_SpinPlayer(thing->player, tmthing->target); } return true; // This doesn't collide with anything, but we want it to effect the player anyway. @@ -1180,10 +1183,13 @@ static boolean PIT_CheckThing(mobj_t *thing) P_KillMobj(thing, tmthing, tmthing); } - else if (thing->type == MT_BOMBEXPLOSION) + else if (thing->type == MT_BOMBEXPLOSION && tmthing->player) { // Player Damage - K_SpinPlayer(tmthing->player, thing->target); + if (thing->state == &states[S_BOMBEXPLOSION1]) + K_ExplodePlayer(tmthing->player, thing->target); + else + K_SpinPlayer(tmthing->player, thing->target); return true; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 1ba05d69..b8a3e93f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2296,7 +2296,6 @@ static boolean P_ZMovement(mobj_t *mo) mo->fuse += ((5 - mo->threshold) * TICRATE); } break; - case MT_SKIM: // skims don't bounce if (mo->z > mo->watertop && mo->z - mo->momz <= mo->watertop) @@ -3039,6 +3038,14 @@ static boolean P_SceneryZMovement(mobj_t *mo) switch (mo->type) { + case MT_BOOMPARTICLE: + if ((mo->flags & MF_BOUNCE) && (mo->z <= mo->floorz || mo->z+mo->height >= mo->ceilingz)) + { + mo->momz = -mo->momz; + mo->z += mo->momz; + S_StartSound(mo, mo->info->activesound); + } + break; case MT_SMALLBUBBLE: if (mo->z <= mo->floorz || mo->z+mo->height >= mo->ceilingz) // Hit the floor, so POP! { @@ -6697,6 +6704,42 @@ void P_MobjThinker(mobj_t *mobj) return; } break; + case MT_SMOLDERING: + if (leveltime % 2 == 0) + { + fixed_t x = P_RandomRange(-35, 35)*mobj->scale; + fixed_t y = P_RandomRange(-35, 35)*mobj->scale; + fixed_t z = P_RandomRange(0, 70)*mobj->scale; + mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE); + smoke->scale = mobj->scale * 2; + smoke->destscale = mobj->scale * 6; + smoke->momz = P_RandomRange(4, 9)*FRACUNIT; + } + break; + case MT_BOOMPARTICLE: + { + fixed_t x = P_RandomRange(-16, 16)*mobj->scale; + fixed_t y = P_RandomRange(-16, 16)*mobj->scale; + fixed_t z = P_RandomRange(0, 32)*mobj->scale; + if (leveltime % 2 == 0) + { + mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_BOSSEXPLODE); + P_SetMobjState(smoke, S_QUICKBOOM1); + smoke->scale = mobj->scale/2; + smoke->destscale = mobj->scale; + } + else + { + mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE); + smoke->scale = mobj->scale; + smoke->destscale = mobj->scale*2; + } + if (mobj->tics <= TICRATE) + { + mobj->destscale = FixedDiv(mobj->scale, 100*FRACUNIT); + } + } + break; case MT_BATTLEBALLOON: if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->mo && mobj->target->player->health > 0 && !mobj->target->player->spectator) @@ -8547,6 +8590,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) else mobj->z = z; + mobj->colorized = false; + #ifdef HAVE_BLUA // DANGER! This can cause P_SpawnMobj to return NULL! // Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks! diff --git a/src/p_mobj.h b/src/p_mobj.h index c8207c56..3617ea40 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -360,6 +360,8 @@ typedef struct mobj_s struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) #endif + boolean colorized; // Whether the mobj uses the starman colormap + // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; diff --git a/src/p_saveg.c b/src/p_saveg.c index 5518c4f8..eaa38813 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -946,9 +946,11 @@ typedef enum MD2_HNEXT = 1<<7, #ifdef ESLOPE MD2_HPREV = 1<<8, - MD2_SLOPE = 1<<9 + MD2_SLOPE = 1<<9, + MD2_COLORIZED = 1<<10 #else - MD2_HPREV = 1<<8 + MD2_HPREV = 1<<8, + MD2_COLORIZED = 1<<9 #endif } mobj_diff2_t; @@ -1143,6 +1145,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (mobj->standingslope) diff2 |= MD2_SLOPE; #endif + if (mobj->colorized) + diff2 |= MD2_COLORIZED; if (diff2 != 0) diff |= MD_MORE; @@ -1262,6 +1266,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (diff2 & MD2_SLOPE) WRITEUINT16(save_p, mobj->standingslope->id); #endif + if (diff2 & MD2_COLORIZED) + WRITEUINT8(save_p, mobj->colorized); WRITEUINT32(save_p, mobj->mobjnum); } @@ -2131,7 +2137,8 @@ static void LoadMobjThinker(actionf_p1 thinker) if (diff2 & MD2_SLOPE) mobj->standingslope = P_SlopeById(READUINT16(save_p)); #endif - + if (diff2 & MD2_COLORIZED) + mobj->colorized = READUINT8(save_p); if (diff & MD_REDFLAG) { diff --git a/src/p_user.c b/src/p_user.c index 978ee1b9..c1864ad3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1513,6 +1513,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) } ghost->color = mobj->color; + ghost->colorized = mobj->colorized; // Kart: they should also be colorized if their origin is ghost->angle = mobj->angle; ghost->sprite = mobj->sprite; @@ -9518,7 +9519,7 @@ void P_PlayerThink(player_t *player) #if 1 // "Blur" a bit when you have speed shoes and are going fast enough if ((player->powers[pw_super] || player->powers[pw_sneakers] - || player->kartstuff[k_driftboost] || player->kartstuff[k_mushroomtimer]) // SRB2kart + || player->kartstuff[k_driftboost] || player->kartstuff[k_mushroomtimer]) && !player->kartstuff[k_startimer] // SRB2kart && (player->speed + abs(player->mo->momz)) > FixedMul(20*FRACUNIT,player->mo->scale)) { mobj_t *gmobj = P_SpawnGhostMobj(player->mo); @@ -10073,4 +10074,6 @@ void P_PlayerAfterThink(player_t *player) if (P_IsObjectOnGround(player->mo)) player->mo->pmomz = 0; + + K_KartPlayerAfterThink(player); } diff --git a/src/r_things.c b/src/r_things.c index 6f88367a..bac05b2f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -827,7 +827,7 @@ static void R_DrawVisSprite(vissprite_t *vis) dc_transmap = vis->transmap; if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_> { - if (vis->mobj->player && vis->mobj->player->kartstuff[k_startimer]) + if (vis->mobj->colorized) dc_translation = R_GetTranslationColormap(TC_STARMAN, vis->mobj->color, GTC_CACHE); else { @@ -851,7 +851,7 @@ static void R_DrawVisSprite(vissprite_t *vis) // New colormap stuff for skins Tails 06-07-2002 if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { - if (vis->mobj->player && vis->mobj->player->kartstuff[k_startimer]) + if (vis->mobj->colorized) dc_translation = R_GetTranslationColormap(TC_STARMAN, vis->mobj->color, GTC_CACHE); else {