mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-02-09 12:32:56 +08:00
Flight stamina cost -20% when Amber or Venti in team
- Reduced stamina not tested in MP. - Stop MovementManager ticker when player goes offline.
This commit is contained in:
parent
00d15a5c89
commit
34df864e1c
@ -24,7 +24,7 @@ public class MovementManager {
|
|||||||
|
|
||||||
public HashMap<String, HashSet<MotionState>> MotionStatesCategorized = new HashMap<>();
|
public HashMap<String, HashSet<MotionState>> MotionStatesCategorized = new HashMap<>();
|
||||||
|
|
||||||
private enum Consumption {
|
private enum ConsumptionType {
|
||||||
None(0),
|
None(0),
|
||||||
|
|
||||||
// consume
|
// consume
|
||||||
@ -46,11 +46,22 @@ public class MovementManager {
|
|||||||
POWERED_FLY(500);
|
POWERED_FLY(500);
|
||||||
|
|
||||||
public final int amount;
|
public final int amount;
|
||||||
Consumption(int amount) {
|
ConsumptionType(int amount) {
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class Consumption {
|
||||||
|
public ConsumptionType consumptionType;
|
||||||
|
public int amount;
|
||||||
|
public Consumption(ConsumptionType ct, int a) {
|
||||||
|
consumptionType = ct;
|
||||||
|
amount = a;
|
||||||
|
}
|
||||||
|
public Consumption(ConsumptionType ct) {
|
||||||
|
this(ct, ct.amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private MotionState previousState = MotionState.MOTION_STANDBY;
|
private MotionState previousState = MotionState.MOTION_STANDBY;
|
||||||
private MotionState currentState = MotionState.MOTION_STANDBY;
|
private MotionState currentState = MotionState.MOTION_STANDBY;
|
||||||
@ -139,6 +150,7 @@ public class MovementManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void resetTimer() {
|
public void resetTimer() {
|
||||||
|
Grasscutter.getLogger().debug("MovementManager ticker stopped");
|
||||||
movementManagerTickTimer.cancel();
|
movementManagerTickTimer.cancel();
|
||||||
movementManagerTickTimer = null;
|
movementManagerTickTimer = null;
|
||||||
}
|
}
|
||||||
@ -269,95 +281,39 @@ public class MovementManager {
|
|||||||
boolean moving = isPlayerMoving();
|
boolean moving = isPlayerMoving();
|
||||||
if (moving || (getCurrentStamina() < getMaximumStamina())) {
|
if (moving || (getCurrentStamina() < getMaximumStamina())) {
|
||||||
// Grasscutter.getLogger().debug("Player moving: " + moving + ", stamina full: " + (getCurrentStamina() >= getMaximumStamina()) + ", recalculate stamina");
|
// Grasscutter.getLogger().debug("Player moving: " + moving + ", stamina full: " + (getCurrentStamina() >= getMaximumStamina()) + ", recalculate stamina");
|
||||||
Consumption consumption = Consumption.None;
|
Consumption consumption = new Consumption(ConsumptionType.None);
|
||||||
|
|
||||||
// TODO: refactor these conditions.
|
// TODO: refactor these conditions.
|
||||||
if (MotionStatesCategorized.get("CLIMB").contains(currentState)) {
|
if (MotionStatesCategorized.get("CLIMB").contains(currentState)) {
|
||||||
if (currentState == MotionState.MOTION_CLIMB) {
|
consumption = getClimbConsumption();
|
||||||
// CLIMB
|
|
||||||
if (previousState != MotionState.MOTION_CLIMB && previousState != MotionState.MOTION_CLIMB_JUMP) {
|
|
||||||
consumption = Consumption.CLIMB_START;
|
|
||||||
} else {
|
|
||||||
consumption = Consumption.CLIMBING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentState == MotionState.MOTION_CLIMB_JUMP) {
|
|
||||||
if (previousState != MotionState.MOTION_CLIMB_JUMP) {
|
|
||||||
consumption = Consumption.CLIMB_JUMP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentState == MotionState.MOTION_JUMP) {
|
|
||||||
if (previousState == MotionState.MOTION_CLIMB) {
|
|
||||||
consumption = Consumption.CLIMB_JUMP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (MotionStatesCategorized.get("SWIM").contains((currentState))) {
|
} else if (MotionStatesCategorized.get("SWIM").contains((currentState))) {
|
||||||
// SWIM
|
consumption = getSwimConsumptions();
|
||||||
if (currentState == MotionState.MOTION_SWIM_MOVE) {
|
|
||||||
consumption = Consumption.SWIMMING;
|
|
||||||
}
|
|
||||||
if (currentState == MotionState.MOTION_SWIM_DASH) {
|
|
||||||
if (previousState != MotionState.MOTION_SWIM_DASH) {
|
|
||||||
consumption = Consumption.SWIM_DASH_START;
|
|
||||||
} else {
|
|
||||||
consumption = Consumption.SWIM_DASH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (MotionStatesCategorized.get("RUN").contains(currentState)) {
|
} else if (MotionStatesCategorized.get("RUN").contains(currentState)) {
|
||||||
// RUN, DASH and WALK
|
consumption = getRunWalkDashConsumption();
|
||||||
// DASH
|
|
||||||
if (currentState == MotionState.MOTION_DASH_BEFORE_SHAKE) {
|
|
||||||
consumption = Consumption.DASH;
|
|
||||||
if (previousState == MotionState.MOTION_DASH_BEFORE_SHAKE) {
|
|
||||||
// only charge once
|
|
||||||
consumption = Consumption.SPRINT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentState == MotionState.MOTION_DASH) {
|
|
||||||
consumption = Consumption.SPRINT;
|
|
||||||
}
|
|
||||||
// RUN
|
|
||||||
if (currentState == MotionState.MOTION_RUN) {
|
|
||||||
consumption = Consumption.RUN;
|
|
||||||
}
|
|
||||||
// WALK
|
|
||||||
if (currentState == MotionState.MOTION_WALK) {
|
|
||||||
consumption = Consumption.WALK;
|
|
||||||
}
|
|
||||||
} else if (MotionStatesCategorized.get("FLY").contains(currentState)) {
|
} else if (MotionStatesCategorized.get("FLY").contains(currentState)) {
|
||||||
// FLY
|
consumption = getFlyConsumption();
|
||||||
consumption = Consumption.FLY;
|
|
||||||
// POWERED_FLY, e.g. wind tunnel
|
|
||||||
if (currentState == MotionState.MOTION_POWERED_FLY) {
|
|
||||||
consumption = Consumption.POWERED_FLY;
|
|
||||||
}
|
|
||||||
} else if (MotionStatesCategorized.get("STANDBY").contains(currentState)) {
|
} else if (MotionStatesCategorized.get("STANDBY").contains(currentState)) {
|
||||||
// STAND
|
consumption = getStandConsumption();
|
||||||
if (currentState == MotionState.MOTION_STANDBY) {
|
|
||||||
consumption = Consumption.STANDBY;
|
|
||||||
}
|
|
||||||
if (currentState == MotionState.MOTION_STANDBY_MOVE) {
|
|
||||||
consumption = Consumption.STANDBY_MOVE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// tick triggered
|
// delay 2 seconds before start recovering - as official server does.
|
||||||
handleDrowning();
|
|
||||||
|
|
||||||
if (cachedSession != null) {
|
if (cachedSession != null) {
|
||||||
if (consumption.amount < 0) {
|
if (consumption.amount < 0) {
|
||||||
staminaRecoverDelay = 0;
|
staminaRecoverDelay = 0;
|
||||||
}
|
}
|
||||||
if (consumption.amount > 0) {
|
if (consumption.amount > 0 && consumption.consumptionType != ConsumptionType.POWERED_FLY) {
|
||||||
if (staminaRecoverDelay < 10) {
|
if (staminaRecoverDelay < 10) {
|
||||||
staminaRecoverDelay++;
|
staminaRecoverDelay++;
|
||||||
consumption = Consumption.None;
|
consumption = new Consumption(ConsumptionType.None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int newStamina = updateStamina(cachedSession, consumption.amount);
|
Grasscutter.getLogger().debug(getCurrentStamina() + "/" + getMaximumStamina() + "\t" + currentState + "\t" + "isMoving: " + isPlayerMoving() + "\t(" + consumption.consumptionType + "," + consumption.amount + ")");
|
||||||
|
updateStamina(cachedSession, consumption.amount);
|
||||||
cachedSession.send(new PacketPlayerPropNotify(player, PlayerProperty.PROP_CUR_PERSIST_STAMINA));
|
cachedSession.send(new PacketPlayerPropNotify(player, PlayerProperty.PROP_CUR_PERSIST_STAMINA));
|
||||||
Grasscutter.getLogger().debug(player.getProperty(PlayerProperty.PROP_CUR_PERSIST_STAMINA) + "/" + player.getProperty(PlayerProperty.PROP_MAX_STAMINA) + "\t" + currentState + "\t" + "isMoving: " + isPlayerMoving() + "\t" + consumption + "(" + consumption.amount + ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tick triggered
|
||||||
|
handleDrowning();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,4 +322,95 @@ public class MovementManager {
|
|||||||
currentCoordinates.getY(), currentCoordinates.getZ());;
|
currentCoordinates.getY(), currentCoordinates.getZ());;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Consumption getClimbConsumption() {
|
||||||
|
Consumption consumption = new Consumption(ConsumptionType.None);
|
||||||
|
if (currentState == MotionState.MOTION_CLIMB) {
|
||||||
|
consumption = new Consumption(ConsumptionType.CLIMBING);
|
||||||
|
if (previousState != MotionState.MOTION_CLIMB && previousState != MotionState.MOTION_CLIMB_JUMP) {
|
||||||
|
consumption = new Consumption(ConsumptionType.CLIMB_START);
|
||||||
|
}
|
||||||
|
if (!isPlayerMoving()) {
|
||||||
|
consumption = new Consumption(ConsumptionType.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentState == MotionState.MOTION_CLIMB_JUMP) {
|
||||||
|
if (previousState != MotionState.MOTION_CLIMB_JUMP) {
|
||||||
|
consumption = new Consumption(ConsumptionType.CLIMB_JUMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return consumption;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Kamisato Ayaka & Mona
|
||||||
|
|
||||||
|
private Consumption getSwimConsumptions() {
|
||||||
|
Consumption consumption = new Consumption(ConsumptionType.None);
|
||||||
|
if (currentState == MotionState.MOTION_SWIM_MOVE) {
|
||||||
|
consumption = new Consumption(ConsumptionType.SWIMMING);
|
||||||
|
}
|
||||||
|
if (currentState == MotionState.MOTION_SWIM_DASH) {
|
||||||
|
consumption = new Consumption(ConsumptionType.SWIM_DASH_START);
|
||||||
|
if (previousState == MotionState.MOTION_SWIM_DASH) {
|
||||||
|
consumption = new Consumption(ConsumptionType.SWIM_DASH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return consumption;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Consumption getRunWalkDashConsumption() {
|
||||||
|
Consumption consumption = new Consumption(ConsumptionType.None);
|
||||||
|
if (currentState == MotionState.MOTION_DASH_BEFORE_SHAKE) {
|
||||||
|
consumption = new Consumption(ConsumptionType.DASH);
|
||||||
|
if (previousState == MotionState.MOTION_DASH_BEFORE_SHAKE) {
|
||||||
|
// only charge once
|
||||||
|
consumption = new Consumption(ConsumptionType.SPRINT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentState == MotionState.MOTION_DASH) {
|
||||||
|
consumption = new Consumption(ConsumptionType.SPRINT);
|
||||||
|
}
|
||||||
|
if (currentState == MotionState.MOTION_RUN) {
|
||||||
|
consumption = new Consumption(ConsumptionType.RUN);
|
||||||
|
}
|
||||||
|
if (currentState == MotionState.MOTION_WALK) {
|
||||||
|
consumption = new Consumption(ConsumptionType.WALK);
|
||||||
|
}
|
||||||
|
return consumption;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Consumption getFlyConsumption() {
|
||||||
|
Consumption consumption = new Consumption(ConsumptionType.FLY);
|
||||||
|
HashMap<Integer, Float> glidingCostReduction = new HashMap<>() {{
|
||||||
|
put(212301, 0.8f); // Amber
|
||||||
|
put(222301, 0.8f); // Venti
|
||||||
|
}};
|
||||||
|
float reduction = 1;
|
||||||
|
for (EntityAvatar entity: cachedSession.getPlayer().getTeamManager().getActiveTeam()) {
|
||||||
|
for (int skillId: entity.getAvatar().getProudSkillList()) {
|
||||||
|
if (glidingCostReduction.containsKey(skillId)) {
|
||||||
|
reduction = glidingCostReduction.get(skillId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
consumption.amount *= reduction;
|
||||||
|
|
||||||
|
// POWERED_FLY, e.g. wind tunnel
|
||||||
|
if (currentState == MotionState.MOTION_POWERED_FLY) {
|
||||||
|
consumption = new Consumption(ConsumptionType.POWERED_FLY);
|
||||||
|
}
|
||||||
|
return consumption;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Consumption getStandConsumption() {
|
||||||
|
Consumption consumption = new Consumption(ConsumptionType.None);
|
||||||
|
if (currentState == MotionState.MOTION_STANDBY) {
|
||||||
|
consumption = new Consumption(ConsumptionType.STANDBY);
|
||||||
|
}
|
||||||
|
if (currentState == MotionState.MOTION_STANDBY_MOVE) {
|
||||||
|
consumption = new Consumption(ConsumptionType.STANDBY_MOVE);
|
||||||
|
}
|
||||||
|
return consumption;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1151,8 +1151,11 @@ public class Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onLogout() {
|
public void onLogout() {
|
||||||
|
// stop stamina calculation
|
||||||
|
getMovementManager().resetTimer();
|
||||||
|
|
||||||
// force to leave the dungeon
|
// force to leave the dungeon
|
||||||
if(getScene().getSceneType() == SceneType.SCENE_DUNGEON){
|
if (getScene().getSceneType() == SceneType.SCENE_DUNGEON) {
|
||||||
this.getServer().getDungeonManager().exitDungeon(this);
|
this.getServer().getDungeonManager().exitDungeon(this);
|
||||||
}
|
}
|
||||||
// Leave world
|
// Leave world
|
||||||
|
Loading…
Reference in New Issue
Block a user