Skip to content

Commit

Permalink
Allow walking away from the statue within 2.5s to stop auto heal.
Browse files Browse the repository at this point in the history
  • Loading branch information
gentlespoon authored and Melledy committed May 6, 2022
1 parent 7109578 commit 1d4a41f
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.managers.MovementManager.MovementManager;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.world.World;
import emu.grasscutter.net.proto.ChangeHpReasonOuterClass;
import emu.grasscutter.net.proto.PropChangeReasonOuterClass;
import emu.grasscutter.server.game.GameSession;
Expand All @@ -14,13 +18,16 @@
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

// Statue of the Seven Manager
public class SotSManager {

// NOTE: Spring volume balance *1 = fight prop HP *100

private final Player player;
private Timer autoRecoverTimer;

public SotSManager(Player player) {
this.player = player;
Expand All @@ -46,26 +53,44 @@ public void setAutoRecoveryPercentage(int percentage) {
public void autoRevive(GameSession session) {
player.getTeamManager().getActiveTeam().forEach(entity -> {
boolean isAlive = entity.isAlive();
float currentHP = entity.getAvatar().getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
float maxHP = entity.getAvatar().getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
// Grasscutter.getLogger().debug("" + entity.getAvatar().getAvatarData().getName() + "\t" + currentHP + "/" + maxHP + "\t" + (isAlive ? "ALIVE":"DEAD"));
float newHP = (float)(maxHP * 0.3);
if (currentHP < newHP) {
updateAvatarCurHP(session, entity, newHP);
}
if (!isAlive) {
float maxHP = entity.getAvatar().getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
float newHP = (float)(maxHP * 0.3);
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
}
});
}

public void scheduleAutoRecover(GameSession session) {
// TODO: play audio effects? possibly client side? - client automatically plays.
// delay 2.5 seconds
new Thread(() -> {
try {
Thread.sleep(2500);
autoRecover(session);
} catch (Exception e) {
Grasscutter.getLogger().error(e.getMessage());
}
}).start();
if (autoRecoverTimer == null) {
autoRecoverTimer = new Timer();
autoRecoverTimer.schedule(new AutoRecoverTimerTick(session), 2500);
}
}

public void cancelAutoRecover() {
if (autoRecoverTimer != null) {
autoRecoverTimer.cancel();
autoRecoverTimer = null;
}
}

private class AutoRecoverTimerTick extends TimerTask
{
private GameSession session;

public AutoRecoverTimerTick(GameSession session) {
this.session = session;
}
public void run() {
autoRecover(session);
cancelAutoRecover();
}
}

public void refillSpringVolume() {
Expand Down Expand Up @@ -124,24 +149,27 @@ public void autoRecover(GameSession session) {

float newHP = currentHP + needSV / 100; // convert SV to HP

// TODO: Figure out why client shows current HP instead of added HP.
// Say an avatar had 12000 and now has 14000, it should show "2000".
// The client always show "+14000" which is incorrect.

entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
session.send(new PacketEntityFightPropChangeReasonNotify(entity, FightProperty.FIGHT_PROP_CUR_HP,
newHP, List.of(3), PropChangeReasonOuterClass.PropChangeReason.PROP_CHANGE_STATUE_RECOVER,
ChangeHpReasonOuterClass.ChangeHpReason.ChangeHpAddStatue));
session.send(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));

Avatar avatar = entity.getAvatar();
avatar.setCurrentHp(newHP);
session.send(new PacketAvatarFightPropUpdateNotify(avatar, FightProperty.FIGHT_PROP_CUR_HP));
player.save();
updateAvatarCurHP(session, entity, newHP);
}
});
}
}

private void updateAvatarCurHP(GameSession session, EntityAvatar entity, float newHP) {
// TODO: Figure out why client shows current HP instead of added HP.
// Say an avatar had 12000 and now has 14000, it should show "2000".
// The client always show "+14000" which is incorrect.
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
session.send(new PacketEntityFightPropChangeReasonNotify(entity, FightProperty.FIGHT_PROP_CUR_HP,
newHP, List.of(3), PropChangeReasonOuterClass.PropChangeReason.PROP_CHANGE_STATUE_RECOVER,
ChangeHpReasonOuterClass.ChangeHpReason.ChangeHpAddStatue));
session.send(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));

Avatar avatar = entity.getAvatar();
avatar.setCurrentHp(newHP);
session.send(new PacketAvatarFightPropUpdateNotify(avatar, FightProperty.FIGHT_PROP_CUR_HP));
player.save();
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package emu.grasscutter.server.packet.recv;

import emu.grasscutter.game.managers.SotSManager.SotSManager;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.server.game.GameSession;

@Opcodes(PacketOpcodes.ExitTransPointRegionNotify)
public class HandlerExitTransPointRegionNotify extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception{
Player player = session.getPlayer();
SotSManager sotsManager = player.getSotSManager();
sotsManager.cancelAutoRecover();
}
}

0 comments on commit 1d4a41f

Please sign in to comment.