Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
ziqian zhang
Grasscutter
Commits
93b3265d
Commit
93b3265d
authored
May 05, 2022
by
gentlespoon
Committed by
Melledy
May 05, 2022
Browse files
Add drowning. Better movement ticking.
parent
81998b9c
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/entity/EntityAvatar.java
View file @
93b3265d
...
@@ -104,6 +104,11 @@ public class EntityAvatar extends GameEntity {
...
@@ -104,6 +104,11 @@ public class EntityAvatar extends GameEntity {
this
.
killedType
=
PlayerDieType
.
PLAYER_DIE_KILL_BY_MONSTER
;
this
.
killedType
=
PlayerDieType
.
PLAYER_DIE_KILL_BY_MONSTER
;
this
.
killedBy
=
killerId
;
this
.
killedBy
=
killerId
;
}
}
public
void
onDeath
(
PlayerDieType
dieType
,
int
killerId
)
{
this
.
killedType
=
dieType
;
this
.
killedBy
=
killerId
;
}
public
SceneAvatarInfo
getSceneAvatarInfo
()
{
public
SceneAvatarInfo
getSceneAvatarInfo
()
{
SceneAvatarInfo
.
Builder
avatarInfo
=
SceneAvatarInfo
.
newBuilder
()
SceneAvatarInfo
.
Builder
avatarInfo
=
SceneAvatarInfo
.
newBuilder
()
...
...
src/main/java/emu/grasscutter/game/managers/MotionManager/MotionManager.java
deleted
100644 → 0
View file @
81998b9c
package
emu.grasscutter.game.managers.MotionManager
;
import
emu.grasscutter.Grasscutter
;
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.game.props.PlayerProperty
;
import
emu.grasscutter.net.proto.EntityMoveInfoOuterClass
;
import
emu.grasscutter.net.proto.MotionStateOuterClass.MotionState
;
import
emu.grasscutter.net.proto.VectorOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketPlayerPropNotify
;
import
emu.grasscutter.utils.Position
;
import
java.util.ArrayList
;
import
java.lang.Math
;
public
class
MotionManager
{
private
enum
Consumption
{
None
(
0
),
// consumers
CLIMB_START
(-
500
),
CLIMBING
(-
150
),
CLIMB_JUMP
(-
2500
),
DASH
(-
1800
),
SPRINT
(-
360
),
FLY
(-
60
),
SWIM_DASH_START
(-
200
),
SWIM_DASH
(-
200
),
SWIMMING
(-
80
),
// restorers
STANDBY
(
500
),
RUN
(
500
),
WALK
(
500
),
STANDBY_MOVE
(
500
);
public
final
int
amount
;
Consumption
(
int
amount
)
{
this
.
amount
=
amount
;
}
}
private
EntityMoveInfoOuterClass
.
EntityMoveInfo
moveInfo
;
private
MotionState
previousState
=
MotionState
.
MOTION_STANDBY
;
private
ArrayList
<
Position
>
previousCoordinates
=
new
ArrayList
<>();
private
final
Player
player
;
private
float
landSpeed
=
0
;
public
MotionManager
(
Player
player
)
{
previousCoordinates
.
add
(
new
Position
(
0
,
0
,
0
));
this
.
player
=
player
;
}
public
void
handle
(
GameSession
session
,
GameEntity
entity
,
EntityMoveInfoOuterClass
.
EntityMoveInfo
moveInfo
)
{
MotionState
state
=
moveInfo
.
getMotionInfo
().
getState
();
setMoveInfo
(
moveInfo
);
if
(
state
==
MotionState
.
MOTION_LAND_SPEED
)
{
setLandSpeed
(
moveInfo
.
getMotionInfo
().
getSpeed
().
getY
());
}
if
(
state
==
MotionState
.
MOTION_FALL_ON_GROUND
)
{
handleFallOnGround
(
session
,
entity
);
}
}
public
void
tick
()
{
if
(
Grasscutter
.
getConfig
().
OpenStamina
){
EntityMoveInfoOuterClass
.
EntityMoveInfo
mInfo
=
moveInfo
;
if
(
mInfo
==
null
)
{
return
;
}
MotionState
state
=
moveInfo
.
getMotionInfo
().
getState
();
Consumption
consumption
=
Consumption
.
None
;
boolean
isMoving
=
false
;
VectorOuterClass
.
Vector
posVector
=
moveInfo
.
getMotionInfo
().
getPos
();
Position
currentCoordinates
=
new
Position
(
posVector
.
getX
(),
posVector
.
getY
(),
posVector
.
getZ
());
float
diffX
=
currentCoordinates
.
getX
()
-
previousCoordinates
.
get
(
0
).
getX
();
float
diffY
=
currentCoordinates
.
getY
()
-
previousCoordinates
.
get
(
0
).
getY
();
float
diffZ
=
currentCoordinates
.
getZ
()
-
previousCoordinates
.
get
(
0
).
getZ
();
if
(
Math
.
abs
(
diffX
)
>
0.3
||
Math
.
abs
(
diffY
)
>
0.3
||
Math
.
abs
(
diffZ
)
>
0.3
)
{
isMoving
=
true
;
}
if
(
isMoving
)
{
// TODO: refactor these conditions.
// CLIMB
if
(
state
==
MotionState
.
MOTION_CLIMB
)
{
if
(
previousState
!=
MotionState
.
MOTION_CLIMB
&&
previousState
!=
MotionState
.
MOTION_CLIMB_JUMP
)
{
consumption
=
Consumption
.
CLIMB_START
;
}
else
{
consumption
=
Consumption
.
CLIMBING
;
}
}
// JUMP
if
(
state
==
MotionState
.
MOTION_CLIMB_JUMP
)
{
if
(
previousState
!=
MotionState
.
MOTION_CLIMB_JUMP
)
{
consumption
=
Consumption
.
CLIMB_JUMP
;
}
}
if
(
state
==
MotionState
.
MOTION_JUMP
)
{
if
(
previousState
==
MotionState
.
MOTION_CLIMB
)
{
consumption
=
Consumption
.
CLIMB_JUMP
;
}
}
// SWIM
if
(
state
==
MotionState
.
MOTION_SWIM_MOVE
)
{
consumption
=
Consumption
.
SWIMMING
;
}
if
(
state
==
MotionState
.
MOTION_SWIM_DASH
)
{
if
(
previousState
!=
MotionState
.
MOTION_SWIM_DASH
)
{
consumption
=
Consumption
.
SWIM_DASH_START
;
}
else
{
consumption
=
Consumption
.
SWIM_DASH
;
}
}
// DASH
if
(
state
==
MotionState
.
MOTION_DASH
)
{
if
(
previousState
==
MotionState
.
MOTION_DASH
)
{
consumption
=
Consumption
.
SPRINT
;
}
else
{
consumption
=
Consumption
.
DASH
;
}
}
// RUN and WALK
if
(
state
==
MotionState
.
MOTION_RUN
)
{
consumption
=
Consumption
.
RUN
;
}
if
(
state
==
MotionState
.
MOTION_WALK
)
{
consumption
=
Consumption
.
WALK
;
}
// FLY
if
(
state
==
MotionState
.
MOTION_FLY
)
{
consumption
=
Consumption
.
FLY
;
}
}
// STAND
if
(
state
==
MotionState
.
MOTION_STANDBY
)
{
consumption
=
Consumption
.
STANDBY
;
}
if
(
state
==
MotionState
.
MOTION_STANDBY_MOVE
)
{
consumption
=
Consumption
.
STANDBY_MOVE
;
}
GameSession
session
=
player
.
getSession
();
updateStamina
(
session
,
consumption
.
amount
);
session
.
send
(
new
PacketPlayerPropNotify
(
session
.
getPlayer
(),
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
));
Grasscutter
.
getLogger
().
debug
(
session
.
getPlayer
().
getProperty
(
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
)
+
" "
+
state
+
" "
+
isMoving
+
" "
+
consumption
+
" "
+
consumption
.
amount
);
previousState
=
state
;
previousCoordinates
.
add
(
currentCoordinates
);
if
(
previousCoordinates
.
size
()
>
3
)
{
previousCoordinates
.
remove
(
0
);
}
}
}
public
void
updateStamina
(
GameSession
session
,
int
amount
)
{
if
(
amount
==
0
)
{
return
;
}
int
currentStamina
=
session
.
getPlayer
().
getProperty
(
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
);
int
playerMaxStamina
=
session
.
getPlayer
().
getProperty
(
PlayerProperty
.
PROP_MAX_STAMINA
);
int
newStamina
=
currentStamina
+
amount
;
if
(
newStamina
<
0
)
{
newStamina
=
0
;
}
if
(
newStamina
>
playerMaxStamina
)
{
newStamina
=
playerMaxStamina
;
}
session
.
getPlayer
().
setProperty
(
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
,
newStamina
);
}
public
void
setMoveInfo
(
EntityMoveInfoOuterClass
.
EntityMoveInfo
moveInfo
)
{
this
.
moveInfo
=
moveInfo
;
}
public
EntityMoveInfoOuterClass
.
EntityMoveInfo
getMoveInfo
()
{
return
moveInfo
;
}
public
void
handleFallOnGround
(
GameSession
session
,
GameEntity
entity
)
{
float
currentHP
=
entity
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
);
float
maxHP
=
entity
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_MAX_HP
);
float
damage
=
0
;
Grasscutter
.
getLogger
().
debug
(
"LandSpeed: "
+
landSpeed
);
if
(
landSpeed
<
-
23.5
)
{
damage
=
(
float
)(
maxHP
*
0.33
);
}
if
(
landSpeed
<
-
25
)
{
damage
=
(
float
)(
maxHP
*
0.5
);
}
if
(
landSpeed
<
-
26.5
)
{
damage
=
(
float
)(
maxHP
*
0.66
);
}
if
(
landSpeed
<
-
28
)
{
damage
=
(
maxHP
*
1
);
}
float
newHP
=
currentHP
-
damage
;
if
(
newHP
<
0
)
{
newHP
=
0
;
}
Grasscutter
.
getLogger
().
debug
(
"Max: "
+
maxHP
+
"\tCurr: "
+
currentHP
+
"\tDamage: "
+
damage
+
"\tnewHP: "
+
newHP
);
entity
.
setFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
,
newHP
);
entity
.
getWorld
().
broadcastPacket
(
new
PacketEntityFightPropUpdateNotify
(
entity
,
FightProperty
.
FIGHT_PROP_CUR_HP
));
if
(
newHP
==
0
)
{
entity
.
getWorld
().
broadcastPacket
(
new
PacketLifeStateChangeNotify
(
0
,
entity
,
LifeState
.
LIFE_DEAD
));
session
.
getPlayer
().
getScene
().
removeEntity
(
entity
);
entity
.
onDeath
(
0
);
}
}
public
void
setLandSpeed
(
float
landSpeed
)
{
this
.
landSpeed
=
landSpeed
;
}
}
src/main/java/emu/grasscutter/game/managers/MovementManager/MovementManager.java
0 → 100644
View file @
93b3265d
package
emu.grasscutter.game.managers.MovementManager
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.entity.EntityAvatar
;
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.game.props.PlayerProperty
;
import
emu.grasscutter.net.proto.EntityMoveInfoOuterClass
;
import
emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo
;
import
emu.grasscutter.net.proto.MotionStateOuterClass.MotionState
;
import
emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType
;
import
emu.grasscutter.net.proto.VectorOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.*
;
import
emu.grasscutter.utils.Position
;
import
org.jetbrains.annotations.NotNull
;
import
java.lang.Math
;
import
java.util.*
;
public
class
MovementManager
{
public
HashMap
<
String
,
HashSet
<
MotionState
>>
MotionStatesCategorized
=
new
HashMap
<>();
private
enum
Consumption
{
None
(
0
),
// consume
CLIMB_START
(-
500
),
CLIMBING
(-
150
),
CLIMB_JUMP
(-
2500
),
DASH
(-
1800
),
SPRINT
(-
360
),
FLY
(-
60
),
SWIM_DASH_START
(-
200
),
SWIM_DASH
(-
200
),
SWIMMING
(-
80
),
// restore
STANDBY
(
500
),
RUN
(
500
),
WALK
(
500
),
STANDBY_MOVE
(
500
),
POWERED_FLY
(
500
);
public
final
int
amount
;
Consumption
(
int
amount
)
{
this
.
amount
=
amount
;
}
}
private
MotionState
previousState
=
MotionState
.
MOTION_STANDBY
;
private
MotionState
currentState
=
MotionState
.
MOTION_STANDBY
;
private
Position
previousCoordinates
=
new
Position
(
0
,
0
,
0
);
private
Position
currentCoordinates
=
new
Position
(
0
,
0
,
0
);
private
final
Player
player
;
private
float
landSpeed
=
0
;
private
Timer
movementManagerTickTimer
;
private
GameSession
cachedSession
=
null
;
private
GameEntity
cachedEntity
=
null
;
private
int
staminaRecoverDelay
=
0
;
public
MovementManager
(
Player
player
)
{
previousCoordinates
.
add
(
new
Position
(
0
,
0
,
0
));
this
.
player
=
player
;
MotionStatesCategorized
.
put
(
"SWIM"
,
new
HashSet
<>(
Arrays
.
asList
(
MotionState
.
MOTION_SWIM_MOVE
,
MotionState
.
MOTION_SWIM_IDLE
,
MotionState
.
MOTION_SWIM_DASH
,
MotionState
.
MOTION_SWIM_JUMP
)));
MotionStatesCategorized
.
put
(
"STANDBY"
,
new
HashSet
<>(
Arrays
.
asList
(
MotionState
.
MOTION_STANDBY
,
MotionState
.
MOTION_STANDBY_MOVE
,
MotionState
.
MOTION_DANGER_STANDBY
,
MotionState
.
MOTION_DANGER_STANDBY_MOVE
,
MotionState
.
MOTION_LADDER_TO_STANDBY
,
MotionState
.
MOTION_JUMP_UP_WALL_FOR_STANDBY
)));
MotionStatesCategorized
.
put
(
"CLIMB"
,
new
HashSet
<>(
Arrays
.
asList
(
MotionState
.
MOTION_CLIMB
,
MotionState
.
MOTION_CLIMB_JUMP
,
MotionState
.
MOTION_STANDBY_TO_CLIMB
,
MotionState
.
MOTION_LADDER_IDLE
,
MotionState
.
MOTION_LADDER_MOVE
,
MotionState
.
MOTION_LADDER_SLIP
,
MotionState
.
MOTION_STANDBY_TO_LADDER
)));
MotionStatesCategorized
.
put
(
"FLY"
,
new
HashSet
<>(
Arrays
.
asList
(
MotionState
.
MOTION_FLY
,
MotionState
.
MOTION_FLY_IDLE
,
MotionState
.
MOTION_FLY_SLOW
,
MotionState
.
MOTION_FLY_FAST
,
MotionState
.
MOTION_POWERED_FLY
)));
MotionStatesCategorized
.
put
(
"RUN"
,
new
HashSet
<>(
Arrays
.
asList
(
MotionState
.
MOTION_DASH
,
MotionState
.
MOTION_DANGER_DASH
,
MotionState
.
MOTION_DASH_BEFORE_SHAKE
,
MotionState
.
MOTION_RUN
,
MotionState
.
MOTION_DANGER_RUN
,
MotionState
.
MOTION_WALK
,
MotionState
.
MOTION_DANGER_WALK
)));
}
public
void
handle
(
GameSession
session
,
EntityMoveInfoOuterClass
.
EntityMoveInfo
moveInfo
,
GameEntity
entity
)
{
if
(
movementManagerTickTimer
==
null
)
{
movementManagerTickTimer
=
new
Timer
();
movementManagerTickTimer
.
scheduleAtFixedRate
(
new
MotionManagerTick
(),
0
,
200
);
}
// cache info for later use in tick
cachedSession
=
session
;
cachedEntity
=
entity
;
MotionInfo
motionInfo
=
moveInfo
.
getMotionInfo
();
moveEntity
(
entity
,
moveInfo
);
VectorOuterClass
.
Vector
posVector
=
motionInfo
.
getPos
();
Position
newPos
=
new
Position
(
posVector
.
getX
(),
posVector
.
getY
(),
posVector
.
getZ
());;
if
(
newPos
.
getX
()
!=
0
&&
newPos
.
getY
()
!=
0
&&
newPos
.
getZ
()
!=
0
)
{
currentCoordinates
=
newPos
;
}
currentState
=
motionInfo
.
getState
();
Grasscutter
.
getLogger
().
debug
(
""
+
currentState
);
handleFallOnGround
(
motionInfo
);
}
public
void
resetTimer
()
{
movementManagerTickTimer
.
cancel
();
movementManagerTickTimer
=
null
;
}
private
void
moveEntity
(
GameEntity
entity
,
EntityMoveInfoOuterClass
.
EntityMoveInfo
moveInfo
)
{
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
());
}
private
boolean
isPlayerMoving
()
{
float
diffX
=
currentCoordinates
.
getX
()
-
previousCoordinates
.
getX
();
float
diffY
=
currentCoordinates
.
getY
()
-
previousCoordinates
.
getY
();
float
diffZ
=
currentCoordinates
.
getZ
()
-
previousCoordinates
.
getZ
();
// Grasscutter.getLogger().debug("isPlayerMoving: " + previousCoordinates + ", " + currentCoordinates + ", " + diffX + ", " + diffY + ", " + diffZ);
return
Math
.
abs
(
diffX
)
>
0.2
||
Math
.
abs
(
diffY
)
>
0.1
||
Math
.
abs
(
diffZ
)
>
0.2
;
}
private
int
getCurrentStamina
()
{
return
player
.
getProperty
(
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
);
}
private
int
getMaximumStamina
()
{
return
player
.
getProperty
(
PlayerProperty
.
PROP_MAX_STAMINA
);
}
// Returns new stamina
public
int
updateStamina
(
GameSession
session
,
int
amount
)
{
int
currentStamina
=
session
.
getPlayer
().
getProperty
(
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
);
if
(
amount
==
0
)
{
return
currentStamina
;
}
int
playerMaxStamina
=
session
.
getPlayer
().
getProperty
(
PlayerProperty
.
PROP_MAX_STAMINA
);
int
newStamina
=
currentStamina
+
amount
;
if
(
newStamina
<
0
)
{
newStamina
=
0
;
}
if
(
newStamina
>
playerMaxStamina
)
{
newStamina
=
playerMaxStamina
;
}
session
.
getPlayer
().
setProperty
(
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
,
newStamina
);
return
newStamina
;
}
private
void
handleFallOnGround
(
@NotNull
MotionInfo
motionInfo
)
{
MotionState
state
=
motionInfo
.
getState
();
// land speed and fall on ground event arrive in different packets
// cache land speed
if
(
state
==
MotionState
.
MOTION_LAND_SPEED
)
{
landSpeed
=
motionInfo
.
getSpeed
().
getY
();
}
if
(
state
==
MotionState
.
MOTION_FALL_ON_GROUND
)
{
float
currentHP
=
cachedEntity
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
);
float
maxHP
=
cachedEntity
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_MAX_HP
);
float
damage
=
0
;
// Grasscutter.getLogger().debug("LandSpeed: " + landSpeed);
if
(
landSpeed
<
-
23.5
)
{
damage
=
(
float
)(
maxHP
*
0.33
);
}
if
(
landSpeed
<
-
25
)
{
damage
=
(
float
)(
maxHP
*
0.5
);
}
if
(
landSpeed
<
-
26.5
)
{
damage
=
(
float
)(
maxHP
*
0.66
);
}
if
(
landSpeed
<
-
28
)
{
damage
=
(
maxHP
*
1
);
}
float
newHP
=
currentHP
-
damage
;
if
(
newHP
<
0
)
{
newHP
=
0
;
}
// Grasscutter.getLogger().debug("Max: " + maxHP + "\tCurr: " + currentHP + "\tDamage: " + damage + "\tnewHP: " + newHP);
cachedEntity
.
setFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
,
newHP
);
cachedEntity
.
getWorld
().
broadcastPacket
(
new
PacketEntityFightPropUpdateNotify
(
cachedEntity
,
FightProperty
.
FIGHT_PROP_CUR_HP
));
if
(
newHP
==
0
)
{
killAvatar
(
cachedSession
,
cachedEntity
,
PlayerDieType
.
PLAYER_DIE_FALL
);
}
landSpeed
=
0
;
}
}
private
void
handleDrowning
()
{
int
stamina
=
getCurrentStamina
();
if
(
stamina
<
10
)
{
boolean
isSwimming
=
MotionStatesCategorized
.
get
(
"SWIM"
).
contains
(
currentState
);
Grasscutter
.
getLogger
().
debug
(
player
.
getProperty
(
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
)
+
"/"
+
player
.
getProperty
(
PlayerProperty
.
PROP_MAX_STAMINA
)
+
"\t"
+
currentState
+
"\t"
+
isSwimming
);
if
(
isSwimming
&&
currentState
!=
MotionState
.
MOTION_SWIM_IDLE
)
{
killAvatar
(
cachedSession
,
cachedEntity
,
PlayerDieType
.
PLAYER_DIE_DRAWN
);
}
}
}
public
void
killAvatar
(
GameSession
session
,
GameEntity
entity
,
PlayerDieType
dieType
)
{
cachedSession
.
send
(
new
PacketAvatarLifeStateChangeNotify
(
cachedSession
.
getPlayer
().
getTeamManager
().
getCurrentAvatarEntity
().
getAvatar
(),
LifeState
.
LIFE_DEAD
,
dieType
));
cachedSession
.
send
(
new
PacketLifeStateChangeNotify
(
cachedEntity
,
LifeState
.
LIFE_DEAD
,
dieType
));
cachedEntity
.
setFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
,
0
);
cachedEntity
.
getWorld
().
broadcastPacket
(
new
PacketEntityFightPropUpdateNotify
(
cachedEntity
,
FightProperty
.
FIGHT_PROP_CUR_HP
));
entity
.
getWorld
().
broadcastPacket
(
new
PacketLifeStateChangeNotify
(
0
,
entity
,
LifeState
.
LIFE_DEAD
));
session
.
getPlayer
().
getScene
().
removeEntity
(
entity
);
((
EntityAvatar
)
entity
).
onDeath
(
dieType
,
0
);
}
private
class
MotionManagerTick
extends
TimerTask
{
public
void
run
()
{
if
(
Grasscutter
.
getConfig
().
OpenStamina
)
{
boolean
moving
=
isPlayerMoving
();
if
(
moving
||
(
getCurrentStamina
()
<
getMaximumStamina
()))
{
Grasscutter
.
getLogger
().
debug
(
"Player moving: "
+
moving
+
", stamina full: "
+
(
getCurrentStamina
()
>=
getMaximumStamina
())
+
", recalculate stamina"
);
Consumption
consumption
=
Consumption
.
None
;
// TODO: refactor these conditions.
if
(
MotionStatesCategorized
.
get
(
"CLIMB"
).
contains
(
currentState
))
{
if
(
currentState
==
MotionState
.
MOTION_CLIMB
)
{
// 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
)))
{
// SWIM
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
))
{
// RUN, DASH and WALK
// DASH
if
(
currentState
==
MotionState
.
MOTION_DASH
)
{
if
(
previousState
==
MotionState
.
MOTION_DASH
)
{
consumption
=
Consumption
.
SPRINT
;
}
else
{
// cost more to start dashing
consumption
=
Consumption
.
DASH
;
}
}
// 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
))
{
// FLY
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
))
{
// STAND
if
(
currentState
==
MotionState
.
MOTION_STANDBY
)
{
consumption
=
Consumption
.
STANDBY
;
}
if
(
currentState
==
MotionState
.
MOTION_STANDBY_MOVE
)
{
consumption
=
Consumption
.
STANDBY_MOVE
;
}
}
// tick triggered
handleDrowning
();
if
(
cachedSession
!=
null
)
{
if
(
consumption
.
amount
<
0
)
{
staminaRecoverDelay
=
0
;
}
if
(
consumption
.
amount
>
0
)
{
if
(
staminaRecoverDelay
<
5
)
{
staminaRecoverDelay
++;
consumption
=
Consumption
.
None
;
}
}
int
newStamina
=
updateStamina
(
cachedSession
,
consumption
.
amount
);
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
+
")"
);
}
}
}
previousState
=
currentState
;
previousCoordinates
=
new
Position
(
currentCoordinates
.
getX
(),
currentCoordinates
.
getY
(),
currentCoordinates
.
getZ
());;
}
}
}
src/main/java/emu/grasscutter/game/player/Player.java
View file @
93b3265d
...
@@ -21,7 +21,7 @@ import emu.grasscutter.game.inventory.GameItem;
...
@@ -21,7 +21,7 @@ import emu.grasscutter.game.inventory.GameItem;
import
emu.grasscutter.game.inventory.Inventory
;
import
emu.grasscutter.game.inventory.Inventory
;
import
emu.grasscutter.game.mail.Mail
;
import
emu.grasscutter.game.mail.Mail
;
import
emu.grasscutter.game.mail.MailHandler
;
import
emu.grasscutter.game.mail.MailHandler
;
import
emu.grasscutter.game.managers.Mo
tion
Manager.Mo
tion
Manager
;
import
emu.grasscutter.game.managers.Mo
vement
Manager.Mo
vement
Manager
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.EntityType
;
import
emu.grasscutter.game.props.EntityType
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.props.PlayerProperty
;
...
@@ -122,7 +122,7 @@ public class Player {
...
@@ -122,7 +122,7 @@ public class Player {
@Transient
private
final
InvokeHandler
<
AbilityInvokeEntry
>
clientAbilityInitFinishHandler
;
@Transient
private
final
InvokeHandler
<
AbilityInvokeEntry
>
clientAbilityInitFinishHandler
;
private
MapMarksManager
mapMarksManager
;
private
MapMarksManager
mapMarksManager
;
@Transient
private
Mo
tion
Manager
mo
tion
Manager
;
@Transient
private
Mo
vement
Manager
mo
vement
Manager
;
@Deprecated
@Deprecated
...
@@ -164,7 +164,7 @@ public class Player {
...
@@ -164,7 +164,7 @@ public class Player {
this
.
shopLimit
=
new
ArrayList
<>();
this
.
shopLimit
=
new
ArrayList
<>();
this
.
messageHandler
=
null
;
this
.
messageHandler
=
null
;
this
.
mapMarksManager
=
new
MapMarksManager
();
this
.
mapMarksManager
=
new
MapMarksManager
();
this
.
mo
tion
Manager
=
new
Mo
tion
Manager
(
this
);
this
.
mo
vement
Manager
=
new
Mo
vement
Manager
(
this
);
}
}
// On player creation
// On player creation
...
@@ -191,7 +191,7 @@ public class Player {
...
@@ -191,7 +191,7 @@ public class Player {
this
.
getRotation
().
set
(
0
,
307
,
0
);
this
.
getRotation
().
set
(
0
,
307
,
0
);
this
.
messageHandler
=
null
;
this
.
messageHandler
=
null
;
this
.
mapMarksManager
=
new
MapMarksManager
();
this
.
mapMarksManager
=
new
MapMarksManager
();
this
.
mo
tion
Manager
=
new
Mo
tion
Manager
(
this
);
this
.
mo
vement
Manager
=
new
Mo
vement
Manager
(
this
);
}
}
public
int
getUid
()
{
public
int
getUid
()
{
...
@@ -974,7 +974,7 @@ public class Player {
...
@@ -974,7 +974,7 @@ public class Player {
return
mapMarksManager
;
return
mapMarksManager
;
}
}
public
Mo
tion
Manager
getMo
tion
Manager
()
{
return
mo
tion
Manager
;
}
public
Mo
vement
Manager
getMo
vement
Manager
()
{
return
mo
vement
Manager
;
}
public
synchronized
void
onTick
()
{
public
synchronized
void
onTick
()
{
// Check ping
// Check ping
...
@@ -1004,33 +1004,9 @@ public class Player {
...
@@ -1004,33 +1004,9 @@ public class Player {
this
.
resetSendPlayerLocTime
();
this
.
resetSendPlayerLocTime
();
}
}
}
}
scheduleStaminaNotify
();
}
}
private
void
scheduleStaminaNotify
()
{
// stamina tick
EntityMoveInfoOuterClass
.
EntityMoveInfo
moveInfo
=
getMotionManager
().
getMoveInfo
();
if
(
moveInfo
==
null
)
{
return
;
}
if
(
getMotionManager
().
getMoveInfo
().
getMotionInfo
().
getState
()
==
MotionStateOuterClass
.
MotionState
.
MOTION_STANDBY
)
{
if
(
getProperty
(
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
)
==
getProperty
(
PlayerProperty
.
PROP_MAX_STAMINA
)
)
{
return
;
}
}
for
(
int
i
=
0
;
i
<=
1000
;
i
+=
200
)
{
Timer
timer
=
new
Timer
();
timer
.
schedule
(
new
TimerTask
()
{
@Override
public
void
run
()
{
getMotionManager
().
tick
();
}
},
i
);
}
}
public
void
resetSendPlayerLocTime
()
{
public
void
resetSendPlayerLocTime
()
{
...
...
src/main/java/emu/grasscutter/game/player/TeamManager.java
View file @
93b3265d
...
@@ -24,6 +24,7 @@ import emu.grasscutter.net.packet.BasePacket;
...
@@ -24,6 +24,7 @@ import emu.grasscutter.net.packet.BasePacket;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType
;
import
emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType
;
import
emu.grasscutter.net.proto.MotionStateOuterClass.MotionState
;
import
emu.grasscutter.net.proto.MotionStateOuterClass.MotionState
;
import
emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType
;
import
emu.grasscutter.server.packet.send.PacketAvatarDieAnimationEndRsp
;
import
emu.grasscutter.server.packet.send.PacketAvatarDieAnimationEndRsp
;
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
;
...
@@ -419,27 +420,37 @@ public class TeamManager {
...
@@ -419,27 +420,37 @@ public class TeamManager {
if
(
deadAvatar
.
isAlive
()
||
deadAvatar
.
getId
()
!=
dieGuid
)
{
if
(
deadAvatar
.
isAlive
()
||
deadAvatar
.
getId
()
!=
dieGuid
)
{
return
;
return
;
}
}
// Replacement avatar
PlayerDieType
dieType
=
deadAvatar
.
getKilledType
();
EntityAvatar
replacement
=
null
;
int
killedBy
=
deadAvatar
.
getKilledBy
();
int
replaceIndex
=
-
1
;
if
(
dieType
==
PlayerDieType
.
PLAYER_DIE_DRAWN
)
{
for
(
int
i
=
0
;
i
<
this
.
getActiveTeam
().
size
();
i
++)
{
// Died in water. Do not replace
EntityAvatar
entity
=
this
.
getActiveTeam
().
get
(
i
);
// The official server has skipped this notify and will just respawn the team immediately after the animation.
if
(
entity
.
isAlive
())
{
// TODO: Perhaps find a way to get vanilla experience?
replaceIndex
=
i
;
getPlayer
().
sendPacket
(
new
PacketWorldPlayerDieNotify
(
dieType
,
killedBy
));
replacement
=
entity
;
break
;
}
}
if
(
replacement
==
null
)
{
// No more living team members...
getPlayer
().
sendPacket
(
new
PacketWorldPlayerDieNotify
(
deadAvatar
.
getKilledType
(),
deadAvatar
.
getKilledBy
()));
}
else
{
}
else
{
// Set index and spawn replacement member
// Replacement avatar
this
.
setCurrentCharacterIndex
(
replaceIndex
);
EntityAvatar
replacement
=
null
;
getPlayer
().
getScene
().
addEntity
(
replacement
);
int
replaceIndex
=
-
1
;
for
(
int
i
=
0
;
i
<
this
.
getActiveTeam
().
size
();
i
++)
{
EntityAvatar
entity
=
this
.
getActiveTeam
().
get
(
i
);
if
(
entity
.
isAlive
())
{
replaceIndex
=
i
;
replacement
=
entity
;
break
;
}
}
if
(
replacement
==
null
)
{
// No more living team members...
getPlayer
().
sendPacket
(
new
PacketWorldPlayerDieNotify
(
dieType
,
killedBy
));
}
else
{
// Set index and spawn replacement member
this
.
setCurrentCharacterIndex
(
replaceIndex
);
getPlayer
().
getScene
().
addEntity
(
replacement
);
}
}
}
// Response packet
// Response packet
...
@@ -492,11 +503,13 @@ public class TeamManager {
...
@@ -492,11 +503,13 @@ public class TeamManager {
public
void
respawnTeam
()
{
public
void
respawnTeam
()
{
// Make sure all team members are dead
// Make sure all team members are dead
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
// Drowning needs revive when there may be other team members still alive.
if
(
entity
.
isAlive
())
{
// for (EntityAvatar entity : getActiveTeam()) {
return
;
// if (entity.isAlive()) {
}
// return;
}
// }
// }
player
.
getMovementManager
().
resetTimer
();
// prevent drowning immediately after respawn
// Revive all team members
// Revive all team members
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerCombatInvocationsNotify.java
View file @
93b3265d
package
emu.grasscutter.server.packet.recv
;
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.managers.MotionManager.MotionManager
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.LifeState
;
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
;
...
@@ -11,9 +8,7 @@ import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry;
...
@@ -11,9 +8,7 @@ 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.server.game.GameSession
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.*
;
@Opcodes
(
PacketOpcodes
.
CombatInvocationsNotify
)
@Opcodes
(
PacketOpcodes
.
CombatInvocationsNotify
)
public
class
HandlerCombatInvocationsNotify
extends
PacketHandler
{
public
class
HandlerCombatInvocationsNotify
extends
PacketHandler
{
...
@@ -33,13 +28,7 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
...
@@ -33,13 +28,7 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
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
());
if
(
entity
!=
null
)
{
if
(
entity
!=
null
)
{
//move
session
.
getPlayer
().
getMovementManager
().
handle
(
session
,
moveInfo
,
entity
);
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
());
session
.
getPlayer
().
getMotionManager
().
handle
(
session
,
entity
,
moveInfo
);
}
}
break
;
break
;
default
:
default
:
...
@@ -52,7 +41,7 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
...
@@ -52,7 +41,7 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
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
());
}
}
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerWorldPlayerReviveReq.java
View file @
93b3265d
...
@@ -3,7 +3,9 @@ package emu.grasscutter.server.packet.recv;
...
@@ -3,7 +3,9 @@ package emu.grasscutter.server.packet.recv;
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.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.proto.WorldPlayerDieNotifyOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketWorldPlayerReviveRsp
;
@Opcodes
(
PacketOpcodes
.
WorldPlayerReviveReq
)
@Opcodes
(
PacketOpcodes
.
WorldPlayerReviveReq
)
public
class
HandlerWorldPlayerReviveReq
extends
PacketHandler
{
public
class
HandlerWorldPlayerReviveReq
extends
PacketHandler
{
...
@@ -11,6 +13,7 @@ public class HandlerWorldPlayerReviveReq extends PacketHandler {
...
@@ -11,6 +13,7 @@ public class HandlerWorldPlayerReviveReq 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
{
session
.
getPlayer
().
getTeamManager
().
respawnTeam
();
session
.
getPlayer
().
getTeamManager
().
respawnTeam
();
session
.
send
(
new
PacketWorldPlayerReviveRsp
());
}
}
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketAvatarLifeStateChangeNotify.java
View file @
93b3265d
...
@@ -9,6 +9,10 @@ import emu.grasscutter.net.packet.BasePacket;
...
@@ -9,6 +9,10 @@ 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
;
import
emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType
;
import
emu.grasscutter.net.proto.ServerBuffOuterClass
;
import
emu.grasscutter.net.proto.ServerBuffOuterClass.ServerBuff
;
import
java.util.ArrayList
;
public
class
PacketAvatarLifeStateChangeNotify
extends
BasePacket
{
public
class
PacketAvatarLifeStateChangeNotify
extends
BasePacket
{
...
@@ -22,7 +26,7 @@ public class PacketAvatarLifeStateChangeNotify extends BasePacket {
...
@@ -22,7 +26,7 @@ public class PacketAvatarLifeStateChangeNotify extends BasePacket {
this
.
setData
(
proto
);
this
.
setData
(
proto
);
}
}
public
PacketAvatarLifeStateChangeNotify
(
Avatar
avatar
,
int
attackerId
,
LifeState
lifeState
)
{
public
PacketAvatarLifeStateChangeNotify
(
Avatar
avatar
,
int
attackerId
,
LifeState
lifeState
)
{
super
(
PacketOpcodes
.
AvatarLifeStateChangeNotify
);
super
(
PacketOpcodes
.
AvatarLifeStateChangeNotify
);
AvatarLifeStateChangeNotify
proto
=
AvatarLifeStateChangeNotify
.
newBuilder
()
AvatarLifeStateChangeNotify
proto
=
AvatarLifeStateChangeNotify
.
newBuilder
()
...
@@ -33,4 +37,26 @@ public class PacketAvatarLifeStateChangeNotify extends BasePacket {
...
@@ -33,4 +37,26 @@ public class PacketAvatarLifeStateChangeNotify extends BasePacket {
this
.
setData
(
proto
);
this
.
setData
(
proto
);
}
}
public
PacketAvatarLifeStateChangeNotify
(
Avatar
avatar
,
LifeState
lifeState
,
PlayerDieType
dieType
)
{
this
(
avatar
,
lifeState
,
null
,
""
,
dieType
);
}
public
PacketAvatarLifeStateChangeNotify
(
Avatar
avatar
,
LifeState
lifeState
,
GameEntity
sourceEntity
,
String
attackTag
,
PlayerDieType
dieType
)
{
super
(
PacketOpcodes
.
AvatarLifeStateChangeNotify
);
AvatarLifeStateChangeNotify
.
Builder
proto
=
AvatarLifeStateChangeNotify
.
newBuilder
();
proto
.
setAvatarGuid
(
avatar
.
getGuid
());
proto
.
setLifeState
(
lifeState
.
getValue
());
if
(
sourceEntity
!=
null
)
{
proto
.
setSourceEntityId
(
sourceEntity
.
getId
());
}
proto
.
setDieType
(
dieType
);
proto
.
setAttackTag
((
attackTag
));
this
.
setData
(
proto
.
build
());
}
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketLifeStateChangeNotify.java
View file @
93b3265d
package
emu.grasscutter.server.packet.send
;
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.entity.GameEntity
;
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.LifeStateChangeNotifyOuterClass.LifeStateChangeNotify
;
import
emu.grasscutter.net.proto.LifeStateChangeNotifyOuterClass.LifeStateChangeNotify
;
import
emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType
;
import
emu.grasscutter.net.proto.ServerBuffOuterClass.ServerBuff
;
import
java.util.ArrayList
;
public
class
PacketLifeStateChangeNotify
extends
BasePacket
{
public
class
PacketLifeStateChangeNotify
extends
BasePacket
{
public
PacketLifeStateChangeNotify
(
GameEntity
attacker
,
GameEntity
target
,
LifeState
lifeState
)
{
public
PacketLifeStateChangeNotify
(
GameEntity
attacker
,
GameEntity
target
,
LifeState
lifeState
)
{
...
@@ -26,7 +31,29 @@ public class PacketLifeStateChangeNotify extends BasePacket {
...
@@ -26,7 +31,29 @@ public class PacketLifeStateChangeNotify extends BasePacket {
.
setLifeState
(
lifeState
.
getValue
())
.
setLifeState
(
lifeState
.
getValue
())
.
setSourceEntityId
(
attackerId
)
.
setSourceEntityId
(
attackerId
)
.
build
();
.
build
();
this
.
setData
(
proto
);
this
.
setData
(
proto
);
}
}
public
PacketLifeStateChangeNotify
(
GameEntity
entity
,
LifeState
lifeState
,
PlayerDieType
dieType
)
{
this
(
entity
,
lifeState
,
null
,
""
,
dieType
);
}
public
PacketLifeStateChangeNotify
(
GameEntity
entity
,
LifeState
lifeState
,
GameEntity
sourceEntity
,
String
attackTag
,
PlayerDieType
dieType
)
{
super
(
PacketOpcodes
.
LifeStateChangeNotify
);
LifeStateChangeNotify
.
Builder
proto
=
LifeStateChangeNotify
.
newBuilder
();
proto
.
setEntityId
(
entity
.
getId
());
proto
.
setLifeState
(
lifeState
.
getValue
());
if
(
sourceEntity
!=
null
)
{
proto
.
setSourceEntityId
(
sourceEntity
.
getId
());
}
proto
.
setAttackTag
(
attackTag
);
proto
.
setDieType
(
dieType
);
this
.
setData
(
proto
.
build
());
}
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketWorldPlayerReviveRsp.java
0 → 100644
View file @
93b3265d
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.world.World
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.WorldPlayerReviveRspOuterClass.WorldPlayerReviveRsp
;
public
class
PacketWorldPlayerReviveRsp
extends
BasePacket
{
public
PacketWorldPlayerReviveRsp
()
{
super
(
PacketOpcodes
.
WorldPlayerReviveRsp
);
WorldPlayerReviveRsp
.
Builder
proto
=
WorldPlayerReviveRsp
.
newBuilder
();
this
.
setData
(
proto
.
build
());
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment