mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-30 19:48:51 +00:00
Allow walking away from the statue within 2.5s to stop auto heal.
This commit is contained in:
parent
71095786b8
commit
1d4a41fd61
@ -2,9 +2,13 @@ package emu.grasscutter.game.managers.SotSManager;
|
|||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
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.player.Player;
|
||||||
import emu.grasscutter.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
|
import emu.grasscutter.game.world.World;
|
||||||
import emu.grasscutter.net.proto.ChangeHpReasonOuterClass;
|
import emu.grasscutter.net.proto.ChangeHpReasonOuterClass;
|
||||||
import emu.grasscutter.net.proto.PropChangeReasonOuterClass;
|
import emu.grasscutter.net.proto.PropChangeReasonOuterClass;
|
||||||
import emu.grasscutter.server.game.GameSession;
|
import emu.grasscutter.server.game.GameSession;
|
||||||
@ -14,6 +18,8 @@ import emu.grasscutter.server.packet.send.PacketEntityFightPropChangeReasonNotif
|
|||||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
// Statue of the Seven Manager
|
// Statue of the Seven Manager
|
||||||
public class SotSManager {
|
public class SotSManager {
|
||||||
@ -21,6 +27,7 @@ public class SotSManager {
|
|||||||
// NOTE: Spring volume balance *1 = fight prop HP *100
|
// NOTE: Spring volume balance *1 = fight prop HP *100
|
||||||
|
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
private Timer autoRecoverTimer;
|
||||||
|
|
||||||
public SotSManager(Player player) {
|
public SotSManager(Player player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
@ -46,26 +53,44 @@ public class SotSManager {
|
|||||||
public void autoRevive(GameSession session) {
|
public void autoRevive(GameSession session) {
|
||||||
player.getTeamManager().getActiveTeam().forEach(entity -> {
|
player.getTeamManager().getActiveTeam().forEach(entity -> {
|
||||||
boolean isAlive = entity.isAlive();
|
boolean isAlive = entity.isAlive();
|
||||||
if (!isAlive) {
|
float currentHP = entity.getAvatar().getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
||||||
float maxHP = entity.getAvatar().getFightProperty(FightProperty.FIGHT_PROP_MAX_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);
|
float newHP = (float)(maxHP * 0.3);
|
||||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
|
if (currentHP < newHP) {
|
||||||
|
updateAvatarCurHP(session, entity, newHP);
|
||||||
|
}
|
||||||
|
if (!isAlive) {
|
||||||
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scheduleAutoRecover(GameSession session) {
|
public void scheduleAutoRecover(GameSession session) {
|
||||||
// TODO: play audio effects? possibly client side? - client automatically plays.
|
if (autoRecoverTimer == null) {
|
||||||
// delay 2.5 seconds
|
autoRecoverTimer = new Timer();
|
||||||
new Thread(() -> {
|
autoRecoverTimer.schedule(new AutoRecoverTimerTick(session), 2500);
|
||||||
try {
|
}
|
||||||
Thread.sleep(2500);
|
}
|
||||||
autoRecover(session);
|
|
||||||
} catch (Exception e) {
|
public void cancelAutoRecover() {
|
||||||
Grasscutter.getLogger().error(e.getMessage());
|
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();
|
||||||
}
|
}
|
||||||
}).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refillSpringVolume() {
|
public void refillSpringVolume() {
|
||||||
@ -124,10 +149,16 @@ public class SotSManager {
|
|||||||
|
|
||||||
float newHP = currentHP + needSV / 100; // convert SV to HP
|
float newHP = currentHP + needSV / 100; // convert SV to HP
|
||||||
|
|
||||||
|
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.
|
// 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".
|
// Say an avatar had 12000 and now has 14000, it should show "2000".
|
||||||
// The client always show "+14000" which is incorrect.
|
// The client always show "+14000" which is incorrect.
|
||||||
|
|
||||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
|
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
|
||||||
session.send(new PacketEntityFightPropChangeReasonNotify(entity, FightProperty.FIGHT_PROP_CUR_HP,
|
session.send(new PacketEntityFightPropChangeReasonNotify(entity, FightProperty.FIGHT_PROP_CUR_HP,
|
||||||
newHP, List.of(3), PropChangeReasonOuterClass.PropChangeReason.PROP_CHANGE_STATUE_RECOVER,
|
newHP, List.of(3), PropChangeReasonOuterClass.PropChangeReason.PROP_CHANGE_STATUE_RECOVER,
|
||||||
@ -139,9 +170,6 @@ public class SotSManager {
|
|||||||
session.send(new PacketAvatarFightPropUpdateNotify(avatar, FightProperty.FIGHT_PROP_CUR_HP));
|
session.send(new PacketAvatarFightPropUpdateNotify(avatar, FightProperty.FIGHT_PROP_CUR_HP));
|
||||||
player.save();
|
player.save();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user