Commit 2074933e authored by BaiSugar's avatar BaiSugar Committed by GitHub
Browse files

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
parent aa06583a
......@@ -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;
}
......
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()));
}
}
});
}
......
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);
}
}
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);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment