mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-27 17:51:16 +00:00
The statues will now automatically regen their HP volume over time.
Max is currently set to 85000 for everyone. Will update after implementing statue levels.
This commit is contained in:
parent
098cf372c9
commit
0102a3ce1e
@ -18,6 +18,8 @@ import java.util.List;
|
|||||||
// Statue of the Seven Manager
|
// Statue of the Seven Manager
|
||||||
public class SotSManager {
|
public class SotSManager {
|
||||||
|
|
||||||
|
// NOTE: Spring volume balance *1 = fight prop HP *100
|
||||||
|
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
|
||||||
public SotSManager(Player player) {
|
public SotSManager(Player player) {
|
||||||
@ -46,7 +48,8 @@ public class SotSManager {
|
|||||||
boolean isAlive = entity.isAlive();
|
boolean isAlive = entity.isAlive();
|
||||||
if (!isAlive) {
|
if (!isAlive) {
|
||||||
float maxHP = entity.getAvatar().getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
float maxHP = entity.getAvatar().getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
||||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, Math.min(150, maxHP));
|
float newHP = (float)(maxHP * 0.3);
|
||||||
|
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
|
||||||
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -65,14 +68,31 @@ public class SotSManager {
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void refillSpringVolume() {
|
||||||
|
// TODO: max spring volume depends on level of the statues in Mondstadt and Liyue.
|
||||||
|
// https://genshin-impact.fandom.com/wiki/Statue_of_The_Seven#:~:text=region%20of%20Inazuma.-,Statue%20Levels,-Upon%20first%20unlocking
|
||||||
|
player.setProperty(PlayerProperty.PROP_MAX_SPRING_VOLUME, 8500000);
|
||||||
|
|
||||||
|
long now = System.currentTimeMillis() / 1000;
|
||||||
|
long secondsSinceLastUsed = now - player.getSpringLastUsed();
|
||||||
|
float percentageRefilled = (float)secondsSinceLastUsed / 15 / 100; // 15s = 1% max volume
|
||||||
|
int maxVolume = player.getProperty(PlayerProperty.PROP_MAX_SPRING_VOLUME);
|
||||||
|
int currentVolume = player.getProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME);
|
||||||
|
if (currentVolume < maxVolume) {
|
||||||
|
int volumeRefilled = (int)(percentageRefilled * maxVolume);
|
||||||
|
int newVolume = currentVolume + volumeRefilled;
|
||||||
|
if (currentVolume + volumeRefilled > maxVolume) {
|
||||||
|
newVolume = maxVolume;
|
||||||
|
}
|
||||||
|
player.setProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME, newVolume);
|
||||||
|
}
|
||||||
|
player.setSpringLastUsed(now);
|
||||||
|
player.save();
|
||||||
|
}
|
||||||
|
|
||||||
// autoRecover checks player setting to see if auto recover is enabled, and refill HP to the predefined level.
|
// autoRecover checks player setting to see if auto recover is enabled, and refill HP to the predefined level.
|
||||||
public void autoRecover(GameSession session) {
|
public void autoRecover(GameSession session) {
|
||||||
// TODO: Implement SotS Spring volume refill over time.
|
// TODO: In MP, respect SotS settings from the HOST.
|
||||||
// Placeholder:
|
|
||||||
player.setProperty(PlayerProperty.PROP_MAX_SPRING_VOLUME, 8500000);
|
|
||||||
player.setProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME, 8500000);
|
|
||||||
|
|
||||||
// TODO: In MP, respect SotS settings from the host.
|
|
||||||
boolean isAutoRecoveryEnabled = getIsAutoRecoveryEnabled();
|
boolean isAutoRecoveryEnabled = getIsAutoRecoveryEnabled();
|
||||||
int autoRecoverPercentage = getAutoRecoveryPercentage();
|
int autoRecoverPercentage = getAutoRecoveryPercentage();
|
||||||
Grasscutter.getLogger().debug("isAutoRecoveryEnabled: " + isAutoRecoveryEnabled + "\tautoRecoverPercentage: " + autoRecoverPercentage);
|
Grasscutter.getLogger().debug("isAutoRecoveryEnabled: " + isAutoRecoveryEnabled + "\tautoRecoverPercentage: " + autoRecoverPercentage);
|
||||||
@ -88,28 +108,37 @@ public class SotSManager {
|
|||||||
|
|
||||||
if (targetHP > currentHP) {
|
if (targetHP > currentHP) {
|
||||||
float needHP = targetHP - currentHP;
|
float needHP = targetHP - currentHP;
|
||||||
|
float needSV = needHP * 100; // convert HP needed to Spring Volume needed
|
||||||
|
|
||||||
int sotsHPBalance = player.getProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME);
|
int sotsSVBalance = player.getProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME);
|
||||||
if (sotsHPBalance >= needHP) {
|
if (sotsSVBalance >= needSV) {
|
||||||
sotsHPBalance -= needHP;
|
// sufficient
|
||||||
player.setProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME, sotsHPBalance);
|
sotsSVBalance -= needSV;
|
||||||
|
} else {
|
||||||
|
// insufficient balance
|
||||||
|
needSV = sotsSVBalance;
|
||||||
|
sotsSVBalance = 0;
|
||||||
|
}
|
||||||
|
player.setProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME, sotsSVBalance);
|
||||||
|
player.setSpringLastUsed(System.currentTimeMillis() / 1000);
|
||||||
|
|
||||||
float newHP = currentHP + needHP;
|
float newHP = currentHP + needSV / 100; // convert SV to HP
|
||||||
|
|
||||||
session.send(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_MAX_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,
|
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,
|
||||||
ChangeHpReasonOuterClass.ChangeHpReason.ChangeHpAddStatue));
|
ChangeHpReasonOuterClass.ChangeHpReason.ChangeHpAddStatue));
|
||||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
|
session.send(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
|
||||||
|
|
||||||
Avatar avatar = entity.getAvatar();
|
Avatar avatar = entity.getAvatar();
|
||||||
session.send(new PacketAvatarFightPropUpdateNotify(avatar, FightProperty.FIGHT_PROP_CUR_HP));
|
|
||||||
avatar.setCurrentHp(newHP);
|
avatar.setCurrentHp(newHP);
|
||||||
|
session.send(new PacketAvatarFightPropUpdateNotify(avatar, FightProperty.FIGHT_PROP_CUR_HP));
|
||||||
player.save();
|
player.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,6 +130,8 @@ public class Player {
|
|||||||
private MapMarksManager mapMarksManager;
|
private MapMarksManager mapMarksManager;
|
||||||
@Transient private MovementManager movementManager;
|
@Transient private MovementManager movementManager;
|
||||||
|
|
||||||
|
private long springLastUsed;
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
|
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
|
||||||
@ -535,6 +537,14 @@ public class Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getSpringLastUsed() {
|
||||||
|
return springLastUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpringLastUsed(long val) {
|
||||||
|
springLastUsed = val;
|
||||||
|
}
|
||||||
|
|
||||||
public SceneLoadState getSceneLoadState() {
|
public SceneLoadState getSceneLoadState() {
|
||||||
return sceneState;
|
return sceneState;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ public class HandlerEnterTransPointRegionNotify extends PacketHandler {
|
|||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception{
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception{
|
||||||
Player player = session.getPlayer();
|
Player player = session.getPlayer();
|
||||||
SotSManager sotsManager = player.getSotSManager();
|
SotSManager sotsManager = player.getSotSManager();
|
||||||
|
|
||||||
|
sotsManager.refillSpringVolume();
|
||||||
sotsManager.autoRevive(session);
|
sotsManager.autoRevive(session);
|
||||||
sotsManager.scheduleAutoRecover(session);
|
sotsManager.scheduleAutoRecover(session);
|
||||||
// TODO: allow interaction with the SotS?
|
// TODO: allow interaction with the SotS?
|
||||||
|
Loading…
Reference in New Issue
Block a user