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
7fdf7498
Commit
7fdf7498
authored
Apr 29, 2022
by
omg-xtao
Committed by
GitHub
Apr 29, 2022
Browse files
Merge branch 'development' into tp
parents
eaed1aa0
4c487e22
Changes
67
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/entity/EntityMonster.java
View file @
7fdf7498
...
@@ -4,6 +4,7 @@ import emu.grasscutter.data.GameData;
...
@@ -4,6 +4,7 @@ import emu.grasscutter.data.GameData;
import
emu.grasscutter.data.common.PropGrowCurve
;
import
emu.grasscutter.data.common.PropGrowCurve
;
import
emu.grasscutter.data.def.MonsterCurveData
;
import
emu.grasscutter.data.def.MonsterCurveData
;
import
emu.grasscutter.data.def.MonsterData
;
import
emu.grasscutter.data.def.MonsterData
;
import
emu.grasscutter.game.dungeons.DungeonChallenge
;
import
emu.grasscutter.game.props.EntityIdType
;
import
emu.grasscutter.game.props.EntityIdType
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.props.PlayerProperty
;
...
@@ -22,6 +23,7 @@ import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
...
@@ -22,6 +23,7 @@ import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
import
emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo
;
import
emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo
;
import
emu.grasscutter.net.proto.SceneMonsterInfoOuterClass.SceneMonsterInfo
;
import
emu.grasscutter.net.proto.SceneMonsterInfoOuterClass.SceneMonsterInfo
;
import
emu.grasscutter.net.proto.SceneWeaponInfoOuterClass.SceneWeaponInfo
;
import
emu.grasscutter.net.proto.SceneWeaponInfoOuterClass.SceneWeaponInfo
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.utils.Position
;
import
emu.grasscutter.utils.Position
;
import
emu.grasscutter.utils.ProtoHelper
;
import
emu.grasscutter.utils.ProtoHelper
;
import
it.unimi.dsi.fastutil.ints.Int2FloatMap
;
import
it.unimi.dsi.fastutil.ints.Int2FloatMap
;
...
@@ -36,9 +38,6 @@ public class EntityMonster extends GameEntity {
...
@@ -36,9 +38,6 @@ public class EntityMonster extends GameEntity {
private
final
Position
bornPos
;
private
final
Position
bornPos
;
private
final
int
level
;
private
final
int
level
;
private
int
weaponEntityId
;
private
int
weaponEntityId
;
private
int
groupId
;
private
int
configId
;
private
int
poseId
;
private
int
poseId
;
public
EntityMonster
(
Scene
scene
,
MonsterData
monsterData
,
Position
pos
,
int
level
)
{
public
EntityMonster
(
Scene
scene
,
MonsterData
monsterData
,
Position
pos
,
int
level
)
{
...
@@ -104,22 +103,6 @@ public class EntityMonster extends GameEntity {
...
@@ -104,22 +103,6 @@ public class EntityMonster extends GameEntity {
return
this
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
)
>
0
f
;
return
this
.
getFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
)
>
0
f
;
}
}
public
int
getGroupId
()
{
return
groupId
;
}
public
void
setGroupId
(
int
groupId
)
{
this
.
groupId
=
groupId
;
}
public
int
getConfigId
()
{
return
configId
;
}
public
void
setConfigId
(
int
configId
)
{
this
.
configId
=
configId
;
}
public
int
getPoseId
()
{
public
int
getPoseId
()
{
return
poseId
;
return
poseId
;
}
}
...
@@ -133,6 +116,12 @@ public class EntityMonster extends GameEntity {
...
@@ -133,6 +116,12 @@ public class EntityMonster extends GameEntity {
if
(
this
.
getSpawnEntry
()
!=
null
)
{
if
(
this
.
getSpawnEntry
()
!=
null
)
{
this
.
getScene
().
getDeadSpawnedEntities
().
add
(
getSpawnEntry
());
this
.
getScene
().
getDeadSpawnedEntities
().
add
(
getSpawnEntry
());
}
}
if
(
getScene
().
getScriptManager
().
isInit
()
&&
this
.
getGroupId
()
>
0
)
{
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_ANY_MONSTER_DIE
,
null
);
}
if
(
getScene
().
getChallenge
()
!=
null
&&
getScene
().
getChallenge
().
getGroup
().
id
==
this
.
getGroupId
())
{
getScene
().
getChallenge
().
onMonsterDie
(
this
);
}
}
}
public
void
recalcStats
()
{
public
void
recalcStats
()
{
...
...
src/main/java/emu/grasscutter/game/entity/EntityVehicle.java
View file @
7fdf7498
...
@@ -25,7 +25,7 @@ import emu.grasscutter.utils.ProtoHelper;
...
@@ -25,7 +25,7 @@ import emu.grasscutter.utils.ProtoHelper;
import
it.unimi.dsi.fastutil.ints.Int2FloatMap
;
import
it.unimi.dsi.fastutil.ints.Int2FloatMap
;
import
it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap
;
import
it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap
;
public
class
EntityVehicle
extends
EntityGadget
{
public
class
EntityVehicle
extends
Entity
Base
Gadget
{
private
final
Player
owner
;
private
final
Player
owner
;
private
final
Int2FloatOpenHashMap
fightProp
;
private
final
Int2FloatOpenHashMap
fightProp
;
...
...
src/main/java/emu/grasscutter/game/entity/GameEntity.java
View file @
7fdf7498
...
@@ -17,6 +17,10 @@ public abstract class GameEntity {
...
@@ -17,6 +17,10 @@ public abstract class GameEntity {
private
final
Scene
scene
;
private
final
Scene
scene
;
private
SpawnDataEntry
spawnEntry
;
private
SpawnDataEntry
spawnEntry
;
private
int
blockId
;
private
int
configId
;
private
int
groupId
;
private
MotionState
moveState
;
private
MotionState
moveState
;
private
int
lastMoveSceneTimeMs
;
private
int
lastMoveSceneTimeMs
;
private
int
lastMoveReliableSeq
;
private
int
lastMoveReliableSeq
;
...
@@ -96,6 +100,30 @@ public abstract class GameEntity {
...
@@ -96,6 +100,30 @@ public abstract class GameEntity {
return
getFightProperties
().
getOrDefault
(
prop
.
getId
(),
0
f
);
return
getFightProperties
().
getOrDefault
(
prop
.
getId
(),
0
f
);
}
}
public
int
getBlockId
()
{
return
blockId
;
}
public
void
setBlockId
(
int
blockId
)
{
this
.
blockId
=
blockId
;
}
public
int
getConfigId
()
{
return
configId
;
}
public
void
setConfigId
(
int
configId
)
{
this
.
configId
=
configId
;
}
public
int
getGroupId
()
{
return
groupId
;
}
public
void
setGroupId
(
int
groupId
)
{
this
.
groupId
=
groupId
;
}
protected
MotionInfo
getMotionInfo
()
{
protected
MotionInfo
getMotionInfo
()
{
MotionInfo
proto
=
MotionInfo
.
newBuilder
()
MotionInfo
proto
=
MotionInfo
.
newBuilder
()
.
setPos
(
getPosition
().
toProto
())
.
setPos
(
getPosition
().
toProto
())
...
...
src/main/java/emu/grasscutter/game/player/TeamManager.java
View file @
7fdf7498
...
@@ -15,7 +15,7 @@ import emu.grasscutter.Grasscutter;
...
@@ -15,7 +15,7 @@ import emu.grasscutter.Grasscutter;
import
emu.grasscutter.data.def.AvatarSkillDepotData
;
import
emu.grasscutter.data.def.AvatarSkillDepotData
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.Entity
Base
Gadget
;
import
emu.grasscutter.game.props.ElementType
;
import
emu.grasscutter.game.props.ElementType
;
import
emu.grasscutter.game.props.EnterReason
;
import
emu.grasscutter.game.props.EnterReason
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.FightProperty
;
...
@@ -54,7 +54,7 @@ public class TeamManager {
...
@@ -54,7 +54,7 @@ public class TeamManager {
@Transient
private
TeamInfo
mpTeam
;
@Transient
private
TeamInfo
mpTeam
;
@Transient
private
int
entityId
;
@Transient
private
int
entityId
;
@Transient
private
final
List
<
EntityAvatar
>
avatars
;
@Transient
private
final
List
<
EntityAvatar
>
avatars
;
@Transient
private
final
Set
<
EntityGadget
>
gadgets
;
@Transient
private
final
Set
<
Entity
Base
Gadget
>
gadgets
;
@Transient
private
final
IntSet
teamResonances
;
@Transient
private
final
IntSet
teamResonances
;
@Transient
private
final
IntSet
teamResonancesConfig
;
@Transient
private
final
IntSet
teamResonancesConfig
;
...
@@ -141,7 +141,7 @@ public class TeamManager {
...
@@ -141,7 +141,7 @@ public class TeamManager {
this
.
entityId
=
entityId
;
this
.
entityId
=
entityId
;
}
}
public
Set
<
EntityGadget
>
getGadgets
()
{
public
Set
<
Entity
Base
Gadget
>
getGadgets
()
{
return
gadgets
;
return
gadgets
;
}
}
...
...
src/main/java/emu/grasscutter/game/props/EntityType.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.game.props
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.stream.Stream
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
public
enum
EntityType
{
None
(
0
),
Avatar
(
1
),
Monster
(
2
),
Bullet
(
3
),
AttackPhyisicalUnit
(
4
),
AOE
(
5
),
Camera
(
6
),
EnviroArea
(
7
),
Equip
(
8
),
MonsterEquip
(
9
),
Grass
(
10
),
Level
(
11
),
NPC
(
12
),
TransPointFirst
(
13
),
TransPointFirstGadget
(
14
),
TransPointSecond
(
15
),
TransPointSecondGadget
(
16
),
DropItem
(
17
),
Field
(
18
),
Gadget
(
19
),
Water
(
20
),
GatherPoint
(
21
),
GatherObject
(
22
),
AirflowField
(
23
),
SpeedupField
(
24
),
Gear
(
25
),
Chest
(
26
),
EnergyBall
(
27
),
ElemCrystal
(
28
),
Timeline
(
29
),
Worktop
(
30
),
Team
(
31
),
Platform
(
32
),
AmberWind
(
33
),
EnvAnimal
(
34
),
SealGadget
(
35
),
Tree
(
36
),
Bush
(
37
),
QuestGadget
(
38
),
Lightning
(
39
),
RewardPoint
(
40
),
RewardStatue
(
41
),
MPLevel
(
42
),
WindSeed
(
43
),
MpPlayRewardPoint
(
44
),
ViewPoint
(
45
),
RemoteAvatar
(
46
),
GeneralRewardPoint
(
47
),
PlayTeam
(
48
),
OfferingGadget
(
49
),
EyePoint
(
50
),
MiracleRing
(
51
),
Foundation
(
52
),
WidgetGadget
(
53
),
PlaceHolder
(
99
);
private
final
int
value
;
private
static
final
Int2ObjectMap
<
EntityType
>
map
=
new
Int2ObjectOpenHashMap
<>();
private
static
final
Map
<
String
,
EntityType
>
stringMap
=
new
HashMap
<>();
static
{
Stream
.
of
(
values
()).
forEach
(
e
->
{
map
.
put
(
e
.
getValue
(),
e
);
stringMap
.
put
(
e
.
name
(),
e
);
});
}
private
EntityType
(
int
value
)
{
this
.
value
=
value
;
}
public
int
getValue
()
{
return
value
;
}
public
static
EntityType
getTypeByValue
(
int
value
)
{
return
map
.
getOrDefault
(
value
,
None
);
}
public
static
EntityType
getTypeByName
(
String
name
)
{
return
stringMap
.
getOrDefault
(
name
,
None
);
}
}
src/main/java/emu/grasscutter/game/world/Scene.java
View file @
7fdf7498
...
@@ -3,9 +3,11 @@ package emu.grasscutter.game.world;
...
@@ -3,9 +3,11 @@ package emu.grasscutter.game.world;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.GameDepot
;
import
emu.grasscutter.data.GameDepot
;
import
emu.grasscutter.data.def.DungeonData
;
import
emu.grasscutter.data.def.MonsterData
;
import
emu.grasscutter.data.def.MonsterData
;
import
emu.grasscutter.data.def.SceneData
;
import
emu.grasscutter.data.def.SceneData
;
import
emu.grasscutter.data.def.WorldLevelData
;
import
emu.grasscutter.data.def.WorldLevelData
;
import
emu.grasscutter.game.dungeons.DungeonChallenge
;
import
emu.grasscutter.game.entity.*
;
import
emu.grasscutter.game.entity.*
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.player.TeamInfo
;
import
emu.grasscutter.game.player.TeamInfo
;
...
@@ -17,6 +19,13 @@ import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
...
@@ -17,6 +19,13 @@ import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult
;
import
emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
import
emu.grasscutter.scripts.SceneScriptManager
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.data.SceneBlock
;
import
emu.grasscutter.scripts.data.SceneGadget
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify
;
import
emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify
;
...
@@ -36,12 +45,19 @@ public class Scene {
...
@@ -36,12 +45,19 @@ public class Scene {
private
final
Set
<
SpawnDataEntry
>
spawnedEntities
;
private
final
Set
<
SpawnDataEntry
>
spawnedEntities
;
private
final
Set
<
SpawnDataEntry
>
deadSpawnedEntities
;
private
final
Set
<
SpawnDataEntry
>
deadSpawnedEntities
;
private
final
Set
<
SceneBlock
>
loadedBlocks
;
private
boolean
dontDestroyWhenEmpty
;
private
boolean
dontDestroyWhenEmpty
;
private
int
time
;
private
int
time
;
private
ClimateType
climate
;
private
ClimateType
climate
;
private
int
weather
;
private
int
weather
;
private
SceneScriptManager
scriptManager
;
private
DungeonChallenge
challenge
;
private
DungeonData
dungeonData
;
private
int
prevScene
;
// Id of the previous scene
private
int
prevScenePoint
;
public
Scene
(
World
world
,
SceneData
sceneData
)
{
public
Scene
(
World
world
,
SceneData
sceneData
)
{
this
.
world
=
world
;
this
.
world
=
world
;
this
.
sceneData
=
sceneData
;
this
.
sceneData
=
sceneData
;
...
@@ -50,9 +66,12 @@ public class Scene {
...
@@ -50,9 +66,12 @@ public class Scene {
this
.
time
=
8
*
60
;
this
.
time
=
8
*
60
;
this
.
climate
=
ClimateType
.
CLIMATE_SUNNY
;
this
.
climate
=
ClimateType
.
CLIMATE_SUNNY
;
this
.
prevScene
=
3
;
this
.
spawnedEntities
=
new
HashSet
<>();
this
.
spawnedEntities
=
new
HashSet
<>();
this
.
deadSpawnedEntities
=
new
HashSet
<>();
this
.
deadSpawnedEntities
=
new
HashSet
<>();
this
.
loadedBlocks
=
new
HashSet
<>();
this
.
scriptManager
=
new
SceneScriptManager
(
this
);
}
}
public
int
getId
()
{
public
int
getId
()
{
...
@@ -111,6 +130,22 @@ public class Scene {
...
@@ -111,6 +130,22 @@ public class Scene {
this
.
weather
=
weather
;
this
.
weather
=
weather
;
}
}
public
int
getPrevScene
()
{
return
prevScene
;
}
public
void
setPrevScene
(
int
prevScene
)
{
this
.
prevScene
=
prevScene
;
}
public
int
getPrevScenePoint
()
{
return
prevScenePoint
;
}
public
void
setPrevScenePoint
(
int
prevPoint
)
{
this
.
prevScenePoint
=
prevPoint
;
}
public
boolean
dontDestroyWhenEmpty
()
{
public
boolean
dontDestroyWhenEmpty
()
{
return
dontDestroyWhenEmpty
;
return
dontDestroyWhenEmpty
;
}
}
...
@@ -119,6 +154,10 @@ public class Scene {
...
@@ -119,6 +154,10 @@ public class Scene {
this
.
dontDestroyWhenEmpty
=
dontDestroyWhenEmpty
;
this
.
dontDestroyWhenEmpty
=
dontDestroyWhenEmpty
;
}
}
public
Set
<
SceneBlock
>
getLoadedBlocks
()
{
return
loadedBlocks
;
}
public
Set
<
SpawnDataEntry
>
getSpawnedEntities
()
{
public
Set
<
SpawnDataEntry
>
getSpawnedEntities
()
{
return
spawnedEntities
;
return
spawnedEntities
;
}
}
...
@@ -127,6 +166,29 @@ public class Scene {
...
@@ -127,6 +166,29 @@ public class Scene {
return
deadSpawnedEntities
;
return
deadSpawnedEntities
;
}
}
public
SceneScriptManager
getScriptManager
()
{
return
scriptManager
;
}
public
DungeonData
getDungeonData
()
{
return
dungeonData
;
}
public
void
setDungeonData
(
DungeonData
dungeonData
)
{
if
(
this
.
dungeonData
!=
null
||
this
.
getSceneType
()
!=
SceneType
.
SCENE_DUNGEON
||
dungeonData
.
getSceneId
()
!=
this
.
getId
())
{
return
;
}
this
.
dungeonData
=
dungeonData
;
}
public
DungeonChallenge
getChallenge
()
{
return
challenge
;
}
public
void
setChallenge
(
DungeonChallenge
challenge
)
{
this
.
challenge
=
challenge
;
}
public
boolean
isInScene
(
GameEntity
entity
)
{
public
boolean
isInScene
(
GameEntity
entity
)
{
return
this
.
entities
.
containsKey
(
entity
.
getId
());
return
this
.
entities
.
containsKey
(
entity
.
getId
());
}
}
...
@@ -151,6 +213,11 @@ public class Scene {
...
@@ -151,6 +213,11 @@ public class Scene {
}
}
public
synchronized
void
removePlayer
(
Player
player
)
{
public
synchronized
void
removePlayer
(
Player
player
)
{
// Remove from challenge if leaving
if
(
this
.
getChallenge
()
!=
null
&&
this
.
getChallenge
().
inProgress
())
{
player
.
sendPacket
(
new
PacketDungeonChallengeFinishNotify
(
this
.
getChallenge
()));
}
// Remove player from scene
// Remove player from scene
getPlayers
().
remove
(
player
);
getPlayers
().
remove
(
player
);
player
.
setScene
(
null
);
player
.
setScene
(
null
);
...
@@ -159,12 +226,12 @@ public class Scene {
...
@@ -159,12 +226,12 @@ public class Scene {
this
.
removePlayerAvatars
(
player
);
this
.
removePlayerAvatars
(
player
);
// Remove player gadgets
// Remove player gadgets
for
(
EntityGadget
gadget
:
player
.
getTeamManager
().
getGadgets
())
{
for
(
Entity
Base
Gadget
gadget
:
player
.
getTeamManager
().
getGadgets
())
{
this
.
removeEntity
(
gadget
);
this
.
removeEntity
(
gadget
);
}
}
// Deregister scene if not in use
// Deregister scene if not in use
if
(
this
.
get
Entities
().
size
()
<=
0
&&
!
this
.
dontDestroyWhenEmpty
())
{
if
(
this
.
get
PlayerCount
()
<=
0
&&
!
this
.
dontDestroyWhenEmpty
())
{
this
.
getWorld
().
deregisterScene
(
this
);
this
.
getWorld
().
deregisterScene
(
this
);
}
}
}
}
...
@@ -279,6 +346,11 @@ public class Scene {
...
@@ -279,6 +346,11 @@ public class Scene {
}
}
}
}
// Sanity check
if
(
target
.
getFightProperties
()
==
null
)
{
return
;
}
// Lose hp
// Lose hp
target
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
,
-
result
.
getDamage
());
target
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
,
-
result
.
getDamage
());
...
@@ -314,9 +386,17 @@ public class Scene {
...
@@ -314,9 +386,17 @@ public class Scene {
}
}
public
void
onTick
()
{
public
void
onTick
()
{
if
(
this
.
getScriptManager
().
isInit
())
{
this
.
checkBlocks
();
}
else
{
// TEMPORARY
this
.
checkSpawns
();
this
.
checkSpawns
();
}
}
// Triggers
this
.
getScriptManager
().
onTick
();
}
// TODO - Test
// TODO - Test
public
void
checkSpawns
()
{
public
void
checkSpawns
()
{
SpatialIndex
<
SpawnGroupEntry
>
list
=
GameDepot
.
getSpawnListById
(
this
.
getId
());
SpatialIndex
<
SpawnGroupEntry
>
list
=
GameDepot
.
getSpawnListById
(
this
.
getId
());
...
@@ -387,6 +467,68 @@ public class Scene {
...
@@ -387,6 +467,68 @@ public class Scene {
}
}
}
}
public
void
checkBlocks
()
{
Set
<
SceneBlock
>
visible
=
new
HashSet
<>();
for
(
Player
player
:
this
.
getPlayers
())
{
for
(
SceneBlock
block
:
getScriptManager
().
getBlocks
())
{
if
(!
block
.
contains
(
player
.
getPos
()))
{
continue
;
}
visible
.
add
(
block
);
}
}
Iterator
<
SceneBlock
>
it
=
this
.
getLoadedBlocks
().
iterator
();
while
(
it
.
hasNext
())
{
SceneBlock
block
=
it
.
next
();
if
(!
visible
.
contains
(
block
))
{
it
.
remove
();
onUnloadBlock
(
block
);
}
}
for
(
SceneBlock
block
:
visible
)
{
if
(!
this
.
getLoadedBlocks
().
contains
(
block
))
{
this
.
onLoadBlock
(
block
);
this
.
getLoadedBlocks
().
add
(
block
);
}
}
}
// TODO optimize
public
void
onLoadBlock
(
SceneBlock
block
)
{
for
(
SceneGroup
group
:
block
.
groups
)
{
// We load the script files for the groups here
if
(!
group
.
isLoaded
())
{
this
.
getScriptManager
().
loadGroupFromScript
(
group
);
}
group
.
triggers
.
forEach
(
getScriptManager
()::
registerTrigger
);
}
// Spawn gadgets AFTER triggers are added
for
(
SceneGroup
group
:
block
.
groups
)
{
this
.
getScriptManager
().
spawnGadgetsInGroup
(
group
);
}
}
public
void
onUnloadBlock
(
SceneBlock
block
)
{
List
<
GameEntity
>
toRemove
=
this
.
getEntities
().
values
().
stream
().
filter
(
e
->
e
.
getBlockId
()
==
block
.
id
).
toList
();
if
(
toRemove
.
size
()
>
0
)
{
toRemove
.
stream
().
forEach
(
this
::
removeEntityDirectly
);
this
.
broadcastPacket
(
new
PacketSceneEntityDisappearNotify
(
toRemove
,
VisionType
.
VISION_REMOVE
));
}
for
(
SceneGroup
group
:
block
.
groups
)
{
group
.
triggers
.
forEach
(
getScriptManager
()::
deregisterTrigger
);
}
}
// Gadgets
// Gadgets
public
void
onPlayerCreateGadget
(
EntityClientGadget
gadget
)
{
public
void
onPlayerCreateGadget
(
EntityClientGadget
gadget
)
{
...
...
src/main/java/emu/grasscutter/game/world/World.java
View file @
7fdf7498
...
@@ -17,14 +17,16 @@ import emu.grasscutter.game.props.EntityIdType;
...
@@ -17,14 +17,16 @@ import emu.grasscutter.game.props.EntityIdType;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.LifeState
;
import
emu.grasscutter.game.props.LifeState
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.DungeonData
;
import
emu.grasscutter.data.def.SceneData
;
import
emu.grasscutter.data.def.SceneData
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.entity.EntityClientGadget
;
import
emu.grasscutter.game.entity.EntityClientGadget
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.Entity
Base
Gadget
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult
;
import
emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult
;
import
emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType
;
import
emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
import
emu.grasscutter.scripts.data.SceneConfig
;
import
emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify
;
import
emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify
;
...
@@ -212,6 +214,14 @@ public class World implements Iterable<Player> {
...
@@ -212,6 +214,14 @@ public class World implements Iterable<Player> {
}
}
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
Position
pos
)
{
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
Position
pos
)
{
return
transferPlayerToScene
(
player
,
sceneId
,
null
,
pos
);
}
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
DungeonData
data
)
{
return
transferPlayerToScene
(
player
,
sceneId
,
data
,
null
);
}
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
DungeonData
dungeonData
,
Position
pos
)
{
if
(
GameData
.
getSceneDataMap
().
get
(
sceneId
)
==
null
)
{
if
(
GameData
.
getSceneDataMap
().
get
(
sceneId
)
==
null
)
{
return
false
;
return
false
;
}
}
...
@@ -230,19 +240,45 @@ public class World implements Iterable<Player> {
...
@@ -230,19 +240,45 @@ public class World implements Iterable<Player> {
}
}
Scene
newScene
=
this
.
getSceneById
(
sceneId
);
Scene
newScene
=
this
.
getSceneById
(
sceneId
);
newScene
.
setDungeonData
(
dungeonData
);
newScene
.
addPlayer
(
player
);
newScene
.
addPlayer
(
player
);
// Dungeon
SceneConfig
config
=
newScene
.
getScriptManager
().
getConfig
();
if
(
pos
==
null
&&
config
!=
null
)
{
if
(
config
.
born_pos
!=
null
)
{
pos
=
newScene
.
getScriptManager
().
getConfig
().
born_pos
;
}
if
(
config
.
born_rot
!=
null
)
{
player
.
getRotation
().
set
(
config
.
born_rot
);
}
}
// Set player position
if
(
pos
==
null
)
{
pos
=
player
.
getPos
();
}
player
.
getPos
().
set
(
pos
);
player
.
getPos
().
set
(
pos
);
if
(
oldScene
!=
null
)
{
if
(
oldScene
!=
null
)
{
newScene
.
setPrevScene
(
oldScene
.
getId
());
oldScene
.
setDontDestroyWhenEmpty
(
false
);
oldScene
.
setDontDestroyWhenEmpty
(
false
);
}
}
// Teleport packet
// Get enter types
if
(
oldScene
==
newScene
)
{
EnterType
enterType
=
EnterType
.
ENTER_JUMP
;
player
.
sendPacket
(
new
PacketPlayerEnterSceneNotify
(
player
,
EnterType
.
ENTER_GOTO
,
EnterReason
.
TransPoint
,
sceneId
,
pos
));
EnterReason
enterReason
=
EnterReason
.
TransPoint
;
}
else
{
player
.
sendPacket
(
new
PacketPlayerEnterSceneNotify
(
player
,
EnterType
.
ENTER_JUMP
,
EnterReason
.
TransPoint
,
sceneId
,
pos
));
if
(
dungeonData
!=
null
)
{
enterType
=
EnterType
.
ENTER_DUNGEON
;
enterReason
=
EnterReason
.
DungeonEnter
;
}
else
if
(
oldScene
==
newScene
)
{
enterType
=
EnterType
.
ENTER_GOTO
;
}
}
// Teleport packet
player
.
sendPacket
(
new
PacketPlayerEnterSceneNotify
(
player
,
enterType
,
enterReason
,
sceneId
,
pos
));
return
true
;
return
true
;
}
}
...
...
src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java
View file @
7fdf7498
...
@@ -355,6 +355,8 @@ public class PacketOpcodes {
...
@@ -355,6 +355,8 @@ public class PacketOpcodes {
public
static
final
int
EvtAvatarSitDownNotify
=
392
;
public
static
final
int
EvtAvatarSitDownNotify
=
392
;
public
static
final
int
EvtAvatarStandUpNotify
=
358
;
public
static
final
int
EvtAvatarStandUpNotify
=
358
;
public
static
final
int
EvtAvatarUpdateFocusNotify
=
365
;
public
static
final
int
EvtAvatarUpdateFocusNotify
=
365
;
public
static
final
int
EvtAvatarLockChairReq
=
354
;
public
static
final
int
EvtAvatarLockChairRsp
=
335
;
public
static
final
int
EvtBeingHitNotify
=
360
;
public
static
final
int
EvtBeingHitNotify
=
360
;
public
static
final
int
EvtBeingHitsCombineNotify
=
381
;
public
static
final
int
EvtBeingHitsCombineNotify
=
381
;
public
static
final
int
EvtBulletDeactiveNotify
=
388
;
public
static
final
int
EvtBulletDeactiveNotify
=
388
;
...
...
src/main/java/emu/grasscutter/plugin/PluginManager.java
View file @
7fdf7498
...
@@ -66,7 +66,7 @@ public final class PluginManager {
...
@@ -66,7 +66,7 @@ public final class PluginManager {
Enumeration
<
JarEntry
>
entries
=
jarFile
.
entries
();
Enumeration
<
JarEntry
>
entries
=
jarFile
.
entries
();
while
(
entries
.
hasMoreElements
())
{
while
(
entries
.
hasMoreElements
())
{
JarEntry
entry
=
entries
.
nextElement
();
JarEntry
entry
=
entries
.
nextElement
();
if
(
entry
.
isDirectory
()
||
!
entry
.
getName
().
endsWith
(
".class"
))
continue
;
if
(
entry
.
isDirectory
()
||
!
entry
.
getName
().
endsWith
(
".class"
)
||
entry
.
getName
().
contains
(
"module-info"
)
)
continue
;
String
className
=
entry
.
getName
().
replace
(
".class"
,
""
).
replace
(
"/"
,
"."
);
String
className
=
entry
.
getName
().
replace
(
".class"
,
""
).
replace
(
"/"
,
"."
);
Class
<?>
clazz
=
loader
.
loadClass
(
className
);
Class
<?>
clazz
=
loader
.
loadClass
(
className
);
}
}
...
...
src/main/java/emu/grasscutter/scripts/SceneScriptManager.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
javax.script.Bindings
;
import
javax.script.CompiledScript
;
import
javax.script.ScriptException
;
import
org.luaj.vm2.LuaTable
;
import
org.luaj.vm2.LuaValue
;
import
org.luaj.vm2.lib.jse.CoerceJavaToLua
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.MonsterData
;
import
emu.grasscutter.data.def.WorldLevelData
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.constants.ScriptGadgetState
;
import
emu.grasscutter.scripts.constants.ScriptRegionShape
;
import
emu.grasscutter.scripts.data.SceneBlock
;
import
emu.grasscutter.scripts.data.SceneConfig
;
import
emu.grasscutter.scripts.data.SceneGadget
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.SceneInitConfig
;
import
emu.grasscutter.scripts.data.SceneMonster
;
import
emu.grasscutter.scripts.data.SceneSuite
;
import
emu.grasscutter.scripts.data.SceneTrigger
;
import
emu.grasscutter.scripts.data.SceneVar
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
public
class
SceneScriptManager
{
private
final
Scene
scene
;
private
final
ScriptLib
scriptLib
;
private
final
LuaValue
scriptLibLua
;
private
final
Map
<
String
,
Integer
>
variables
;
private
Bindings
bindings
;
private
SceneConfig
config
;
private
List
<
SceneBlock
>
blocks
;
private
Int2ObjectOpenHashMap
<
Set
<
SceneTrigger
>>
triggers
;
private
boolean
isInit
;
public
SceneScriptManager
(
Scene
scene
)
{
this
.
scene
=
scene
;
this
.
scriptLib
=
new
ScriptLib
(
this
);
this
.
scriptLibLua
=
CoerceJavaToLua
.
coerce
(
this
.
scriptLib
);
this
.
triggers
=
new
Int2ObjectOpenHashMap
<>();
this
.
variables
=
new
HashMap
<>();
// TEMPORARY
if
(
this
.
getScene
().
getId
()
<
10
)
{
return
;
}
// Create
this
.
init
();
}
public
Scene
getScene
()
{
return
scene
;
}
public
ScriptLib
getScriptLib
()
{
return
scriptLib
;
}
public
LuaValue
getScriptLibLua
()
{
return
scriptLibLua
;
}
public
Bindings
getBindings
()
{
return
bindings
;
}
public
SceneConfig
getConfig
()
{
return
config
;
}
public
List
<
SceneBlock
>
getBlocks
()
{
return
blocks
;
}
public
Map
<
String
,
Integer
>
getVariables
()
{
return
variables
;
}
public
Set
<
SceneTrigger
>
getTriggersByEvent
(
int
eventId
)
{
return
triggers
.
computeIfAbsent
(
eventId
,
e
->
new
HashSet
<>());
}
public
void
registerTrigger
(
SceneTrigger
trigger
)
{
getTriggersByEvent
(
trigger
.
event
).
add
(
trigger
);
}
public
void
deregisterTrigger
(
SceneTrigger
trigger
)
{
getTriggersByEvent
(
trigger
.
event
).
remove
(
trigger
);
}
// TODO optimize
public
SceneGroup
getGroupById
(
int
groupId
)
{
for
(
SceneBlock
block
:
this
.
getScene
().
getLoadedBlocks
())
{
for
(
SceneGroup
group
:
block
.
groups
)
{
if
(
group
.
id
==
groupId
)
{
return
group
;
}
}
}
return
null
;
}
private
void
init
()
{
// Get compiled script if cached
CompiledScript
cs
=
ScriptLoader
.
getScriptByPath
(
Grasscutter
.
getConfig
().
SCRIPTS_FOLDER
+
"Scene/"
+
getScene
().
getId
()
+
"/scene"
+
getScene
().
getId
()
+
"."
+
ScriptLoader
.
getScriptType
());
if
(
cs
==
null
)
{
Grasscutter
.
getLogger
().
warn
(
"No script found for scene "
+
getScene
().
getId
());
return
;
}
// Create bindings
bindings
=
ScriptLoader
.
getEngine
().
createBindings
();
// Set variables
bindings
.
put
(
"EventType"
,
new
EventType
());
// TODO - make static class to avoid instantiating a new class every scene
bindings
.
put
(
"GadgetState"
,
new
ScriptGadgetState
());
bindings
.
put
(
"RegionShape"
,
new
ScriptRegionShape
());
bindings
.
put
(
"ScriptLib"
,
getScriptLib
());
// Eval script
try
{
cs
.
eval
(
getBindings
());
this
.
config
=
ScriptLoader
.
getSerializer
().
toObject
(
SceneConfig
.
class
,
bindings
.
get
(
"scene_config"
));
// TODO optimize later
// Create blocks
List
<
Integer
>
blockIds
=
ScriptLoader
.
getSerializer
().
toList
(
Integer
.
class
,
bindings
.
get
(
"blocks"
));
List
<
SceneBlock
>
blocks
=
ScriptLoader
.
getSerializer
().
toList
(
SceneBlock
.
class
,
bindings
.
get
(
"block_rects"
));
for
(
int
i
=
0
;
i
<
blocks
.
size
();
i
++)
{
SceneBlock
block
=
blocks
.
get
(
0
);
block
.
id
=
blockIds
.
get
(
i
);
loadBlockFromScript
(
block
);
}
this
.
blocks
=
blocks
;
}
catch
(
ScriptException
e
)
{
Grasscutter
.
getLogger
().
error
(
"Error running script"
,
e
);
return
;
}
// TEMP
this
.
isInit
=
true
;
}
public
boolean
isInit
()
{
return
isInit
;
}
private
void
loadBlockFromScript
(
SceneBlock
block
)
{
CompiledScript
cs
=
ScriptLoader
.
getScriptByPath
(
Grasscutter
.
getConfig
().
SCRIPTS_FOLDER
+
"Scene/"
+
getScene
().
getId
()
+
"/scene"
+
getScene
().
getId
()
+
"_block"
+
block
.
id
+
"."
+
ScriptLoader
.
getScriptType
());
if
(
cs
==
null
)
{
return
;
}
// Eval script
try
{
cs
.
eval
(
getBindings
());
// Set groups
block
.
groups
=
ScriptLoader
.
getSerializer
().
toList
(
SceneGroup
.
class
,
bindings
.
get
(
"groups"
));
block
.
groups
.
forEach
(
g
->
g
.
block_id
=
block
.
id
);
}
catch
(
ScriptException
e
)
{
Grasscutter
.
getLogger
().
error
(
"Error loading block "
+
block
.
id
+
" in scene "
+
getScene
().
getId
(),
e
);
}
}
public
void
loadGroupFromScript
(
SceneGroup
group
)
{
// Set flag here so if there is no script, we dont call this function over and over again.
group
.
setLoaded
(
true
);
CompiledScript
cs
=
ScriptLoader
.
getScriptByPath
(
Grasscutter
.
getConfig
().
SCRIPTS_FOLDER
+
"Scene/"
+
getScene
().
getId
()
+
"/scene"
+
getScene
().
getId
()
+
"_group"
+
group
.
id
+
"."
+
ScriptLoader
.
getScriptType
());
if
(
cs
==
null
)
{
return
;
}
// Eval script
try
{
cs
.
eval
(
getBindings
());
// Set
group
.
monsters
=
ScriptLoader
.
getSerializer
().
toList
(
SceneMonster
.
class
,
bindings
.
get
(
"monsters"
));
group
.
gadgets
=
ScriptLoader
.
getSerializer
().
toList
(
SceneGadget
.
class
,
bindings
.
get
(
"gadgets"
));
group
.
triggers
=
ScriptLoader
.
getSerializer
().
toList
(
SceneTrigger
.
class
,
bindings
.
get
(
"triggers"
));
group
.
suites
=
ScriptLoader
.
getSerializer
().
toList
(
SceneSuite
.
class
,
bindings
.
get
(
"suites"
));
group
.
init_config
=
ScriptLoader
.
getSerializer
().
toObject
(
SceneInitConfig
.
class
,
bindings
.
get
(
"init_config"
));
// Add variables to suite
List
<
SceneVar
>
variables
=
ScriptLoader
.
getSerializer
().
toList
(
SceneVar
.
class
,
bindings
.
get
(
"variables"
));
variables
.
forEach
(
var
->
this
.
getVariables
().
put
(
var
.
name
,
var
.
value
));
// Add monsters to suite TODO optimize
HashMap
<
Integer
,
SceneMonster
>
map
=
(
HashMap
<
Integer
,
SceneMonster
>)
group
.
monsters
.
stream
().
collect
(
Collectors
.
toMap
(
m
->
m
.
config_id
,
m
->
m
));
for
(
SceneSuite
suite
:
group
.
suites
)
{
suite
.
sceneMonsters
=
new
ArrayList
<>(
suite
.
monsters
.
size
());
for
(
int
id
:
suite
.
monsters
)
{
SceneMonster
monster
=
map
.
get
(
id
);
if
(
monster
!=
null
)
{
suite
.
sceneMonsters
.
add
(
monster
);
}
}
}
}
catch
(
ScriptException
e
)
{
Grasscutter
.
getLogger
().
error
(
"Error loading group "
+
group
.
id
+
" in scene "
+
getScene
().
getId
(),
e
);
}
}
public
void
onTick
()
{
checkTriggers
();
}
public
void
checkTriggers
()
{
}
public
void
spawnGadgetsInGroup
(
SceneGroup
group
)
{
for
(
SceneGadget
g
:
group
.
gadgets
)
{
EntityGadget
entity
=
new
EntityGadget
(
getScene
(),
g
.
gadget_id
,
g
.
pos
);
if
(
entity
.
getGadgetData
()
==
null
)
continue
;
entity
.
setBlockId
(
group
.
block_id
);
entity
.
setConfigId
(
g
.
config_id
);
entity
.
setGroupId
(
group
.
id
);
entity
.
getRotation
().
set
(
g
.
rot
);
entity
.
setState
(
g
.
state
);
getScene
().
addEntity
(
entity
);
this
.
callEvent
(
EventType
.
EVENT_GADGET_CREATE
,
new
ScriptArgs
(
entity
.
getConfigId
()));
}
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
,
int
suiteIndex
)
{
spawnMonstersInGroup
(
group
,
group
.
getSuiteByIndex
(
suiteIndex
));
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
)
{
spawnMonstersInGroup
(
group
,
null
);
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
,
SceneSuite
suite
)
{
List
<
SceneMonster
>
monsters
=
group
.
monsters
;
if
(
suite
!=
null
)
{
monsters
=
suite
.
sceneMonsters
;
}
List
<
GameEntity
>
toAdd
=
new
ArrayList
<>();
for
(
SceneMonster
monster
:
monsters
)
{
MonsterData
data
=
GameData
.
getMonsterDataMap
().
get
(
monster
.
monster_id
);
if
(
data
==
null
)
{
continue
;
}
// Calculate level
int
level
=
monster
.
level
;
if
(
getScene
().
getDungeonData
()
!=
null
)
{
level
=
getScene
().
getDungeonData
().
getShowLevel
();
}
else
if
(
getScene
().
getWorld
().
getWorldLevel
()
>
0
)
{
WorldLevelData
worldLevelData
=
GameData
.
getWorldLevelDataMap
().
get
(
getScene
().
getWorld
().
getWorldLevel
());
if
(
worldLevelData
!=
null
)
{
level
=
worldLevelData
.
getMonsterLevel
();
}
}
// Spawn mob
EntityMonster
entity
=
new
EntityMonster
(
getScene
(),
data
,
monster
.
pos
,
level
);
entity
.
getRotation
().
set
(
monster
.
rot
);
entity
.
setGroupId
(
group
.
id
);
entity
.
setConfigId
(
monster
.
config_id
);
toAdd
.
add
(
entity
);
}
if
(
toAdd
.
size
()
>
0
)
{
getScene
().
addEntities
(
toAdd
);
for
(
GameEntity
entity
:
toAdd
)
{
callEvent
(
EventType
.
EVENT_ANY_MONSTER_LIVE
,
new
ScriptArgs
(
entity
.
getConfigId
()));
}
}
}
// Events
public
void
callEvent
(
int
eventType
,
ScriptArgs
params
)
{
for
(
SceneTrigger
trigger
:
this
.
getTriggersByEvent
(
eventType
))
{
LuaValue
condition
=
null
;
if
(
trigger
.
condition
!=
null
&&
!
trigger
.
condition
.
isEmpty
())
{
condition
=
(
LuaValue
)
this
.
getBindings
().
get
(
trigger
.
condition
);
}
LuaValue
ret
=
LuaValue
.
TRUE
;
if
(
condition
!=
null
)
{
LuaValue
args
=
LuaValue
.
NIL
;
if
(
params
!=
null
)
{
args
=
CoerceJavaToLua
.
coerce
(
params
);
}
ret
=
condition
.
call
(
this
.
getScriptLibLua
(),
args
);
}
if
(
ret
.
checkboolean
()
==
true
)
{
LuaValue
action
=
(
LuaValue
)
this
.
getBindings
().
get
(
trigger
.
action
);
action
.
call
(
this
.
getScriptLibLua
(),
LuaValue
.
NIL
);
}
}
}
}
src/main/java/emu/grasscutter/scripts/ScriptLib.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Optional
;
import
org.luaj.vm2.LuaTable
;
import
org.luaj.vm2.LuaValue
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.MonsterData
;
import
emu.grasscutter.game.dungeons.DungeonChallenge
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.SceneMonster
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
emu.grasscutter.server.packet.send.PacketGadgetStateNotify
;
import
emu.grasscutter.server.packet.send.PacketWorktopOptionNotify
;
public
class
ScriptLib
{
private
final
SceneScriptManager
sceneScriptManager
;
public
ScriptLib
(
SceneScriptManager
sceneScriptManager
)
{
this
.
sceneScriptManager
=
sceneScriptManager
;
}
public
SceneScriptManager
getSceneScriptManager
()
{
return
sceneScriptManager
;
}
public
int
SetGadgetStateByConfigId
(
int
configId
,
int
gadgetState
)
{
Optional
<
GameEntity
>
entity
=
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
.
getConfigId
()
==
configId
).
findFirst
();
if
(
entity
.
isEmpty
())
{
return
1
;
}
if
(!(
entity
.
get
()
instanceof
EntityGadget
))
{
return
1
;
}
EntityGadget
gadget
=
(
EntityGadget
)
entity
.
get
();
gadget
.
setState
(
gadgetState
);
getSceneScriptManager
().
getScene
().
broadcastPacket
(
new
PacketGadgetStateNotify
(
gadget
,
gadgetState
));
return
0
;
}
public
int
SetGroupGadgetStateByConfigId
(
int
groupId
,
int
configId
,
int
gadgetState
)
{
List
<
GameEntity
>
list
=
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
.
getGroupId
()
==
groupId
).
toList
();
for
(
GameEntity
entity
:
list
)
{
if
(!(
entity
instanceof
EntityGadget
))
{
continue
;
}
EntityGadget
gadget
=
(
EntityGadget
)
entity
;
gadget
.
setState
(
gadgetState
);
getSceneScriptManager
().
getScene
().
broadcastPacket
(
new
PacketGadgetStateNotify
(
gadget
,
gadgetState
));
}
return
0
;
}
public
int
SetWorktopOptionsByGroupId
(
int
groupId
,
int
configId
,
int
[]
options
)
{
Optional
<
GameEntity
>
entity
=
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
.
getConfigId
()
==
configId
&&
e
.
getGroupId
()
==
groupId
).
findFirst
();
if
(
entity
.
isEmpty
())
{
return
1
;
}
if
(!(
entity
.
get
()
instanceof
EntityGadget
))
{
return
1
;
}
EntityGadget
gadget
=
(
EntityGadget
)
entity
.
get
();
gadget
.
addWorktopOptions
(
options
);
getSceneScriptManager
().
getScene
().
broadcastPacket
(
new
PacketWorktopOptionNotify
(
gadget
));
return
0
;
}
public
int
DelWorktopOptionByGroupId
(
int
groupId
,
int
configId
,
int
option
)
{
Optional
<
GameEntity
>
entity
=
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
.
getConfigId
()
==
configId
&&
e
.
getGroupId
()
==
groupId
).
findFirst
();
if
(
entity
.
isEmpty
())
{
return
1
;
}
if
(!(
entity
.
get
()
instanceof
EntityGadget
))
{
return
1
;
}
EntityGadget
gadget
=
(
EntityGadget
)
entity
.
get
();
gadget
.
removeWorktopOption
(
option
);
getSceneScriptManager
().
getScene
().
broadcastPacket
(
new
PacketWorktopOptionNotify
(
gadget
));
return
0
;
}
// Some fields are guessed
public
int
AutoMonsterTide
(
int
challengeIndex
,
int
groupId
,
int
[]
config_ids
,
int
param4
,
int
param5
,
int
param6
)
{
SceneGroup
group
=
getSceneScriptManager
().
getGroupById
(
groupId
);
if
(
group
==
null
||
group
.
monsters
==
null
)
{
return
1
;
}
// TODO just spawn all from group for now
this
.
getSceneScriptManager
().
spawnMonstersInGroup
(
group
);
return
0
;
}
public
int
AddExtraGroupSuite
(
int
groupId
,
int
suite
)
{
SceneGroup
group
=
getSceneScriptManager
().
getGroupById
(
groupId
);
if
(
group
==
null
||
group
.
monsters
==
null
)
{
return
1
;
}
// TODO just spawn all from group for now
this
.
getSceneScriptManager
().
spawnMonstersInGroup
(
group
,
suite
);
return
0
;
}
// param3 (probably time limit for timed dungeons)
public
int
ActiveChallenge
(
int
challengeId
,
int
challengeIndex
,
int
param3
,
int
groupId
,
int
param4
,
int
param5
)
{
SceneGroup
group
=
getSceneScriptManager
().
getGroupById
(
groupId
);
if
(
group
==
null
||
group
.
monsters
==
null
)
{
return
1
;
}
DungeonChallenge
challenge
=
new
DungeonChallenge
(
getSceneScriptManager
().
getScene
(),
group
);
challenge
.
setChallengeId
(
challengeId
);
challenge
.
setChallengeIndex
(
challengeIndex
);
getSceneScriptManager
().
getScene
().
setChallenge
(
challenge
);
challenge
.
start
();
return
0
;
}
public
int
GetGroupMonsterCountByGroupId
(
int
groupId
)
{
return
(
int
)
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
instanceof
EntityMonster
&&
e
.
getGroupId
()
==
groupId
)
.
count
();
}
public
int
GetGroupVariableValue
(
String
var
)
{
return
getSceneScriptManager
().
getVariables
().
getOrDefault
(
var
,
0
);
}
public
LuaValue
ChangeGroupVariableValue
(
String
var
,
int
value
)
{
getSceneScriptManager
().
getVariables
().
put
(
var
,
value
);
return
LuaValue
.
ZERO
;
}
public
int
RefreshGroup
(
LuaTable
table
)
{
// Kill and Respawn?
int
groupId
=
table
.
get
(
"group_id"
).
toint
();
int
suite
=
table
.
get
(
"suite"
).
toint
();
SceneGroup
group
=
getSceneScriptManager
().
getGroupById
(
groupId
);
if
(
group
==
null
||
group
.
monsters
==
null
)
{
return
1
;
}
// TODO just spawn all from group for now
this
.
getSceneScriptManager
().
spawnMonstersInGroup
(
group
,
suite
);
return
0
;
}
public
void
PrintContextLog
(
String
msg
)
{
Grasscutter
.
getLogger
().
info
(
"[LUA] "
+
msg
);
}
}
src/main/java/emu/grasscutter/scripts/ScriptLoader.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileReader
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.Map
;
import
javax.script.Compilable
;
import
javax.script.CompiledScript
;
import
javax.script.ScriptEngine
;
import
javax.script.ScriptEngineFactory
;
import
javax.script.ScriptEngineManager
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.scripts.serializer.LuaSerializer
;
import
emu.grasscutter.scripts.serializer.Serializer
;
public
class
ScriptLoader
{
private
static
ScriptEngineManager
sm
;
private
static
ScriptEngine
engine
;
private
static
ScriptEngineFactory
factory
;
private
static
String
fileType
;
private
static
Serializer
serializer
;
private
static
Map
<
String
,
CompiledScript
>
scripts
=
new
HashMap
<>();
public
synchronized
static
void
init
()
throws
Exception
{
if
(
sm
!=
null
)
{
throw
new
Exception
(
"Script loader already initialized"
);
}
sm
=
new
ScriptEngineManager
();
engine
=
sm
.
getEngineByName
(
"luaj"
);
factory
=
getEngine
().
getFactory
();
fileType
=
"lua"
;
serializer
=
new
LuaSerializer
();
}
public
static
ScriptEngine
getEngine
()
{
return
engine
;
}
public
static
String
getScriptType
()
{
return
fileType
;
}
public
static
Serializer
getSerializer
()
{
return
serializer
;
}
public
static
CompiledScript
getScriptByPath
(
String
path
)
{
CompiledScript
sc
=
scripts
.
get
(
path
);
Grasscutter
.
getLogger
().
info
(
"Loaded "
+
path
);
if
(
sc
==
null
)
{
File
file
=
new
File
(
path
);
if
(!
file
.
exists
())
return
null
;
try
(
FileReader
fr
=
new
FileReader
(
file
))
{
sc
=
((
Compilable
)
getEngine
()).
compile
(
fr
);
scripts
.
put
(
path
,
sc
);
}
catch
(
Exception
e
)
{
//e.printStackTrace();
return
null
;
}
}
return
sc
;
}
}
src/main/java/emu/grasscutter/scripts/constants/EventType.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts.constants
;
public
class
EventType
{
public
static
final
int
EVENT_NONE
=
0
;
public
static
final
int
EVENT_ANY_MONSTER_DIE
=
1
;
public
static
final
int
EVENT_ANY_GADGET_DIE
=
2
;
public
static
final
int
EVENT_VARIABLE_CHANGE
=
3
;
public
static
final
int
EVENT_ENTER_REGION
=
4
;
public
static
final
int
EVENT_LEAVE_REGION
=
5
;
public
static
final
int
EVENT_GADGET_CREATE
=
6
;
public
static
final
int
EVENT_GADGET_STATE_CHANGE
=
7
;
public
static
final
int
EVENT_DUNGEON_SETTLE
=
8
;
public
static
final
int
EVENT_SELECT_OPTION
=
9
;
public
static
final
int
EVENT_CLIENT_EXECUTE
=
10
;
public
static
final
int
EVENT_ANY_MONSTER_LIVE
=
11
;
public
static
final
int
EVENT_SPECIFIC_MONSTER_HP_CHANGE
=
12
;
public
static
final
int
EVENT_CITY_LEVELUP_UNLOCK_DUNGEON_ENTRY
=
13
;
public
static
final
int
EVENT_DUNGEON_BROADCAST_ONTIMER
=
14
;
public
static
final
int
EVENT_TIMER_EVENT
=
15
;
public
static
final
int
EVENT_CHALLENGE_SUCCESS
=
16
;
public
static
final
int
EVENT_CHALLENGE_FAIL
=
17
;
public
static
final
int
EVENT_SEAL_BATTLE_BEGIN
=
18
;
public
static
final
int
EVENT_SEAL_BATTLE_END
=
19
;
public
static
final
int
EVENT_GATHER
=
20
;
public
static
final
int
EVENT_QUEST_FINISH
=
21
;
public
static
final
int
EVENT_MONSTER_BATTLE
=
22
;
public
static
final
int
EVENT_CITY_LEVELUP
=
23
;
public
static
final
int
EVENT_CUTSCENE_END
=
24
;
public
static
final
int
EVENT_AVATAR_NEAR_PLATFORM
=
25
;
public
static
final
int
EVENT_PLATFORM_REACH_POINT
=
26
;
public
static
final
int
EVENT_UNLOCK_TRANS_POINT
=
27
;
public
static
final
int
EVENT_QUEST_START
=
28
;
public
static
final
int
EVENT_GROUP_LOAD
=
29
;
public
static
final
int
EVENT_GROUP_WILL_UNLOAD
=
30
;
public
static
final
int
EVENT_GROUP_WILL_REFRESH
=
31
;
public
static
final
int
EVENT_GROUP_REFRESH
=
32
;
public
static
final
int
EVENT_DUNGEON_REWARD_GET
=
33
;
public
static
final
int
EVENT_SPECIFIC_GADGET_HP_CHANGE
=
34
;
public
static
final
int
EVENT_MONSTER_TIDE_OVER
=
35
;
public
static
final
int
EVENT_MONSTER_TIDE_CREATE
=
36
;
public
static
final
int
EVENT_MONSTER_TIDE_DIE
=
37
;
public
static
final
int
EVENT_SEALAMP_PHASE_CHANGE
=
38
;
public
static
final
int
EVENT_BLOSSOM_PROGRESS_FINISH
=
39
;
public
static
final
int
EVENT_BLOSSOM_CHEST_DIE
=
40
;
public
static
final
int
EVENT_GADGET_PLAY_START
=
41
;
public
static
final
int
EVENT_GADGET_PLAY_START_CD
=
42
;
public
static
final
int
EVENT_GADGET_PLAY_STOP
=
43
;
public
static
final
int
EVENT_GADGET_LUA_NOTIFY
=
44
;
public
static
final
int
EVENT_MP_PLAY_PREPARE
=
45
;
public
static
final
int
EVENT_MP_PLAY_BATTLE
=
46
;
public
static
final
int
EVENT_MP_PLAY_PREPARE_INTERRUPT
=
47
;
public
static
final
int
EVENT_SELECT_DIFFICULTY
=
48
;
public
static
final
int
EVENT_SCENE_MP_PLAY_BATTLE_STATE
=
49
;
public
static
final
int
EVENT_SCENE_MP_PLAY_BATTLE_STAGE_CHANGE
=
50
;
public
static
final
int
EVENT_SCENE_MP_PLAY_BATTLE_RESULT
=
51
;
public
static
final
int
EVENT_SEAL_BATTLE_PROGRESS_DECREASE
=
52
;
public
static
final
int
EVENT_GENERAL_REWARD_DIE
=
53
;
public
static
final
int
EVENT_SCENE_MP_PLAY_BATTLE_INTERRUPT
=
54
;
public
static
final
int
EVENT_MONSTER_DIE_BEFORE_LEAVE_SCENE
=
55
;
public
static
final
int
EVENT_SCENE_MP_PLAY_OPEN
=
56
;
public
static
final
int
EVENT_OFFERING_LEVELUP
=
57
;
public
static
final
int
EVENT_DUNGEON_REVIVE
=
58
;
public
static
final
int
EVENT_SCENE_MP_PLAY_ALL_AVATAR_DIE
=
59
;
public
static
final
int
EVENT_DUNGEON_ALL_AVATAR_DIE
=
60
;
public
static
final
int
EVENT_GENERAL_REWARD_TAKEN
=
61
;
public
static
final
int
EVENT_PLATFORM_REACH_ARRAYPOINT
=
62
;
public
static
final
int
EVENT_SCENE_MULTISTAGE_PLAY_STAGE_END
=
63
;
public
static
final
int
EVENT_SCENE_MULTISTAGE_PLAY_END_STAGE_REQ
=
64
;
public
static
final
int
EVENT_MECHANICUS_PICKED_CARD
=
65
;
public
static
final
int
EVENT_POOL_MONSTER_TIDE_OVER
=
66
;
public
static
final
int
EVENT_POOL_MONSTER_TIDE_CREATE
=
67
;
public
static
final
int
EVENT_POOL_MONSTER_TIDE_DIE
=
68
;
public
static
final
int
EVENT_DUNGEON_AVATAR_SLIP_DIE
=
69
;
public
static
final
int
EVENT_GALLERY_START
=
70
;
public
static
final
int
EVENT_GALLERY_STOP
=
71
;
public
static
final
int
EVENT_TIME_AXIS_PASS
=
72
;
public
static
final
int
EVENT_FLEUR_FAIR_DUNGEON_ALL_PLAYER_ENTER
=
73
;
public
static
final
int
EVENT_GADGETTALK_DONE
=
74
;
public
static
final
int
EVENT_SET_GAME_TIME
=
75
;
public
static
final
int
EVENT_HIDE_AND_SEEK_PLAYER_QUIT
=
76
;
public
static
final
int
EVENT_AVATAR_DIE
=
77
;
}
src/main/java/emu/grasscutter/scripts/constants/ScriptGadgetState.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts.constants
;
public
class
ScriptGadgetState
{
public
static
final
int
Default
=
0
;
public
static
final
int
GatherDrop
=
1
;
public
static
final
int
ChestLocked
=
101
;
public
static
final
int
ChestOpened
=
102
;
public
static
final
int
ChestTrap
=
103
;
public
static
final
int
ChestBramble
=
104
;
public
static
final
int
ChestFrozen
=
105
;
public
static
final
int
ChestRock
=
106
;
public
static
final
int
GearStart
=
201
;
public
static
final
int
GearStop
=
202
;
public
static
final
int
GearAction1
=
203
;
public
static
final
int
GearAction2
=
204
;
public
static
final
int
CrystalResonate1
=
301
;
public
static
final
int
CrystalResonate2
=
302
;
public
static
final
int
CrystalExplode
=
303
;
public
static
final
int
CrystalDrain
=
304
;
public
static
final
int
StatueActive
=
401
;
public
static
final
int
Action01
=
901
;
public
static
final
int
Action02
=
902
;
public
static
final
int
Action03
=
903
;
}
src/main/java/emu/grasscutter/scripts/constants/ScriptRegionShape.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts.constants
;
public
class
ScriptRegionShape
{
public
static
final
int
NONE
=
0
;
public
static
final
int
SPHERE
=
1
;
public
static
final
int
CUBIC
=
2
;
}
src/main/java/emu/grasscutter/scripts/data/SceneBlock.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts.data
;
import
java.util.List
;
import
emu.grasscutter.utils.Position
;
public
class
SceneBlock
{
public
int
id
;
public
Position
max
;
public
Position
min
;
public
List
<
SceneGroup
>
groups
;
public
boolean
contains
(
Position
pos
)
{
return
pos
.
getX
()
<=
max
.
getX
()
&&
pos
.
getX
()
>=
min
.
getX
()
&&
pos
.
getZ
()
<=
max
.
getZ
()
&&
pos
.
getZ
()
>=
min
.
getZ
();
}
}
src/main/java/emu/grasscutter/scripts/data/SceneConfig.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.utils.Position
;
public
class
SceneConfig
{
public
Position
vision_anchor
;
public
Position
born_pos
;
public
Position
born_rot
;
public
Position
begin_pos
;
public
Position
size
;
}
src/main/java/emu/grasscutter/scripts/data/SceneGadget.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.utils.Position
;
public
class
SceneGadget
{
public
int
level
;
public
int
config_id
;
public
int
gadget_id
;
public
int
state
;
public
Position
pos
;
public
Position
rot
;
}
src/main/java/emu/grasscutter/scripts/data/SceneGroup.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts.data
;
import
java.util.List
;
import
emu.grasscutter.utils.Position
;
public
class
SceneGroup
{
public
transient
int
block_id
;
// Not an actual variable in the scripts but we will keep it here for reference
public
int
id
;
public
int
refresh_id
;
public
Position
pos
;
public
List
<
SceneMonster
>
monsters
;
public
List
<
SceneGadget
>
gadgets
;
public
List
<
SceneTrigger
>
triggers
;
public
List
<
SceneSuite
>
suites
;
public
SceneInitConfig
init_config
;
private
transient
boolean
isLoaded
;
// Not an actual variable in the scripts either
public
boolean
isLoaded
()
{
return
isLoaded
;
}
public
boolean
setLoaded
(
boolean
loaded
)
{
return
loaded
;
}
public
SceneSuite
getSuiteByIndex
(
int
index
)
{
return
suites
.
get
(
index
-
1
);
}
}
src/main/java/emu/grasscutter/scripts/data/SceneInitConfig.java
0 → 100644
View file @
7fdf7498
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.utils.Position
;
public
class
SceneInitConfig
{
public
int
suite
;
public
int
end_suite
;
public
int
rand_suite
;
}
Prev
1
2
3
4
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