diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index d65909bd6..72dc8b4d3 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -3675,6 +3675,15 @@ INT_SUBTYPE_STAR_DOOR = 0x00000020 --- @type integer INT_SUBTYPE_TWIRL_BOUNCE = 0x00000080 +--- @type integer +PVP_ATTACK_KNOCKBACK_TIMER_DEFAULT = 10 + +--- @type integer +PVP_ATTACK_KNOCKBACK_TIMER_OVERRIDE = -5 + +--- @type integer +PVP_ATTACK_OVERRIDE_VANILLA_INVINCIBILITY = 0x0000FFFF + --- @class InteractionFlag --- @type InteractionFlag @@ -5549,6 +5558,14 @@ PLAYER_INTERACTIONS_SOLID = 1 --- @type PlayerInteractions PLAYER_INTERACTIONS_PVP = 2 +--- @class PvpType + +--- @type PvpType +PLAYER_PVP_CLASSIC = 0 + +--- @type PvpType +PLAYER_PVP_REVAMPED = 1 + --- @type integer MAX_DESCRIPTION_STRING = 20 diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index d3fd460fb..4ee642e49 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -2034,6 +2034,7 @@ --- @field public pauseAnywhere integer --- @field public playerInteractions PlayerInteractions --- @field public playerKnockbackStrength integer +--- @field public pvpType PvpType --- @field public skipIntro integer --- @field public stayInLevelAfterStar integer diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 683e6a3ba..73d016e68 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -45,6 +45,7 @@ - [enum BouncyLevelBounds](#enum-BouncyLevelBounds) - [enum NetworkSystemType](#enum-NetworkSystemType) - [enum PlayerInteractions](#enum-PlayerInteractions) + - [enum PvpType](#enum-PvpType) - [network_player.h](#network_playerh) - [enum NetworkPlayerType](#enum-NetworkPlayerType) - [obj_behaviors.c](#obj_behaviorsc) @@ -1295,6 +1296,9 @@ - INT_SUBTYPE_SIGN - INT_SUBTYPE_STAR_DOOR - INT_SUBTYPE_TWIRL_BOUNCE +- PVP_ATTACK_KNOCKBACK_TIMER_DEFAULT +- PVP_ATTACK_KNOCKBACK_TIMER_OVERRIDE +- PVP_ATTACK_OVERRIDE_VANILLA_INVINCIBILITY ### [enum InteractionFlag](#InteractionFlag) | Identifier | Value | @@ -2006,6 +2010,12 @@ | PLAYER_INTERACTIONS_SOLID | 1 | | PLAYER_INTERACTIONS_PVP | 2 | +### [enum PvpType](#PvpType) +| Identifier | Value | +| :--------- | :---- | +| PLAYER_PVP_CLASSIC | 0 | +| PLAYER_PVP_REVAMPED | 1 | + [:arrow_up_small:](#)
diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 112aec3a0..1bbadc3fc 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -2563,6 +2563,7 @@ | pauseAnywhere | `integer` | | | playerInteractions | [enum PlayerInteractions](constants.md#enum-PlayerInteractions) | | | playerKnockbackStrength | `integer` | | +| pvpType | [enum PvpType](constants.md#enum-PvpType) | | | skipIntro | `integer` | | | stayInLevelAfterStar | `integer` | | diff --git a/include/types.h b/include/types.h index 9ff10e0f2..7860eae12 100644 --- a/include/types.h +++ b/include/types.h @@ -428,7 +428,7 @@ struct MarioState /*????*/ u8 wasNetworkVisible; /*????*/ f32 minimumBoneY; /*????*/ f32 curAnimOffset; - /*????*/ u8 knockbackTimer; + /*????*/ s8 knockbackTimer; /*????*/ u8 specialTripleJump; /*????*/ Vec3f wallNormal; /*????*/ u8 visibleToEnemies; diff --git a/lang/English.ini b/lang/English.ini index 146294cdf..2950733c9 100644 --- a/lang/English.ini +++ b/lang/English.ini @@ -194,6 +194,9 @@ WEAK = "Weak" NORMAL = "Normal" TOO_MUCH = "Too much" KNOCKBACK_STRENGTH = "Knockback Strength" +CLASSIC_PVP = "Classic" +REVAMPED_PVP = "Revamped" +PVP_MODE = "Player PvP Mode" LEAVE_LEVEL = "Leave Level" STAY_IN_LEVEL = "Stay In Level" NONSTOP = "Non-Stop" diff --git a/src/game/interaction.c b/src/game/interaction.c index b6f34487b..49fe062c5 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -159,7 +159,7 @@ u32 determine_interaction(struct MarioState *m, struct Object *o) { if (interaction == 0 && action & ACT_FLAG_ATTACKING) { u32 flags = (MARIO_PUNCHING | MARIO_KICKING | MARIO_TRIPPING); if ((action == ACT_PUNCHING || action == ACT_MOVE_PUNCHING || action == ACT_JUMP_KICK) || - (m->flags & flags && interaction & INT_LUA)) { + ((m->flags & flags) && (interaction & INT_LUA))) { s16 dYawToObject = mario_obj_angle_to_object(m, o) - m->faceAngle[1]; if (m->flags & MARIO_PUNCHING) { @@ -668,16 +668,21 @@ u32 determine_knockback_action(struct MarioState *m, UNUSED s32 arg) { // set knockback very high when dealing with player attacks if (m->interactObj != NULL && (m->interactObj->oInteractType & INTERACT_PLAYER) && terrainIndex != 2) { f32 scaler = 1; + s8 hasBeenPunched = FALSE; +#define IF_REVAMPED_PVP(Is, IsNot) gServerSettings.pvpType == PLAYER_PVP_REVAMPED ? (Is) : (IsNot); for (s32 i = 0; i < MAX_PLAYERS; i++) { struct MarioState* m2 = &gMarioStates[i]; if (!is_player_active(m2)) { continue; } if (m2->marioObj == NULL) { continue; } if (m2->marioObj != m->interactObj) { continue; } - if (m2->action == ACT_JUMP_KICK) { scaler = 2.0f; } - if (m2->action == ACT_DIVE) { scaler += fabs(m2->forwardVel * 0.01); } + // Redundent check in case the kicking flag somehow gets missed + if (m2->action == ACT_JUMP_KICK || m2->flags & MARIO_KICKING) { scaler = IF_REVAMPED_PVP(1.85f, 2.0f); } + else if (m2->action == ACT_DIVE) { scaler = 1 + IF_REVAMPED_PVP(m2->forwardVel * 0.005f, 0); } + else if ((m2->flags & MARIO_PUNCHING)) { scaler = IF_REVAMPED_PVP(0.18f, 1.0f); hasBeenPunched = gServerSettings.pvpType == PLAYER_PVP_REVAMPED; } if (m2->flags & MARIO_METAL_CAP) { scaler *= 1.25f; } break; } + if (m->flags & MARIO_METAL_CAP) { scaler *= 0.5f; if (scaler < 1) { scaler = 1; } @@ -692,8 +697,8 @@ u32 determine_knockback_action(struct MarioState *m, UNUSED s32 arg) { m->vel[2] = -mag * coss(m->interactObj->oFaceAngleYaw); m->slideVelX = m->vel[0]; m->slideVelZ = m->vel[2]; - m->knockbackTimer = 10; - + m->knockbackTimer = hasBeenPunched ? PVP_ATTACK_KNOCKBACK_TIMER_OVERRIDE : PVP_ATTACK_KNOCKBACK_TIMER_DEFAULT; +#undef IF_REVAMPED_PVP m->faceAngle[1] = m->interactObj->oFaceAngleYaw + (sign == 1.0f ? 0 : 0x8000); } @@ -826,8 +831,7 @@ u32 take_damage_and_knock_back(struct MarioState *m, struct Object *o) { } update_mario_sound_and_camera(m); - return drop_and_set_mario_action(m, determine_knockback_action(m, o->oDamageOrCoinValue), - damage); + return drop_and_set_mario_action(m, determine_knockback_action(m, o->oDamageOrCoinValue), damage); } return FALSE; @@ -1319,11 +1323,16 @@ static u8 resolve_player_collision(struct MarioState* m, struct MarioState* m2) } u8 determine_player_damage_value(u32 interaction) { - if (interaction & INT_GROUND_POUND) { return 4; } - if (interaction & (INT_TWIRL | INT_PUNCH | INT_TRIP)) { return 3; } - if (interaction & INT_KICK) { return 2; } - if (interaction & INT_SLIDE_KICK) { return 2; } - return 1; + if (gServerSettings.pvpType == PLAYER_PVP_REVAMPED) { + if (interaction & INT_GROUND_POUND) { return 3; } + if (interaction & (INT_KICK | INT_SLIDE_KICK | INT_TRIP | INT_TWIRL)) { return 2; } + return 1; + } else { + if (interaction & INT_GROUND_POUND_OR_TWIRL) { return 3; } + if (interaction & INT_KICK) { return 2; } + if (interaction & INT_ATTACK_SLIDE) { return 1; } + return 2; + } } u8 player_is_sliding(struct MarioState* m) { @@ -1354,14 +1363,25 @@ u8 passes_pvp_interaction_checks(struct MarioState* attacker, struct MarioState* || attacker->action == ACT_LONG_JUMP || attacker->action == ACT_SIDE_FLIP || attacker->action == ACT_BACKFLIP || attacker->action == ACT_TRIPLE_JUMP || attacker->action == ACT_WALL_KICK_AIR || attacker->action == ACT_WATER_JUMP - || attacker->action == ACT_STEEP_JUMP || attacker->action == ACT_HOLD_JUMP); + || attacker->action == ACT_STEEP_JUMP || attacker->action == ACT_HOLD_JUMP + || attacker->action == ACT_FREEFALL || attacker->action == ACT_LEDGE_GRAB + || attacker->action == ACT_FORWARD_ROLLOUT || attacker->action == ACT_BACKWARD_ROLLOUT); u8 isVictimIntangible = (victim->action & ACT_FLAG_INTANGIBLE); u8 isVictimGroundPounding = (victim->action == ACT_GROUND_POUND) && (victim->actionState != 0); - if (victim->knockbackTimer > 0) { + u8 isVictimInRolloutFlip = (victim->action == ACT_FORWARD_ROLLOUT || victim->action == ACT_BACKWARD_ROLLOUT) && (victim->actionState == 1); + if (victim->knockbackTimer != 0) { return false; } - return (!isInvulnerable && !isIgnoredAttack && !isAttackerInvulnerable && !isVictimIntangible && !isVictimGroundPounding); + if (gServerSettings.pvpType == PLAYER_PVP_REVAMPED && + (attacker->action == ACT_PUNCHING || attacker->action == ACT_MOVE_PUNCHING) && + (victim->action == ACT_SOFT_BACKWARD_GROUND_KB || victim->action == ACT_SOFT_FORWARD_GROUND_KB)) { + return true; + } else if (attacker->flags & MARIO_TRIPPING) { + return false; + } + + return (!isInvulnerable && !isIgnoredAttack && !isAttackerInvulnerable && !isVictimIntangible && !isVictimGroundPounding && !isVictimInRolloutFlip); } u32 interact_player(struct MarioState* m, UNUSED u32 interactType, struct Object* o) { @@ -1437,6 +1457,8 @@ u32 interact_player_pvp(struct MarioState* attacker, struct MarioState* victim) // see if it was an attack u32 interaction = determine_interaction(attacker, cVictim->marioObj); + // Specfically override jump kicks to prevent low damage and low knockback kicks + if (interaction & INT_HIT_FROM_BELOW && attacker->action == ACT_JUMP_KICK) { interaction = INT_KICK; } if (!(interaction & INT_ANY_ATTACK) || (interaction & INT_HIT_FROM_ABOVE) || !passes_pvp_interaction_checks(attacker, cVictim)) { return FALSE; } @@ -1450,21 +1472,32 @@ u32 interact_player_pvp(struct MarioState* attacker, struct MarioState* victim) } // determine if slide attack should be ignored + // Ground pounds will always be able to hit if ((interaction & INT_ATTACK_SLIDE) || player_is_sliding(cVictim)) { // determine the difference in velocities - Vec3f velDiff; - vec3f_dif(velDiff, attacker->vel, cVictim->vel); - - if (attacker->action == ACT_SLIDE_KICK_SLIDE || attacker->action == ACT_SLIDE_KICK) { - // if the difference vectors are not different enough, do not attack - if (vec3f_length(attacker->vel) < 15) { return FALSE; } + //Vec3f velDiff; + //vec3f_dif(velDiff, attacker->vel, cVictim->vel); + if (gServerSettings.pvpType == PLAYER_PVP_REVAMPED && attacker->action == ACT_GROUND_POUND) { + // do nothing } else { - // if the difference vectors are not different enough, do not attack - if (vec3f_length(attacker->vel) < 40) { return FALSE; } - } + if (attacker->action == ACT_SLIDE_KICK_SLIDE || attacker->action == ACT_SLIDE_KICK) { + // if the difference vectors are not different enough, do not attack + if (vec3f_length(attacker->vel) < 15) { return FALSE; } + } else { + // if the difference vectors are not different enough, do not attack + if (vec3f_length(attacker->vel) < 40) { return FALSE; } + } - // if the victim is going faster, do not attack - if (vec3f_length(cVictim->vel) > vec3f_length(attacker->vel)) { return FALSE; } + // if the victim is going faster, do not attack + // However if the victim is diving and the attacker is slidekicking, do not check speed + if (vec3f_length(cVictim->vel) > vec3f_length(attacker->vel)) { + if (gServerSettings.pvpType == PLAYER_PVP_REVAMPED && (attacker->action == ACT_SLIDE_KICK && cVictim->action == ACT_DIVE)) { + // do nothing, meaning don't exit + } else { + return FALSE; + } + } + } } // determine if ground pound should be ignored @@ -1493,7 +1526,9 @@ u32 interact_player_pvp(struct MarioState* attacker, struct MarioState* victim) victim->invincTimer = max(victim->invincTimer, 3); take_damage_and_knock_back(victim, attacker->marioObj); - bounce_back_from_attack(attacker, interaction); + if (gServerSettings.pvpType != PLAYER_PVP_REVAMPED || !(attacker->flags & MARIO_PUNCHING)) { + bounce_back_from_attack(attacker, interaction); + } victim->interactObj = NULL; smlua_call_event_hooks_mario_params(HOOK_ON_PVP_ATTACK, attacker, victim, interaction); diff --git a/src/game/interaction.h b/src/game/interaction.h index 045937a87..ce5527a6a 100644 --- a/src/game/interaction.h +++ b/src/game/interaction.h @@ -100,6 +100,10 @@ enum InteractionFlag { #define ATTACK_FAST_ATTACK 5 #define ATTACK_FROM_BELOW 6 +#define PVP_ATTACK_KNOCKBACK_TIMER_DEFAULT 10 +#define PVP_ATTACK_KNOCKBACK_TIMER_OVERRIDE -5 +#define PVP_ATTACK_OVERRIDE_VANILLA_INVINCIBILITY 0x0000FFFF + #define INT_STATUS_ATTACK_MASK 0x000000FF #define INT_STATUS_HOOT_GRABBED_BY_MARIO (1 << 0) /* 0x00000001 */ diff --git a/src/game/mario.c b/src/game/mario.c index 1b30893bd..06049177f 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1970,6 +1970,8 @@ s32 execute_mario_action(UNUSED struct Object *o) { if (gMarioState->knockbackTimer > 0) { gMarioState->knockbackTimer--; + } else if (gMarioState->knockbackTimer < 0) { + gMarioState->knockbackTimer++; } // hide inactive players diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index 66d6fb2ea..602727819 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -1160,8 +1160,10 @@ u32 common_air_knockback_step(struct MarioState *m, u32 landAction, u32 hardFall if (m->interactObj == NULL || !(m->interactObj->oInteractType & INTERACT_PLAYER)) { mario_set_forward_vel(m, speed); } + } else if (m->knockbackTimer < 0) { + // do nothing } else { - m->knockbackTimer = 10; + m->knockbackTimer = PVP_ATTACK_KNOCKBACK_TIMER_DEFAULT; } stepResult = perform_air_step(m, 0); diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 3b94cf618..c8add04f6 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -1678,8 +1678,10 @@ s32 common_ground_knockback_action(struct MarioState *m, s32 animation, s32 arg2 m->forwardVel = -32.0f; } } + } else if (m->knockbackTimer < 0) { + // do nothing } else { - m->knockbackTimer = 10; + m->knockbackTimer = PVP_ATTACK_KNOCKBACK_TIMER_DEFAULT; } animFrame = set_character_animation(m, animation); diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 0ac1be2f5..091024890 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -170,6 +170,7 @@ bool configMenuDemos = false; bool configDisablePopups = false; char configLanguage[MAX_CONFIG_STRING] = ""; bool configDynosLocalPlayerModelOnly = false; +unsigned int configPvpMode = PLAYER_PVP_CLASSIC; // CoopNet settings char configCoopNetIp[MAX_CONFIG_STRING] = DEFAULT_COOPNET_IP; unsigned int configCoopNetPort = DEFAULT_COOPNET_PORT; @@ -300,6 +301,7 @@ static const struct ConfigOption options[] = { {.name = "coop_menu_level", .type = CONFIG_TYPE_UINT, .uintValue = &configMenuLevel}, {.name = "coop_menu_sound", .type = CONFIG_TYPE_UINT, .uintValue = &configMenuSound}, {.name = "coop_menu_random", .type = CONFIG_TYPE_BOOL, .boolValue = &configMenuRandom}, + {.name = "player_pvp_mode", .type = CONFIG_TYPE_UINT, .uintValue = &configPvpMode}, // {.name = "coop_menu_demos", .type = CONFIG_TYPE_BOOL, .boolValue = &configMenuDemos}, {.name = "disable_popups", .type = CONFIG_TYPE_BOOL, .boolValue = &configDisablePopups}, {.name = "language", .type = CONFIG_TYPE_STRING, .stringValue = (char*)&configLanguage, .maxStringLength = MAX_CONFIG_STRING}, diff --git a/src/pc/configfile.h b/src/pc/configfile.h index aa080e1e7..5d38f8d14 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -123,6 +123,7 @@ extern bool configMenuDemos; extern bool configDisablePopups; extern char configLanguage[MAX_CONFIG_STRING]; extern bool configDynosLocalPlayerModelOnly; +extern unsigned int configPvpMode; // CoopNet settings extern char configCoopNetIp[MAX_CONFIG_STRING]; extern unsigned int configCoopNetPort; diff --git a/src/pc/djui/djui_panel_host_settings.c b/src/pc/djui/djui_panel_host_settings.c index 33e15fbcc..36d7a8d83 100644 --- a/src/pc/djui/djui_panel_host_settings.c +++ b/src/pc/djui/djui_panel_host_settings.c @@ -55,6 +55,9 @@ void djui_panel_host_settings_create(struct DjuiBase* caller) { char* kChoices[3] = { DLANG(HOST_SETTINGS, WEAK), DLANG(HOST_SETTINGS, NORMAL), DLANG(HOST_SETTINGS, TOO_MUCH) }; djui_selectionbox_create(body, DLANG(HOST_SETTINGS, KNOCKBACK_STRENGTH), kChoices, 3, &sKnockbackIndex, djui_panel_host_settings_knockback_change); + char* pChoices[2] = { DLANG(HOST_SETTINGS, CLASSIC_PVP), DLANG(HOST_SETTINGS, REVAMPED_PVP) }; + djui_selectionbox_create(body, DLANG(HOST_SETTINGS, PVP_MODE), pChoices, 2, &configPvpMode, NULL); + char* lChoices[3] = { DLANG(HOST_SETTINGS, LEAVE_LEVEL), DLANG(HOST_SETTINGS, STAY_IN_LEVEL), DLANG(HOST_SETTINGS, NONSTOP) }; djui_selectionbox_create(body, DLANG(HOST_SETTINGS, ON_STAR_COLLECTION), lChoices, 3, &configStayInLevelAfterStar, NULL); diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 6ad328248..678eb53de 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -1156,7 +1156,7 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "interactObj", LVT_COBJECT_P, offsetof(struct MarioState, interactObj), false, LOT_OBJECT }, { "invincTimer", LVT_S16, offsetof(struct MarioState, invincTimer), false, LOT_NONE }, { "isSnoring", LVT_U8, offsetof(struct MarioState, isSnoring), false, LOT_NONE }, - { "knockbackTimer", LVT_U8, offsetof(struct MarioState, knockbackTimer), false, LOT_NONE }, + { "knockbackTimer", LVT_S8, offsetof(struct MarioState, knockbackTimer), false, LOT_NONE }, { "marioBodyState", LVT_COBJECT_P, offsetof(struct MarioState, marioBodyState), true, LOT_MARIOBODYSTATE }, { "marioObj", LVT_COBJECT_P, offsetof(struct MarioState, marioObj), true, LOT_OBJECT }, { "minimumBoneY", LVT_F32, offsetof(struct MarioState, minimumBoneY), false, LOT_NONE }, @@ -2227,7 +2227,7 @@ static struct LuaObjectField sRayIntersectionInfoFields[LUA_RAY_INTERSECTION_INF { "surface", LVT_COBJECT_P, offsetof(struct RayIntersectionInfo, surface), false, LOT_SURFACE }, }; -#define LUA_SERVER_SETTINGS_FIELD_COUNT 12 +#define LUA_SERVER_SETTINGS_FIELD_COUNT 13 static struct LuaObjectField sServerSettingsFields[LUA_SERVER_SETTINGS_FIELD_COUNT] = { { "bouncyLevelBounds", LVT_S32, offsetof(struct ServerSettings, bouncyLevelBounds), false, LOT_NONE }, { "bubbleDeath", LVT_U8, offsetof(struct ServerSettings, bubbleDeath), false, LOT_NONE }, @@ -2239,6 +2239,7 @@ static struct LuaObjectField sServerSettingsFields[LUA_SERVER_SETTINGS_FIELD_COU { "pauseAnywhere", LVT_U8, offsetof(struct ServerSettings, pauseAnywhere), false, LOT_NONE }, { "playerInteractions", LVT_S32, offsetof(struct ServerSettings, playerInteractions), false, LOT_NONE }, { "playerKnockbackStrength", LVT_U8, offsetof(struct ServerSettings, playerKnockbackStrength), false, LOT_NONE }, + { "pvpType", LVT_S32, offsetof(struct ServerSettings, pvpType), false, LOT_NONE }, { "skipIntro", LVT_U8, offsetof(struct ServerSettings, skipIntro), false, LOT_NONE }, { "stayInLevelAfterStar", LVT_U8, offsetof(struct ServerSettings, stayInLevelAfterStar), false, LOT_NONE }, }; diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 1b66ca230..764a1c4f4 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -1445,6 +1445,9 @@ char gSmluaConstants[] = "" "ATTACK_GROUND_POUND_OR_TWIRL = 4\n" "ATTACK_FAST_ATTACK = 5\n" "ATTACK_FROM_BELOW = 6\n" +"PVP_ATTACK_KNOCKBACK_TIMER_DEFAULT = 10\n" +"PVP_ATTACK_KNOCKBACK_TIMER_OVERRIDE = -5\n" +"PVP_ATTACK_OVERRIDE_VANILLA_INVINCIBILITY = 0x0000FFFF\n" "INT_STATUS_ATTACK_MASK = 0x000000FF\n" "INT_STATUS_HOOT_GRABBED_BY_MARIO = (1 << 0)\n" "INT_STATUS_MARIO_UNK1 = (1 << 1)\n" @@ -2035,6 +2038,8 @@ char gSmluaConstants[] = "" "BOUNCY_LEVEL_BOUNDS_OFF = 0\n" "BOUNCY_LEVEL_BOUNDS_ON = 1\n" "BOUNCY_LEVEL_BOUNDS_ON_CAP = 2\n" +"PLAYER_PVP_CLASSIC = 0\n" +"PLAYER_PVP_REVAMPED = 1\n" "UNKNOWN_LOCAL_INDEX = (-1)\n" "UNKNOWN_GLOBAL_INDEX = (-1)\n" "UNKNOWN_NETWORK_INDEX = (-1)\n" diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 105fadc93..0d910545d 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -84,6 +84,7 @@ struct ServerSettings gServerSettings = { .nametags = TRUE, .maxPlayers = MAX_PLAYERS, .pauseAnywhere = FALSE, + .pvpType = PLAYER_PVP_CLASSIC, }; struct NametagsSettings gNametagsSettings = { @@ -130,6 +131,7 @@ bool network_init(enum NetworkType inNetworkType, bool reconnecting) { gServerSettings.nametags = configNametags; gServerSettings.maxPlayers = configAmountofPlayers; gServerSettings.pauseAnywhere = configPauseAnywhere; + gServerSettings.pvpType = configPvpMode; #if defined(RAPI_DUMMY) || defined(WAPI_DUMMY) gServerSettings.headlessServer = (inNetworkType == NT_SERVER); #else diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 85779a261..5437ee941 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -69,9 +69,15 @@ enum BouncyLevelBounds { BOUNCY_LEVEL_BOUNDS_ON_CAP, }; +enum PvpType { + PLAYER_PVP_CLASSIC, + PLAYER_PVP_REVAMPED +}; + struct ServerSettings { enum PlayerInteractions playerInteractions; enum BouncyLevelBounds bouncyLevelBounds; + enum PvpType pvpType; u8 playerKnockbackStrength; u8 stayInLevelAfterStar; u8 skipIntro;