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
2f39aff4
Commit
2f39aff4
authored
Apr 29, 2022
by
memetrollsXD
Committed by
GitHub
Apr 29, 2022
Browse files
Merge pull request #355 from Grasscutters/dungeon-scripts
Implemented Dungeon Support
parents
789e5f57
6d987430
Changes
55
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/world/Scene.java
View file @
2f39aff4
...
@@ -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,7 +386,15 @@ public class Scene {
...
@@ -314,7 +386,15 @@ public class Scene {
}
}
public
void
onTick
()
{
public
void
onTick
()
{
this
.
checkSpawns
();
if
(
this
.
getScriptManager
().
isInit
())
{
this
.
checkBlocks
();
}
else
{
// TEMPORARY
this
.
checkSpawns
();
}
// Triggers
this
.
getScriptManager
().
onTick
();
}
}
// TODO - Test
// TODO - Test
...
@@ -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 @
2f39aff4
...
@@ -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
;
}
}
...
@@ -224,25 +234,51 @@ public class World implements Iterable<Player> {
...
@@ -224,25 +234,51 @@ public class World implements Iterable<Player> {
// Dont deregister scenes if the player is going to tp back into them
// Dont deregister scenes if the player is going to tp back into them
if
(
oldScene
.
getId
()
==
sceneId
)
{
if
(
oldScene
.
getId
()
==
sceneId
)
{
oldScene
.
setDontDestroyWhenEmpty
(
true
);
oldScene
.
setDontDestroyWhenEmpty
(
true
);
}
}
oldScene
.
removePlayer
(
player
);
oldScene
.
removePlayer
(
player
);
}
}
Scene
newScene
=
this
.
getSceneById
(
sceneId
);
Scene
newScene
=
this
.
getSceneById
(
sceneId
);
newScene
.
setDungeonData
(
dungeonData
);
newScene
.
addPlayer
(
player
);
newScene
.
addPlayer
(
player
);
player
.
getPos
().
set
(
pos
);
// 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
);
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/scripts/SceneScriptManager.java
0 → 100644
View file @
2f39aff4
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 @
2f39aff4
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 @
2f39aff4
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 @
2f39aff4
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 @
2f39aff4
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 @
2f39aff4
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 @
2f39aff4
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 @
2f39aff4
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 @
2f39aff4
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 @
2f39aff4
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 @
2f39aff4
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.utils.Position
;
public
class
SceneInitConfig
{
public
int
suite
;
public
int
end_suite
;
public
int
rand_suite
;
}
src/main/java/emu/grasscutter/scripts/data/SceneMonster.java
0 → 100644
View file @
2f39aff4
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.utils.Position
;
public
class
SceneMonster
{
public
int
level
;
public
int
config_id
;
public
int
monster_id
;
public
Position
pos
;
public
Position
rot
;
}
src/main/java/emu/grasscutter/scripts/data/SceneSuite.java
0 → 100644
View file @
2f39aff4
package
emu.grasscutter.scripts.data
;
import
java.util.List
;
import
emu.grasscutter.utils.Position
;
public
class
SceneSuite
{
public
List
<
Integer
>
monsters
;
public
List
<
String
>
triggers
;
public
int
rand_weight
;
public
transient
List
<
SceneMonster
>
sceneMonsters
;
}
src/main/java/emu/grasscutter/scripts/data/SceneTrigger.java
0 → 100644
View file @
2f39aff4
package
emu.grasscutter.scripts.data
;
public
class
SceneTrigger
{
public
String
name
;
public
int
config_id
;
public
int
event
;
public
String
source
;
public
String
condition
;
public
String
action
;
}
src/main/java/emu/grasscutter/scripts/data/SceneVar.java
0 → 100644
View file @
2f39aff4
package
emu.grasscutter.scripts.data
;
public
class
SceneVar
{
public
String
name
;
public
int
value
;
public
boolean
no_refresh
;
}
src/main/java/emu/grasscutter/scripts/data/ScriptArgs.java
0 → 100644
View file @
2f39aff4
package
emu.grasscutter.scripts.data
;
public
class
ScriptArgs
{
public
int
param1
;
public
int
param2
;
public
int
param3
;
public
ScriptArgs
()
{
}
public
ScriptArgs
(
int
param1
)
{
this
.
param1
=
param1
;
}
public
ScriptArgs
(
int
param1
,
int
param2
)
{
this
.
param1
=
param1
;
this
.
param2
=
param2
;
}
public
int
getParam1
()
{
return
param1
;
}
public
ScriptArgs
setParam1
(
int
param1
)
{
this
.
param1
=
param1
;
return
this
;
}
public
int
getParam2
()
{
return
param2
;
}
public
ScriptArgs
setParam2
(
int
param2
)
{
this
.
param2
=
param2
;
return
this
;
}
public
int
getParam3
()
{
return
param3
;
}
public
ScriptArgs
setParam3
(
int
param3
)
{
this
.
param3
=
param3
;
return
this
;
}
}
src/main/java/emu/grasscutter/scripts/serializer/LuaSerializer.java
0 → 100644
View file @
2f39aff4
package
emu.grasscutter.scripts.serializer
;
import
java.lang.reflect.Field
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.luaj.vm2.LuaTable
;
import
org.luaj.vm2.LuaValue
;
public
class
LuaSerializer
implements
Serializer
{
@Override
public
<
T
>
List
<
T
>
toList
(
Class
<
T
>
type
,
Object
obj
)
{
return
serializeList
(
type
,
(
LuaTable
)
obj
);
}
@Override
public
<
T
>
T
toObject
(
Class
<
T
>
type
,
Object
obj
)
{
return
serialize
(
type
,
(
LuaTable
)
obj
);
}
public
<
T
>
List
<
T
>
serializeList
(
Class
<
T
>
type
,
LuaTable
table
)
{
List
<
T
>
list
=
new
ArrayList
();
try
{
LuaValue
[]
keys
=
table
.
keys
();
for
(
LuaValue
k
:
keys
)
{
try
{
LuaValue
keyValue
=
table
.
get
(
k
);
T
object
=
null
;
if
(
keyValue
.
istable
())
{
object
=
serialize
(
type
,
keyValue
.
checktable
());
}
else
if
(
keyValue
.
isint
())
{
object
=
(
T
)
(
Integer
)
keyValue
.
toint
();
}
else
if
(
keyValue
.
isnumber
())
{
object
=
(
T
)
(
Float
)
keyValue
.
tofloat
();
// terrible...
}
else
if
(
keyValue
.
isstring
())
{
object
=
(
T
)
keyValue
.
tojstring
();
}
else
{
object
=
(
T
)
keyValue
;
}
if
(
object
!=
null
)
{
list
.
add
(
object
);
}
}
catch
(
Exception
ex
)
{
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
list
;
}
public
<
T
>
T
serialize
(
Class
<
T
>
type
,
LuaTable
table
)
{
T
object
=
null
;
if
(
type
==
List
.
class
)
{
try
{
Class
<
T
>
listType
=
(
Class
<
T
>)
type
.
getTypeParameters
()[
0
].
getClass
();
return
(
T
)
serializeList
(
listType
,
table
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
try
{
object
=
type
.
getDeclaredConstructor
().
newInstance
(
null
);
LuaValue
[]
keys
=
table
.
keys
();
for
(
LuaValue
k
:
keys
)
{
try
{
Field
field
=
object
.
getClass
().
getDeclaredField
(
k
.
checkjstring
());
if
(
field
==
null
)
{
continue
;
}
field
.
setAccessible
(
true
);
LuaValue
keyValue
=
table
.
get
(
k
);
if
(
keyValue
.
istable
())
{
field
.
set
(
object
,
serialize
(
field
.
getType
(),
keyValue
.
checktable
()));
}
else
if
(
field
.
getType
().
equals
(
float
.
class
))
{
field
.
setFloat
(
object
,
keyValue
.
tofloat
());
}
else
if
(
field
.
getType
().
equals
(
int
.
class
))
{
field
.
setInt
(
object
,
keyValue
.
toint
());
}
else
if
(
field
.
getType
().
equals
(
String
.
class
))
{
field
.
set
(
object
,
keyValue
.
tojstring
());
}
else
{
field
.
set
(
object
,
keyValue
);
}
}
catch
(
Exception
ex
)
{
//ex.printStackTrace();
continue
;
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
object
;
}
}
src/main/java/emu/grasscutter/scripts/serializer/Serializer.java
0 → 100644
View file @
2f39aff4
package
emu.grasscutter.scripts.serializer
;
import
java.util.List
;
import
org.luaj.vm2.LuaTable
;
public
interface
Serializer
{
public
<
T
>
List
<
T
>
toList
(
Class
<
T
>
type
,
Object
obj
);
public
<
T
>
T
toObject
(
Class
<
T
>
type
,
Object
obj
);
}
Prev
1
2
3
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