Give correct amount of energy for collecting particles/orbs, and consume energy on burst cast.

This commit is contained in:
ImmuState 2022-05-19 20:01:41 -07:00 committed by Melledy
parent 2f6beda8ff
commit 542f37d0fb
4 changed files with 71 additions and 14 deletions

View File

@ -493,6 +493,9 @@ public class Avatar {
// Get hp percent, set to 100% if none // Get hp percent, set to 100% if none
float hpPercent = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0 ? 1f : this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) / this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP); float hpPercent = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0 ? 1f : this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) / this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
// Store current energy value for later
float currentEnergy = (data.getSkillDepot() != null) ? this.getFightProperty(data.getSkillDepot().getElementType().getCurEnergyProp()) : 0f;
// Clear properties // Clear properties
this.getFightProperties().clear(); this.getFightProperties().clear();
@ -514,7 +517,8 @@ public class Avatar {
if (data.getSkillDepot() != null && data.getSkillDepot().getEnergySkillData() != null) { if (data.getSkillDepot() != null && data.getSkillDepot().getEnergySkillData() != null) {
ElementType element = data.getSkillDepot().getElementType(); ElementType element = data.getSkillDepot().getElementType();
this.setFightProperty(element.getMaxEnergyProp(), data.getSkillDepot().getEnergySkillData().getCostElemVal()); this.setFightProperty(element.getMaxEnergyProp(), data.getSkillDepot().getEnergySkillData().getCostElemVal());
this.setFightProperty((element.getMaxEnergyProp().getId() % 70) + 1000, data.getSkillDepot().getEnergySkillData().getCostElemVal()); this.setFightProperty(element.getCurEnergyProp(), currentEnergy);
//this.setFightProperty((element.getMaxEnergyProp().getId() % 70) + 1000, data.getSkillDepot().getEnergySkillData().getCostElemVal());
} }
// Artifacts // Artifacts

View File

@ -1,5 +1,6 @@
package emu.grasscutter.game.entity; package emu.grasscutter.game.entity;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.GameConstants; import emu.grasscutter.GameConstants;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.AvatarData; import emu.grasscutter.data.def.AvatarData;
@ -129,13 +130,27 @@ public class EntityAvatar extends GameEntity {
} }
public void addEnergy(float amount) { public void addEnergy(float amount) {
this.addEnergy(amount, false);
}
public void addEnergy(float amount, boolean isFlat) {
// Get current and maximum energy for this avatar.
FightProperty curEnergyProp = getAvatar().getSkillDepot().getElementType().getCurEnergyProp(); FightProperty curEnergyProp = getAvatar().getSkillDepot().getElementType().getCurEnergyProp();
FightProperty maxEnergyProp = getAvatar().getSkillDepot().getElementType().getMaxEnergyProp(); FightProperty maxEnergyProp = getAvatar().getSkillDepot().getElementType().getMaxEnergyProp();
// Get energy recharge.
float energyRecharge = this.getFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY);
// Scale amount by energy recharge, if the amount is not flat.
if (!isFlat) {
amount *= energyRecharge;
}
// Determine the new energy value.
float curEnergy = this.getFightProperty(curEnergyProp); float curEnergy = this.getFightProperty(curEnergyProp);
float maxEnergy = this.getFightProperty(maxEnergyProp); float maxEnergy = this.getFightProperty(maxEnergyProp);
float newEnergy = Math.min(curEnergy + amount, maxEnergy); float newEnergy = Math.min(curEnergy + amount, maxEnergy);
// Set energy and notify.
if (newEnergy != curEnergy) { if (newEnergy != curEnergy) {
setFightProperty(curEnergyProp, newEnergy); setFightProperty(curEnergyProp, newEnergy);

View File

@ -4,6 +4,7 @@ import java.util.*;
import dev.morphia.annotations.Entity; import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Transient; import dev.morphia.annotations.Transient;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.GameConstants; import emu.grasscutter.GameConstants;
import emu.grasscutter.data.def.AvatarSkillDepotData; import emu.grasscutter.data.def.AvatarSkillDepotData;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
@ -19,6 +20,7 @@ import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType; import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState; import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState;
import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType; import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAvatarDieAnimationEndRsp; import emu.grasscutter.server.packet.send.PacketAvatarDieAnimationEndRsp;
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify; import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify; import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
@ -583,20 +585,55 @@ public class TeamManager {
} }
public synchronized void addEnergyToTeam(GameItem energyBall) { public synchronized void addEnergyToTeam(GameItem energyBall) {
// TODO // Check if the item is indeed an energy particle/orb.
float baseEnergy = 2; if (energyBall.getItemId() < 2001 ||energyBall.getItemId() > 2024) {
return;
for (int i = 0; i < getActiveTeam().size(); i++) {
EntityAvatar entity = getActiveTeam().get(i);
float energyGain = baseEnergy;
// Active character gets full hp
if (getCurrentCharacterIndex() != i) {
energyGain *= Math.max(1.0 - (getActiveTeam().size() * .1f), .6f);
} }
entity.addEnergy(energyGain); // Determine the base amount of energy given by the particle/orb.
// Particles have a base amount of 1.0, and orbs a base amount of 3.0.
float baseEnergy = (energyBall.getItemId() <= 2008) ? 3.0f : 1.0f;
// Add energy to every team member.
for (int i = 0; i < this.getActiveTeam().size(); i++) {
EntityAvatar entity = this.getActiveTeam().get(i);
// On-field vs off-field multiplier.
float offFieldPenalty = (this.getCurrentCharacterIndex() == i) ? 1.0f : 1.0f - this.getActiveTeam().size() * 0.1f;
// Same element/neutral bonus.
ElementType avatarElement = entity.getAvatar().getSkillDepot().getElementType();
ElementType ballElement = switch (energyBall.getItemId()) {
case 2001, 2017 -> ElementType.Fire;
case 2002, 2018 -> ElementType.Water;
case 2003, 2019 -> ElementType.Grass;
case 2004, 2020 -> ElementType.Electric;
case 2005, 2021 -> ElementType.Wind;
case 2006, 2022 -> ElementType.Ice;
case 2007, 2023 -> ElementType.Rock;
default -> null;
};
float elementBonus = (ballElement == null) ? 2.0f : (avatarElement == ballElement) ? 3.0f : 1.0f;
// Add the energy.
entity.addEnergy(baseEnergy * elementBonus * offFieldPenalty);
}
}
public void handleEvtDoSkillSuccNotify(GameSession session, int skillId, int casterId) {
// Determine the entity that has cast the skill.
Optional<EntityAvatar> caster = this.getActiveTeam().stream()
.filter(character -> character.getId() == casterId)
.findFirst();
if (caster.isEmpty()) {
return;
}
Avatar avatar = caster.get().getAvatar();
// If the cast skill was a burst, consume energy.
if (skillId == avatar.getSkillDepot().getEnergySkill()) {
float consumedEnergy = avatar.getFightProperty(avatar.getSkillDepot().getElementType().getMaxEnergyProp());
avatar.getAsEntity().addEnergy(-consumedEnergy);
} }
} }

View File

@ -19,5 +19,6 @@ public class HandlerEvtDoSkillSuccNotify extends PacketHandler {
Vector forwardVector = notify.getForward(); Vector forwardVector = notify.getForward();
Position forward = new Position(forwardVector.getX(), forwardVector.getY(), forwardVector.getZ()); Position forward = new Position(forwardVector.getX(), forwardVector.getY(), forwardVector.getZ());
session.getPlayer().getStaminaManager().handleEvtDoSkillSuccNotify(session, skillId, casterId); session.getPlayer().getStaminaManager().handleEvtDoSkillSuccNotify(session, skillId, casterId);
session.getPlayer().getTeamManager().handleEvtDoSkillSuccNotify(session, skillId, casterId);
} }
} }