mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-10 04:12:54 +08:00
Add the god statue's blood return display and stamina system (#520)
* Fix announcement display * Approaching StatuesOfTheSeven will restore all health of the current team * Added god statue's blood return display and stamina system * fix error fix error * fix file
This commit is contained in:
parent
aa06583a45
commit
2074933e96
@ -24,6 +24,7 @@ public final class Config {
|
||||
public DispatchServerOptions DispatchServer = new DispatchServerOptions();
|
||||
public String Language = "en_us";
|
||||
|
||||
public Boolean OpenStamina = true;
|
||||
public GameServerOptions getGameServerOptions() {
|
||||
return GameServer;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CombatInvocationsNotifyOuterClass.CombatInvocationsNotify;
|
||||
@ -8,15 +10,20 @@ import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry;
|
||||
import emu.grasscutter.net.proto.EntityMoveInfoOuterClass.EntityMoveInfo;
|
||||
import emu.grasscutter.net.proto.EvtBeingHitInfoOuterClass.EvtBeingHitInfo;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState;
|
||||
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
@Opcodes(PacketOpcodes.CombatInvocationsNotify)
|
||||
public class HandlerCombatInvocationsNotify extends PacketHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
CombatInvocationsNotify notif = CombatInvocationsNotify.parseFrom(payload);
|
||||
|
||||
for (CombatInvokeEntry entry : notif.getInvokeListList()) {
|
||||
switch (entry.getArgumentType()) {
|
||||
case COMBAT_EVT_BEING_HIT:
|
||||
@ -28,29 +35,93 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
|
||||
// Handle movement
|
||||
EntityMoveInfo moveInfo = EntityMoveInfo.parseFrom(entry.getCombatData());
|
||||
GameEntity entity = session.getPlayer().getScene().getEntityById(moveInfo.getEntityId());
|
||||
MotionState state = moveInfo.getMotionInfo().getState();
|
||||
if (entity != null) {
|
||||
//move
|
||||
entity.getPosition().set(moveInfo.getMotionInfo().getPos());
|
||||
entity.getRotation().set(moveInfo.getMotionInfo().getRot());
|
||||
entity.setLastMoveSceneTimeMs(moveInfo.getSceneTime());
|
||||
entity.setLastMoveReliableSeq(moveInfo.getReliableSeq());
|
||||
entity.setMotionState(moveInfo.getMotionInfo().getState());
|
||||
|
||||
if(Grasscutter.getConfig().OpenStamina){
|
||||
//consume stamina
|
||||
int curStamina = session.getPlayer().getProperty(PlayerProperty.PROP_CUR_PERSIST_STAMINA);
|
||||
int maxStamina = session.getPlayer().getProperty(PlayerProperty.PROP_MAX_STAMINA);
|
||||
if (CONSUME_STAMINA_LIST.contains(state)) {
|
||||
|
||||
//In the water exhausted stamina
|
||||
|
||||
//Climbing the wall stays in place
|
||||
|
||||
//Sprint in the water
|
||||
if (state == MotionState.MOTION_SWIM_DASH) {
|
||||
curStamina -= 700;
|
||||
}
|
||||
//wall jump
|
||||
else if (state == MotionState.MOTION_CLIMB_JUMP) {
|
||||
curStamina -= 2000;
|
||||
}
|
||||
//climb the wall slowly
|
||||
else if (state == MotionState.MOTION_CLIMB) {
|
||||
curStamina -= 800;
|
||||
}
|
||||
else if (state == MotionState.MOTION_DASH_BEFORE_SHAKE) {
|
||||
curStamina -= 2500;
|
||||
}
|
||||
else {
|
||||
curStamina -= 500;
|
||||
}
|
||||
|
||||
session.getPlayer().setProperty(PlayerProperty.PROP_CUR_PERSIST_STAMINA, curStamina);
|
||||
session.send(new PacketPlayerPropNotify(session.getPlayer(), PlayerProperty.PROP_CUR_PERSIST_STAMINA));
|
||||
break;
|
||||
}
|
||||
//restore stamina
|
||||
if (RESTORE_STAMINA_LIST.contains(state)) {
|
||||
if(state == MotionState.MOTION_STANDBY) {
|
||||
Vector speed = moveInfo.getMotionInfo().getSpeed();
|
||||
if(speed.getX() != 0 && speed.getZ() != 0 && speed.getY() != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
curStamina += 1000;
|
||||
if (curStamina >= maxStamina) {
|
||||
curStamina = maxStamina;
|
||||
}
|
||||
session.getPlayer().setProperty(PlayerProperty.PROP_CUR_PERSIST_STAMINA, curStamina);
|
||||
session.send(new PacketPlayerPropNotify(session.getPlayer(), PlayerProperty.PROP_CUR_PERSIST_STAMINA));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
session.getPlayer().getCombatInvokeHandler().addEntry(entry.getForwardType(), entry);
|
||||
}
|
||||
|
||||
// Handles sending combat invokes to other players/server
|
||||
|
||||
if (notif.getInvokeListList().size() > 0) {
|
||||
session.getPlayer().getCombatInvokeHandler().update(session.getPlayer());
|
||||
}
|
||||
|
||||
// Handle attack results last
|
||||
// Handle attack results last
|
||||
while (!session.getPlayer().getAttackResults().isEmpty()) {
|
||||
session.getPlayer().getScene().handleAttack(session.getPlayer().getAttackResults().poll());
|
||||
}
|
||||
}
|
||||
|
||||
private static MotionState[] consumeStaminaTypes = new MotionState[]{
|
||||
MotionState.MOTION_CLIMB, MotionState.MOTION_CLIMB_JUMP, MotionState.MOTION_SWIM_DASH,
|
||||
MotionState.MOTION_SWIM_MOVE, MotionState.MOTION_FLY, MotionState.MOTION_DASH,
|
||||
MotionState.MOTION_DASH_BEFORE_SHAKE, MotionState.MOTION_FIGHT, MotionState.MOTION_JUMP_UP_WALL_FOR_STANDBY,
|
||||
MotionState.MOTION_FLY_SLOW
|
||||
};
|
||||
private static MotionState[] restoreStaminaTypes = new MotionState[]{
|
||||
MotionState.MOTION_STANDBY, MotionState.MOTION_RUN, MotionState.MOTION_WALK,
|
||||
MotionState.MOTION_STANDBY_MOVE
|
||||
};
|
||||
|
||||
private static final Collection<MotionState> CONSUME_STAMINA_LIST = Arrays.asList(consumeStaminaTypes);
|
||||
private static final Collection<MotionState> RESTORE_STAMINA_LIST = Arrays.asList(restoreStaminaTypes);
|
||||
}
|
||||
|
@ -4,9 +4,15 @@ import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeHpReasonOuterClass.ChangeHpReason;
|
||||
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropChangeReasonNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Opcodes(PacketOpcodes.EnterTransPointRegionNotify)
|
||||
public class HandlerEnterTransPointRegionNotify extends PacketHandler {
|
||||
@ -14,13 +20,23 @@ public class HandlerEnterTransPointRegionNotify extends PacketHandler {
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception{
|
||||
session.getPlayer().getTeamManager().getActiveTeam().forEach(entity -> {
|
||||
boolean isAlive = entity.isAlive();
|
||||
entity.setFightProperty(
|
||||
FightProperty.FIGHT_PROP_CUR_HP,
|
||||
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)
|
||||
);
|
||||
entity.getWorld().broadcastPacket(new PacketAvatarFightPropUpdateNotify(entity.getAvatar(), FightProperty.FIGHT_PROP_CUR_HP));
|
||||
if (!isAlive) {
|
||||
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
||||
if(entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) != entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)){
|
||||
Float hp = entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)-entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
||||
|
||||
session.send(new PacketEntityFightPropUpdateNotify(entity,FightProperty.FIGHT_PROP_MAX_HP));
|
||||
|
||||
session.send(new PacketEntityFightPropChangeReasonNotify(
|
||||
entity, FightProperty.FIGHT_PROP_CUR_HP, hp, List.of(3),
|
||||
PropChangeReason.PROP_CHANGE_STATUE_RECOVER, ChangeHpReason.ChangeHpAddStatue));
|
||||
|
||||
entity.setFightProperty(
|
||||
FightProperty.FIGHT_PROP_CUR_HP,
|
||||
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)
|
||||
);
|
||||
session.send(new PacketAvatarFightPropUpdateNotify(entity.getAvatar(), FightProperty.FIGHT_PROP_CUR_HP));
|
||||
if (!isAlive) {
|
||||
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.LifeState;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AvatarLifeStateChangeNotifyOuterClass.AvatarLifeStateChangeNotify;
|
||||
import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType;
|
||||
|
||||
public class PacketAvatarLifeStateChangeNotify extends BasePacket {
|
||||
|
||||
@ -19,4 +22,15 @@ public class PacketAvatarLifeStateChangeNotify extends BasePacket {
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
public PacketAvatarLifeStateChangeNotify(Avatar avatar,int attackerId,LifeState lifeState) {
|
||||
super(PacketOpcodes.AvatarLifeStateChangeNotify);
|
||||
|
||||
AvatarLifeStateChangeNotify proto = AvatarLifeStateChangeNotify.newBuilder()
|
||||
.setAvatarGuid(avatar.getGuid())
|
||||
.setLifeState(lifeState.getValue())
|
||||
.setMoveReliableSeq(attackerId)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeHpReasonOuterClass.ChangeHpReason;
|
||||
import emu.grasscutter.net.proto.EntityFightPropChangeReasonNotifyOuterClass.EntityFightPropChangeReasonNotify;
|
||||
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PacketEntityFightPropChangeReasonNotify extends BasePacket {
|
||||
public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, List<Integer> param, PropChangeReason reason, ChangeHpReason changeHpReason) {
|
||||
super(PacketOpcodes.EntityFightPropChangeReasonNotify);
|
||||
EntityFightPropChangeReasonNotify.Builder proto = EntityFightPropChangeReasonNotify.newBuilder()
|
||||
.setEntityId(entity.getId())
|
||||
.setPropType(prop.getId())
|
||||
.setPropDelta(value)
|
||||
.setReason(reason)
|
||||
.setChangeHpReason(changeHpReason);
|
||||
for(int p: param){
|
||||
proto.addParamList(p);
|
||||
}
|
||||
this.setData(proto);
|
||||
}
|
||||
public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, PropChangeReason reason, ChangeHpReason changeHpReason) {
|
||||
super(PacketOpcodes.EntityFightPropChangeReasonNotify);
|
||||
EntityFightPropChangeReasonNotify proto = EntityFightPropChangeReasonNotify.newBuilder()
|
||||
.setEntityId(entity.getId())
|
||||
.setPropType(prop.getId())
|
||||
.setPropDelta(value)
|
||||
.setReason(reason)
|
||||
.setChangeHpReason(changeHpReason)
|
||||
.build();
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user