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
d05b3207
Commit
d05b3207
authored
Aug 04, 2022
by
Magix
Committed by
GitHub
Aug 04, 2022
Browse files
Add more events
Merge pull request #1516 from Grasscutters/more-events
parents
9a104f6f
a3e0f7f5
Changes
23
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/command/commands/TeleportAllCommand.java
View file @
d05b3207
...
...
@@ -3,7 +3,7 @@ package emu.grasscutter.command.commands;
import
emu.grasscutter.command.Command
;
import
emu.grasscutter.command.CommandHandler
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.
utils.Position
;
import
emu.grasscutter.
server.event.player.PlayerTeleportEvent.TeleportType
;
import
java.util.List
;
...
...
@@ -22,9 +22,8 @@ public final class TeleportAllCommand implements CommandHandler {
for
(
Player
player
:
targetPlayer
.
getWorld
().
getPlayers
())
{
if
(
player
.
equals
(
targetPlayer
))
continue
;
Position
pos
=
targetPlayer
.
getPosition
();
player
.
getWorld
().
transferPlayerToScene
(
player
,
targetPlayer
.
getSceneId
(),
pos
);
player
.
getWorld
().
transferPlayerToScene
(
player
,
targetPlayer
.
getSceneId
(),
TeleportType
.
COMMAND
,
targetPlayer
.
getPosition
()
);
}
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.teleportAll.success"
));
...
...
src/main/java/emu/grasscutter/command/commands/TeleportCommand.java
View file @
d05b3207
...
...
@@ -3,6 +3,7 @@ package emu.grasscutter.command.commands;
import
emu.grasscutter.command.Command
;
import
emu.grasscutter.command.CommandHandler
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType
;
import
emu.grasscutter.utils.Position
;
import
java.util.List
;
...
...
@@ -40,20 +41,21 @@ public final class TeleportCommand implements CommandHandler {
}
// Fallthrough
case
3
:
try
{
x
=
parseRelative
(
args
.
get
(
0
),
x
);
y
=
parseRelative
(
args
.
get
(
1
),
y
);
z
=
parseRelative
(
args
.
get
(
2
),
z
);
x
=
this
.
parseRelative
(
args
.
get
(
0
),
x
);
y
=
this
.
parseRelative
(
args
.
get
(
1
),
y
);
z
=
this
.
parseRelative
(
args
.
get
(
2
),
z
);
}
catch
(
NumberFormatException
ignored
)
{
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.teleport.invalid_position"
));
}
break
;
default
:
sendUsageMessage
(
sender
);
this
.
sendUsageMessage
(
sender
);
return
;
}
Position
target_pos
=
new
Position
(
x
,
y
,
z
);
boolean
result
=
targetPlayer
.
getWorld
().
transferPlayerToScene
(
targetPlayer
,
sceneId
,
target_pos
);
boolean
result
=
targetPlayer
.
getWorld
().
transferPlayerToScene
(
targetPlayer
,
sceneId
,
TeleportType
.
COMMAND
,
target_pos
);
if
(!
result
)
{
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.teleport.exists_error"
));
}
else
{
...
...
src/main/java/emu/grasscutter/game/entity/EntityAvatar.java
View file @
d05b3207
...
...
@@ -30,6 +30,7 @@ import emu.grasscutter.net.proto.SceneAvatarInfoOuterClass.SceneAvatarInfo;
import
emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo
;
import
emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo
;
import
emu.grasscutter.net.proto.VectorOuterClass.Vector
;
import
emu.grasscutter.server.event.player.PlayerMoveEvent
;
import
emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropChangeReasonNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
...
...
@@ -40,28 +41,28 @@ import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import
it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap
;
public
class
EntityAvatar
extends
GameEntity
{
private
final
Avatar
avatar
;
private
final
Avatar
avatar
;
private
PlayerDieType
killedType
;
private
int
killedBy
;
private
PlayerDieType
killedType
;
private
int
killedBy
;
public
EntityAvatar
(
Scene
scene
,
Avatar
avatar
)
{
super
(
scene
);
this
.
avatar
=
avatar
;
this
.
avatar
.
setCurrentEnergy
();
this
.
id
=
getScene
().
getWorld
().
getNextEntityId
(
EntityIdType
.
AVATAR
);
public
EntityAvatar
(
Scene
scene
,
Avatar
avatar
)
{
super
(
scene
);
this
.
avatar
=
avatar
;
this
.
avatar
.
setCurrentEnergy
();
this
.
id
=
getScene
().
getWorld
().
getNextEntityId
(
EntityIdType
.
AVATAR
);
GameItem
weapon
=
this
.
getAvatar
().
getWeapon
();
if
(
weapon
!=
null
)
{
weapon
.
setWeaponEntityId
(
getScene
().
getWorld
().
getNextEntityId
(
EntityIdType
.
WEAPON
));
}
}
GameItem
weapon
=
this
.
getAvatar
().
getWeapon
();
if
(
weapon
!=
null
)
{
weapon
.
setWeaponEntityId
(
getScene
().
getWorld
().
getNextEntityId
(
EntityIdType
.
WEAPON
));
}
}
public
EntityAvatar
(
Avatar
avatar
)
{
super
(
null
);
this
.
avatar
=
avatar
;
this
.
avatar
.
setCurrentEnergy
();
}
public
EntityAvatar
(
Avatar
avatar
)
{
super
(
null
);
this
.
avatar
=
avatar
;
this
.
avatar
.
setCurrentEnergy
();
}
public
Player
getPlayer
()
{
return
avatar
.
getPlayer
();
...
...
@@ -70,72 +71,76 @@ public class EntityAvatar extends GameEntity {
@Override
public
Position
getPosition
()
{
return
getPlayer
().
getPosition
();
}
@Override
public
Position
getRotation
()
{
return
getPlayer
().
getRotation
();
}
public
Avatar
getAvatar
()
{
return
avatar
;
}
public
int
getKilledBy
()
{
return
killedBy
;
}
public
PlayerDieType
getKilledType
()
{
return
killedType
;
}
@Override
public
boolean
isAlive
()
{
return
this
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
)
>
0
f
;
}
@Override
public
Int2FloatOpenHashMap
getFightProperties
()
{
return
getAvatar
().
getFightProperties
();
}
public
int
getWeaponEntityId
()
{
if
(
getAvatar
().
getWeapon
()
!=
null
)
{
return
getAvatar
().
getWeapon
().
getWeaponEntityId
();
}
return
0
;
}
}
@Override
public
Position
getRotation
()
{
return
getPlayer
().
getRotation
();
}
public
Avatar
getAvatar
()
{
return
avatar
;
}
public
int
getKilledBy
()
{
return
killedBy
;
}
public
PlayerDieType
getKilledType
()
{
return
killedType
;
}
@Override
public
boolean
isAlive
()
{
return
this
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
)
>
0
f
;
}
@Override
public
Int2FloatOpenHashMap
getFightProperties
()
{
return
getAvatar
().
getFightProperties
();
}
public
int
getWeaponEntityId
()
{
if
(
getAvatar
().
getWeapon
()
!=
null
)
{
return
getAvatar
().
getWeapon
().
getWeaponEntityId
();
}
return
0
;
}
@Override
public
void
onDeath
(
int
killerId
)
{
super
.
onDeath
(
killerId
);
// Invoke super class's onDeath() method.
this
.
killedType
=
PlayerDieType
.
PLAYER_DIE_TYPE_KILL_BY_MONSTER
;
this
.
killedBy
=
killerId
;
clearEnergy
(
ChangeEnergyReason
.
CHANGE_ENERGY_REASON_NONE
);
}
public
void
onDeath
(
PlayerDieType
dieType
,
int
killerId
)
{
this
.
killedType
=
dieType
;
this
.
killedBy
=
killerId
;
clearEnergy
(
ChangeEnergyReason
.
CHANGE_ENERGY_REASON_NONE
);
}
public
void
onDeath
(
PlayerDieType
dieType
,
int
killerId
)
{
super
.
onDeath
(
killerId
);
// Invoke super class's onDeath() method.
@Override
public
float
heal
(
float
amount
)
{
float
healed
=
super
.
heal
(
amount
);
this
.
killedType
=
dieType
;
this
.
killedBy
=
killerId
;
clearEnergy
(
ChangeEnergyReason
.
CHANGE_ENERGY_REASON_NONE
);
}
@Override
public
float
heal
(
float
amount
)
{
float
healed
=
super
.
heal
(
amount
);
if
(
healed
>
0
f
)
{
getScene
().
broadcastPacket
(
if
(
healed
>
0
f
)
{
getScene
().
broadcastPacket
(
new
PacketEntityFightPropChangeReasonNotify
(
this
,
FightProperty
.
FIGHT_PROP_CUR_HP
,
healed
,
PropChangeReason
.
PROP_CHANGE_REASON_ABILITY
,
ChangeHpReason
.
CHANGE_HP_REASON_ADD_ABILITY
)
);
}
);
}
return
healed
;
}
return
healed
;
}
public
void
clearEnergy
(
ChangeEnergyReason
reason
)
{
// Fight props.
FightProperty
curEnergyProp
=
this
.
getAvatar
().
getSkillDepot
().
getElementType
().
getCurEnergyProp
();
FightProperty
maxEnergyProp
=
this
.
getAvatar
().
getSkillDepot
().
getElementType
().
getMaxEnergyProp
();
public
void
clearEnergy
(
ChangeEnergyReason
reason
)
{
// Fight props.
FightProperty
curEnergyProp
=
this
.
getAvatar
().
getSkillDepot
().
getElementType
().
getCurEnergyProp
();
FightProperty
maxEnergyProp
=
this
.
getAvatar
().
getSkillDepot
().
getElementType
().
getMaxEnergyProp
();
// Get max energy.
float
maxEnergy
=
this
.
avatar
.
getFightProperty
(
maxEnergyProp
);
...
...
@@ -146,172 +151,189 @@ public class EntityAvatar extends GameEntity {
// Send packets.
this
.
getScene
().
broadcastPacket
(
new
PacketEntityFightPropUpdateNotify
(
this
,
curEnergyProp
));
if
(
reason
==
ChangeEnergyReason
.
CHANGE_ENERGY_REASON_SKILL_START
)
{
this
.
getScene
().
broadcastPacket
(
new
PacketEntityFightPropChangeReasonNotify
(
this
,
curEnergyProp
,
-
maxEnergy
,
reason
));
}
}
if
(
reason
==
ChangeEnergyReason
.
CHANGE_ENERGY_REASON_SKILL_START
)
{
this
.
getScene
().
broadcastPacket
(
new
PacketEntityFightPropChangeReasonNotify
(
this
,
curEnergyProp
,
-
maxEnergy
,
reason
));
}
}
public
void
addEnergy
(
float
amount
,
PropChangeReason
reason
)
{
this
.
addEnergy
(
amount
,
reason
,
false
);
}
public
void
addEnergy
(
float
amount
,
PropChangeReason
reason
,
boolean
isFlat
)
{
// Get current and maximum energy for this avatar.
FightProperty
curEnergyProp
=
this
.
getAvatar
().
getSkillDepot
().
getElementType
().
getCurEnergyProp
();
FightProperty
maxEnergyProp
=
this
.
getAvatar
().
getSkillDepot
().
getElementType
().
getMaxEnergyProp
();
public
void
addEnergy
(
float
amount
,
PropChangeReason
reason
)
{
this
.
addEnergy
(
amount
,
reason
,
false
);
}
public
void
addEnergy
(
float
amount
,
PropChangeReason
reason
,
boolean
isFlat
)
{
// Get current and maximum energy for this avatar.
FightProperty
curEnergyProp
=
this
.
getAvatar
().
getSkillDepot
().
getElementType
().
getCurEnergyProp
();
FightProperty
maxEnergyProp
=
this
.
getAvatar
().
getSkillDepot
().
getElementType
().
getMaxEnergyProp
();
float
curEnergy
=
this
.
getFightProperty
(
curEnergyProp
);
float
maxEnergy
=
this
.
getFightProperty
(
maxEnergyProp
);
float
curEnergy
=
this
.
getFightProperty
(
curEnergyProp
);
float
maxEnergy
=
this
.
getFightProperty
(
maxEnergyProp
);
// Get energy recharge.
float
energyRecharge
=
this
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_CHARGE_EFFICIENCY
);
// Get energy recharge.
float
energyRecharge
=
this
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_CHARGE_EFFICIENCY
);
// Scale amount by energy recharge, if the amount is not flat.
if
(!
isFlat
)
{
amount
*=
energyRecharge
;
}
// Determine the new energy value.
float
newEnergy
=
Math
.
min
(
curEnergy
+
amount
,
maxEnergy
);
// Set energy and notify.
if
(
newEnergy
!=
curEnergy
)
{
this
.
avatar
.
setCurrentEnergy
(
curEnergyProp
,
newEnergy
);
this
.
getScene
().
broadcastPacket
(
new
PacketAvatarFightPropUpdateNotify
(
this
.
getAvatar
(),
curEnergyProp
));
this
.
getScene
().
broadcastPacket
(
new
PacketEntityFightPropChangeReasonNotify
(
this
,
curEnergyProp
,
newEnergy
,
reason
));
}
}
public
SceneAvatarInfo
getSceneAvatarInfo
()
{
SceneAvatarInfo
.
Builder
avatarInfo
=
SceneAvatarInfo
.
newBuilder
()
.
setUid
(
this
.
getPlayer
().
getUid
())
.
setAvatarId
(
this
.
getAvatar
().
getAvatarId
())
.
setGuid
(
this
.
getAvatar
().
getGuid
())
.
setPeerId
(
this
.
getPlayer
().
getPeerId
())
.
addAllTalentIdList
(
this
.
getAvatar
().
getTalentIdList
())
.
setCoreProudSkillLevel
(
this
.
getAvatar
().
getCoreProudSkillLevel
())
.
putAllSkillLevelMap
(
this
.
getAvatar
().
getSkillLevelMap
())
.
setSkillDepotId
(
this
.
getAvatar
().
getSkillDepotId
())
.
addAllInherentProudSkillList
(
this
.
getAvatar
().
getProudSkillList
())
.
putAllProudSkillExtraLevelMap
(
this
.
getAvatar
().
getProudSkillBonusMap
())
.
addAllTeamResonanceList
(
this
.
getAvatar
().
getPlayer
().
getTeamManager
().
getTeamResonances
())
.
setWearingFlycloakId
(
this
.
getAvatar
().
getFlyCloak
())
.
setCostumeId
(
this
.
getAvatar
().
getCostume
())
.
setBornTime
(
this
.
getAvatar
().
getBornTime
());
for
(
GameItem
item
:
avatar
.
getEquips
().
values
())
{
if
(
item
.
getItemData
().
getEquipType
()
==
EquipType
.
EQUIP_WEAPON
)
{
avatarInfo
.
setWeapon
(
item
.
createSceneWeaponInfo
());
}
else
{
avatarInfo
.
addReliquaryList
(
item
.
createSceneReliquaryInfo
());
}
avatarInfo
.
addEquipIdList
(
item
.
getItemId
());
}
return
avatarInfo
.
build
();
}
@Override
public
SceneEntityInfo
toProto
()
{
EntityAuthorityInfo
authority
=
EntityAuthorityInfo
.
newBuilder
()
.
setAbilityInfo
(
AbilitySyncStateInfo
.
newBuilder
())
.
setRendererChangedInfo
(
EntityRendererChangedInfo
.
newBuilder
())
.
setAiInfo
(
SceneEntityAiInfo
.
newBuilder
().
setIsAiOpen
(
true
).
setBornPos
(
Vector
.
newBuilder
()))
.
setBornPos
(
Vector
.
newBuilder
())
.
build
();
SceneEntityInfo
.
Builder
entityInfo
=
SceneEntityInfo
.
newBuilder
()
.
setEntityId
(
getId
())
.
setEntityType
(
ProtEntityType
.
PROT_ENTITY_TYPE_AVATAR
)
.
addAnimatorParaList
(
AnimatorParameterValueInfoPair
.
newBuilder
())
.
setEntityClientData
(
EntityClientData
.
newBuilder
())
.
setEntityAuthorityInfo
(
authority
)
.
setLastMoveSceneTimeMs
(
this
.
getLastMoveSceneTimeMs
())
.
setLastMoveReliableSeq
(
this
.
getLastMoveReliableSeq
())
.
setLifeState
(
this
.
getLifeState
().
getValue
());
if
(
this
.
getScene
()
!=
null
)
{
entityInfo
.
setMotionInfo
(
this
.
getMotionInfo
());
}
for
(
Int2FloatMap
.
Entry
entry
:
getFightProperties
().
int2FloatEntrySet
())
{
if
(
entry
.
getIntKey
()
==
0
)
{
continue
;
}
FightPropPair
fightProp
=
FightPropPair
.
newBuilder
().
setPropType
(
entry
.
getIntKey
()).
setPropValue
(
entry
.
getFloatValue
()).
build
();
entityInfo
.
addFightPropList
(
fightProp
);
}
PropPair
pair
=
PropPair
.
newBuilder
()
.
setType
(
PlayerProperty
.
PROP_LEVEL
.
getId
())
.
setPropValue
(
ProtoHelper
.
newPropValue
(
PlayerProperty
.
PROP_LEVEL
,
getAvatar
().
getLevel
()))
.
build
();
entityInfo
.
addPropList
(
pair
);
entityInfo
.
setAvatar
(
this
.
getSceneAvatarInfo
());
return
entityInfo
.
build
();
}
public
AbilityControlBlock
getAbilityControlBlock
()
{
AvatarData
data
=
this
.
getAvatar
().
getAvatarData
();
AbilityControlBlock
.
Builder
abilityControlBlock
=
AbilityControlBlock
.
newBuilder
();
int
embryoId
=
0
;
// Add avatar abilities
if
(
data
.
getAbilities
()
!=
null
)
{
for
(
int
id
:
data
.
getAbilities
())
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
id
)
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
}
// Add default abilities
for
(
int
id
:
GameConstants
.
DEFAULT_ABILITY_HASHES
)
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
id
)
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
// Add team resonances
for
(
int
id
:
this
.
getPlayer
().
getTeamManager
().
getTeamResonancesConfig
())
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
id
)
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
// Add skill depot abilities
AvatarSkillDepotData
skillDepot
=
GameData
.
getAvatarSkillDepotDataMap
().
get
(
this
.
getAvatar
().
getSkillDepotId
());
if
(
skillDepot
!=
null
&&
skillDepot
.
getAbilities
()
!=
null
)
{
for
(
int
id
:
skillDepot
.
getAbilities
())
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
id
)
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
}
// Add equip abilities
if
(
this
.
getAvatar
().
getExtraAbilityEmbryos
().
size
()
>
0
)
{
for
(
String
skill
:
this
.
getAvatar
().
getExtraAbilityEmbryos
())
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
Utils
.
abilityHash
(
skill
))
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
}
//
return
abilityControlBlock
.
build
();
// Determine the new energy value.
float
newEnergy
=
Math
.
min
(
curEnergy
+
amount
,
maxEnergy
);
// Set energy and notify.
if
(
newEnergy
!=
curEnergy
)
{
this
.
avatar
.
setCurrentEnergy
(
curEnergyProp
,
newEnergy
);
this
.
getScene
().
broadcastPacket
(
new
PacketAvatarFightPropUpdateNotify
(
this
.
getAvatar
(),
curEnergyProp
));
this
.
getScene
().
broadcastPacket
(
new
PacketEntityFightPropChangeReasonNotify
(
this
,
curEnergyProp
,
newEnergy
,
reason
));
}
}
public
SceneAvatarInfo
getSceneAvatarInfo
()
{
SceneAvatarInfo
.
Builder
avatarInfo
=
SceneAvatarInfo
.
newBuilder
()
.
setUid
(
this
.
getPlayer
().
getUid
())
.
setAvatarId
(
this
.
getAvatar
().
getAvatarId
())
.
setGuid
(
this
.
getAvatar
().
getGuid
())
.
setPeerId
(
this
.
getPlayer
().
getPeerId
())
.
addAllTalentIdList
(
this
.
getAvatar
().
getTalentIdList
())
.
setCoreProudSkillLevel
(
this
.
getAvatar
().
getCoreProudSkillLevel
())
.
putAllSkillLevelMap
(
this
.
getAvatar
().
getSkillLevelMap
())
.
setSkillDepotId
(
this
.
getAvatar
().
getSkillDepotId
())
.
addAllInherentProudSkillList
(
this
.
getAvatar
().
getProudSkillList
())
.
putAllProudSkillExtraLevelMap
(
this
.
getAvatar
().
getProudSkillBonusMap
())
.
addAllTeamResonanceList
(
this
.
getAvatar
().
getPlayer
().
getTeamManager
().
getTeamResonances
())
.
setWearingFlycloakId
(
this
.
getAvatar
().
getFlyCloak
())
.
setCostumeId
(
this
.
getAvatar
().
getCostume
())
.
setBornTime
(
this
.
getAvatar
().
getBornTime
());
for
(
GameItem
item
:
avatar
.
getEquips
().
values
())
{
if
(
item
.
getItemData
().
getEquipType
()
==
EquipType
.
EQUIP_WEAPON
)
{
avatarInfo
.
setWeapon
(
item
.
createSceneWeaponInfo
());
}
else
{
avatarInfo
.
addReliquaryList
(
item
.
createSceneReliquaryInfo
());
}
avatarInfo
.
addEquipIdList
(
item
.
getItemId
());
}
return
avatarInfo
.
build
();
}
@Override
public
SceneEntityInfo
toProto
()
{
EntityAuthorityInfo
authority
=
EntityAuthorityInfo
.
newBuilder
()
.
setAbilityInfo
(
AbilitySyncStateInfo
.
newBuilder
())
.
setRendererChangedInfo
(
EntityRendererChangedInfo
.
newBuilder
())
.
setAiInfo
(
SceneEntityAiInfo
.
newBuilder
().
setIsAiOpen
(
true
).
setBornPos
(
Vector
.
newBuilder
()))
.
setBornPos
(
Vector
.
newBuilder
())
.
build
();
SceneEntityInfo
.
Builder
entityInfo
=
SceneEntityInfo
.
newBuilder
()
.
setEntityId
(
getId
())
.
setEntityType
(
ProtEntityType
.
PROT_ENTITY_TYPE_AVATAR
)
.
addAnimatorParaList
(
AnimatorParameterValueInfoPair
.
newBuilder
())
.
setEntityClientData
(
EntityClientData
.
newBuilder
())
.
setEntityAuthorityInfo
(
authority
)
.
setLastMoveSceneTimeMs
(
this
.
getLastMoveSceneTimeMs
())
.
setLastMoveReliableSeq
(
this
.
getLastMoveReliableSeq
())
.
setLifeState
(
this
.
getLifeState
().
getValue
());
if
(
this
.
getScene
()
!=
null
)
{
entityInfo
.
setMotionInfo
(
this
.
getMotionInfo
());
}
for
(
Int2FloatMap
.
Entry
entry
:
getFightProperties
().
int2FloatEntrySet
())
{
if
(
entry
.
getIntKey
()
==
0
)
{
continue
;
}
FightPropPair
fightProp
=
FightPropPair
.
newBuilder
().
setPropType
(
entry
.
getIntKey
()).
setPropValue
(
entry
.
getFloatValue
()).
build
();
entityInfo
.
addFightPropList
(
fightProp
);
}
PropPair
pair
=
PropPair
.
newBuilder
()
.
setType
(
PlayerProperty
.
PROP_LEVEL
.
getId
())
.
setPropValue
(
ProtoHelper
.
newPropValue
(
PlayerProperty
.
PROP_LEVEL
,
getAvatar
().
getLevel
()))
.
build
();
entityInfo
.
addPropList
(
pair
);
entityInfo
.
setAvatar
(
this
.
getSceneAvatarInfo
());
return
entityInfo
.
build
();
}
public
AbilityControlBlock
getAbilityControlBlock
()
{
AvatarData
data
=
this
.
getAvatar
().
getAvatarData
();
AbilityControlBlock
.
Builder
abilityControlBlock
=
AbilityControlBlock
.
newBuilder
();
int
embryoId
=
0
;
// Add avatar abilities
if
(
data
.
getAbilities
()
!=
null
)
{
for
(
int
id
:
data
.
getAbilities
())
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
id
)
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
}
// Add default abilities
for
(
int
id
:
GameConstants
.
DEFAULT_ABILITY_HASHES
)
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
id
)
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
// Add team resonances
for
(
int
id
:
this
.
getPlayer
().
getTeamManager
().
getTeamResonancesConfig
())
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
id
)
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
// Add skill depot abilities
AvatarSkillDepotData
skillDepot
=
GameData
.
getAvatarSkillDepotDataMap
().
get
(
this
.
getAvatar
().
getSkillDepotId
());
if
(
skillDepot
!=
null
&&
skillDepot
.
getAbilities
()
!=
null
)
{
for
(
int
id
:
skillDepot
.
getAbilities
())
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
id
)
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
}
// Add equip abilities
if
(
this
.
getAvatar
().
getExtraAbilityEmbryos
().
size
()
>
0
)
{
for
(
String
skill
:
this
.
getAvatar
().
getExtraAbilityEmbryos
())
{
AbilityEmbryo
emb
=
AbilityEmbryo
.
newBuilder
()
.
setAbilityId
(++
embryoId
)
.
setAbilityNameHash
(
Utils
.
abilityHash
(
skill
))
.
setAbilityOverrideNameHash
(
GameConstants
.
DEFAULT_ABILITY_NAME
)
.
build
();
abilityControlBlock
.
addAbilityEmbryoList
(
emb
);
}
}
//
return
abilityControlBlock
.
build
();
}
/**
* Move this entity to a new position.
* Additionally invoke player move event.
* @param newPosition The new position.
* @param rotation The new rotation.
*/
@Override
public
void
move
(
Position
newPosition
,
Position
rotation
)
{
// Invoke player move event.
PlayerMoveEvent
event
=
new
PlayerMoveEvent
(
this
.
getPlayer
(),
PlayerMoveEvent
.
MoveType
.
PLAYER
,
this
.
getPosition
(),
newPosition
);
event
.
call
();
// Set position and rotation.
super
.
move
(
event
.
getDestination
(),
rotation
);
}
}
src/main/java/emu/grasscutter/game/entity/EntityBaseGadget.java
View file @
d05b3207
...
...
@@ -8,11 +8,11 @@ public abstract class EntityBaseGadget extends GameEntity {
public
EntityBaseGadget
(
Scene
scene
)
{
super
(
scene
);
}
public
abstract
int
getGadgetId
();
@Override
public
void
onDeath
(
int
killerId
)
{
super
.
onDeath
(
killerId
);
// Invoke super class's onDeath() method.
}
}
src/main/java/emu/grasscutter/game/entity/EntityClientGadget.java
View file @
d05b3207
...
...
@@ -3,7 +3,6 @@ package emu.grasscutter.game.entity;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.game.world.World
;
import
emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo
;
import
emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair
;
import
emu.grasscutter.net.proto.ClientGadgetInfoOuterClass
;
...
...
@@ -11,7 +10,6 @@ import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityIn
import
emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData
;
import
emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo
;
import
emu.grasscutter.net.proto.EvtCreateGadgetNotifyOuterClass.EvtCreateGadgetNotify
;
import
emu.grasscutter.net.proto.GadgetClientParamOuterClass.GadgetClientParam
;
import
emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo
;
import
emu.grasscutter.net.proto.PropPairOuterClass.PropPair
;
import
emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType
;
...
...
@@ -25,10 +23,10 @@ import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
public
class
EntityClientGadget
extends
EntityBaseGadget
{
private
final
Player
owner
;
private
final
Position
pos
;
private
final
Position
rot
;
private
int
configId
;
private
int
campId
;
private
int
campType
;
...
...
@@ -37,7 +35,7 @@ public class EntityClientGadget extends EntityBaseGadget {
private
boolean
asyncLoad
;
private
int
originalOwnerEntityId
;
public
EntityClientGadget
(
Scene
scene
,
Player
player
,
EvtCreateGadgetNotify
notify
)
{
super
(
scene
);
this
.
owner
=
player
;
...
...
@@ -59,20 +57,20 @@ public class EntityClientGadget extends EntityBaseGadget {
this
.
originalOwnerEntityId
=
this
.
ownerEntityId
;
}
}
@Override
public
int
getGadgetId
()
{
return
configId
;
}
public
Player
getOwner
()
{
return
owner
;
}
public
int
getCampId
()
{
return
campId
;
}
public
int
getCampType
()
{
return
campType
;
}
...
...
@@ -80,7 +78,7 @@ public class EntityClientGadget extends EntityBaseGadget {
public
int
getOwnerEntityId
()
{
return
ownerEntityId
;
}
public
int
getTargetEntityId
()
{
return
targetEntityId
;
}
...
...
@@ -95,7 +93,7 @@ public class EntityClientGadget extends EntityBaseGadget {
@Override
public
void
onDeath
(
int
killerId
)
{
super
.
onDeath
(
killerId
);
// Invoke super class's onDeath() method.
}
@Override
...
...
@@ -124,7 +122,7 @@ public class EntityClientGadget extends EntityBaseGadget {
.
setAiInfo
(
SceneEntityAiInfo
.
newBuilder
().
setIsAiOpen
(
true
).
setBornPos
(
Vector
.
newBuilder
()))
.
setBornPos
(
Vector
.
newBuilder
())
.
build
();
SceneEntityInfo
.
Builder
entityInfo
=
SceneEntityInfo
.
newBuilder
()
.
setEntityId
(
getId
())
.
setEntityType
(
ProtEntityType
.
PROT_ENTITY_TYPE_GADGET
)
...
...
@@ -133,13 +131,13 @@ public class EntityClientGadget extends EntityBaseGadget {
.
setEntityClientData
(
EntityClientData
.
newBuilder
())
.
setEntityAuthorityInfo
(
authority
)
.
setLifeState
(
1
);
PropPair
pair
=
PropPair
.
newBuilder
()
.
setType
(
PlayerProperty
.
PROP_LEVEL
.
getId
())
.
setPropValue
(
ProtoHelper
.
newPropValue
(
PlayerProperty
.
PROP_LEVEL
,
1
))
.
build
();
entityInfo
.
addPropList
(
pair
);
ClientGadgetInfoOuterClass
.
ClientGadgetInfo
clientGadget
=
ClientGadgetInfoOuterClass
.
ClientGadgetInfo
.
newBuilder
()
.
setCampId
(
this
.
getCampId
())
.
setCampType
(
this
.
getCampType
())
...
...
@@ -147,7 +145,7 @@ public class EntityClientGadget extends EntityBaseGadget {
.
setTargetEntityId
(
this
.
getTargetEntityId
())
.
setAsyncLoad
(
this
.
isAsyncLoad
())
.
build
();
SceneGadgetInfo
.
Builder
gadgetInfo
=
SceneGadgetInfo
.
newBuilder
()
.
setGadgetId
(
this
.
getGadgetId
())
.
setOwnerEntityId
(
this
.
getOwnerEntityId
())
...
...
@@ -157,7 +155,7 @@ public class EntityClientGadget extends EntityBaseGadget {
.
setAuthorityPeerId
(
this
.
getOwner
().
getPeerId
());
entityInfo
.
setGadget
(
gadgetInfo
);
return
entityInfo
.
build
();
}
}
src/main/java/emu/grasscutter/game/entity/EntityGadget.java
View file @
d05b3207
...
...
@@ -175,6 +175,8 @@ public class EntityGadget extends EntityBaseGadget {
@Override
public
void
onDeath
(
int
killerId
)
{
super
.
onDeath
(
killerId
);
// Invoke super class's onDeath() method.
if
(
this
.
getSpawnEntry
()
!=
null
)
{
this
.
getScene
().
getDeadSpawnedEntities
().
add
(
getSpawnEntry
());
}
...
...
src/main/java/emu/grasscutter/game/entity/EntityMonster.java
View file @
d05b3207
...
...
@@ -158,6 +158,8 @@ public class EntityMonster extends GameEntity {
@Override
public
void
onDeath
(
int
killerId
)
{
super
.
onDeath
(
killerId
);
// Invoke super class's onDeath() method.
if
(
this
.
getSpawnEntry
()
!=
null
)
{
this
.
getScene
().
getDeadSpawnedEntities
().
add
(
getSpawnEntry
());
}
...
...
src/main/java/emu/grasscutter/game/entity/GameEntity.java
View file @
d05b3207
...
...
@@ -15,6 +15,7 @@ import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
import
emu.grasscutter.net.proto.MotionStateOuterClass.MotionState
;
import
emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo
;
import
emu.grasscutter.net.proto.VectorOuterClass.Vector
;
import
emu.grasscutter.server.event.entity.EntityDeathEvent
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.utils.Position
;
import
it.unimi.dsi.fastutil.ints.Int2FloatMap
;
...
...
@@ -23,64 +24,64 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
public
abstract
class
GameEntity
{
protected
int
id
;
private
final
Scene
scene
;
private
SpawnDataEntry
spawnEntry
;
private
int
blockId
;
private
int
configId
;
private
int
groupId
;
private
MotionState
moveState
;
private
int
lastMoveSceneTimeMs
;
private
int
lastMoveReliableSeq
;
// Abilities
private
Map
<
String
,
Float
>
metaOverrideMap
;
private
Int2ObjectMap
<
String
>
metaModifiers
;
public
GameEntity
(
Scene
scene
)
{
this
.
scene
=
scene
;
this
.
moveState
=
MotionState
.
MOTION_STATE_NONE
;
}
public
int
getId
()
{
return
this
.
id
;
}
public
int
getEntityType
()
{
return
getId
()
>>
24
;
}
public
World
getWorld
()
{
return
this
.
getScene
().
getWorld
();
}
public
Scene
getScene
()
{
return
this
.
scene
;
}
public
boolean
isAlive
()
{
return
true
;
}
public
LifeState
getLifeState
()
{
return
isAlive
()
?
LifeState
.
LIFE_ALIVE
:
LifeState
.
LIFE_DEAD
;
}
public
Map
<
String
,
Float
>
getMetaOverrideMap
()
{
if
(
this
.
metaOverrideMap
==
null
)
{
this
.
metaOverrideMap
=
new
HashMap
<>();
}
return
this
.
metaOverrideMap
;
}
public
Int2ObjectMap
<
String
>
getMetaModifiers
()
{
if
(
this
.
metaModifiers
==
null
)
{
this
.
metaModifiers
=
new
Int2ObjectOpenHashMap
<>();
}
return
this
.
metaModifiers
;
}
protected
int
id
;
private
final
Scene
scene
;
private
SpawnDataEntry
spawnEntry
;
private
int
blockId
;
private
int
configId
;
private
int
groupId
;
private
MotionState
moveState
;
private
int
lastMoveSceneTimeMs
;
private
int
lastMoveReliableSeq
;
// Abilities
private
Map
<
String
,
Float
>
metaOverrideMap
;
private
Int2ObjectMap
<
String
>
metaModifiers
;
public
GameEntity
(
Scene
scene
)
{
this
.
scene
=
scene
;
this
.
moveState
=
MotionState
.
MOTION_STATE_NONE
;
}
public
int
getId
()
{
return
this
.
id
;
}
public
int
getEntityType
()
{
return
getId
()
>>
24
;
}
public
World
getWorld
()
{
return
this
.
getScene
().
getWorld
();
}
public
Scene
getScene
()
{
return
this
.
scene
;
}
public
boolean
isAlive
()
{
return
true
;
}
public
LifeState
getLifeState
()
{
return
isAlive
()
?
LifeState
.
LIFE_ALIVE
:
LifeState
.
LIFE_DEAD
;
}
public
Map
<
String
,
Float
>
getMetaOverrideMap
()
{
if
(
this
.
metaOverrideMap
==
null
)
{
this
.
metaOverrideMap
=
new
HashMap
<>();
}
return
this
.
metaOverrideMap
;
}
public
Int2ObjectMap
<
String
>
getMetaModifiers
()
{
if
(
this
.
metaModifiers
==
null
)
{
this
.
metaModifiers
=
new
Int2ObjectOpenHashMap
<>();
}
return
this
.
metaModifiers
;
}
public
abstract
Int2FloatOpenHashMap
getFightProperties
();
...
...
@@ -230,6 +231,17 @@ public abstract class GameEntity {
}
}
/**
* Move this entity to a new position.
* @param position The new position.
* @param rotation The new rotation.
*/
public
void
move
(
Position
position
,
Position
rotation
)
{
// Set the position and rotation.
this
.
getPosition
().
set
(
position
);
this
.
getRotation
().
set
(
rotation
);
}
/**
* Called when a player interacts with this entity
* @param player Player that is interacting with this entity
...
...
@@ -251,7 +263,9 @@ public abstract class GameEntity {
* @param killerId Entity id of the entity that killed this entity
*/
public
void
onDeath
(
int
killerId
)
{
// Invoke entity death event.
EntityDeathEvent
event
=
new
EntityDeathEvent
(
this
,
killerId
);
event
.
call
();
}
public
abstract
SceneEntityInfo
toProto
();
...
...
src/main/java/emu/grasscutter/game/managers/energy/EnergyManager.java
View file @
d05b3207
...
...
@@ -28,7 +28,6 @@ import emu.grasscutter.net.proto.EvtBeingHitInfoOuterClass.EvtBeingHitInfo;
import
emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.utils.Position
;
import
it.unimi.dsi.fastutil.ints.Int2IntMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
...
...
@@ -42,15 +41,14 @@ import java.util.Optional;
import
java.util.concurrent.ThreadLocalRandom
;
import
static
emu
.
grasscutter
.
config
.
Configuration
.
GAME_OPTIONS
;
import
static
java
.
util
.
Map
.
entry
;
import
com.google.gson.reflect.TypeToken
;
import
com.google.protobuf.InvalidProtocolBufferException
;
public
class
EnergyManager
extends
BasePlayerManager
{
private
final
Map
<
EntityAvatar
,
Integer
>
avatarNormalProbabilities
;
// energyUsage for each player
private
B
oolean
energyUsage
;
private
b
oolean
energyUsage
;
// Should energy usage be enabled for this player?
private
final
static
Int2ObjectMap
<
List
<
EnergyDropInfo
>>
energyDropData
=
new
Int2ObjectOpenHashMap
<>();
private
final
static
Int2ObjectMap
<
List
<
SkillParticleGenerationInfo
>>
skillParticleGenerationData
=
new
Int2ObjectOpenHashMap
<>();
...
...
@@ -90,9 +88,9 @@ public class EnergyManager extends BasePlayerManager {
}
}
/**
********
Particle creation for elemental skills.
*********
*/
/**
*
Particle creation for elemental skills.
*/
private
int
getBallCountForAvatar
(
int
avatarId
)
{
// We default to two particles.
int
count
=
2
;
...
...
@@ -120,12 +118,12 @@ public class EnergyManager extends BasePlayerManager {
}
private
int
getBallIdForElement
(
ElementType
element
)
{
// If we have no element, we default to an elementless particle.
// If we have no element, we default to an element
-
less particle.
if
(
element
==
null
)
{
return
2024
;
}
// Otherwise, we determin the particle's ID based on the element.
// Otherwise, we determin
e
the particle's ID based on the element.
return
switch
(
element
)
{
case
Fire
->
2017
;
case
Water
->
2018
;
...
...
@@ -156,7 +154,7 @@ public class EnergyManager extends BasePlayerManager {
int
amount
=
2
;
// Try to get the casting avatar from the player's party.
Optional
<
EntityAvatar
>
avatarEntity
=
getCastingAvatarEntityForEnergy
(
invoke
.
getEntityId
());
Optional
<
EntityAvatar
>
avatarEntity
=
this
.
getCastingAvatarEntityForEnergy
(
invoke
.
getEntityId
());
// Bug: invokes twice sometimes, Ayato, Keqing
// ToDo: deal with press, hold difference. deal with charge(Beidou, Yunjin)
...
...
@@ -174,20 +172,21 @@ public class EnergyManager extends BasePlayerManager {
// particles we have to generate.
if
(
skillDepotData
!=
null
)
{
ElementType
element
=
skillDepotData
.
getElementType
();
itemId
=
getBallIdForElement
(
element
);
itemId
=
this
.
getBallIdForElement
(
element
);
}
}
}
// Generate the particles.
for
(
int
i
=
0
;
i
<
amount
;
i
++)
{
generateElemBall
(
itemId
,
new
Position
(
action
.
getPos
()),
1
);
this
.
generateElemBall
(
itemId
,
new
Position
(
action
.
getPos
()),
1
);
}
}
/**********
Pickup of elemental particles and orbs.
**********/
/**
* Pickup of elemental particles and orbs.
* @param elemBall The elemental particle or orb.
*/
public
void
handlePickupElemBall
(
GameItem
elemBall
)
{
// Check if the item is indeed an energy particle/orb.
if
(
elemBall
.
getItemId
()
<
2001
||
elemBall
.
getItemId
()
>
2024
)
{
...
...
@@ -242,9 +241,10 @@ public class EnergyManager extends BasePlayerManager {
}
}
/**********
Energy generation for NAs/CAs.
**********/
/**
* Energy generation for NAs/CAs.
* @param avatar The avatar.
*/
private
void
generateEnergyForNormalAndCharged
(
EntityAvatar
avatar
)
{
// This logic is based on the descriptions given in
// https://genshin-impact.fandom.com/wiki/Energy#Energy_Generated_by_Normal_Attacks
...
...
@@ -290,11 +290,10 @@ public class EnergyManager extends BasePlayerManager {
// Make sure the target is an actual enemy.
GameEntity
targetEntity
=
this
.
player
.
getScene
().
getEntityById
(
attackRes
.
getDefenseId
());
if
(!(
targetEntity
instanceof
EntityMonster
))
{
if
(!(
targetEntity
instanceof
EntityMonster
targetMonster
))
{
return
;
}
EntityMonster
targetMonster
=
(
EntityMonster
)
targetEntity
;
MonsterType
targetType
=
targetMonster
.
getMonsterData
().
getType
();
if
(
targetType
!=
MonsterType
.
MONSTER_ORDINARY
&&
targetType
!=
MonsterType
.
MONSTER_BOSS
)
{
return
;
...
...
@@ -319,10 +318,10 @@ public class EnergyManager extends BasePlayerManager {
this
.
generateEnergyForNormalAndCharged
(
attackerEntity
.
get
());
}
/*
* Energy logic related to using skills.
*/
/**********
Energy logic related to using skills.
**********/
private
void
handleBurstCast
(
Avatar
avatar
,
int
skillId
)
{
// Don't do anything if energy usage is disabled.
if
(!
GAME_OPTIONS
.
energyUsage
||
!
this
.
energyUsage
)
{
...
...
@@ -351,9 +350,10 @@ public class EnergyManager extends BasePlayerManager {
this
.
handleBurstCast
(
avatar
,
skillId
);
}
/**********
Monster energy drops.
**********/
/*
* Monster energy drops.
*/
private
void
generateElemBallDrops
(
EntityMonster
monster
,
int
dropId
)
{
// Generate all drops specified for the given drop id.
if
(!
energyDropData
.
containsKey
(
dropId
))
{
...
...
@@ -365,6 +365,7 @@ public class EnergyManager extends BasePlayerManager {
this
.
generateElemBall
(
info
.
getBallId
(),
monster
.
getPosition
(),
info
.
getCount
());
}
}
public
void
handleMonsterEnergyDrop
(
EntityMonster
monster
,
float
hpBeforeDamage
,
float
hpAfterDamage
)
{
// Make sure this is actually a monster.
// Note that some wildlife also has that type, like boars or birds.
...
...
@@ -373,7 +374,7 @@ public class EnergyManager extends BasePlayerManager {
return
;
}
// Calculate the HP tresholds for before and after the damage was taken.
// Calculate the HP t
h
resholds for before and after the damage was taken.
float
maxHp
=
monster
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_MAX_HP
);
float
thresholdBefore
=
hpBeforeDamage
/
maxHp
;
float
thresholdAfter
=
hpAfterDamage
/
maxHp
;
...
...
@@ -386,19 +387,20 @@ public class EnergyManager extends BasePlayerManager {
float
threshold
=
drop
.
getHpPercent
()
/
100.0f
;
if
(
threshold
<
thresholdBefore
&&
threshold
>=
thresholdAfter
)
{
generateElemBallDrops
(
monster
,
drop
.
getDropId
());
this
.
generateElemBallDrops
(
monster
,
drop
.
getDropId
());
}
}
// Handle kill drops.
if
(
hpAfterDamage
<=
0
&&
monster
.
getMonsterData
().
getKillDropId
()
!=
0
)
{
generateElemBallDrops
(
monster
,
monster
.
getMonsterData
().
getKillDropId
());
this
.
generateElemBallDrops
(
monster
,
monster
.
getMonsterData
().
getKillDropId
());
}
}
/**********
Utility.
**********/
/*
* Utilities.
*/
private
void
generateElemBall
(
int
ballId
,
Position
position
,
int
count
)
{
// Generate a particle/orb with the specified parameters.
ItemData
itemData
=
GameData
.
getItemDataMap
().
get
(
ballId
);
...
...
@@ -417,7 +419,7 @@ public class EnergyManager extends BasePlayerManager {
// that cast the skill.
// Try to get the invoking entity from the scene.
GameEntity
entity
=
player
.
getScene
().
getEntityById
(
invokeEntityId
);
GameEntity
entity
=
this
.
player
.
getScene
().
getEntityById
(
invokeEntityId
);
// Determine the ID of the entity that originally cast this skill. If the scene entity is null,
// or not an `EntityClientGadget`, we assume that we are directly looking at the casting avatar
...
...
@@ -430,20 +432,20 @@ public class EnergyManager extends BasePlayerManager {
:
((
EntityClientGadget
)
entity
).
getOriginalOwnerEntityId
();
// Finally, find the avatar entity in the player's team.
return
player
.
getTeamManager
().
getActiveTeam
()
return
this
.
player
.
getTeamManager
().
getActiveTeam
()
.
stream
()
.
filter
(
character
->
character
.
getId
()
==
avatarEntityId
)
.
findFirst
();
}
public
B
oolean
getEnergyUsage
()
{
return
energyUsage
;
public
b
oolean
getEnergyUsage
()
{
return
this
.
energyUsage
;
}
public
void
setEnergyUsage
(
B
oolean
energyUsage
)
{
public
void
setEnergyUsage
(
b
oolean
energyUsage
)
{
this
.
energyUsage
=
energyUsage
;
if
(!
energyUsage
)
{
// Refill team energy if usage is disabled
for
(
EntityAvatar
entityAvatar
:
player
.
getTeamManager
().
getActiveTeam
())
{
for
(
EntityAvatar
entityAvatar
:
this
.
player
.
getTeamManager
().
getActiveTeam
())
{
entityAvatar
.
addEnergy
(
1000
,
PropChangeReason
.
PROP_CHANGE_REASON_GM
,
true
);
}
}
...
...
src/main/java/emu/grasscutter/game/managers/mapmark/MapMarksManager.java
View file @
d05b3207
...
...
@@ -5,11 +5,11 @@ import emu.grasscutter.game.player.Player;
import
emu.grasscutter.net.proto.MapMarkPointTypeOuterClass.MapMarkPointType
;
import
emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq
;
import
emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq.Operation
;
import
emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType
;
import
emu.grasscutter.server.packet.send.PacketMarkMapRsp
;
import
emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify
;
import
emu.grasscutter.utils.Position
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
MapMarksManager
extends
BasePlayerManager
{
...
...
@@ -20,7 +20,7 @@ public class MapMarksManager extends BasePlayerManager {
}
public
Map
<
String
,
MapMark
>
getMapMarks
()
{
return
getPlayer
().
getMapMarks
();
return
this
.
getPlayer
().
getMapMarks
();
}
public
void
handleMapMarkReq
(
MarkMapReq
req
)
{
...
...
@@ -30,26 +30,26 @@ public class MapMarksManager extends BasePlayerManager {
MapMark
createMark
=
new
MapMark
(
req
.
getMark
());
// keep teleporting functionality on fishhook mark.
if
(
createMark
.
getMapMarkPointType
()
==
MapMarkPointType
.
MAP_MARK_POINT_TYPE_FISH_POOL
)
{
teleport
(
player
,
createMark
);
this
.
teleport
(
player
,
createMark
);
return
;
}
addMapMark
(
createMark
);
this
.
addMapMark
(
createMark
);
}
case
OPERATION_MOD
->
{
MapMark
oldMark
=
new
MapMark
(
req
.
getOld
());
removeMapMark
(
oldMark
.
getPosition
());
this
.
removeMapMark
(
oldMark
.
getPosition
());
MapMark
newMark
=
new
MapMark
(
req
.
getMark
());
addMapMark
(
newMark
);
this
.
addMapMark
(
newMark
);
}
case
OPERATION_DEL
->
{
MapMark
deleteMark
=
new
MapMark
(
req
.
getMark
());
removeMapMark
(
deleteMark
.
getPosition
());
this
.
removeMapMark
(
deleteMark
.
getPosition
());
}
}
if
(
op
!=
Operation
.
OPERATION_GET
)
{
save
();
this
.
save
();
}
player
.
getSession
().
send
(
new
PacketMarkMapRsp
(
getMapMarks
()));
player
.
getSession
().
send
(
new
PacketMarkMapRsp
(
this
.
getMapMarks
()));
}
public
String
getMapMarkKey
(
Position
position
)
{
...
...
@@ -57,27 +57,25 @@ public class MapMarksManager extends BasePlayerManager {
}
public
void
removeMapMark
(
Position
position
)
{
getMapMarks
().
remove
(
getMapMarkKey
(
position
));
this
.
getMapMarks
().
remove
(
this
.
getMapMarkKey
(
position
));
}
public
void
addMapMark
(
MapMark
mapMark
)
{
if
(
getMapMarks
().
size
()
<
mapMarkMaxCount
)
{
getMapMarks
().
put
(
getMapMarkKey
(
mapMark
.
getPosition
()),
mapMark
);
if
(
this
.
getMapMarks
().
size
()
<
mapMarkMaxCount
)
{
this
.
getMapMarks
().
put
(
this
.
getMapMarkKey
(
mapMark
.
getPosition
()),
mapMark
);
}
}
private
void
teleport
(
Player
player
,
MapMark
mapMark
)
{
float
y
;
try
{
y
=
(
f
loat
)
Integer
.
parse
In
t
(
mapMark
.
getName
());
y
=
F
loat
.
parse
Floa
t
(
mapMark
.
getName
());
}
catch
(
Exception
e
)
{
y
=
300
;
}
Position
pos
=
mapMark
.
getPosition
();
player
.
getPosition
().
set
(
pos
.
getX
(),
y
,
pos
.
getZ
());
if
(
mapMark
.
getSceneId
()
!=
player
.
getSceneId
())
{
player
.
getWorld
().
transferPlayerToScene
(
player
,
mapMark
.
getSceneId
(),
player
.
getPosition
());
}
player
.
getWorld
().
transferPlayerToScene
(
player
,
mapMark
.
getSceneId
(),
TeleportType
.
MAP
,
new
Position
(
pos
.
getX
(),
y
,
pos
.
getZ
()));
player
.
getScene
().
broadcastPacket
(
new
PacketSceneEntityAppearNotify
(
player
));
}
}
src/main/java/emu/grasscutter/game/player/TeamManager.java
View file @
d05b3207
...
...
@@ -20,6 +20,7 @@ import emu.grasscutter.net.packet.PacketOpcodes;
import
emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType
;
import
emu.grasscutter.net.proto.MotionStateOuterClass.MotionState
;
import
emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType
;
import
emu.grasscutter.server.event.player.PlayerTeamDeathEvent
;
import
emu.grasscutter.server.packet.send.PacketAvatarDieAnimationEndRsp
;
import
emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify
;
...
...
@@ -76,7 +77,7 @@ public class TeamManager extends BasePlayerDataManager {
}
public
World
getWorld
()
{
return
getPlayer
().
getWorld
();
return
this
.
getPlayer
().
getWorld
();
}
public
Map
<
Integer
,
TeamInfo
>
getTeams
()
{
...
...
@@ -123,7 +124,7 @@ public class TeamManager extends BasePlayerDataManager {
}
public
long
getCurrentCharacterGuid
()
{
return
getCurrentAvatarEntity
().
getAvatar
().
getGuid
();
return
this
.
getCurrentAvatarEntity
().
getAvatar
().
getGuid
();
}
public
TeamInfo
getCurrentTeamInfo
()
{
...
...
@@ -166,20 +167,20 @@ public class TeamManager extends BasePlayerDataManager {
}
public
EntityAvatar
getCurrentAvatarEntity
()
{
return
getActiveTeam
().
get
(
currentCharacterIndex
);
return
this
.
getActiveTeam
().
get
(
currentCharacterIndex
);
}
public
boolean
isSpawned
()
{
return
getPlayer
().
getScene
()
!=
null
&&
getPlayer
().
getScene
().
getEntities
().
containsKey
(
getCurrentAvatarEntity
().
getId
());
return
this
.
getPlayer
().
getScene
()
!=
null
&&
this
.
getPlayer
().
getScene
().
getEntities
().
containsKey
(
this
.
getCurrentAvatarEntity
().
getId
());
}
public
int
getMaxTeamSize
()
{
if
(
getPlayer
().
isInMultiplayer
())
{
if
(
this
.
getPlayer
().
isInMultiplayer
())
{
int
max
=
GAME_OPTIONS
.
avatarLimits
.
multiplayerTeam
;
if
(
getPlayer
().
getWorld
().
getHost
()
==
this
.
getPlayer
())
{
return
Math
.
max
(
1
,
(
int
)
Math
.
ceil
(
max
/
(
double
)
getWorld
().
getPlayerCount
()));
if
(
this
.
getPlayer
().
getWorld
().
getHost
()
==
this
.
getPlayer
())
{
return
Math
.
max
(
1
,
(
int
)
Math
.
ceil
(
max
/
(
double
)
this
.
getWorld
().
getPlayerCount
()));
}
return
Math
.
max
(
1
,
(
int
)
Math
.
floor
(
max
/
(
double
)
getWorld
().
getPlayerCount
()));
return
Math
.
max
(
1
,
(
int
)
Math
.
floor
(
max
/
(
double
)
this
.
getWorld
().
getPlayerCount
()));
}
return
GAME_OPTIONS
.
avatarLimits
.
singlePlayerTeam
;
...
...
@@ -191,14 +192,14 @@ public class TeamManager extends BasePlayerDataManager {
* Returns true if there is space to add the number of avatars to the team.
*/
public
boolean
canAddAvatarsToTeam
(
TeamInfo
team
,
int
avatars
)
{
return
team
.
size
()
+
avatars
<=
getMaxTeamSize
();
return
team
.
size
()
+
avatars
<=
this
.
getMaxTeamSize
();
}
/**
* Returns true if there is space to add to the team.
*/
public
boolean
canAddAvatarToTeam
(
TeamInfo
team
)
{
return
canAddAvatarsToTeam
(
team
,
1
);
return
this
.
canAddAvatarsToTeam
(
team
,
1
);
}
/**
...
...
@@ -209,7 +210,7 @@ public class TeamManager extends BasePlayerDataManager {
if
(
this
.
useTemporarilyTeamIndex
!=
-
1
)
{
return
false
;
}
return
canAddAvatarsToTeam
(
this
.
getCurrentTeamInfo
(),
avatars
);
return
this
.
canAddAvatarsToTeam
(
this
.
getCurrentTeamInfo
(),
avatars
);
}
/**
...
...
@@ -217,7 +218,7 @@ public class TeamManager extends BasePlayerDataManager {
* If the current team is temporary, returns false.
*/
public
boolean
canAddAvatarToCurrentTeam
()
{
return
canAddAvatarsToCurrentTeam
(
1
);
return
this
.
canAddAvatarsToCurrentTeam
(
1
);
}
/**
...
...
@@ -226,7 +227,7 @@ public class TeamManager extends BasePlayerDataManager {
* If some can not be added, returns false and does not add any.
*/
public
boolean
addAvatarsToTeam
(
TeamInfo
team
,
Collection
<
Avatar
>
avatars
)
{
if
(!
canAddAvatarsToTeam
(
team
,
avatars
.
size
()))
{
if
(!
this
.
canAddAvatarsToTeam
(
team
,
avatars
.
size
()))
{
return
false
;
}
...
...
@@ -237,20 +238,20 @@ public class TeamManager extends BasePlayerDataManager {
if
(
this
.
getPlayer
().
isInMultiplayer
())
{
if
(
team
.
equals
(
this
.
getMpTeam
()))
{
// MP team Packet
this
.
updateTeamEntities
(
new
PacketChangeMpTeamAvatarRsp
(
getPlayer
(),
team
));
this
.
updateTeamEntities
(
new
PacketChangeMpTeamAvatarRsp
(
this
.
getPlayer
(),
team
));
}
}
else
{
// SP team update packet
getPlayer
().
sendPacket
(
new
PacketAvatarTeamUpdateNotify
(
getPlayer
()));
this
.
getPlayer
().
sendPacket
(
new
PacketAvatarTeamUpdateNotify
(
this
.
getPlayer
()));
int
teamId
=
this
.
getTeamId
(
team
);
if
(
teamId
!=
-
1
)
{
// This is one of the player's teams
// Update entites
if
(
teamId
==
this
.
getCurrentTeamId
())
{
this
.
updateTeamEntities
(
new
PacketSetUpAvatarTeamRsp
(
getPlayer
(),
teamId
,
team
));
this
.
updateTeamEntities
(
new
PacketSetUpAvatarTeamRsp
(
this
.
getPlayer
(),
teamId
,
team
));
}
else
{
getPlayer
().
sendPacket
(
new
PacketSetUpAvatarTeamRsp
(
getPlayer
(),
teamId
,
team
));
this
.
getPlayer
().
sendPacket
(
new
PacketSetUpAvatarTeamRsp
(
this
.
getPlayer
(),
teamId
,
team
));
}
}
}
...
...
@@ -263,7 +264,7 @@ public class TeamManager extends BasePlayerDataManager {
* Returns true if successful.
*/
public
boolean
addAvatarToTeam
(
TeamInfo
team
,
Avatar
avatar
)
{
return
addAvatarsToTeam
(
team
,
Collections
.
singleton
(
avatar
));
return
this
.
addAvatarsToTeam
(
team
,
Collections
.
singleton
(
avatar
));
}
/**
...
...
@@ -276,7 +277,7 @@ public class TeamManager extends BasePlayerDataManager {
if
(
this
.
useTemporarilyTeamIndex
!=
-
1
)
{
return
false
;
}
return
addAvatarsToTeam
(
this
.
getCurrentTeamInfo
(),
avatars
);
return
this
.
addAvatarsToTeam
(
this
.
getCurrentTeamInfo
(),
avatars
);
}
/**
...
...
@@ -285,7 +286,7 @@ public class TeamManager extends BasePlayerDataManager {
* Returns true if successful.
*/
public
boolean
addAvatarToCurrentTeam
(
Avatar
avatar
)
{
return
addAvatarsToCurrentTeam
(
Collections
.
singleton
(
avatar
));
return
this
.
addAvatarsToCurrentTeam
(
Collections
.
singleton
(
avatar
));
}
private
void
updateTeamResonances
()
{
...
...
@@ -294,7 +295,7 @@ public class TeamManager extends BasePlayerDataManager {
this
.
getTeamResonances
().
clear
();
this
.
getTeamResonancesConfig
().
clear
();
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
for
(
EntityAvatar
entity
:
this
.
getActiveTeam
())
{
AvatarSkillDepotData
skillData
=
entity
.
getAvatar
().
getAvatarData
().
getSkillDepot
();
if
(
skillData
!=
null
)
{
map
.
addTo
(
skillData
.
getElementType
().
getValue
(),
1
);
...
...
@@ -329,7 +330,7 @@ public class TeamManager extends BasePlayerDataManager {
Int2ObjectMap
<
EntityAvatar
>
existingAvatars
=
new
Int2ObjectOpenHashMap
<>();
int
prevSelectedAvatarIndex
=
-
1
;
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
for
(
EntityAvatar
entity
:
this
.
getActiveTeam
())
{
existingAvatars
.
put
(
entity
.
getAvatar
().
getAvatarId
(),
entity
);
}
...
...
@@ -348,7 +349,7 @@ public class TeamManager extends BasePlayerDataManager {
prevSelectedAvatarIndex
=
i
;
}
}
else
{
entity
=
new
EntityAvatar
(
getPlayer
().
getScene
(),
getPlayer
().
getAvatars
().
getAvatarById
(
avatarId
));
entity
=
new
EntityAvatar
(
this
.
getPlayer
().
getScene
(),
this
.
getPlayer
().
getAvatars
().
getAvatarById
(
avatarId
));
}
this
.
getActiveTeam
().
add
(
entity
);
...
...
@@ -356,7 +357,7 @@ public class TeamManager extends BasePlayerDataManager {
// Unload removed entities
for
(
EntityAvatar
entity
:
existingAvatars
.
values
())
{
getPlayer
().
getScene
().
removeEntity
(
entity
);
this
.
getPlayer
().
getScene
().
removeEntity
(
entity
);
entity
.
getAvatar
().
save
();
}
...
...
@@ -368,33 +369,33 @@ public class TeamManager extends BasePlayerDataManager {
this
.
currentCharacterIndex
=
prevSelectedAvatarIndex
;
// Update team resonances
updateTeamResonances
();
this
.
updateTeamResonances
();
// Packets
getPlayer
().
getWorld
().
broadcastPacket
(
new
PacketSceneTeamUpdateNotify
(
getPlayer
()));
this
.
getPlayer
().
getWorld
().
broadcastPacket
(
new
PacketSceneTeamUpdateNotify
(
this
.
getPlayer
()));
// Skill charges packet - Yes, this is official server behavior as of 2.6.0
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
for
(
EntityAvatar
entity
:
this
.
getActiveTeam
())
{
if
(
entity
.
getAvatar
().
getSkillExtraChargeMap
().
size
()
>
0
)
{
getPlayer
().
sendPacket
(
new
PacketAvatarSkillInfoNotify
(
entity
.
getAvatar
()));
this
.
getPlayer
().
sendPacket
(
new
PacketAvatarSkillInfoNotify
(
entity
.
getAvatar
()));
}
}
// Run callback
if
(
responsePacket
!=
null
)
{
getPlayer
().
sendPacket
(
responsePacket
);
this
.
getPlayer
().
sendPacket
(
responsePacket
);
}
// Check if character changed
if
(
currentEntity
!=
getCurrentAvatarEntity
())
{
if
(
currentEntity
!=
this
.
getCurrentAvatarEntity
())
{
// Remove and Add
getPlayer
().
getScene
().
replaceEntity
(
currentEntity
,
getCurrentAvatarEntity
());
this
.
getPlayer
().
getScene
().
replaceEntity
(
currentEntity
,
this
.
getCurrentAvatarEntity
());
}
}
public
synchronized
void
setupAvatarTeam
(
int
teamId
,
List
<
Long
>
list
)
{
// Sanity checks
if
(
list
.
size
()
==
0
||
list
.
size
()
>
getMaxTeamSize
()
||
getPlayer
().
isInMultiplayer
())
{
if
(
list
.
size
()
==
0
||
list
.
size
()
>
this
.
getMaxTeamSize
()
||
this
.
getPlayer
().
isInMultiplayer
())
{
return
;
}
...
...
@@ -407,7 +408,7 @@ public class TeamManager extends BasePlayerDataManager {
// Set team data
LinkedHashSet
<
Avatar
>
newTeam
=
new
LinkedHashSet
<>();
for
(
Long
aLong
:
list
)
{
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
aLong
);
Avatar
avatar
=
this
.
getPlayer
().
getAvatars
().
getAvatarByGuid
(
aLong
);
if
(
avatar
==
null
||
newTeam
.
contains
(
avatar
))
{
// Should never happen
return
;
...
...
@@ -422,7 +423,7 @@ public class TeamManager extends BasePlayerDataManager {
public
void
setupMpTeam
(
List
<
Long
>
list
)
{
// Sanity checks
if
(
list
.
size
()
==
0
||
list
.
size
()
>
getMaxTeamSize
()
||
!
getPlayer
().
isInMultiplayer
())
{
if
(
list
.
size
()
==
0
||
list
.
size
()
>
this
.
getMaxTeamSize
()
||
!
this
.
getPlayer
().
isInMultiplayer
())
{
return
;
}
...
...
@@ -431,7 +432,7 @@ public class TeamManager extends BasePlayerDataManager {
// Set team data
LinkedHashSet
<
Avatar
>
newTeam
=
new
LinkedHashSet
<>();
for
(
Long
aLong
:
list
)
{
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
aLong
);
Avatar
avatar
=
this
.
getPlayer
().
getAvatars
().
getAvatarByGuid
(
aLong
);
if
(
avatar
==
null
||
newTeam
.
contains
(
avatar
))
{
// Should never happen
return
;
...
...
@@ -447,14 +448,14 @@ public class TeamManager extends BasePlayerDataManager {
public
void
setupTemporaryTeam
(
List
<
List
<
Long
>>
guidList
)
{
this
.
temporaryTeam
=
guidList
.
stream
().
map
(
list
->
{
// Sanity checks
if
(
list
.
size
()
==
0
||
list
.
size
()
>
getMaxTeamSize
())
{
if
(
list
.
size
()
==
0
||
list
.
size
()
>
this
.
getMaxTeamSize
())
{
return
null
;
}
// Set team data
LinkedHashSet
<
Avatar
>
newTeam
=
new
LinkedHashSet
<>();
for
(
Long
aLong
:
list
)
{
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
aLong
);
Avatar
avatar
=
this
.
getPlayer
().
getAvatars
().
getAvatarByGuid
(
aLong
);
if
(
avatar
==
null
||
newTeam
.
contains
(
avatar
))
{
// Should never happen
return
null
;
...
...
@@ -474,7 +475,7 @@ public class TeamManager extends BasePlayerDataManager {
public
void
useTemporaryTeam
(
int
index
)
{
this
.
useTemporarilyTeamIndex
=
index
;
updateTeamEntities
(
null
);
this
.
updateTeamEntities
(
null
);
}
public
void
cleanTemporaryTeam
()
{
...
...
@@ -485,11 +486,11 @@ public class TeamManager extends BasePlayerDataManager {
this
.
useTemporarilyTeamIndex
=
-
1
;
this
.
temporaryTeam
=
null
;
updateTeamEntities
(
null
);
this
.
updateTeamEntities
(
null
);
}
public
synchronized
void
setCurrentTeam
(
int
teamId
)
{
//
if
(
getPlayer
().
isInMultiplayer
())
{
if
(
this
.
getPlayer
().
isInMultiplayer
())
{
return
;
}
...
...
@@ -514,7 +515,7 @@ public class TeamManager extends BasePlayerDataManager {
teamInfo
.
setName
(
teamName
);
// Packet
getPlayer
().
sendPacket
(
new
PacketChangeTeamNameRsp
(
teamId
,
teamName
));
this
.
getPlayer
().
sendPacket
(
new
PacketChangeTeamNameRsp
(
teamId
,
teamName
));
}
public
synchronized
void
changeAvatar
(
long
guid
)
{
...
...
@@ -526,10 +527,10 @@ public class TeamManager extends BasePlayerDataManager {
EntityAvatar
newEntity
=
null
;
int
index
=
-
1
;
for
(
int
i
=
0
;
i
<
getActiveTeam
().
size
();
i
++)
{
if
(
guid
==
getActiveTeam
().
get
(
i
).
getAvatar
().
getGuid
())
{
for
(
int
i
=
0
;
i
<
this
.
getActiveTeam
().
size
();
i
++)
{
if
(
guid
==
this
.
getActiveTeam
().
get
(
i
).
getAvatar
().
getGuid
())
{
index
=
i
;
newEntity
=
getActiveTeam
().
get
(
i
);
newEntity
=
this
.
getActiveTeam
().
get
(
i
);
}
}
...
...
@@ -544,8 +545,8 @@ public class TeamManager extends BasePlayerDataManager {
oldEntity
.
setMotionState
(
MotionState
.
MOTION_STATE_STANDBY
);
// Remove and Add
getPlayer
().
getScene
().
replaceEntity
(
oldEntity
,
newEntity
);
getPlayer
().
sendPacket
(
new
PacketChangeAvatarRsp
(
guid
));
this
.
getPlayer
().
getScene
().
replaceEntity
(
oldEntity
,
newEntity
);
this
.
getPlayer
().
sendPacket
(
new
PacketChangeAvatarRsp
(
guid
));
}
public
void
onAvatarDie
(
long
dieGuid
)
{
...
...
@@ -562,7 +563,7 @@ public class TeamManager extends BasePlayerDataManager {
// Died in water. Do not replace
// The official server has skipped this notify and will just respawn the team immediately after the animation.
// TODO: Perhaps find a way to get vanilla experience?
getPlayer
().
sendPacket
(
new
PacketWorldPlayerDieNotify
(
dieType
,
killedBy
));
this
.
getPlayer
().
sendPacket
(
new
PacketWorldPlayerDieNotify
(
dieType
,
killedBy
));
}
else
{
// Replacement avatar
EntityAvatar
replacement
=
null
;
...
...
@@ -579,20 +580,24 @@ public class TeamManager extends BasePlayerDataManager {
if
(
replacement
==
null
)
{
// No more living team members...
getPlayer
().
sendPacket
(
new
PacketWorldPlayerDieNotify
(
dieType
,
killedBy
));
this
.
getPlayer
().
sendPacket
(
new
PacketWorldPlayerDieNotify
(
dieType
,
killedBy
));
// Invoke player team death event.
PlayerTeamDeathEvent
event
=
new
PlayerTeamDeathEvent
(
this
.
getPlayer
(),
this
.
getActiveTeam
().
get
(
this
.
getCurrentCharacterIndex
()));
event
.
call
();
}
else
{
// Set index and spawn replacement member
this
.
setCurrentCharacterIndex
(
replaceIndex
);
getPlayer
().
getScene
().
addEntity
(
replacement
);
this
.
getPlayer
().
getScene
().
addEntity
(
replacement
);
}
}
// Response packet
getPlayer
().
sendPacket
(
new
PacketAvatarDieAnimationEndRsp
(
deadAvatar
.
getId
(),
0
));
this
.
getPlayer
().
sendPacket
(
new
PacketAvatarDieAnimationEndRsp
(
deadAvatar
.
getId
(),
0
));
}
public
boolean
reviveAvatar
(
Avatar
avatar
)
{
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
for
(
EntityAvatar
entity
:
this
.
getActiveTeam
())
{
if
(
entity
.
getAvatar
()
==
avatar
)
{
if
(
entity
.
isAlive
())
{
return
false
;
...
...
@@ -602,8 +607,8 @@ public class TeamManager extends BasePlayerDataManager {
FightProperty
.
FIGHT_PROP_CUR_HP
,
entity
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_MAX_HP
)
*
.
1
f
);
getPlayer
().
sendPacket
(
new
PacketAvatarFightPropUpdateNotify
(
entity
.
getAvatar
(),
FightProperty
.
FIGHT_PROP_CUR_HP
));
getPlayer
().
sendPacket
(
new
PacketAvatarLifeStateChangeNotify
(
entity
.
getAvatar
()));
this
.
getPlayer
().
sendPacket
(
new
PacketAvatarFightPropUpdateNotify
(
entity
.
getAvatar
(),
FightProperty
.
FIGHT_PROP_CUR_HP
));
this
.
getPlayer
().
sendPacket
(
new
PacketAvatarLifeStateChangeNotify
(
entity
.
getAvatar
()));
return
true
;
}
}
...
...
@@ -612,7 +617,7 @@ public class TeamManager extends BasePlayerDataManager {
}
public
boolean
healAvatar
(
Avatar
avatar
,
int
healRate
,
int
healAmount
)
{
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
for
(
EntityAvatar
entity
:
this
.
getActiveTeam
())
{
if
(
entity
.
getAvatar
()
==
avatar
)
{
if
(!
entity
.
isAlive
())
{
return
false
;
...
...
@@ -627,8 +632,8 @@ public class TeamManager extends BasePlayerDataManager {
entity
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_MAX_HP
)
)
);
getPlayer
().
sendPacket
(
new
PacketAvatarFightPropUpdateNotify
(
entity
.
getAvatar
(),
FightProperty
.
FIGHT_PROP_CUR_HP
));
getPlayer
().
sendPacket
(
new
PacketAvatarLifeStateChangeNotify
(
entity
.
getAvatar
()));
this
.
getPlayer
().
sendPacket
(
new
PacketAvatarFightPropUpdateNotify
(
entity
.
getAvatar
(),
FightProperty
.
FIGHT_PROP_CUR_HP
));
this
.
getPlayer
().
sendPacket
(
new
PacketAvatarLifeStateChangeNotify
(
entity
.
getAvatar
()));
return
true
;
}
}
...
...
@@ -646,29 +651,29 @@ public class TeamManager extends BasePlayerDataManager {
player
.
getStaminaManager
().
stopSustainedStaminaHandler
();
// prevent drowning immediately after respawn
// Revive all team members
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
for
(
EntityAvatar
entity
:
this
.
getActiveTeam
())
{
entity
.
setFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
,
entity
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_MAX_HP
)
*
.
4
f
);
getPlayer
().
sendPacket
(
new
PacketAvatarFightPropUpdateNotify
(
entity
.
getAvatar
(),
FightProperty
.
FIGHT_PROP_CUR_HP
));
getPlayer
().
sendPacket
(
new
PacketAvatarLifeStateChangeNotify
(
entity
.
getAvatar
()));
this
.
getPlayer
().
sendPacket
(
new
PacketAvatarFightPropUpdateNotify
(
entity
.
getAvatar
(),
FightProperty
.
FIGHT_PROP_CUR_HP
));
this
.
getPlayer
().
sendPacket
(
new
PacketAvatarLifeStateChangeNotify
(
entity
.
getAvatar
()));
}
// Teleport player
getPlayer
().
sendPacket
(
new
PacketPlayerEnterSceneNotify
(
getPlayer
(),
EnterType
.
ENTER_TYPE_SELF
,
EnterReason
.
Revival
,
3
,
GameConstants
.
START_POSITION
));
this
.
getPlayer
().
sendPacket
(
new
PacketPlayerEnterSceneNotify
(
this
.
getPlayer
(),
EnterType
.
ENTER_TYPE_SELF
,
EnterReason
.
Revival
,
3
,
GameConstants
.
START_POSITION
));
// Set player position
player
.
setSceneId
(
3
);
player
.
getPosition
().
set
(
GameConstants
.
START_POSITION
);
// Packets
getPlayer
().
sendPacket
(
new
BasePacket
(
PacketOpcodes
.
WorldPlayerReviveRsp
));
this
.
getPlayer
().
sendPacket
(
new
BasePacket
(
PacketOpcodes
.
WorldPlayerReviveRsp
));
}
public
void
saveAvatars
()
{
// Save all avatars from active team
for
(
EntityAvatar
entity
:
getActiveTeam
())
{
for
(
EntityAvatar
entity
:
this
.
getActiveTeam
())
{
entity
.
getAvatar
().
save
();
}
}
...
...
src/main/java/emu/grasscutter/game/systems/InventorySystem.java
View file @
d05b3207
...
...
@@ -30,6 +30,7 @@ import emu.grasscutter.game.shop.ShopChestBatchUseTable;
import
emu.grasscutter.game.shop.ShopChestTable
;
import
emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam
;
import
emu.grasscutter.net.proto.MaterialInfoOuterClass.MaterialInfo
;
import
emu.grasscutter.server.event.player.PlayerUseFoodEvent
;
import
emu.grasscutter.server.game.BaseGameSystem
;
import
emu.grasscutter.server.game.GameServer
;
import
emu.grasscutter.server.packet.send.*
;
...
...
@@ -812,38 +813,49 @@ public class InventorySystem extends BaseGameSystem {
int
used
=
0
;
boolean
useSuccess
=
false
;
ItemData
itemData
=
useItem
.
getItemData
();
// Use
switch
(
useItem
.
getI
temData
()
.
getMaterialType
())
{
switch
(
i
temData
.
getMaterialType
())
{
case
MATERIAL_FOOD:
if
(
useItem
.
getI
temData
()
.
getUseTarget
()
==
ItemUseTarget
.
ITEM_USE_TARGET_SPECIFY_DEAD_AVATAR
)
{
if
(
i
temData
.
getUseTarget
()
==
ItemUseTarget
.
ITEM_USE_TARGET_SPECIFY_DEAD_AVATAR
)
{
if
(
target
==
null
)
{
break
;
}
used
=
player
.
getTeamManager
().
reviveAvatar
(
target
)
?
1
:
0
;
// Invoke player use food event.
PlayerUseFoodEvent
event
=
new
PlayerUseFoodEvent
(
player
,
itemData
,
target
.
getAsEntity
());
// Call the event.
event
.
call
();
if
(!
event
.
isCanceled
())
{
used
=
player
.
getTeamManager
().
reviveAvatar
(
target
)
?
1
:
0
;
}
}
else
{
used
=
1
;
}
break
;
case
MATERIAL_NOTICE_ADD_HP:
if
(
useItem
.
getI
temData
()
.
getUseTarget
()
==
ItemUseTarget
.
ITEM_USE_TARGET_SPECIFY_ALIVE_AVATAR
)
{
if
(
i
temData
.
getUseTarget
()
==
ItemUseTarget
.
ITEM_USE_TARGET_SPECIFY_ALIVE_AVATAR
)
{
if
(
target
==
null
)
{
break
;
}
int
[]
SatiationParams
=
useItem
.
getItemData
().
getSatiationParams
();
used
=
player
.
getTeamManager
().
healAvatar
(
target
,
SatiationParams
[
0
],
SatiationParams
[
1
])
?
1
:
0
;
// Invoke player use food event.
PlayerUseFoodEvent
event
=
new
PlayerUseFoodEvent
(
player
,
itemData
,
target
.
getAsEntity
());
// Call the event.
event
.
call
();
if
(!
event
.
isCanceled
())
{
int
[]
SatiationParams
=
itemData
.
getSatiationParams
();
used
=
player
.
getTeamManager
().
healAvatar
(
target
,
SatiationParams
[
0
],
SatiationParams
[
1
])
?
1
:
0
;
}
}
break
;
case
MATERIAL_CONSUME:
// Make sure we have usage data for this material.
if
(
useItem
.
getI
temData
()
.
getItemUse
()
==
null
)
{
if
(
i
temData
.
getItemUse
()
==
null
)
{
break
;
}
ItemUseOp
useOp
=
useItem
.
getI
temData
()
.
getItemUse
().
get
(
0
).
getUseOp
();
ItemUseOp
useOp
=
i
temData
.
getItemUse
().
get
(
0
).
getUseOp
();
// Unlock item based on use operation
useSuccess
=
switch
(
useOp
)
{
case
ITEM_USE_UNLOCK_FORGE
->
player
.
getForgingManager
().
unlockForgingBlueprint
(
useItem
);
...
...
@@ -854,7 +866,7 @@ public class InventorySystem extends BaseGameSystem {
break
;
case
MATERIAL_FURNITURE_FORMULA:
case
MATERIAL_FURNITURE_SUITE_FORMULA:
if
(
useItem
.
getI
temData
()
.
getItemUse
()
==
null
)
{
if
(
i
temData
.
getItemUse
()
==
null
)
{
break
;
}
useSuccess
=
player
.
getFurnitureManager
().
unlockFurnitureOrSuite
(
useItem
);
...
...
@@ -862,7 +874,7 @@ public class InventorySystem extends BaseGameSystem {
break
;
case
MATERIAL_CONSUME_BATCH_USE:
// Make sure we have usage data for this material.
if
(
useItem
.
getI
temData
()
.
getItemUse
()
==
null
)
{
if
(
i
temData
.
getItemUse
()
==
null
)
{
break
;
}
...
...
@@ -889,11 +901,11 @@ public class InventorySystem extends BaseGameSystem {
}
for
(
ItemParamData
itemParamData
:
shopChestTable
.
getContainsItem
())
{
ItemData
itemData
=
GameData
.
getItemDataMap
().
get
(
itemParamData
.
getId
());
if
(
itemData
==
null
)
{
ItemData
containedItem
=
GameData
.
getItemDataMap
().
get
(
itemParamData
.
getId
());
if
(
containedItem
==
null
)
{
continue
;
}
rewardItemList
.
add
(
new
GameItem
(
itemData
,
itemParamData
.
getCount
()));
rewardItemList
.
add
(
new
GameItem
(
containedItem
,
itemParamData
.
getCount
()));
}
if
(!
rewardItemList
.
isEmpty
())
{
...
...
@@ -919,12 +931,12 @@ public class InventorySystem extends BaseGameSystem {
}
int
optionItemId
=
shopChestBatchUseTable
.
getOptionItem
().
get
(
optionId
-
1
);
ItemData
itemData
=
GameData
.
getItemDataMap
().
get
(
optionItemId
);
if
(
itemData
==
null
)
{
ItemData
optionItem
=
GameData
.
getItemDataMap
().
get
(
optionItemId
);
if
(
optionItem
==
null
)
{
break
;
}
player
.
getInventory
().
addItem
(
new
GameItem
(
itemData
,
count
),
ActionReason
.
Shop
);
player
.
getInventory
().
addItem
(
new
GameItem
(
optionItem
,
count
),
ActionReason
.
Shop
);
used
=
count
;
break
;
...
...
@@ -944,23 +956,23 @@ public class InventorySystem extends BaseGameSystem {
// we return the item to make UseItemRsp a success.
if
(
used
>
0
)
{
// Handle use params, mainly server buffs
for
(
ItemUseData
useData
:
useItem
.
getI
temData
()
.
getItemUse
())
{
for
(
ItemUseData
useData
:
i
temData
.
getItemUse
())
{
switch
(
useData
.
getUseOp
())
{
case
ITEM_USE_ADD_SERVER_BUFF
->
{
int
buffId
=
Integer
.
parseInt
(
useData
.
getUseParam
()[
0
]);
float
time
=
Float
.
parseFloat
(
useData
.
getUseParam
()[
1
]);
player
.
getBuffManager
().
addBuff
(
buffId
,
time
);
}
default
->
{}
}
}
// Remove item from inventory since we used it
player
.
getInventory
().
removeItem
(
useItem
,
used
);
return
useItem
;
}
if
(
useSuccess
)
{
return
useItem
;
}
...
...
src/main/java/emu/grasscutter/game/world/World.java
View file @
d05b3207
...
...
@@ -17,6 +17,8 @@ import emu.grasscutter.data.excels.SceneData;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType
;
import
emu.grasscutter.scripts.data.SceneConfig
;
import
emu.grasscutter.server.event.player.PlayerTeleportEvent
;
import
emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType
;
import
emu.grasscutter.server.game.GameServer
;
import
emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify
;
import
emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify
;
...
...
@@ -53,7 +55,7 @@ public class World implements Iterable<Player> {
this
.
players
=
Collections
.
synchronizedList
(
new
ArrayList
<>());
this
.
scenes
=
Int2ObjectMaps
.
synchronize
(
new
Int2ObjectOpenHashMap
<>());
this
.
levelEntityId
=
getNextEntityId
(
EntityIdType
.
MPLEVEL
);
this
.
levelEntityId
=
this
.
getNextEntityId
(
EntityIdType
.
MPLEVEL
);
this
.
worldLevel
=
player
.
getWorldLevel
();
this
.
isMultiplayer
=
isMultiplayer
;
...
...
@@ -101,7 +103,7 @@ public class World implements Iterable<Player> {
public
Scene
getSceneById
(
int
sceneId
)
{
// Get scene normally
Scene
scene
=
getScenes
().
get
(
sceneId
);
Scene
scene
=
this
.
getScenes
().
get
(
sceneId
);
if
(
scene
!=
null
)
{
return
scene
;
}
...
...
@@ -118,7 +120,7 @@ public class World implements Iterable<Player> {
}
public
int
getPlayerCount
()
{
return
getPlayers
().
size
();
return
this
.
getPlayers
().
size
();
}
public
boolean
isMultiplayer
()
{
...
...
@@ -131,7 +133,7 @@ public class World implements Iterable<Player> {
public
synchronized
void
addPlayer
(
Player
player
)
{
// Check if player already in
if
(
getPlayers
().
contains
(
player
))
{
if
(
this
.
getPlayers
().
contains
(
player
))
{
return
;
}
...
...
@@ -142,11 +144,11 @@ public class World implements Iterable<Player> {
// Register
player
.
setWorld
(
this
);
getPlayers
().
add
(
player
);
this
.
getPlayers
().
add
(
player
);
// Set player variables
player
.
setPeerId
(
this
.
getNextPeerId
());
player
.
getTeamManager
().
setEntityId
(
getNextEntityId
(
EntityIdType
.
TEAM
));
player
.
getTeamManager
().
setEntityId
(
this
.
getNextEntityId
(
EntityIdType
.
TEAM
));
// Copy main team to multiplayer team
if
(
this
.
isMultiplayer
())
{
...
...
@@ -169,12 +171,12 @@ public class World implements Iterable<Player> {
player
.
sendPacket
(
new
PacketDelTeamEntityNotify
(
player
.
getSceneId
(),
getPlayers
().
stream
().
map
(
p
->
p
.
getTeamManager
().
getEntityId
()).
collect
(
Collectors
.
toList
())
this
.
getPlayers
().
stream
().
map
(
p
->
p
.
getTeamManager
().
getEntityId
()).
collect
(
Collectors
.
toList
())
)
);
// Deregister
getPlayers
().
remove
(
player
);
this
.
getPlayers
().
remove
(
player
);
player
.
setWorld
(
null
);
// Remove from scene
...
...
@@ -187,7 +189,7 @@ public class World implements Iterable<Player> {
}
// Disband world if host leaves
if
(
getHost
()
==
player
)
{
if
(
this
.
getHost
()
==
player
)
{
List
<
Player
>
kicked
=
new
ArrayList
<>(
this
.
getPlayers
());
for
(
Player
victim
:
kicked
)
{
World
world
=
new
World
(
victim
);
...
...
@@ -207,14 +209,28 @@ public class World implements Iterable<Player> {
}
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
Position
pos
)
{
return
transferPlayerToScene
(
player
,
sceneId
,
null
,
pos
);
return
this
.
transferPlayerToScene
(
player
,
sceneId
,
TeleportType
.
INTERNAL
,
null
,
pos
);
}
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
TeleportType
teleportType
,
Position
pos
)
{
return
this
.
transferPlayerToScene
(
player
,
sceneId
,
teleportType
,
null
,
pos
);
}
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
DungeonData
data
)
{
return
transferPlayerToScene
(
player
,
sceneId
,
data
,
null
);
return
this
.
transferPlayerToScene
(
player
,
sceneId
,
TeleportType
.
DUNGEON
,
data
,
null
);
}
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
DungeonData
dungeonData
,
Position
pos
)
{
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
TeleportType
teleportType
,
DungeonData
dungeonData
,
Position
teleportTo
)
{
// Call player teleport event.
PlayerTeleportEvent
event
=
new
PlayerTeleportEvent
(
player
,
teleportType
,
player
.
getPosition
(),
teleportTo
);
// Call event & check if it was canceled.
event
.
call
();
if
(
event
.
isCanceled
())
{
return
false
;
// Teleport was canceled.
}
// Set the destination.
teleportTo
=
event
.
getDestination
();
if
(
GameData
.
getSceneDataMap
().
get
(
sceneId
)
==
null
)
{
return
false
;
}
...
...
@@ -224,7 +240,7 @@ public class World implements Iterable<Player> {
if
(
player
.
getScene
()
!=
null
)
{
oldScene
=
player
.
getScene
();
// Dont deregister scenes if the player is going to tp back into them
// Don
'
t deregister scenes if the player is going to tp back into them
if
(
oldScene
.
getId
()
==
sceneId
)
{
oldScene
.
setDontDestroyWhenEmpty
(
true
);
}
...
...
@@ -238,9 +254,9 @@ public class World implements Iterable<Player> {
// Dungeon
SceneConfig
config
=
newScene
.
getScriptManager
().
getConfig
();
if
(
pos
==
null
&&
config
!=
null
)
{
if
(
teleportTo
==
null
&&
config
!=
null
)
{
if
(
config
.
born_pos
!=
null
)
{
pos
=
newScene
.
getScriptManager
().
getConfig
().
born_pos
;
teleportTo
=
newScene
.
getScriptManager
().
getConfig
().
born_pos
;
}
if
(
config
.
born_rot
!=
null
)
{
player
.
getRotation
().
set
(
config
.
born_rot
);
...
...
@@ -248,11 +264,11 @@ public class World implements Iterable<Player> {
}
// Set player position
if
(
pos
==
null
)
{
pos
=
player
.
getPosition
();
if
(
teleportTo
==
null
)
{
teleportTo
=
player
.
getPosition
();
}
player
.
getPosition
().
set
(
pos
);
player
.
getPosition
().
set
(
teleportTo
);
if
(
oldScene
!=
null
)
{
newScene
.
setPrevScene
(
oldScene
.
getId
());
...
...
@@ -276,12 +292,12 @@ public class World implements Iterable<Player> {
}
// Teleport packet
player
.
sendPacket
(
new
PacketPlayerEnterSceneNotify
(
player
,
enterType
,
enterReason
,
sceneId
,
pos
));
player
.
sendPacket
(
new
PacketPlayerEnterSceneNotify
(
player
,
enterType
,
enterReason
,
sceneId
,
teleportTo
));
return
true
;
}
private
void
updatePlayerInfos
(
Player
paramPlayer
)
{
for
(
Player
player
:
getPlayers
())
{
for
(
Player
player
:
this
.
getPlayers
())
{
// Dont send packets if player is logging in and filter out joining player
if
(!
player
.
hasSentLoginPackets
()
||
player
==
paramPlayer
)
{
continue
;
...
...
@@ -292,7 +308,7 @@ public class World implements Iterable<Player> {
player
.
getTeamManager
().
getMpTeam
().
copyFrom
(
player
.
getTeamManager
().
getMpTeam
(),
player
.
getTeamManager
().
getMaxTeamSize
());
player
.
getTeamManager
().
updateTeamEntities
(
null
);
}
// Dont send packets if player is loading into the scene
if
(
player
.
getSceneLoadState
().
getValue
()
<
SceneLoadState
.
INIT
.
getValue
()
)
{
// World player info packets
...
...
@@ -326,6 +342,6 @@ public class World implements Iterable<Player> {
@Override
public
Iterator
<
Player
>
iterator
()
{
return
getPlayers
().
iterator
();
return
this
.
getPlayers
().
iterator
();
}
}
src/main/java/emu/grasscutter/server/event/entity/EntityDeathEvent.java
0 → 100644
View file @
d05b3207
package
emu.grasscutter.server.event.entity
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.server.event.types.EntityEvent
;
import
emu.grasscutter.utils.Location
;
import
lombok.Getter
;
import
javax.annotation.Nullable
;
public
final
class
EntityDeathEvent
extends
EntityEvent
{
@Getter
private
final
Location
deathLocation
;
@Getter
@Nullable
private
final
GameEntity
killer
;
public
EntityDeathEvent
(
GameEntity
entity
,
int
killerId
)
{
super
(
entity
);
this
.
deathLocation
=
new
Location
(
entity
.
getScene
(),
entity
.
getPosition
());
this
.
killer
=
entity
.
getScene
().
getEntityById
(
killerId
);
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/event/game/CommandResponseEvent.java
deleted
100644 → 0
View file @
9a104f6f
package
emu.grasscutter.server.event.game
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.event.types.ServerEvent
;
/**
* @deprecated Will be removed in 1.2.3-dev or 1.3.0.
*/
@Deprecated
(
since
=
"1.2.2-dev"
,
forRemoval
=
true
)
public
final
class
CommandResponseEvent
extends
ServerEvent
{
private
String
message
;
private
Player
player
;
public
CommandResponseEvent
(
Type
type
,
Player
player
,
String
message
)
{
super
(
type
);
this
.
message
=
message
;
this
.
player
=
player
;
}
public
String
getMessage
()
{
return
message
;
}
public
Player
getPlayer
()
{
return
player
;
}
}
src/main/java/emu/grasscutter/server/event/player/PlayerMoveEvent.java
0 → 100644
View file @
d05b3207
package
emu.grasscutter.server.event.player
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.event.types.PlayerEvent
;
import
emu.grasscutter.utils.Position
;
/**
* TODO: Allow plugins to change the position of the player.
*/
public
final
class
PlayerMoveEvent
extends
PlayerEvent
{
private
final
MoveType
type
;
private
final
Position
from
;
private
final
Position
to
;
public
PlayerMoveEvent
(
Player
player
,
MoveType
type
,
Position
from
,
Position
to
)
{
super
(
player
);
this
.
type
=
type
;
this
.
from
=
from
;
this
.
to
=
to
;
}
public
MoveType
getMoveType
()
{
return
this
.
type
;
}
public
Position
getSource
()
{
return
this
.
from
;
}
public
Position
getDestination
()
{
return
this
.
to
;
}
public
enum
MoveType
{
/**
* The player has sent a combat invocation to move.
*/
PLAYER
,
/**
* The server has requested that the player moves.
*/
SERVER
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/event/player/PlayerTeamDeathEvent.java
0 → 100644
View file @
d05b3207
package
emu.grasscutter.server.event.player
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.event.types.PlayerEvent
;
import
lombok.Getter
;
/**
* This event is invoked when the ENTIRE TEAM dies.
* To listen for one player death, use {@link emu.grasscutter.server.event.entity.EntityDeathEvent}.
*/
public
final
class
PlayerTeamDeathEvent
extends
PlayerEvent
{
@Getter
private
final
EntityAvatar
selectedAvatar
;
public
PlayerTeamDeathEvent
(
Player
player
,
EntityAvatar
selectedAvatar
)
{
super
(
player
);
this
.
selectedAvatar
=
selectedAvatar
;
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/event/player/PlayerTeleportEvent.java
0 → 100644
View file @
d05b3207
package
emu.grasscutter.server.event.player
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.event.Cancellable
;
import
emu.grasscutter.server.event.types.PlayerEvent
;
import
emu.grasscutter.utils.Position
;
public
final
class
PlayerTeleportEvent
extends
PlayerEvent
implements
Cancellable
{
private
final
TeleportType
type
;
private
final
Position
from
;
private
Position
to
;
public
PlayerTeleportEvent
(
Player
player
,
TeleportType
type
,
Position
from
,
Position
to
)
{
super
(
player
);
this
.
type
=
type
;
this
.
from
=
from
;
this
.
to
=
to
;
}
public
TeleportType
getTeleportType
()
{
return
this
.
type
;
}
public
Position
getSource
()
{
return
this
.
from
;
}
public
Position
getDestination
()
{
return
this
.
to
;
}
public
void
setDestination
(
Position
to
)
{
this
.
to
=
to
;
}
public
enum
TeleportType
{
/**
* There is no specified reason to teleport.
*/
INTERNAL
,
/**
* The player has asked to teleport to a waypoint.
*/
WAYPOINT
,
/**
* The player has asked to teleport using the map.
*/
MAP
,
/**
* The player has asked to teleport into a dungeon.
*/
DUNGEON
,
/**
* The player has asked to teleport using the command.
*/
COMMAND
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/event/player/PlayerUseFoodEvent.java
0 → 100644
View file @
d05b3207
package
emu.grasscutter.server.event.player
;
import
emu.grasscutter.data.excels.ItemData
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.event.Cancellable
;
import
emu.grasscutter.server.event.types.PlayerEvent
;
import
lombok.Getter
;
import
lombok.Setter
;
/**
* This event is invoked when the player uses food on an avatar.
*/
public
final
class
PlayerUseFoodEvent
extends
PlayerEvent
implements
Cancellable
{
@Getter
@Setter
private
ItemData
foodUsed
;
@Getter
private
final
EntityAvatar
selectedAvatar
;
public
PlayerUseFoodEvent
(
Player
player
,
ItemData
foodUsed
,
EntityAvatar
selectedAvatar
)
{
super
(
player
);
this
.
foodUsed
=
foodUsed
;
this
.
selectedAvatar
=
selectedAvatar
;
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/packet/recv/HandlerCombatInvocationsNotify.java
View file @
d05b3207
...
...
@@ -60,8 +60,7 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
new
Position
(
motionInfo
.
getRot
()),
motionState
);
event
.
call
();
entity
.
getPosition
().
set
(
motionInfo
.
getPos
());
entity
.
getRotation
().
set
(
motionInfo
.
getRot
());
entity
.
move
(
event
.
getPosition
(),
event
.
getRotation
());
entity
.
setLastMoveSceneTimeMs
(
moveInfo
.
getSceneTime
());
entity
.
setLastMoveReliableSeq
(
moveInfo
.
getReliableSeq
());
entity
.
setMotionState
(
motionState
);
...
...
Prev
1
2
Next
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