Skip to content

Commit

Permalink
Fix tower mob level and hp scaling (#2430)
Browse files Browse the repository at this point in the history
  • Loading branch information
longfruit authored Nov 9, 2023
1 parent 1fac319 commit 0bbeaf2
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class TowerLevelData extends GameResource {
private int levelGroupId;
private int dungeonId;
private List<TowerLevelCond> conds;
private int monsterLevel;

public static class TowerLevelCond {
private TowerCondType towerCondType;
Expand Down
16 changes: 5 additions & 11 deletions src/main/java/emu/grasscutter/game/ability/AbilityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public final class AbilityManager extends BasePlayerManager {
}

@Getter private boolean abilityInvulnerable = false;
@Getter private Consumer<Integer> clearBurstEnergy;
private int burstCasterId;
private int burstSkillId;

Expand All @@ -59,7 +58,6 @@ public AbilityManager(Player player) {
}

public void removePendingEnergyClear() {
this.clearBurstEnergy = null;
this.burstCasterId = 0;
this.burstSkillId = 0;
}
Expand Down Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -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;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/emu/grasscutter/game/entity/EntityMonster.java
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/emu/grasscutter/game/tower/TowerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -93,8 +98,17 @@ public void teamSelect(int floor, List<List<Long>> 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();

Expand Down Expand Up @@ -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--) {
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/emu/grasscutter/game/world/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<SceneNpcBornEntry> npcBornEntries = ConcurrentHashMap.newKeySet();
for (Player player : this.getPlayers()) {
Expand Down
13 changes: 1 addition & 12 deletions src/main/java/emu/grasscutter/scripts/SceneScriptManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 0bbeaf2

Please sign in to comment.