Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions soh/soh/Enhancements/enhancementTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ typedef enum {
DAMAGE_OHKO
} DamageMultType;

typedef enum {
PVP_DAMAGE_MULT_1X,
PVP_DAMAGE_MULT_2X,
PVP_DAMAGE_MULT_4X,
PVP_DAMAGE_MULT_8X,
PVP_DAMAGE_MULT_OHKO,
} PvpDamageMult;

typedef enum {
DAMPE_NONE,
DAMPE_NORMAL,
Expand Down
1 change: 1 addition & 0 deletions soh/soh/Network/Anchor/Anchor.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ typedef struct {
typedef struct {
uint32_t ownerClientId;
u8 pvpMode; // 0 = off, 1 = on, 2 = on with friendly fire
u8 pvpDamageMult; // 0 = 1x, 1 = 2x, 2 = 4x, 3 = 8x, 4 = OHKO
u8 showLocationsMode; // 0 = none, 1 = team, 2 = all
u8 teleportMode; // 0 = off, 1 = team, 2 = all
u8 syncItemsAndFlags; // 0 = off, 1 = on
Expand Down
15 changes: 15 additions & 0 deletions soh/soh/Network/Anchor/Menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ extern std::shared_ptr<AnchorRoomWindow> mAnchorRoomWindow;
} // namespace SohGui

static const char* pvpModes[3] = { "Off", "On", "On + Friendly Fire" };
static const char* pvpDamageMults[5] = {
"1x: Kokiri sword slash damages quarter heart.",
"2x: Kokiri sword slash damages half heart.",
"4x: Kokiri sword slash damages one heart.",
"8x: Kokiri sword slash damages two hearts.",
"One Hit KO",
};
static std::vector<const char*> teleportModes = { "None", "Team Only", "All" };
static std::vector<const char*> showLocationsModes = { "None", "Team Only", "All" };

Expand Down Expand Up @@ -174,6 +181,14 @@ void AnchorAdminMenu(WidgetInfo& info) {
.Color(THEME_COLOR))) {
anchor->SendPacket_UpdateRoomState();
}
if (UIWidgets::CVarCombobox("PvP Damage Multiplier:", CVAR_REMOTE_ANCHOR("RoomSettings.PvpDamageMult"),
pvpDamageMults,
UIWidgets::ComboboxOptions()
.DefaultIndex(1)
.LabelPosition(UIWidgets::LabelPositions::Above)
.Color(THEME_COLOR))) {
anchor->SendPacket_UpdateRoomState();
}
if (UIWidgets::CVarCombobox("Show Locations For:", CVAR_REMOTE_ANCHOR("RoomSettings.ShowLocationsMode"),
showLocationsModes,
UIWidgets::ComboboxOptions()
Expand Down
21 changes: 20 additions & 1 deletion soh/soh/Network/Anchor/Packets/DamagePlayer.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "soh/Network/Anchor/Anchor.h"
#include <nlohmann/json.hpp>
#include <libultraship/libultraship.h>
#include "soh/Enhancements/enhancementTypes.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"

extern "C" {
Expand All @@ -14,6 +15,24 @@ void func_80838280(Player* player);
* DAMAGE_PLAYER
*/

int GetPvpDamageMultiplier(const RoomState& roomState) {
uint8_t damageOption = roomState.pvpDamageMult;
switch (damageOption) {
case PVP_DAMAGE_MULT_1X:
return 1;
case PVP_DAMAGE_MULT_2X:
return 2;
case PVP_DAMAGE_MULT_4X:
return 4;
case PVP_DAMAGE_MULT_8X:
return 8;
case PVP_DAMAGE_MULT_OHKO:
return 256;
default:
return 1;
}
}

void Anchor::SendPacket_DamagePlayer(u32 clientId, u8 damageEffect, u8 damage) {
if (!IsSaveLoaded()) {
return;
Expand Down Expand Up @@ -47,7 +66,7 @@ void Anchor::HandlePacket_DamagePlayer(nlohmann::json payload) {
u8 damageEffect = payload["damageEffect"].get<u8>();
u8 damage = payload["damage"].get<u8>();

self->actor.colChkInfo.damage = damage * 8; // Arbitrary number currently, need to fine tune
self->actor.colChkInfo.damage = damage * GetPvpDamageMultiplier(roomState) * 4;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a u8, with OHKO you're going to overflow it

passing damage as parameter to GetPvpDamageMultiplier you could have OHKO ignore damage value & return 63 (need to avoid overflow from * 4). But I'm also thinking might as well push the * 4 down too, renaming GetPvpDamageMultiplier to TransformPvpDamage


if (damageEffect == DUMMY_PLAYER_HIT_RESPONSE_FIRE) {
for (int i = 0; i < ARRAY_COUNT(self->bodyFlameTimers); i++) {
Expand Down
3 changes: 3 additions & 0 deletions soh/soh/Network/Anchor/Packets/UpdateRoomState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ nlohmann::json Anchor::PrepRoomState() {
if (isGlobalRoom) {
// Global room uses hardcoded settings
payload["pvpMode"] = 0;
payload["pvpDamageMult"] = 0;
payload["showLocationsMode"] = 0;
payload["teleportMode"] = 0;
payload["syncItemsAndFlags"] = 0;
} else {
payload["pvpMode"] = CVarGetInteger(CVAR_REMOTE_ANCHOR("RoomSettings.PvpMode"), 1);
payload["pvpDamageMult"] = CVarGetInteger(CVAR_REMOTE_ANCHOR("RoomSettings.PvpDamageMult"), 1);
payload["showLocationsMode"] = CVarGetInteger(CVAR_REMOTE_ANCHOR("RoomSettings.ShowLocationsMode"), 1);
payload["teleportMode"] = CVarGetInteger(CVAR_REMOTE_ANCHOR("RoomSettings.TeleportMode"), 1);
payload["syncItemsAndFlags"] = CVarGetInteger(CVAR_REMOTE_ANCHOR("RoomSettings.SyncItemsAndFlags"), 1);
Expand All @@ -49,6 +51,7 @@ void Anchor::HandlePacket_UpdateRoomState(nlohmann::json payload) {

roomState.ownerClientId = payload["state"]["ownerClientId"].get<uint32_t>();
roomState.pvpMode = payload["state"]["pvpMode"].get<u8>();
roomState.pvpDamageMult = payload["state"]["pvpDamageMult"].get<u8>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this client joins a room that is hosted by an older client (without this setting) this will result in a crash. Could you do a conditional check here? I think there is probably some examples somewhere, if not here then in the older anchor code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch. Changed it to not explicitly using a conditional, but instead calling .value() to use value of pvpDamageMult if it exists in the payload, or a default of 1 if it doesn't, which should correspond to the old 2x behavior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find, I'll probably migrate to using this in a few other places as well.

roomState.showLocationsMode = payload["state"]["showLocationsMode"].get<u8>();
roomState.teleportMode = payload["state"]["teleportMode"].get<u8>();
roomState.syncItemsAndFlags = payload["state"]["syncItemsAndFlags"].get<u8>();
Expand Down
Loading