Skip to content

Commit

Permalink
Clean-up the energy manager
Browse files Browse the repository at this point in the history
  • Loading branch information
KingRainbow44 committed Aug 2, 2022
1 parent c357050 commit b9b4b6f
Showing 1 changed file with 40 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;

Expand All @@ -42,15 +41,14 @@
import java.util.concurrent.ThreadLocalRandom;

import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
import static java.util.Map.entry;

import com.google.gson.reflect.TypeToken;
import com.google.protobuf.InvalidProtocolBufferException;

public class EnergyManager extends BasePlayerManager {
private final Map<EntityAvatar, Integer> avatarNormalProbabilities;
// energyUsage for each player
private Boolean energyUsage;

private boolean energyUsage; // Should energy usage be enabled for this player?
private final static Int2ObjectMap<List<EnergyDropInfo>> energyDropData = new Int2ObjectOpenHashMap<>();
private final static Int2ObjectMap<List<SkillParticleGenerationInfo>> skillParticleGenerationData = new Int2ObjectOpenHashMap<>();

Expand Down Expand Up @@ -90,9 +88,9 @@ public static void initialize() {
}
}

/**********
Particle creation for elemental skills.
**********/
/**
* Particle creation for elemental skills.
*/
private int getBallCountForAvatar(int avatarId) {
// We default to two particles.
int count = 2;
Expand Down Expand Up @@ -120,12 +118,12 @@ private int getBallCountForAvatar(int avatarId) {
}

private int getBallIdForElement(ElementType element) {
// If we have no element, we default to an elementless particle.
// If we have no element, we default to an element-less particle.
if (element == null) {
return 2024;
}

// Otherwise, we determin the particle's ID based on the element.
// Otherwise, we determine the particle's ID based on the element.
return switch (element) {
case Fire -> 2017;
case Water -> 2018;
Expand Down Expand Up @@ -156,7 +154,7 @@ public void handleGenerateElemBall(AbilityInvokeEntry invoke) throws InvalidProt
int amount = 2;

// Try to get the casting avatar from the player's party.
Optional<EntityAvatar> avatarEntity = getCastingAvatarEntityForEnergy(invoke.getEntityId());
Optional<EntityAvatar> avatarEntity = this.getCastingAvatarEntityForEnergy(invoke.getEntityId());

// Bug: invokes twice sometimes, Ayato, Keqing
// ToDo: deal with press, hold difference. deal with charge(Beidou, Yunjin)
Expand All @@ -174,20 +172,21 @@ public void handleGenerateElemBall(AbilityInvokeEntry invoke) throws InvalidProt
// particles we have to generate.
if (skillDepotData != null) {
ElementType element = skillDepotData.getElementType();
itemId = getBallIdForElement(element);
itemId = this.getBallIdForElement(element);
}
}
}

// Generate the particles.
for (int i = 0; i < amount; i++) {
generateElemBall(itemId, new Position(action.getPos()), 1);
this.generateElemBall(itemId, new Position(action.getPos()), 1);
}
}

