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
67ac0d70
Commit
67ac0d70
authored
Jun 23, 2022
by
Akka
Committed by
Melledy
Jun 23, 2022
Browse files
add region entity
parent
1c6c5813
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/entity/EntityRegion.java
0 → 100644
View file @
67ac0d70
package
emu.grasscutter.game.entity
;
import
emu.grasscutter.game.props.EntityIdType
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.net.proto.SceneEntityInfoOuterClass
;
import
emu.grasscutter.scripts.data.SceneRegion
;
import
emu.grasscutter.utils.Position
;
import
it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap
;
import
lombok.Getter
;
import
java.util.Set
;
import
java.util.concurrent.ConcurrentHashMap
;
@Getter
public
class
EntityRegion
extends
GameEntity
{
private
final
Position
position
;
private
boolean
hasNewEntities
;
private
final
Set
<
Integer
>
entities
;
// Ids of entities inside this region
private
final
SceneRegion
metaRegion
;
public
EntityRegion
(
Scene
scene
,
SceneRegion
region
)
{
super
(
scene
);
this
.
id
=
getScene
().
getWorld
().
getNextEntityId
(
EntityIdType
.
REGION
);
setGroupId
(
region
.
group
.
id
);
setBlockId
(
region
.
group
.
block_id
);
setConfigId
(
region
.
config_id
);
this
.
position
=
region
.
pos
.
clone
();
this
.
entities
=
ConcurrentHashMap
.
newKeySet
();
this
.
metaRegion
=
region
;
}
public
void
addEntity
(
GameEntity
entity
)
{
if
(
this
.
getEntities
().
contains
(
entity
.
getId
()))
{
return
;
}
this
.
getEntities
().
add
(
entity
.
getId
());
this
.
hasNewEntities
=
true
;
}
public
boolean
hasNewEntities
()
{
return
hasNewEntities
;
}
public
void
resetNewEntities
()
{
hasNewEntities
=
false
;
}
public
void
removeEntity
(
GameEntity
entity
)
{
this
.
getEntities
().
remove
(
entity
.
getId
());
}
@Override
public
Int2FloatOpenHashMap
getFightProperties
()
{
return
null
;
}
@Override
public
Position
getPosition
()
{
return
position
;
}
@Override
public
Position
getRotation
()
{
return
null
;
}
@Override
public
SceneEntityInfoOuterClass
.
SceneEntityInfo
toProto
()
{
/**
* The Region Entity would not be sent to client.
*/
return
null
;
}
}
src/main/java/emu/grasscutter/game/props/EntityIdType.java
View file @
67ac0d70
...
@@ -5,10 +5,11 @@ public enum EntityIdType {
...
@@ -5,10 +5,11 @@ public enum EntityIdType {
MONSTER
(
0x02
),
MONSTER
(
0x02
),
NPC
(
0x03
),
NPC
(
0x03
),
GADGET
(
0x04
),
GADGET
(
0x04
),
WEAPON
(
0x06
),
REGION
(
0x05
),
WEAPON
(
0x06
),
TEAM
(
0x09
),
TEAM
(
0x09
),
MPLEVEL
(
0x0b
);
MPLEVEL
(
0x0b
);
private
final
int
id
;
private
final
int
id
;
private
EntityIdType
(
int
id
)
{
private
EntityIdType
(
int
id
)
{
...
...
src/main/java/emu/grasscutter/game/world/Scene.java
View file @
67ac0d70
...
@@ -30,24 +30,25 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
...
@@ -30,24 +30,25 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import
org.danilopianini.util.SpatialIndex
;
import
org.danilopianini.util.SpatialIndex
;
import
java.util.*
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.CopyOnWriteArrayList
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
public
class
Scene
{
public
class
Scene
{
private
final
World
world
;
private
final
World
world
;
private
final
SceneData
sceneData
;
private
final
SceneData
sceneData
;
private
final
List
<
Player
>
players
;
private
final
List
<
Player
>
players
;
private
final
Int2ObjectMap
<
GameEntity
>
entities
;
private
final
Map
<
Integer
,
GameEntity
>
entities
;
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
final
Set
<
SceneBlock
>
loadedBlocks
;
private
boolean
dontDestroyWhenEmpty
;
private
boolean
dontDestroyWhenEmpty
;
private
int
autoCloseTime
;
private
int
autoCloseTime
;
private
int
time
;
private
int
time
;
private
ClimateType
climate
;
private
ClimateType
climate
;
private
int
weather
;
private
int
weather
;
private
SceneScriptManager
scriptManager
;
private
SceneScriptManager
scriptManager
;
private
WorldChallenge
challenge
;
private
WorldChallenge
challenge
;
private
List
<
DungeonSettleListener
>
dungeonSettleListeners
;
private
List
<
DungeonSettleListener
>
dungeonSettleListeners
;
...
@@ -57,19 +58,19 @@ public class Scene {
...
@@ -57,19 +58,19 @@ public class Scene {
public
Scene
(
World
world
,
SceneData
sceneData
)
{
public
Scene
(
World
world
,
SceneData
sceneData
)
{
this
.
world
=
world
;
this
.
world
=
world
;
this
.
sceneData
=
sceneData
;
this
.
sceneData
=
sceneData
;
this
.
players
=
Collections
.
synchronizedList
(
new
ArrayList
<>()
)
;
this
.
players
=
new
CopyOnWrite
ArrayList
<>();
this
.
entities
=
Int2ObjectMaps
.
synchronize
(
new
Int2ObjectOp
enHashMap
<>()
)
;
this
.
entities
=
new
Concurr
en
t
HashMap
<>();
this
.
time
=
8
*
60
;
this
.
time
=
8
*
60
;
this
.
climate
=
ClimateType
.
CLIMATE_SUNNY
;
this
.
climate
=
ClimateType
.
CLIMATE_SUNNY
;
this
.
prevScene
=
3
;
this
.
prevScene
=
3
;
this
.
spawnedEntities
=
new
Hash
Set
<>
();
this
.
spawnedEntities
=
ConcurrentHashMap
.
newKey
Set
();
this
.
deadSpawnedEntities
=
new
Hash
Set
<>
();
this
.
deadSpawnedEntities
=
ConcurrentHashMap
.
newKey
Set
();
this
.
loadedBlocks
=
new
Hash
Set
<>
();
this
.
loadedBlocks
=
ConcurrentHashMap
.
newKey
Set
();
this
.
scriptManager
=
new
SceneScriptManager
(
this
);
this
.
scriptManager
=
new
SceneScriptManager
(
this
);
}
}
public
int
getId
()
{
public
int
getId
()
{
return
sceneData
.
getId
();
return
sceneData
.
getId
();
}
}
...
@@ -89,15 +90,15 @@ public class Scene {
...
@@ -89,15 +90,15 @@ public class Scene {
public
List
<
Player
>
getPlayers
()
{
public
List
<
Player
>
getPlayers
()
{
return
players
;
return
players
;
}
}
public
int
getPlayerCount
()
{
public
int
getPlayerCount
()
{
return
this
.
getPlayers
().
size
();
return
this
.
getPlayers
().
size
();
}
}
public
Int2ObjectMap
<
GameEntity
>
getEntities
()
{
public
Map
<
Integer
,
GameEntity
>
getEntities
()
{
return
entities
;
return
entities
;
}
}
public
GameEntity
getEntityById
(
int
id
)
{
public
GameEntity
getEntityById
(
int
id
)
{
return
this
.
entities
.
get
(
id
);
return
this
.
entities
.
get
(
id
);
}
}
...
@@ -629,15 +630,10 @@ public class Scene {
...
@@ -629,15 +630,10 @@ public class Scene {
var
suiteData
=
group
.
getSuiteByIndex
(
suite
);
var
suiteData
=
group
.
getSuiteByIndex
(
suite
);
suiteData
.
sceneTriggers
.
forEach
(
getScriptManager
()::
registerTrigger
);
suiteData
.
sceneTriggers
.
forEach
(
getScriptManager
()::
registerTrigger
);
entities
.
addAll
(
suiteData
.
sceneGadgets
.
stream
()
entities
.
addAll
(
scriptManager
.
getGadgetsInGroupSuite
(
group
,
suiteData
));
.
map
(
g
->
scriptManager
.
createGadget
(
group
.
id
,
group
.
block_id
,
g
))
entities
.
addAll
(
scriptManager
.
getMonstersInGroupSuite
(
group
,
suiteData
));
.
filter
(
Objects:
:
nonNull
)
.
toList
());
entities
.
addAll
(
suiteData
.
sceneMonsters
.
stream
()
.
map
(
mob
->
scriptManager
.
createMonster
(
group
.
id
,
group
.
block_id
,
mob
))
.
filter
(
Objects:
:
nonNull
)
.
toList
());
scriptManager
.
registerRegionInGroupSuite
(
group
,
suiteData
);
}
}
scriptManager
.
meetEntities
(
entities
);
scriptManager
.
meetEntities
(
entities
);
...
@@ -654,19 +650,18 @@ public class Scene {
...
@@ -654,19 +650,18 @@ public class Scene {
toRemove
.
forEach
(
this
::
removeEntityDirectly
);
toRemove
.
forEach
(
this
::
removeEntityDirectly
);
this
.
broadcastPacket
(
new
PacketSceneEntityDisappearNotify
(
toRemove
,
VisionType
.
VISION_TYPE_REMOVE
));
this
.
broadcastPacket
(
new
PacketSceneEntityDisappearNotify
(
toRemove
,
VisionType
.
VISION_TYPE_REMOVE
));
}
}
for
(
SceneGroup
group
:
block
.
groups
.
values
())
{
for
(
SceneGroup
group
:
block
.
groups
.
values
())
{
if
(
group
.
triggers
!=
null
){
if
(
group
.
triggers
!=
null
){
group
.
triggers
.
values
().
forEach
(
getScriptManager
()::
deregisterTrigger
);
group
.
triggers
.
values
().
forEach
(
getScriptManager
()::
deregisterTrigger
);
}
}
if
(
group
.
regions
!=
null
){
if
(
group
.
regions
!=
null
){
group
.
regions
.
forEach
(
getScriptManager
()::
deregisterRegion
);
group
.
regions
.
values
().
forEach
(
getScriptManager
()::
deregisterRegion
);
}
}
}
}
scriptManager
.
getLoadedGroupSetPerBlock
().
remove
(
block
.
id
);
scriptManager
.
getLoadedGroupSetPerBlock
().
remove
(
block
.
id
);
Grasscutter
.
getLogger
().
info
(
"Scene {} Block {} is unloaded."
,
this
.
getId
(),
block
.
id
);
Grasscutter
.
getLogger
().
info
(
"Scene {} Block {} is unloaded."
,
this
.
getId
(),
block
.
id
);
}
}
// Gadgets
// Gadgets
public
void
onPlayerCreateGadget
(
EntityClientGadget
gadget
)
{
public
void
onPlayerCreateGadget
(
EntityClientGadget
gadget
)
{
...
...
src/main/java/emu/grasscutter/scripts/SceneScriptManager.java
View file @
67ac0d70
...
@@ -6,10 +6,7 @@ import emu.grasscutter.Grasscutter;
...
@@ -6,10 +6,7 @@ import emu.grasscutter.Grasscutter;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.excels.MonsterData
;
import
emu.grasscutter.data.excels.MonsterData
;
import
emu.grasscutter.data.excels.WorldLevelData
;
import
emu.grasscutter.data.excels.WorldLevelData
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.*
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.entity.EntityNPC
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.constants.EventType
;
...
@@ -17,17 +14,12 @@ import emu.grasscutter.scripts.data.*;
...
@@ -17,17 +14,12 @@ import emu.grasscutter.scripts.data.*;
import
emu.grasscutter.scripts.service.ScriptMonsterSpawnService
;
import
emu.grasscutter.scripts.service.ScriptMonsterSpawnService
;
import
emu.grasscutter.scripts.service.ScriptMonsterTideService
;
import
emu.grasscutter.scripts.service.ScriptMonsterTideService
;
import
io.netty.util.concurrent.FastThreadLocalThread
;
import
io.netty.util.concurrent.FastThreadLocalThread
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
import
org.luaj.vm2.LuaError
;
import
org.luaj.vm2.LuaError
;
import
org.luaj.vm2.LuaValue
;
import
org.luaj.vm2.LuaValue
;
import
org.luaj.vm2.lib.jse.CoerceJavaToLua
;
import
org.luaj.vm2.lib.jse.CoerceJavaToLua
;
import
java.util.*
;
import
java.util.*
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.*
;
import
java.util.concurrent.LinkedBlockingDeque
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
public
class
SceneScriptManager
{
public
class
SceneScriptManager
{
...
@@ -38,15 +30,15 @@ public class SceneScriptManager {
...
@@ -38,15 +30,15 @@ public class SceneScriptManager {
/**
/**
* current triggers controlled by RefreshGroup
* current triggers controlled by RefreshGroup
*/
*/
private
final
Int2ObjectOpenHashMap
<
Set
<
SceneTrigger
>>
currentTriggers
;
private
final
Map
<
Integer
,
Set
<
SceneTrigger
>>
currentTriggers
;
private
final
Int2ObjectOpenHashMap
<
SceneRegion
>
regions
;
private
final
Map
<
Integer
,
EntityRegion
>
regions
;
// <EntityId-Region>
private
Map
<
Integer
,
SceneGroup
>
sceneGroups
;
private
final
Map
<
Integer
,
SceneGroup
>
sceneGroups
;
private
ScriptMonsterTideService
scriptMonsterTideService
;
private
ScriptMonsterTideService
scriptMonsterTideService
;
private
ScriptMonsterSpawnService
scriptMonsterSpawnService
;
private
ScriptMonsterSpawnService
scriptMonsterSpawnService
;
/**
/**
* blockid - loaded groupSet
* blockid - loaded groupSet
*/
*/
private
Int2ObjectMap
<
Set
<
SceneGroup
>>
loadedGroupSetPerBlock
;
private
final
Map
<
Integer
,
Set
<
SceneGroup
>>
loadedGroupSetPerBlock
;
public
static
final
ExecutorService
eventExecutor
;
public
static
final
ExecutorService
eventExecutor
;
static
{
static
{
eventExecutor
=
new
ThreadPoolExecutor
(
4
,
4
,
eventExecutor
=
new
ThreadPoolExecutor
(
4
,
4
,
...
@@ -55,23 +47,23 @@ public class SceneScriptManager {
...
@@ -55,23 +47,23 @@ public class SceneScriptManager {
}
}
public
SceneScriptManager
(
Scene
scene
)
{
public
SceneScriptManager
(
Scene
scene
)
{
this
.
scene
=
scene
;
this
.
scene
=
scene
;
this
.
currentTriggers
=
new
Int2ObjectOp
enHashMap
<>();
this
.
currentTriggers
=
new
Concurr
en
t
HashMap
<>();
this
.
regions
=
new
Int2ObjectOp
enHashMap
<>();
this
.
regions
=
new
Concurr
en
t
HashMap
<>();
this
.
variables
=
new
HashMap
<>();
this
.
variables
=
new
Concurrent
HashMap
<>();
this
.
sceneGroups
=
new
HashMap
<>();
this
.
sceneGroups
=
new
Concurrent
HashMap
<>();
this
.
scriptMonsterSpawnService
=
new
ScriptMonsterSpawnService
(
this
);
this
.
scriptMonsterSpawnService
=
new
ScriptMonsterSpawnService
(
this
);
this
.
loadedGroupSetPerBlock
=
new
Int2ObjectOp
enHashMap
<>();
this
.
loadedGroupSetPerBlock
=
new
Concurr
en
t
HashMap
<>();
// TEMPORARY
// TEMPORARY
if
(
this
.
getScene
().
getId
()
<
10
&&
!
Grasscutter
.
getConfig
().
server
.
game
.
enableScriptInBigWorld
)
{
if
(
this
.
getScene
().
getId
()
<
10
&&
!
Grasscutter
.
getConfig
().
server
.
game
.
enableScriptInBigWorld
)
{
return
;
return
;
}
}
// Create
// Create
this
.
init
();
this
.
init
();
}
}
public
Scene
getScene
()
{
public
Scene
getScene
()
{
return
scene
;
return
scene
;
}
}
...
@@ -123,19 +115,25 @@ public class SceneScriptManager {
...
@@ -123,19 +115,25 @@ public class SceneScriptManager {
spawnMonstersInGroup
(
group
,
suite
);
spawnMonstersInGroup
(
group
,
suite
);
spawnGadgetsInGroup
(
group
,
suite
);
spawnGadgetsInGroup
(
group
,
suite
);
}
}
public
Scene
Region
getRegionById
(
int
id
)
{
public
Entity
Region
getRegionById
(
int
id
)
{
return
regions
.
get
(
id
);
return
regions
.
get
(
id
);
}
}
public
void
registerRegion
(
Scene
Region
region
)
{
public
void
registerRegion
(
Entity
Region
region
)
{
regions
.
put
(
region
.
config_id
,
region
);
regions
.
put
(
region
.
getId
()
,
region
);
}
}
public
void
registerRegionInGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
public
void
deregisterRegion
(
SceneRegion
region
)
{
suite
.
sceneRegions
.
stream
().
map
(
region
->
new
EntityRegion
(
this
.
getScene
(),
region
))
regions
.
remove
(
region
.
config_id
);
.
forEach
(
this
::
registerRegion
);
}
public
synchronized
void
deregisterRegion
(
SceneRegion
region
)
{
var
instance
=
regions
.
values
().
stream
()
.
filter
(
r
->
r
.
getConfigId
()
==
region
.
config_id
)
.
findFirst
();
instance
.
ifPresent
(
entityRegion
->
regions
.
remove
(
entityRegion
.
getId
()));
}
}
public
Int2ObjectMap
<
Set
<
SceneGroup
>>
getLoadedGroupSetPerBlock
()
{
public
Map
<
Integer
,
Set
<
SceneGroup
>>
getLoadedGroupSetPerBlock
()
{
return
loadedGroupSetPerBlock
;
return
loadedGroupSetPerBlock
;
}
}
...
@@ -182,53 +180,61 @@ public class SceneScriptManager {
...
@@ -182,53 +180,61 @@ public class SceneScriptManager {
}
}
this
.
sceneGroups
.
put
(
group
.
id
,
group
);
this
.
sceneGroups
.
put
(
group
.
id
,
group
);
if
(
group
.
regions
!=
null
){
group
.
regions
.
forEach
(
this
::
registerRegion
);
}
}
}
public
void
checkRegions
()
{
public
void
checkRegions
()
{
if
(
this
.
regions
.
size
()
==
0
)
{
if
(
this
.
regions
.
size
()
==
0
)
{
return
;
return
;
}
}
for
(
SceneRegion
region
:
this
.
regions
.
values
())
{
for
(
var
region
:
this
.
regions
.
values
())
{
getScene
().
getEntities
().
values
()
getScene
().
getEntities
().
values
()
.
stream
()
.
stream
()
.
filter
(
e
->
e
.
getEntityType
()
<=
2
&&
region
.
contains
(
e
.
getPosition
()))
.
filter
(
e
->
e
.
getEntityType
()
<=
2
&&
region
.
getMetaRegion
().
contains
(
e
.
getPosition
()))
.
forEach
(
region:
:
addEntity
);
.
forEach
(
region:
:
addEntity
);
if
(
region
.
hasNewEntities
())
{
if
(
region
.
hasNewEntities
())
{
// This is not how it works, source_eid should be region entity id, but we dont have an entity for regions yet
callEvent
(
EventType
.
EVENT_ENTER_REGION
,
new
ScriptArgs
(
region
.
getConfigId
()).
setSourceEntityId
(
region
.
getId
()));
callEvent
(
EventType
.
EVENT_ENTER_REGION
,
new
ScriptArgs
(
region
.
config_id
).
setSourceEntityId
(
region
.
config_id
));
region
.
resetNewEntities
();
region
.
resetNewEntities
();
}
}
}
}
}
}
public
List
<
EntityGadget
>
getGadgetsInGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
return
suite
.
sceneGadgets
.
stream
()
.
map
(
g
->
createGadget
(
group
.
id
,
group
.
block_id
,
g
))
.
filter
(
Objects:
:
nonNull
)
.
toList
();
}
public
List
<
EntityMonster
>
getMonstersInGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
return
suite
.
sceneMonsters
.
stream
()
.
map
(
mob
->
createMonster
(
group
.
id
,
group
.
block_id
,
mob
))
.
filter
(
Objects:
:
nonNull
)
.
toList
();
}
public
void
addGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
public
void
addGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
spawnMonstersInGroup
(
group
,
suite
);
// we added trigger first
spawnGadgetsInGroup
(
group
,
suite
);
registerTrigger
(
suite
.
sceneTriggers
);
registerTrigger
(
suite
.
sceneTriggers
);
var
toCreate
=
new
ArrayList
<
GameEntity
>();
toCreate
.
addAll
(
getGadgetsInGroupSuite
(
group
,
suite
));
toCreate
.
addAll
(
getMonstersInGroupSuite
(
group
,
suite
));
addEntities
(
toCreate
);
registerRegionInGroupSuite
(
group
,
suite
);
}
}
public
void
removeGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
public
void
removeGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
deregisterTrigger
(
suite
.
sceneTriggers
);
removeMonstersInGroup
(
group
,
suite
);
removeMonstersInGroup
(
group
,
suite
);
removeGadgetsInGroup
(
group
,
suite
);
removeGadgetsInGroup
(
group
,
suite
);
deregisterTrigger
(
suite
.
sceneTriggers
);
}
suite
.
sceneRegions
.
forEach
(
this
::
deregisterRegion
);
public
void
spawnGadgetsInGroup
(
SceneGroup
group
,
int
suiteIndex
)
{
spawnGadgetsInGroup
(
group
,
group
.
getSuiteByIndex
(
suiteIndex
));
}
public
void
spawnGadgetsInGroup
(
SceneGroup
group
)
{
spawnGadgetsInGroup
(
group
,
null
);
}
}
public
void
spawnGadgetsInGroup
(
SceneGroup
group
,
SceneSuite
suite
)
{
public
void
spawnGadgetsInGroup
(
SceneGroup
group
,
SceneSuite
suite
)
{
var
gadgets
=
group
.
gadgets
.
values
();
var
gadgets
=
group
.
gadgets
.
values
();
if
(
suite
!=
null
)
{
if
(
suite
!=
null
)
{
gadgets
=
suite
.
sceneGadgets
;
gadgets
=
suite
.
sceneGadgets
;
}
}
...
@@ -240,13 +246,6 @@ public class SceneScriptManager {
...
@@ -240,13 +246,6 @@ public class SceneScriptManager {
this
.
addEntities
(
toCreate
);
this
.
addEntities
(
toCreate
);
}
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
,
int
suiteIndex
)
{
var
suite
=
group
.
getSuiteByIndex
(
suiteIndex
);
if
(
suite
==
null
){
return
;
}
spawnMonstersInGroup
(
group
,
suite
);
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
,
SceneSuite
suite
)
{
public
void
spawnMonstersInGroup
(
SceneGroup
group
,
SceneSuite
suite
)
{
if
(
suite
==
null
||
suite
.
sceneMonsters
.
size
()
<=
0
){
if
(
suite
==
null
||
suite
.
sceneMonsters
.
size
()
<=
0
){
return
;
return
;
...
@@ -254,11 +253,6 @@ public class SceneScriptManager {
...
@@ -254,11 +253,6 @@ public class SceneScriptManager {
this
.
addEntities
(
suite
.
sceneMonsters
.
stream
()
this
.
addEntities
(
suite
.
sceneMonsters
.
stream
()
.
map
(
mob
->
createMonster
(
group
.
id
,
group
.
block_id
,
mob
)).
toList
());
.
map
(
mob
->
createMonster
(
group
.
id
,
group
.
block_id
,
mob
)).
toList
());
}
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
)
{
this
.
addEntities
(
group
.
monsters
.
values
().
stream
()
.
map
(
mob
->
createMonster
(
group
.
id
,
group
.
block_id
,
mob
)).
toList
());
}
public
void
startMonsterTideInGroup
(
SceneGroup
group
,
Integer
[]
ordersConfigId
,
int
tideCount
,
int
sceneLimit
)
{
public
void
startMonsterTideInGroup
(
SceneGroup
group
,
Integer
[]
ordersConfigId
,
int
tideCount
,
int
sceneLimit
)
{
this
.
scriptMonsterTideService
=
this
.
scriptMonsterTideService
=
...
...
src/main/java/emu/grasscutter/scripts/ScriptLib.java
View file @
67ac0d70
...
@@ -309,22 +309,22 @@ public class ScriptLib {
...
@@ -309,22 +309,22 @@ public class ScriptLib {
return
0
;
return
0
;
}
}
public
int
GetRegionEntityCount
(
LuaTable
table
)
{
public
int
GetRegionEntityCount
(
LuaTable
table
)
{
logger
.
debug
(
"[LUA] Call GetRegionEntityCount with {}"
,
logger
.
debug
(
"[LUA] Call GetRegionEntityCount with {}"
,
printTable
(
table
));
printTable
(
table
));
int
regionId
=
table
.
get
(
"region_eid"
).
toint
();
int
regionId
=
table
.
get
(
"region_eid"
).
toint
();
int
entityType
=
table
.
get
(
"entity_type"
).
toint
();
int
entityType
=
table
.
get
(
"entity_type"
).
toint
();
SceneRegion
region
=
this
.
getSceneScriptManager
().
getRegionById
(
regionId
);
var
region
=
this
.
getSceneScriptManager
().
getRegionById
(
regionId
);
if
(
region
==
null
)
{
if
(
region
==
null
)
{
return
0
;
return
0
;
}
}
return
(
int
)
region
.
getEntities
().
intS
tream
().
filter
(
e
->
e
>>
24
==
entityType
).
count
();
return
(
int
)
region
.
getEntities
().
s
tream
().
filter
(
e
->
e
>>
24
==
entityType
).
count
();
}
}
public
void
PrintContextLog
(
String
msg
)
{
public
void
PrintContextLog
(
String
msg
)
{
logger
.
info
(
"[LUA] "
+
msg
);
logger
.
info
(
"[LUA] "
+
msg
);
}
}
...
...
src/main/java/emu/grasscutter/scripts/data/SceneGroup.java
View file @
67ac0d70
...
@@ -34,10 +34,10 @@ public class SceneGroup {
...
@@ -34,10 +34,10 @@ public class SceneGroup {
public
Map
<
Integer
,
SceneGadget
>
gadgets
;
// <ConfigId, Gadgets>
public
Map
<
Integer
,
SceneGadget
>
gadgets
;
// <ConfigId, Gadgets>
public
Map
<
String
,
SceneTrigger
>
triggers
;
public
Map
<
String
,
SceneTrigger
>
triggers
;
public
Map
<
Integer
,
SceneNPC
>
npc
;
// <NpcId, NPC>
public
Map
<
Integer
,
SceneNPC
>
npc
;
// <NpcId, NPC>
public
List
<
SceneRegion
>
regions
;
public
Map
<
Integer
,
SceneRegion
>
regions
;
public
List
<
SceneSuite
>
suites
;
public
List
<
SceneSuite
>
suites
;
public
List
<
SceneVar
>
variables
;
public
List
<
SceneVar
>
variables
;
public
SceneBusiness
business
;
public
SceneBusiness
business
;
public
SceneGarbage
garbages
;
public
SceneGarbage
garbages
;
public
SceneInitConfig
init_config
;
public
SceneInitConfig
init_config
;
...
@@ -115,9 +115,12 @@ public class SceneGroup {
...
@@ -115,9 +115,12 @@ public class SceneGroup {
triggers
.
values
().
forEach
(
t
->
t
.
currentGroup
=
this
);
triggers
.
values
().
forEach
(
t
->
t
.
currentGroup
=
this
);
suites
=
ScriptLoader
.
getSerializer
().
toList
(
SceneSuite
.
class
,
bindings
.
get
(
"suites"
));
suites
=
ScriptLoader
.
getSerializer
().
toList
(
SceneSuite
.
class
,
bindings
.
get
(
"suites"
));
regions
=
ScriptLoader
.
getSerializer
().
toList
(
SceneRegion
.
class
,
bindings
.
get
(
"regions"
));
regions
=
ScriptLoader
.
getSerializer
().
toList
(
SceneRegion
.
class
,
bindings
.
get
(
"regions"
)).
stream
()
.
collect
(
Collectors
.
toMap
(
x
->
x
.
config_id
,
y
->
y
));
regions
.
values
().
forEach
(
m
->
m
.
group
=
this
);
init_config
=
ScriptLoader
.
getSerializer
().
toObject
(
SceneInitConfig
.
class
,
bindings
.
get
(
"init_config"
));
init_config
=
ScriptLoader
.
getSerializer
().
toObject
(
SceneInitConfig
.
class
,
bindings
.
get
(
"init_config"
));
// Garbages TODO fix properly later
// Garbages TODO fix properly later
Object
garbagesValue
=
bindings
.
get
(
"garbages"
);
Object
garbagesValue
=
bindings
.
get
(
"garbages"
);
if
(
garbagesValue
!=
null
&&
garbagesValue
instanceof
LuaValue
garbagesTable
)
{
if
(
garbagesValue
!=
null
&&
garbagesValue
instanceof
LuaValue
garbagesTable
)
{
...
@@ -157,12 +160,19 @@ public class SceneGroup {
...
@@ -157,12 +160,19 @@ public class SceneGroup {
.
map
(
triggers:
:
get
)
.
map
(
triggers:
:
get
)
.
toList
()
.
toList
()
);
);
suite
.
sceneRegions
=
new
ArrayList
<>(
suite
.
regions
.
stream
()
.
filter
(
regions:
:
containsKey
)
.
map
(
regions:
:
get
)
.
toList
()
);
}
}
}
catch
(
ScriptException
e
)
{
}
catch
(
ScriptException
e
)
{
Grasscutter
.
getLogger
().
error
(
"Error loading group "
+
id
+
" in scene "
+
sceneId
,
e
);
Grasscutter
.
getLogger
().
error
(
"Error loading group "
+
id
+
" in scene "
+
sceneId
,
e
);
}
}
Grasscutter
.
getLogger
().
info
(
"group {} in scene {} is loaded successfully."
,
id
,
sceneId
);
Grasscutter
.
getLogger
().
info
(
"group {} in scene {} is loaded successfully."
,
id
,
sceneId
);
return
this
;
return
this
;
}
}
...
...
src/main/java/emu/grasscutter/scripts/data/SceneRegion.java
View file @
67ac0d70
package
emu.grasscutter.scripts.data
;
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.scripts.constants.ScriptRegionShape
;
import
emu.grasscutter.scripts.constants.ScriptRegionShape
;
import
emu.grasscutter.utils.Position
;
import
emu.grasscutter.utils.Position
;
import
it.unimi.dsi.fastutil.ints.IntOpenHashSet
;
import
it.unimi.dsi.fastutil.ints.IntSet
;
import
lombok.Data
;
import
lombok.Setter
;
import
lombok.Setter
;
import
lombok.ToString
;
@ToString
@Setter
@Setter
public
class
SceneRegion
{
public
class
SceneRegion
{
public
int
config_id
;
public
int
config_id
;
public
int
shape
;
public
int
shape
;
public
Position
pos
;
public
Position
pos
;
// for CUBIC
public
Position
size
;
public
Position
size
;
// for SPHERE
private
boolean
hasNewEntities
;
public
int
radius
;
private
final
IntSet
entities
;
// Ids of entities inside this region
public
SceneRegion
()
{
this
.
entities
=
new
IntOpenHashSet
();
}
public
IntSet
getEntities
()
{
return
entities
;
}
public
void
addEntity
(
GameEntity
entity
)
{
public
transient
SceneGroup
group
;
if
(
this
.
getEntities
().
contains
(
entity
.
getId
()))
{
public
boolean
contains
(
Position
position
)
{
return
;
}
this
.
getEntities
().
add
(
entity
.
getId
());
this
.
hasNewEntities
=
true
;
}
public
void
removeEntity
(
GameEntity
entity
)
{
this
.
getEntities
().
remove
(
entity
.
getId
());
}
public
boolean
contains
(
Position
p
)
{
switch
(
shape
)
{
switch
(
shape
)
{
case
ScriptRegionShape
.
CUBIC
:
case
ScriptRegionShape
.
CUBIC
:
return
(
Math
.
abs
(
pos
.
getX
()
-
p
.
getX
())
<=
size
.
getX
())
&&
return
(
Math
.
abs
(
pos
.
getX
()
-
position
.
getX
())
<=
size
.
getX
())
&&
(
Math
.
abs
(
pos
.
getZ
()
-
p
.
getZ
())
<=
size
.
getZ
());
(
Math
.
abs
(
pos
.
getY
()
-
position
.
getY
())
<=
size
.
getY
())
&&
(
Math
.
abs
(
pos
.
getZ
()
-
position
.
getZ
())
<=
size
.
getZ
());
case
ScriptRegionShape
.
SPHERE
:
case
ScriptRegionShape
.
SPHERE
:
return
false
;
var
x
=
Math
.
pow
(
pos
.
getX
()
-
position
.
getX
(),
2
);
var
y
=
Math
.
pow
(
pos
.
getY
()
-
position
.
getY
(),
2
);
var
z
=
Math
.
pow
(
pos
.
getZ
()
-
position
.
getZ
(),
2
);
return
x
+
y
+
z
<=
(
radius
^
2
);
}
}
return
false
;
return
false
;
}
}
public
boolean
hasNewEntities
()
{
return
hasNewEntities
;
}
public
void
resetNewEntities
()
{
hasNewEntities
=
false
;
}
}
}
src/main/java/emu/grasscutter/scripts/data/SceneSuite.java
View file @
67ac0d70
...
@@ -11,9 +11,12 @@ public class SceneSuite {
...
@@ -11,9 +11,12 @@ public class SceneSuite {
public
List
<
Integer
>
monsters
;
public
List
<
Integer
>
monsters
;
public
List
<
Integer
>
gadgets
;
public
List
<
Integer
>
gadgets
;
public
List
<
String
>
triggers
;
public
List
<
String
>
triggers
;
public
int
rand_weight
;
public
List
<
Integer
>
regions
;
public
int
rand_weight
;
public
transient
List
<
SceneMonster
>
sceneMonsters
;
public
transient
List
<
SceneMonster
>
sceneMonsters
;
public
transient
List
<
SceneGadget
>
sceneGadgets
;
public
transient
List
<
SceneGadget
>
sceneGadgets
;
public
transient
List
<
SceneTrigger
>
sceneTriggers
;
public
transient
List
<
SceneTrigger
>
sceneTriggers
;
public
transient
List
<
SceneRegion
>
sceneRegions
;
}
}
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