From 13328006d3d57ad83212f956e74a0cc4900d2c8c Mon Sep 17 00:00:00 2001 From: longfruit Date: Tue, 7 Nov 2023 19:29:12 -0800 Subject: [PATCH] Fix tower mob level and hp scaling --- .../data/excels/tower/TowerLevelData.java | 1 + .../game/ability/AbilityManager.java | 16 +++++--------- .../game/dungeons/DungeonManager.java | 9 ++++++-- .../game/entity/EntityMonster.java | 22 +++++++++++++++++++ .../grasscutter/game/tower/TowerManager.java | 18 +++++++++++++-- .../emu/grasscutter/game/world/Scene.java | 14 ++++++++++++ .../scripts/SceneScriptManager.java | 13 +---------- 7 files changed, 66 insertions(+), 27 deletions(-) diff --git a/src/main/java/emu/grasscutter/data/excels/tower/TowerLevelData.java b/src/main/java/emu/grasscutter/data/excels/tower/TowerLevelData.java index b4486cca7cd..e9fd62ff6e8 100644 --- a/src/main/java/emu/grasscutter/data/excels/tower/TowerLevelData.java +++ b/src/main/java/emu/grasscutter/data/excels/tower/TowerLevelData.java @@ -13,6 +13,7 @@ public class TowerLevelData extends GameResource { private int levelGroupId; private int dungeonId; private List conds; + private int monsterLevel; public static class TowerLevelCond { private TowerCondType towerCondType; diff --git a/src/main/java/emu/grasscutter/game/ability/AbilityManager.java b/src/main/java/emu/grasscutter/game/ability/AbilityManager.java index 1ac6177f528..6be1c33a9ed 100644 --- a/src/main/java/emu/grasscutter/game/ability/AbilityManager.java +++ b/src/main/java/emu/grasscutter/game/ability/AbilityManager.java @@ -49,7 +49,6 @@ public final class AbilityManager extends BasePlayerManager { } @Getter private boolean abilityInvulnerable = false; - @Getter private Consumer clearBurstEnergy; private int burstCasterId; private int burstSkillId; @@ -59,7 +58,6 @@ public AbilityManager(Player player) { } public void removePendingEnergyClear() { - this.clearBurstEnergy = null; this.burstCasterId = 0; this.burstSkillId = 0; } @@ -96,15 +94,16 @@ private void onPossibleElementalBurst(Ability ability, AbilityModifier modifier, > 0; } - if (this.clearBurstEnergy != null - && this.burstCasterId == entityId + if (this.burstCasterId == entityId && (ability.getAvatarSkillStartIds().contains(this.burstSkillId) || skillInvincibility)) { Grasscutter.getLogger() .trace( "Caster ID's {} burst successful, clearing energy and setting invulnerability", entityId); this.abilityInvulnerable = true; - this.clearBurstEnergy.accept(entityId); + this.player + .getEnergyManager() + .handleEvtDoSkillSuccNotify(this.player.getSession(), this.burstSkillId, this.burstCasterId); this.removePendingEnergyClear(); } } @@ -337,13 +336,8 @@ public void onSkillStart(Player player, int skillId, int casterId) { } // Track this elemental burst to possibly clear avatar energy later. - this.clearBurstEnergy = - (ignored) -> - player - .getEnergyManager() - .handleEvtDoSkillSuccNotify(player.getSession(), skillId, casterId); - this.burstCasterId = casterId; this.burstSkillId = skillId; + this.burstCasterId = casterId; } /** diff --git a/src/main/java/emu/grasscutter/game/dungeons/DungeonManager.java b/src/main/java/emu/grasscutter/game/dungeons/DungeonManager.java index 4c1698f81b4..6419f0a7694 100644 --- a/src/main/java/emu/grasscutter/game/dungeons/DungeonManager.java +++ b/src/main/java/emu/grasscutter/game/dungeons/DungeonManager.java @@ -82,8 +82,13 @@ public boolean isFinishedSuccessfully() { } public int getLevelForMonster(int id) { - // TODO should use levelConfigMap? and how? - return dungeonData.getShowLevel(); + if (isTowerDungeon()) { + // Tower dungeons have their own level setting in TowerLevelData + return scene.getPlayers().get(0).getTowerManager().getCurrentMonsterLevel(); + } else { + // TODO should use levelConfigMap? and how? + return dungeonData.getShowLevel(); + } } public boolean activateRespawnPoint(int pointId) { diff --git a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java index 0ff36a61457..4656c9d5014 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java @@ -355,6 +355,28 @@ public void recalcStats() { + (this.getFightProperty(c.getBase()) * (1f + this.getFightProperty(c.getPercent()))))); + // If in tower, scale max hp by + // +50%: Floors 3 – 7 + // +100%: Floors 8 – 11 + // +150%: Floor 12 + var dungeonManager = getScene().getDungeonManager(); + var towerManager = getScene().getPlayers().get(0).getTowerManager(); + if (dungeonManager != null && dungeonManager.isTowerDungeon() && towerManager != null) { + var floor = towerManager.getCurrentFloorNumber(); + float additionalScaleFactor = 0f; + if (floor >= 12) { + additionalScaleFactor = 1.5f; + } else if (floor >= 8) { + additionalScaleFactor = 1.f; + } else if (floor >= 3) { + additionalScaleFactor = .5f; + } + + this.setFightProperty( + FightProperty.FIGHT_PROP_MAX_HP, + this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * (1 + additionalScaleFactor)); + } + // Set current hp this.setFightProperty( FightProperty.FIGHT_PROP_CUR_HP, diff --git a/src/main/java/emu/grasscutter/game/tower/TowerManager.java b/src/main/java/emu/grasscutter/game/tower/TowerManager.java index 2574aee0f9a..aeb006be5a3 100644 --- a/src/main/java/emu/grasscutter/game/tower/TowerManager.java +++ b/src/main/java/emu/grasscutter/game/tower/TowerManager.java @@ -29,6 +29,11 @@ public int getCurrentFloorId() { return this.getTowerData().currentFloorId; } + /** floor number: 1 - 12 **/ + public int getCurrentFloorNumber() { + return GameData.getTowerFloorDataMap().get(getCurrentFloorId()).getFloorIndex(); + } + public int getCurrentLevelId() { return this.getTowerData().currentLevelId + this.getTowerData().currentLevel; } @@ -93,8 +98,17 @@ public void teamSelect(int floor, List> towerTeams) { player.getTeamManager().setupTemporaryTeam(towerTeams); } + public TowerLevelData getCurrentTowerLevelDataMap() { + return GameData.getTowerLevelDataMap().get(getCurrentLevelId()); + } + + public int getCurrentMonsterLevel() { + // monsterLevel given in TowerLevelExcelConfigData.json is off by one. + return getCurrentTowerLevelDataMap().getMonsterLevel() + 1; + } + public void enterLevel(int enterPointId) { - var levelData = GameData.getTowerLevelDataMap().get(getCurrentLevelId()); + var levelData = getCurrentTowerLevelDataMap(); var dungeonId = levelData.getDungeonId(); @@ -140,7 +154,7 @@ public int getCurLevelStars() { return 0; } - var levelData = GameData.getTowerLevelDataMap().get(getCurrentLevelId()); + var levelData = getCurrentTowerLevelDataMap(); // 0-based indexing. "star" = 0 means checking for 1-star conditions. int star; for (star = 2; star >= 0; star--) { diff --git a/src/main/java/emu/grasscutter/game/world/Scene.java b/src/main/java/emu/grasscutter/game/world/Scene.java index d1511114e27..baa6d0aafbf 100644 --- a/src/main/java/emu/grasscutter/game/world/Scene.java +++ b/src/main/java/emu/grasscutter/game/world/Scene.java @@ -767,6 +767,20 @@ public int getEntityLevel(int baseLevel, int worldLevelOverride) { return level; } + public int getLevelForMonster(int configId, int defaultLevel) { + if (getDungeonManager() != null) { + return getDungeonManager().getLevelForMonster(configId); + } else if (getWorld().getWorldLevel() > 0) { + var worldLevelData = + GameData.getWorldLevelDataMap().get(getWorld().getWorldLevel()); + + if (worldLevelData != null) { + return worldLevelData.getMonsterLevel(); + } + } + return defaultLevel; + } + public void checkNpcGroup() { Set npcBornEntries = ConcurrentHashMap.newKeySet(); for (Player player : this.getPlayers()) { diff --git a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java index 71f40da246e..4e5229600e2 100644 --- a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java +++ b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java @@ -1069,18 +1069,7 @@ public EntityMonster createMonster(int groupId, int blockId, SceneMonster monste } // Calculate level - int level = monster.level; - - if (getScene().getDungeonManager() != null) { - level = getScene().getDungeonManager().getLevelForMonster(monster.config_id); - } else if (getScene().getWorld().getWorldLevel() > 0) { - var worldLevelData = - GameData.getWorldLevelDataMap().get(getScene().getWorld().getWorldLevel()); - - if (worldLevelData != null) { - level = worldLevelData.getMonsterLevel(); - } - } + int level = getScene().getLevelForMonster(monster.config_id, monster.level); // Spawn mob EntityMonster entity = new EntityMonster(getScene(), data, monster.pos, monster.rot, level);