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
Expand all
Show 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
;
...
...
@@ -108,12 +109,16 @@ public class EntityAvatar extends GameEntity {
@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
)
{
super
.
onDeath
(
killerId
);
// Invoke super class's onDeath() method.
this
.
killedType
=
dieType
;
this
.
killedBy
=
killerId
;
clearEnergy
(
ChangeEnergyReason
.
CHANGE_ENERGY_REASON_NONE
);
...
...
@@ -314,4 +319,21 @@ public class EntityAvatar extends GameEntity {
//
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
...
...
@@ -13,6 +13,6 @@ public abstract class EntityBaseGadget extends GameEntity {
@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
;
...
...
@@ -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
...
...
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
;
...
...
@@ -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
This diff is collapsed.
Click to expand it.
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,37 +813,48 @@ 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
;
}
// 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
();
// 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
)
{
...
...
@@ -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,7 +956,7 @@ 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
]);
...
...
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
,
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.
}
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
DungeonData
dungeonData
,
Position
pos
)
{
// 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
;
...
...
@@ -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