diff --git a/src/d_main.cpp b/src/d_main.cpp index 1d1f0f298..d9a1a6e0f 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -94,7 +94,7 @@ #define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291 #define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b #define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9 -#define ASSET_HASH_MAIN_PK3 0x049b68caee0ba709 +#define ASSET_HASH_MAIN_PK3 0x28ffde2e8c416914 #define ASSET_HASH_MAPPATCH_PK3 0x1745690024efbaf8 #define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461 #ifdef USE_PATCH_FILE diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f8797afcf..1685ae648 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -546,6 +546,15 @@ consvar_t cv_kartstacking_flame_accelboost = CVAR_INIT ("vanillaboost_flame_acce consvar_t cv_kartstacking_flame_handleboost = CVAR_INIT ("vanillaboost_flame_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); consvar_t cv_kartstacking_flame_stackable = CVAR_INIT ("vanillaboost_flame_stackable", "On", CV_NETVAR|CV_GUARD, CV_OnOff, NULL); +consvar_t cv_kartstacking_attraction_speedboost_himin = CVAR_INIT ("vanillaboost_attraction_speedboost_himin", "0.5", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); +consvar_t cv_kartstacking_attraction_speedboost_himax = CVAR_INIT ("vanillaboost_attraction_speedboost_himax", "0.6", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); +consvar_t cv_kartstacking_attraction_speedboost_normmin = CVAR_INIT ("vanillaboost_attraction_speedboost_normmin", "0.25", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); +consvar_t cv_kartstacking_attraction_speedboost_normmax = CVAR_INIT ("vanillaboost_attraction_speedboost_normmax", "0.3", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); +consvar_t cv_kartstacking_attraction_accelboost_hi = CVAR_INIT ("vanillaboost_attraction_accelboost_hi", "10.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); +consvar_t cv_kartstacking_attraction_accelboost_norm = CVAR_INIT ("vanillaboost_attraction_accelboost_norm", "4.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); +consvar_t cv_kartstacking_attraction_handleboost = CVAR_INIT ("vanillaboost_sttraction_handleboost", "0.25", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); +consvar_t cv_kartstacking_attraction_stackable = CVAR_INIT ("vanillaboost_sttraction_stackable", "On", CV_NETVAR|CV_GUARD, CV_OnOff, NULL); + consvar_t cv_kartstacking_start_speedboost = CVAR_INIT ("vanillaboost_start_speedboost", "0.25", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); consvar_t cv_kartstacking_start_accelboost = CVAR_INIT ("vanillaboost_start_accelboost", "6.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); consvar_t cv_kartstacking_start_handleboost = CVAR_INIT ("vanillaboost_start_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 2038284e6..fe8c5c486 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -134,6 +134,15 @@ extern consvar_t cv_kartstacking_flame_accelboost; extern consvar_t cv_kartstacking_flame_handleboost; extern consvar_t cv_kartstacking_flame_stackable; +extern consvar_t cv_kartstacking_attraction_speedboost_himin; +extern consvar_t cv_kartstacking_attraction_speedboost_himax; +extern consvar_t cv_kartstacking_attraction_speedboost_normmin; +extern consvar_t cv_kartstacking_attraction_speedboost_normmax; +extern consvar_t cv_kartstacking_attraction_accelboost_hi; +extern consvar_t cv_kartstacking_attraction_accelboost_norm; +extern consvar_t cv_kartstacking_attraction_handleboost; +extern consvar_t cv_kartstacking_attraction_stackable; + extern consvar_t cv_kartstacking_grow_speedboost; extern consvar_t cv_kartstacking_grow_accelboost; extern consvar_t cv_kartstacking_grow_handleboost; diff --git a/src/g_game.c b/src/g_game.c index cc312c14f..c711a8aef 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1472,31 +1472,37 @@ fixed_t localshakinessfac[MAXSPLITSCREENPLAYERS]; vector3_t localsmoothedaccel[MAXSPLITSCREENPLAYERS]; vector3_t localgravityvectors[MAXSPLITSCREENPLAYERS]; +// the time it takes in our acceleration smoothing for 'A' to get halfway to 'B' +#define SmoothingHalfTime (0.025) // thresholds of trust for accel shakiness. less shakiness = more trust -#define ShakinessMaxThreshold (80*FRACUNIT/100) +#define ShakinessMaxThreshold (50*FRACUNIT/100) #define ShakinessMinThreshold (32*FRACUNIT/100) // when we trust the accel a lot (the controller is "still"), how quickly do we correct our gravity vector? #define CorrectionStillRate (FRACUNIT) // when we don't trust the accel (the controller is "shaky"), how quickly do we correct our gravity vector? #define CorrectionShakyRate (FRACUNIT/8) // if our old gravity vector is close enough to our new one, limit further corrections to this proportion of the rotation speed -#define CorrectionGyroFactor (FRACUNIT/5) +#define CorrectionGyroFactor (FRACUNIT/4) // thresholds for what's considered "close enough" -#define CorrectionGyroMinThreshold (2*FRACUNIT/100) -#define CorrectionGyroMaxThreshold (FRACUNIT/4) +#define CorrectionGyroMinThreshold (5*FRACUNIT/100) +#define CorrectionGyroMaxThreshold (FRACUNIT/3) // no matter what, always apply a minimum of this much correction to our gravity vector -#define CorrectionMinimumSpeed (9*FRACUNIT/100) +#define CorrectionMinimumSpeed (10*FRACUNIT/100) void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel) { // convert gyro input to reverse rotation - const fixed_t smoothFactor = 800*FRACUNIT/1000; vector3_t invAccel = {-accel.x, -accel.y, -accel.z}; fixed_t gravCorrectionRate = 0; + // scaling is reversed, smaller time scales = larger steps in this code + // (1/timescale)/dt + fixed_t deltaseconds = FixedDiv(FRACUNIT, max(cv_timescale.value, FRACUNIT/20))/TICRATE; + // we don't have exp2 and we actually need it here to take timescale into account :( + fixed_t smoothFactor = FloatToFixed(exp2(-FixedToFloat(deltaseconds) / SmoothingHalfTime)); fixed_t angleRate; fixed_t correctionLimit; vector4_t invRotation = AngleAxis( - FixedMul(FV3_Length(&gyro), FRACUNIT/TICRATE), + FixedMul(FV3_Length(&gyro), deltaseconds), -gyro.x, -gyro.y, -gyro.z @@ -1556,9 +1562,9 @@ void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel) CONS_Debug(DBG_IMU, "Correction Rate: %4.2f\n", FixedToFloat(gravCorrectionRate)); FV3_Load(&correction, - FixedMul(gravityToAccel.x, gravCorrectionRate/TICRATE), - FixedMul(gravityToAccel.y, gravCorrectionRate/TICRATE), - FixedMul(gravityToAccel.z, gravCorrectionRate/TICRATE) + FixedMul(gravityToAccel.x, FixedMul(deltaseconds, gravCorrectionRate)), + FixedMul(gravityToAccel.y, FixedMul(deltaseconds, gravCorrectionRate)), + FixedMul(gravityToAccel.z, FixedMul(deltaseconds, gravCorrectionRate)) ); if (FV3_LengthSquared(&correction) < FV3_LengthSquared(&gravityToAccel)) { diff --git a/src/g_game.h b/src/g_game.h index a42a90c5e..1984812cb 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -154,7 +154,8 @@ typedef enum } motionsensortype_e; #define MAXGAMEPADTILT (50*FRACUNIT/100) -#define ACCELEROMETERGRAVITY ((fixed_t)(9.80665f * ((float)FRACUNIT))) +// #define ACCELEROMETERGRAVITY ((fixed_t)(9.80665f * ((float)FRACUNIT))) +#define ACCELEROMETERGRAVITY 642688 #define GAMEPADSHAKETHRESHOLD (UINT8_MAX/2) #define TILTTOSTICKEASE 6 boolean G_GetGamepadCanUseTilt(INT32 p); diff --git a/src/h_timers.cpp b/src/h_timers.cpp index 8559aef55..37f2e5875 100644 --- a/src/h_timers.cpp +++ b/src/h_timers.cpp @@ -301,6 +301,12 @@ void K_DisplayItemTimers(void) {qche("K_TIFLMS")}, 1, }, + { // attractionshield + "attractionshield", + stplyr->attractionattack, + {qche("K_TIATTR")}, + 1, + }, }; // insert sortable timers diff --git a/src/k_collide.c b/src/k_collide.c index eea78d7a3..2df3c9214 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -1206,6 +1206,20 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) return true; } + // Attraction Shield tackle damage + t1Condition = (t1->player->attractionattack && t1->player->attractionattack_hipower); + t2Condition = (t2->player->attractionattack && t2->player->attractionattack_hipower); + if (t1Condition == true && t2Condition == false) + { + P_DamageMobj(t2, t1, t1, 1, DMG_FLIPOVER); + return true; + } + else if (t1Condition == false && t2Condition == true) + { + P_DamageMobj(t1, t2, t2, 1, DMG_FLIPOVER); + return true; + } + // Battle Mode Sneaker and Bubble damage // (Pogo Spring damage is handled in head-stomping code) if (gametypes[gametype]->rules & GTR_BUMPERS) diff --git a/src/k_hud.c b/src/k_hud.c index bb654aed2..dd6d14df7 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1533,6 +1533,20 @@ static void K_drawKartItem(void) } else if (stplyr->attractioncharge > 0) { + if (leveltime & 2) + { + if (stplyr->attractioncharge >= ATTRACTIONCHARGETIME) + { + colormode = TC_BLINK; + localcolor = SKINCOLOR_WHITE; + } + localpatch = K_GetCachedItemPatch(KITEM_THUNDERSHIELD, tiny, 0); + } + else + { + localpatch = kp_nodraw; + } + itembar = FixedDiv(stplyr->attractioncharge, ATTRACTIONCHARGETIME); } else if (stplyr->bricktimer > 0) diff --git a/src/k_items.c b/src/k_items.c index 7d2b32354..c543f8d93 100644 --- a/src/k_items.c +++ b/src/k_items.c @@ -1928,16 +1928,6 @@ void K_DoAttractionShield(player_t *player, boolean hipower) mo->color = SKINCOLOR_CYAN; mo->scale = player->mo->scale*3 + (player->mo->scale/2); - // spawn horizontal bolts; - for (i=0; i<7; i++) - { - mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK); - mo->angle = P_RandomRange(0, 359)*ANG1; - mo->fuse = P_RandomRange(20, 50); - P_SetTarget(&mo->target, player->mo); - P_SetMobjState(mo, S_KLIT1); - } - // spawn the radius thing: an = ANGLE_22h; for (i=0; i<15; i++) @@ -2336,6 +2326,11 @@ void K_PlayerItemThink(player_t *player, boolean onground) K_PlayAttackTaunt(player->mo); K_UpdateHnextList(player, false); K_BotResetItemConfirm(player, false); + + if (player->itemamount <= 0) + { + player->itemflags &= ~IF_SEEKING; + } } break; case KITEM_MINE: diff --git a/src/k_kart.c b/src/k_kart.c index 48b3f93c0..80e9544a8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -340,6 +340,15 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartstacking_flame_handleboost); CV_RegisterVar(&cv_kartstacking_flame_stackable); + CV_RegisterVar(&cv_kartstacking_attraction_speedboost_himin); + CV_RegisterVar(&cv_kartstacking_attraction_speedboost_himax); + CV_RegisterVar(&cv_kartstacking_attraction_speedboost_normmin); + CV_RegisterVar(&cv_kartstacking_attraction_speedboost_normmax); + CV_RegisterVar(&cv_kartstacking_attraction_accelboost_hi); + CV_RegisterVar(&cv_kartstacking_attraction_accelboost_norm); + CV_RegisterVar(&cv_kartstacking_attraction_handleboost); + CV_RegisterVar(&cv_kartstacking_attraction_stackable); + CV_RegisterVar(&cv_kartstacking_start_speedboost); CV_RegisterVar(&cv_kartstacking_start_accelboost); CV_RegisterVar(&cv_kartstacking_start_handleboost); @@ -2921,7 +2930,7 @@ static void K_GetKartBoostPower(player_t *player) if (player->attractionboost) { - K_DoBoost(player, player->attractionboost, (player->attractionattack_hipower) ? 3*FRACUNIT : FRACUNIT, FRACUNIT/4, true, false); // + ???% top speed, + 300% acceleration + K_DoBoost(player, player->attractionboost, (player->attractionattack_hipower) ? ATTRACTIONACCELHI : ATTRACTIONACCELNORM, ATTRACTIONHANDLEBOOST, ATTRACTIONSTACKABLE, false); // + ???% top speed, + 300% acceleration } if (player->slopeboost || player->slopeaccel) @@ -8034,7 +8043,6 @@ void K_KartPlayerAfterThink(player_t *player) { player->attractionboost = 0; player->attractionattack_hipower = false; - player->itemflags &= ~(IF_SEEKING|IF_PASSIVESEEKING); } } @@ -11786,9 +11794,11 @@ boolean K_NullDriftTiltEnabled(void) } #define TargetThreshold (80*FRACUNIT/100) +#define TargetAngleAssist (FRACUNIT/2) void K_KartAttractHomingAttack(player_t *player) { fixed_t influence = 0; + fixed_t angleassist = 0; INT32 lastTarg = player->lastitemtarget; if (lastTarg >= 0) @@ -11801,10 +11811,25 @@ void K_KartAttractHomingAttack(player_t *player) mobj_t *targMo = players[lastTarg].mo; vector2_t targetdirection = {targMo->x - player->mo->x, targMo->y - player->mo->y}; vector2_t movedirection = {P_ReturnThrustX(NULL, player->mo->angle, FRACUNIT), P_ReturnThrustY(NULL, player->mo->angle, FRACUNIT)}; - + fixed_t targetangle = AngleFixed(R_PointToAngle2(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy, targMo->x + targMo->momx, targMo->y + targMo->momy)); + FV2_Normalize(&movedirection); FV2_Normalize(&targetdirection); - influence = FixedDiv(CLAMP(FV2_Dot(&movedirection, &targetdirection), 0, TargetThreshold), TargetThreshold); + influence = FixedDiv(CLAMP(FV2_Dot(&targetdirection, &movedirection), 0, TargetThreshold), TargetThreshold); + + if (FV2_Dot(&targetdirection, &movedirection) > 0) + { + angleassist = (targetangle - AngleFixed(player->mo->angle)); + if (angleassist < -180*FRACUNIT) + { + angleassist += 360*FRACUNIT; + } + else if (angleassist > 180*FRACUNIT) + { + angleassist -= 360*FRACUNIT; + } + angleassist = FixedMul(CLAMP(angleassist, -TargetAngleAssist, TargetAngleAssist), influence); + } } } @@ -11813,28 +11838,48 @@ void K_KartAttractHomingAttack(player_t *player) && player->bumpUnstuck == 0) { mobj_t *mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK); - mo->angle = P_RandomRange(-30, 30)*ANG1 + R_PointToAngle2(0,0, player->mo->momx, player->mo->momy) - ANGLE_180; + angle_t effectangle = player->mo->angle; + if (player->speed > 0) + { + effectangle = R_PointToAngle2(0,0, player->mo->momx, player->mo->momy); + } + mo->angle = P_RandomRange(-30, 30)*ANG1 + (effectangle - ANGLE_180); mo->fuse = P_RandomRange(10, 20); - P_SetScale(mo, player->mo->scale); - mo->destscale = mo->scale/2; + P_SetScale(mo, player->mo->scale/2); + mo->destscale = mo->scale/3; P_SetTarget(&mo->target, player->mo); P_SetMobjState(mo, S_KLIT1); - mo->renderflags |= RF_ADD|RF_FULLBRIGHT; - P_SpawnGhostMobj(player->mo); + mo->renderflags |= RF_ADD|RF_FULLBRIGHT|RF_TRANS50; + mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK); + P_SetMobjState(mo, S_KSPARK1); + mo->renderflags |= RF_ADD|RF_FULLBRIGHT|RF_TRANS30; + + P_SpawnGhostMobj(player->mo); - if (player->attractionattack_hipower) + if (player->attractionattack_hipower && lastTarg >= 0) { - player->attractionboost = Easing_InCubic(influence, 50*FRACUNIT/100, 60*FRACUNIT/100); + player->attractionboost = Easing_InCubic(influence, ATTRACTIONSPEEDHIMIN, ATTRACTIONSPEEDHIMAX); } else { - player->attractionboost = Easing_InCubic(influence, 25*FRACUNIT/100, 30*FRACUNIT/100); + player->attractionboost = Easing_InCubic(influence, ATTRACTIONSPEEDNORMMIN, ATTRACTIONSPEEDNORMMAX); } + if (angleassist) + { + player->mo->angle += FixedAngle(angleassist); + P_SetPlayerAngle(player, player->mo->angle); + } + player->attractionattack--; } else + { + player->attractionattack = 0; + } + + if (player->attractionattack <= 0) { player->attractionattack = 0; player->attractionattack_hipower = false; diff --git a/src/k_kart.h b/src/k_kart.h index 76c70cbdf..ce84cfd18 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -139,6 +139,15 @@ extern vector3_t clusterpoint, clusterdtf; #define FLAMEHANDLEBOOST CV_Get(&cv_kartstacking_flame_handleboost) #define FLAMESTACKABLE CV_Get(&cv_kartstacking_flame_stackable) +#define ATTRACTIONSPEEDHIMIN CV_Get(&cv_kartstacking_attraction_speedboost_himin) +#define ATTRACTIONSPEEDHIMAX CV_Get(&cv_kartstacking_attraction_speedboost_himax) +#define ATTRACTIONSPEEDNORMMIN CV_Get(&cv_kartstacking_attraction_speedboost_normmin) +#define ATTRACTIONSPEEDNORMMAX CV_Get(&cv_kartstacking_attraction_speedboost_normmax) +#define ATTRACTIONACCELHI CV_Get(&cv_kartstacking_attraction_accelboost_hi) +#define ATTRACTIONACCELNORM CV_Get(&cv_kartstacking_attraction_accelboost_norm) +#define ATTRACTIONHANDLEBOOST CV_Get(&cv_kartstacking_attraction_handleboost) +#define ATTRACTIONSTACKABLE CV_Get(&cv_kartstacking_attraction_stackable) + #define ALTSHRINKTIME CV_Get(&cv_kartaltshrinktime) #define SHRINKSPEEDBOOST CV_Get(&cv_kartstacking_altshrink_speedboost) #define SHRINKACCELBOOST CV_Get(&cv_kartstacking_altshrink_accelboost) diff --git a/src/p_inter.c b/src/p_inter.c index b01195ea9..7aae0290e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -24,6 +24,7 @@ #include "st_stuff.h" #include "hu_stuff.h" #include "lua_hook.h" +#include "lua_script.h" // lua_compatmode #include "m_cond.h" // unlockables, emblems, etc #include "p_setup.h" #include "m_cheat.h" // objectplace @@ -2041,21 +2042,38 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, // Determines what ShouldX Hook's status should be used. static UINT8 P_ShouldHookDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { - UINT8 shouldDamage = LUA_HookShouldDamage(target, inflictor, source, damage, damagetype); - UINT8 shouldSpin = LUA_HookShouldSpin(target, inflictor, source, damage, damagetype); - UINT8 shouldExplode = LUA_HookShouldExplode(target, inflictor, source, damage, damagetype); - UINT8 shouldSquish = LUA_HookShouldSquish(target, inflictor, source, damage, damagetype); + boolean targetisplayer = false; + const boolean killer = (damagetype & DMG_DEATHMASK); + INT32 use_damage = damage; + + if (target && (!P_MobjWasRemoved(target)) && target->player) + { + targetisplayer = true; + } + + if (lua_compatmode && targetisplayer && killer) + { + // Before the introduction of dedicated damage types, this magic number was used to kill players. + use_damage = 10000; + } + + UINT8 shouldDamage = LUA_HookShouldDamage(target, inflictor, source, use_damage, damagetype); + UINT8 shouldSpin = LUA_HookShouldSpin(target, inflictor, source, use_damage, damagetype); + UINT8 shouldExplode = LUA_HookShouldExplode(target, inflictor, source, use_damage, damagetype); + UINT8 shouldSquish = LUA_HookShouldSquish(target, inflictor, source, use_damage, damagetype); UINT8 status; const UINT8 type = (damagetype & DMG_TYPEMASK); - status = shouldDamage; - if (shouldSpin > 0 && ((type == DMG_NORMAL) || (type == DMG_WIPEOUT) || (type == DMG_FLIPOVER))) - status = shouldSpin; - else if (shouldExplode > 0 && ((type == DMG_EXPLODE) || (type == DMG_KARMA))) - status = shouldExplode; - else if (shouldSquish > 0 && (type == DMG_SQUISH)) - status = shouldSquish; + if (!killer) + { + if (shouldSpin > 0 && ((type == DMG_NORMAL) || (type == DMG_WIPEOUT) || (type == DMG_FLIPOVER))) + status = shouldSpin; + else if (shouldExplode > 0 && ((type == DMG_EXPLODE) || (type == DMG_KARMA))) + status = shouldExplode; + else if (shouldSquish > 0 && (type == DMG_SQUISH)) + status = shouldSquish; + } return status; }