mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-10 17:33:02 +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 DispatchServerOptions DispatchServer = new DispatchServerOptions();
|
||||||
public String Language = "en_us";
|
public String Language = "en_us";
|
||||||
|
|
||||||
|
public Boolean OpenStamina = true;
|
||||||
public GameServerOptions getGameServerOptions() {
|
public GameServerOptions getGameServerOptions() {
|
||||||
return GameServer;
|
return GameServer;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.CombatInvocationsNotifyOuterClass.CombatInvocationsNotify;
|
import emu.grasscutter.net.proto.CombatInvocationsNotifyOuterClass.CombatInvocationsNotify;
|
||||||
@ -8,7 +10,13 @@ import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry;
|
|||||||
import emu.grasscutter.net.proto.EntityMoveInfoOuterClass.EntityMoveInfo;
|
import emu.grasscutter.net.proto.EntityMoveInfoOuterClass.EntityMoveInfo;
|
||||||
import emu.grasscutter.net.proto.EvtBeingHitInfoOuterClass.EvtBeingHitInfo;
|
import emu.grasscutter.net.proto.EvtBeingHitInfoOuterClass.EvtBeingHitInfo;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
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.game.GameSession;
|
||||||
|
import emu.grasscutter.server.packet.send.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
@Opcodes(PacketOpcodes.CombatInvocationsNotify)
|
@Opcodes(PacketOpcodes.CombatInvocationsNotify)
|
||||||
public class HandlerCombatInvocationsNotify extends PacketHandler {
|
public class HandlerCombatInvocationsNotify extends PacketHandler {
|
||||||
@ -16,7 +24,6 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
CombatInvocationsNotify notif = CombatInvocationsNotify.parseFrom(payload);
|
CombatInvocationsNotify notif = CombatInvocationsNotify.parseFrom(payload);
|
||||||
|
|
||||||
for (CombatInvokeEntry entry : notif.getInvokeListList()) {
|
for (CombatInvokeEntry entry : notif.getInvokeListList()) {
|
||||||
switch (entry.getArgumentType()) {
|
switch (entry.getArgumentType()) {
|
||||||
case COMBAT_EVT_BEING_HIT:
|
case COMBAT_EVT_BEING_HIT:
|
||||||
@ -28,12 +35,64 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
|
|||||||
// Handle movement
|
// Handle movement
|
||||||
EntityMoveInfo moveInfo = EntityMoveInfo.parseFrom(entry.getCombatData());
|
EntityMoveInfo moveInfo = EntityMoveInfo.parseFrom(entry.getCombatData());
|
||||||
GameEntity entity = session.getPlayer().getScene().getEntityById(moveInfo.getEntityId());
|
GameEntity entity = session.getPlayer().getScene().getEntityById(moveInfo.getEntityId());
|
||||||
|
MotionState state = moveInfo.getMotionInfo().getState();
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
|
//move
|
||||||
entity.getPosition().set(moveInfo.getMotionInfo().getPos());
|
entity.getPosition().set(moveInfo.getMotionInfo().getPos());
|
||||||
entity.getRotation().set(moveInfo.getMotionInfo().getRot());
|
entity.getRotation().set(moveInfo.getMotionInfo().getRot());
|
||||||
entity.setLastMoveSceneTimeMs(moveInfo.getSceneTime());
|
entity.setLastMoveSceneTimeMs(moveInfo.getSceneTime());
|
||||||
entity.setLastMoveReliableSeq(moveInfo.getReliableSeq());
|
entity.setLastMoveReliableSeq(moveInfo.getReliableSeq());
|
||||||
entity.setMotionState(moveInfo.getMotionInfo().getState());
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -43,14 +102,26 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
|
|||||||
session.getPlayer().getCombatInvokeHandler().addEntry(entry.getForwardType(), entry);
|
session.getPlayer().getCombatInvokeHandler().addEntry(entry.getForwardType(), entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles sending combat invokes to other players/server
|
|
||||||
if (notif.getInvokeListList().size() > 0) {
|
if (notif.getInvokeListList().size() > 0) {
|
||||||
session.getPlayer().getCombatInvokeHandler().update(session.getPlayer());
|
session.getPlayer().getCombatInvokeHandler().update(session.getPlayer());
|
||||||
}
|
}
|
||||||
|
// Handle attack results last
|
||||||
// Handle attack results last
|
|
||||||
while (!session.getPlayer().getAttackResults().isEmpty()) {
|
while (!session.getPlayer().getAttackResults().isEmpty()) {
|
||||||
session.getPlayer().getScene().handleAttack(session.getPlayer().getAttackResults().poll());
|
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.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
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.game.GameSession;
|
||||||
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
|
||||||
import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
|
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)
|
@Opcodes(PacketOpcodes.EnterTransPointRegionNotify)
|
||||||
public class HandlerEnterTransPointRegionNotify extends PacketHandler {
|
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{
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception{
|
||||||
session.getPlayer().getTeamManager().getActiveTeam().forEach(entity -> {
|
session.getPlayer().getTeamManager().getActiveTeam().forEach(entity -> {
|
||||||
boolean isAlive = entity.isAlive();
|
boolean isAlive = entity.isAlive();
|
||||||
entity.setFightProperty(
|
if(entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) != entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)){
|
||||||
FightProperty.FIGHT_PROP_CUR_HP,
|
Float hp = entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)-entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
||||||
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)
|
|
||||||
);
|
session.send(new PacketEntityFightPropUpdateNotify(entity,FightProperty.FIGHT_PROP_MAX_HP));
|
||||||
entity.getWorld().broadcastPacket(new PacketAvatarFightPropUpdateNotify(entity.getAvatar(), FightProperty.FIGHT_PROP_CUR_HP));
|
|
||||||
if (!isAlive) {
|
session.send(new PacketEntityFightPropChangeReasonNotify(
|
||||||
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
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;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
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.FightProperty;
|
||||||
import emu.grasscutter.game.props.LifeState;
|
import emu.grasscutter.game.props.LifeState;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.AvatarLifeStateChangeNotifyOuterClass.AvatarLifeStateChangeNotify;
|
import emu.grasscutter.net.proto.AvatarLifeStateChangeNotifyOuterClass.AvatarLifeStateChangeNotify;
|
||||||
|
import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType;
|
||||||
|
|
||||||
public class PacketAvatarLifeStateChangeNotify extends BasePacket {
|
public class PacketAvatarLifeStateChangeNotify extends BasePacket {
|
||||||
|
|
||||||
@ -19,4 +22,15 @@ public class PacketAvatarLifeStateChangeNotify extends BasePacket {
|
|||||||
|
|
||||||
this.setData(proto);
|
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