/**********
Pickup of elemental particles and orbs.
**********/
/**
* Pickup of elemental particles and orbs.
* @param elemBall The elemental particle or orb.
*/
public void handlePickupElemBall(GameItem elemBall) {
// Check if the item is indeed an energy particle/orb.
if (elemBall.getItemId() < 2001 ||elemBall.getItemId() > 2024) {
Expand Down Expand Up @@ -242,9 +241,10 @@ public void handlePickupElemBall(GameItem elemBall) {
}
}

/**********
Energy generation for NAs/CAs.
**********/
/**
* Energy generation for NAs/CAs.
* @param avatar The avatar.
*/
private void generateEnergyForNormalAndCharged(EntityAvatar avatar) {
// This logic is based on the descriptions given in
// https://genshin-impact.fandom.com/wiki/Energy#Energy_Generated_by_Normal_Attacks
Expand Down Expand Up @@ -290,11 +290,10 @@ public void handleAttackHit(EvtBeingHitInfo hitInfo) {

// Make sure the target is an actual enemy.
GameEntity targetEntity = this.player.getScene().getEntityById(attackRes.getDefenseId());
if (!(targetEntity instanceof EntityMonster)) {
if (!(targetEntity instanceof EntityMonster targetMonster)) {
return;
}

EntityMonster targetMonster = (EntityMonster)targetEntity;
MonsterType targetType = targetMonster.getMonsterData().getType();
if (targetType != MonsterType.MONSTER_ORDINARY && targetType != MonsterType.MONSTER_BOSS) {
return;
Expand All @@ -319,10 +318,10 @@ public void handleAttackHit(EvtBeingHitInfo hitInfo) {
this.generateEnergyForNormalAndCharged(attackerEntity.get());
}

/*
* Energy logic related to using skills.
*/

/**********
Energy logic related to using skills.
**********/
private void handleBurstCast(Avatar avatar, int skillId) {
// Don't do anything if energy usage is disabled.
if (!GAME_OPTIONS.energyUsage || !this.energyUsage) {
Expand Down Expand Up @@ -351,9 +350,10 @@ public void handleEvtDoSkillSuccNotify(GameSession session, int skillId, int cas
this.handleBurstCast(avatar, skillId);
}

/**********
Monster energy drops.
**********/
/*
* Monster energy drops.
*/

private void generateElemBallDrops(EntityMonster monster, int dropId) {
// Generate all drops specified for the given drop id.
if (!energyDropData.containsKey(dropId)) {
Expand All @@ -365,6 +365,7 @@ private void generateElemBallDrops(EntityMonster monster, int dropId) {
this.generateElemBall(info.getBallId(), monster.getPosition(), info.getCount());
}
}

public void handleMonsterEnergyDrop(EntityMonster monster, float hpBeforeDamage, float hpAfterDamage) {
// Make sure this is actually a monster.
// Note that some wildlife also has that type, like boars or birds.
Expand All @@ -373,7 +374,7 @@ public void handleMonsterEnergyDrop(EntityMonster monster, float hpBeforeDamage,
return;
}

// Calculate the HP tresholds for before and after the damage was taken.
// Calculate the HP thresholds for before and after the damage was taken.
float maxHp = monster.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
float thresholdBefore = hpBeforeDamage / maxHp;
float thresholdAfter = hpAfterDamage / maxHp;
Expand All @@ -386,19 +387,20 @@ public void handleMonsterEnergyDrop(EntityMonster monster, float hpBeforeDamage,

float threshold = drop.getHpPercent() / 100.0f;
if (threshold < thresholdBefore && threshold >= thresholdAfter) {
generateElemBallDrops(monster, drop.getDropId());
this.generateElemBallDrops(monster, drop.getDropId());
}
}

// Handle kill drops.
if (hpAfterDamage <= 0 && monster.getMonsterData().getKillDropId() != 0) {
generateElemBallDrops(monster, monster.getMonsterData().getKillDropId());
this.generateElemBallDrops(monster, monster.getMonsterData().getKillDropId());
}
}

/**********
Utility.
**********/
/*
* Utilities.
*/

private void generateElemBall(int ballId, Position position, int count) {
// Generate a particle/orb with the specified parameters.
ItemData itemData = GameData.getItemDataMap().get(ballId);
Expand All @@ -417,7 +419,7 @@ private Optional<EntityAvatar> getCastingAvatarEntityForEnergy(int invokeEntityI
// that cast the skill.

// Try to get the invoking entity from the scene.
GameEntity entity = player.getScene().getEntityById(invokeEntityId);
GameEntity entity = this.player.getScene().getEntityById(invokeEntityId);

// Determine the ID of the entity that originally cast this skill. If the scene entity is null,
// or not an `EntityClientGadget`, we assume that we are directly looking at the casting avatar
Expand All @@ -430,20 +432,20 @@ private Optional<EntityAvatar> getCastingAvatarEntityForEnergy(int invokeEntityI
: ((EntityClientGadget)entity).getOriginalOwnerEntityId();

// Finally, find the avatar entity in the player's team.
return player.getTeamManager().getActiveTeam()
return this.player.getTeamManager().getActiveTeam()
.stream()
.filter(character -> character.getId() == avatarEntityId)
.findFirst();
}

public Boolean getEnergyUsage() {
return energyUsage;
public boolean getEnergyUsage() {
return this.energyUsage;
}

public void setEnergyUsage(Boolean energyUsage) {
public void setEnergyUsage(boolean energyUsage) {
this.energyUsage = energyUsage;
if (!energyUsage) { // Refill team energy if usage is disabled
for (EntityAvatar entityAvatar : player.getTeamManager().getActiveTeam()) {
for (EntityAvatar entityAvatar : this.player.getTeamManager().getActiveTeam()) {
entityAvatar.addEnergy(1000, PropChangeReason.PROP_CHANGE_REASON_GM,true);
}
}
Expand Down

0 comments on commit b9b4b6f

Please sign in to comment.