@@ -5,7 +5,7 @@ import type {
55 spawnedEvent ,
66 spawnedEventSignal ,
77} from '../@types/globalThis'
8- import { Dimension , LocationOutOfWorldBoundariesError , system , Vector3 } from '@minecraft/server'
8+ import { Dimension , LocationOutOfWorldBoundariesError , Player , system , Vector3 } from '@minecraft/server'
99
1010import { register } from '@minecraft/server-gametest'
1111
@@ -30,23 +30,23 @@ import './plugins/task'
3030import './plugins/gui'
3131import './plugins/autoFishing'
3232import './plugins/killedBySimPlayer'
33- import './plugins/setting'
33+ // import './plugins/setting'
3434import './plugins/showCommandsList'
35- import { playerMove } from "../lib/xboyEvents/move" ;
35+ import { playerMove } from "../lib/xboyEvents/move" ;
3636import { cannotHandledExceptionWarningText , CommandError , commandManager , getLocationFromEntityLike } from '../lib/yumeCommand/CommandRegistry' ;
3737import '../lib/yumeCommand/scriptEventHandler'
3838
3939const overworld = world . getDimension ( 'overworld' )
40- const tickWaitTimes = 20 * 60 * 60 * 24 * 365
40+ const tickWaitTimes = 20 * 60 * 60 * 24 * 365
41+ const max_simulatedPlayerCount = 5
4142// all of SimulatedPlayer List
42- export const simulatedPlayers = { }
43+ export const simulatedPlayers = { }
4344
4445// simulatedPlayers[PID] = simulatedPlayer;
4546// simulatedPlayers[simulatedPlayer.id] = PID;
4647
4748export let initSucceed = false
4849
49-
5050let randomTickSpeed = 1
5151let doDayLightCycle = true
5252let doMobSpawning = true
@@ -55,51 +55,119 @@ let doMobSpawning = true
5555
5656 randomTickSpeed = world . gameRules . randomTickSpeed
5757 doDayLightCycle = world . gameRules . doDayLightCycle
58- doMobSpawning = world . gameRules . doMobSpawning
58+ doMobSpawning = world . gameRules . doMobSpawning
5959
60- world . sendMessage ( '[模拟玩家] 随机刻->' + randomTickSpeed + '时间->' + doDayLightCycle + '生物生成->' + doMobSpawning )
60+ world . sendMessage ( '[模拟玩家] 随机刻->' + randomTickSpeed + '时间->' + doDayLightCycle + '生物生成->' + doMobSpawning )
6161}
6262// ?
6363
64- let spawnSimulatedPlayer : ( location :Vector3 , dimension :Dimension , pid : number ) => SimulatedPlayer
65- let spawnSimulatedPlayerByNameTag : ( location :Vector3 , dimension :Dimension , nameTag : string ) => SimulatedPlayer
66- let testWorldLocation : Vector3
67- let testWorldDimension : Dimension
64+ let spawnSimulatedPlayerByNameTag : ( location : Vector3 , dimension : Dimension , nameTag : string ) => SimulatedPlayer
65+ let testWorldLocation : Vector3
66+ let testWorldDimension : Dimension
67+
68+
69+ if ( ! world . structureManager . get ( 'xboyMinemcSIM:void' ) )
70+ world . structureManager . createEmpty ( 'xboyMinemcSIM:void' , { x : 1 , y : 1 , z : 1 } ) . saveToWorld ( )
71+
72+ const GetGlobalPID = ( ) => world . scoreboard . getObjective ( '##FlashPlayer##' ) . addScore ( '##currentPID' , 1 )
73+
74+ // 新增每个玩家的个人假人控制ID
75+ // 使用一个动态属性来管理每个玩家的个人假人控制ID
76+ // 为了一致所以暂不全部迁移到动态属性
77+ const currentPID4EveryPlayer = new Map < string , number > ( )
78+ const GetCurrentPID4Player = ( playerId : string ) : number | null => {
79+ const _max_simulatedPlayerCount = GetPlayerSimulatedPlayerCount ( playerId )
80+ if ( _max_simulatedPlayerCount <= 0 ) return null
81+ const value = currentPID4EveryPlayer . get ( playerId ) ?? 0
82+
83+ // 获取此玩家当前可用假人数量
84+ const valid_CurrentPID_List = [ ]
85+ for ( let i = 1 ; i <= _max_simulatedPlayerCount ; i ++ ) {
86+ const PID = GetPlayerPID2GlobalPID ( playerId , i )
87+ if ( ! PID ) { valid_CurrentPID_List . push ( i ) ; continue }
88+ if ( ! simulatedPlayers [ PID ] ?. isValid ) { valid_CurrentPID_List . push ( i ) ; continue }
89+ }
90+
91+
92+ if ( valid_CurrentPID_List . length <= 0 ) return null
93+ return currentPID4EveryPlayer . set ( playerId , value + 1 ) . get ( playerId )
94+ }
95+ // 将这个这个每次重启游戏重置为1的玩家假人PID和全局递增PID挂钩并且存储在动态属性以供持久化假人信息
96+ // 每次玩家请求一个假人都会分配一个玩家个人假人PID
97+ // 如果查询到这个玩家的个人假人PID和全局挂钩则将此个人假人PID指向此全局PID以关联持久化信息
98+ // 否则获取一个新的全局PID关联到此假人并且存储到动态属性
99+ // simulatedPlayers中依旧使用全局PID
100+ function SetPlayerPID2GlobalPID ( playerId : string , CurrentPID4Player : number , GlobalPID : number ) {
101+ // const ex = {
102+ // "-56789": {
103+ // "GlobalPID": 1234567890
104+ // }
105+ // }
106+ // 苦一苦存储,骂名我来担
107+ let data = < string > world . getDynamicProperty ( "info4EveryPlayer_" + playerId ) ?? "{}"
108+ const dataObject = JSON . parse ( data )
109+ if ( ! dataObject [ CurrentPID4Player ] )
110+ dataObject [ CurrentPID4Player ] = { }
111+ dataObject [ CurrentPID4Player ] [ "GlobalPID" ] = GlobalPID
112+ data = JSON . stringify ( dataObject )
113+ world . setDynamicProperty ( "info4EveryPlayer_" + playerId , data )
114+ }
115+ const GetPlayerPID2GlobalPID = ( playerId : string , CurrentPID4Player : number ) : number => {
116+ const data = < string > world . getDynamicProperty ( "info4EveryPlayer_" + playerId ) ?? "{}"
117+ const dataObject = JSON . parse ( data )
118+ let GlobalPID = dataObject ?. [ CurrentPID4Player ] ?. GlobalPID
119+ if ( ! GlobalPID )
120+ SetPlayerPID2GlobalPID ( playerId , CurrentPID4Player , GlobalPID = GetGlobalPID ( ) )
121+ return GlobalPID as number
122+ }
68123
124+ // 每个玩家享受单独的假人限额
125+ const GetPlayerSimulatedPlayerCount = ( playerId : string ) : number => {
126+ const data = < string > world . getDynamicProperty ( "info4EveryPlayer_" + playerId ) ?? "{}"
127+ const dataObject = JSON . parse ( data )
128+ let _max_simulatedPlayerCount = dataObject ?. _max_simulatedPlayerCount
129+ if ( ! _max_simulatedPlayerCount ) {
130+ _max_simulatedPlayerCount = max_simulatedPlayerCount
131+ SetPlayerSimulatedPlayerCount ( playerId , _max_simulatedPlayerCount )
132+ world . sendMessage ( '[模拟玩家] 每个玩家享受单独的假人限额: ' + _max_simulatedPlayerCount )
133+ }
134+ return _max_simulatedPlayerCount as number
135+ }
69136
70- if ( ! world . structureManager . get ( 'xboyMinemcSIM:void' ) )
71- world . structureManager . createEmpty ( 'xboyMinemcSIM:void' , { x :1 , y :1 , z :1 } ) . saveToWorld ( )
137+ const SetPlayerSimulatedPlayerCount = ( playerId : string , count : number ) => {
138+ let data = < string > world . getDynamicProperty ( "info4EveryPlayer_" + playerId ) ?? "{}"
139+ const dataObject = JSON . parse ( data )
140+ dataObject . _max_simulatedPlayerCount = count
141+ data = JSON . stringify ( dataObject )
142+ world . setDynamicProperty ( "info4EveryPlayer_" + playerId , data )
143+ }
72144
73- let currentPID = 0
74- const GetPID = ( ) => ++ currentPID
75145
76146
77- export const initialized : initializedEventSignal = new EventSignal < initializedEvent > ( )
78- export const spawned : spawnedEventSignal = new EventSignal < spawnedEvent > ( )
147+ export const initialized : initializedEventSignal = new EventSignal < initializedEvent > ( )
148+ export const spawned : spawnedEventSignal = new EventSignal < spawnedEvent > ( )
79149
80- register ( '我是云梦' , '假人' , ( test :Test ) => {
81- testWorldLocation = test . worldBlockLocation ( { x :0 , y :0 , z :0 } )
82- testWorldLocation [ "worldBlockLocation" ] = ( v3 :Vector3 ) => test . worldBlockLocation ( v3 )
150+ register ( '我是云梦' , '假人' , ( test : Test ) => {
151+ testWorldLocation = test . worldBlockLocation ( { x : 0 , y : 0 , z : 0 } )
152+ testWorldLocation [ "worldBlockLocation" ] = ( v3 : Vector3 ) => test . worldBlockLocation ( v3 )
83153
84154
85155 world . gameRules . randomTickSpeed = randomTickSpeed
86156 world . gameRules . doDayLightCycle = doDayLightCycle
87157 world . gameRules . doMobSpawning = doMobSpawning
88158
89- spawnSimulatedPlayer = ( location :Vector3 , dimension :Dimension , pid : number ) :SimulatedPlayer => {
90- return spawnSimulatedPlayerByNameTag ( location , dimension , `工具人-${ pid } ` )
91- }
92- spawnSimulatedPlayerByNameTag = ( location :Vector3 , dimension :Dimension , nameTag : string ) :SimulatedPlayer => {
159+ spawnSimulatedPlayerByNameTag = ( location : Vector3 , dimension : Dimension , nameTag : string ) : SimulatedPlayer => {
93160
94- const simulatedPlayer = test . spawnSimulatedPlayer ( { x :0 , y :8 , z :0 } , nameTag )
161+ // 是的,这个nameTag在这里实际先被作为name
162+ const simulatedPlayer = test . spawnSimulatedPlayer ( { x : 0 , y : 8 , z : 0 } , nameTag )
95163 simulatedPlayer . addTag ( 'Backpack2Barrel_init' )
96164 simulatedPlayer . addTag ( SIGN . YUME_SIM_SIGN )
97165 simulatedPlayer . addTag ( SIGN . AUTO_RESPAWN_SIGN )
98166 try {
99167 //@ts -ignore
100- simulatedPlayer . setSpawnPoint ( { ...location , dimension} )
168+ simulatedPlayer . setSpawnPoint ( { ...location , dimension } )
101169 //@ts -ignore
102- simulatedPlayer . teleport ( location , { dimension} )
170+ simulatedPlayer . teleport ( location , { dimension } )
103171 } catch ( e ) {
104172 if ( e instanceof LocationOutOfWorldBoundariesError ) {
105173 console . warn ( '[模拟玩家] 有东西尝试在非法位置生成假人,已阻止' ) ;
@@ -116,59 +184,40 @@ register('我是云梦', '假人', (test:Test) => {
116184 initSucceed = true
117185 console . log ( '[模拟玩家] 初始化完成,输入“假人创建”或“ffpp”' )
118186} )
119- . maxTicks ( tickWaitTimes )
120- . structureName ( 'xboyMinemcSIM:void' ) ;
187+ . maxTicks ( tickWaitTimes )
188+ . structureName ( 'xboyMinemcSIM:void' ) ;
121189// .maxTicks(2)
122190// .maxAttempts(tickWaitTimes)
123191// .requiredSuccessfulAttempts(tickWaitTimes)
124192// .padding(0)
125193
126- // 记分板PID初始化 写的烂 执行两次
127- verify ( )
128- verify ( )
129-
130- let z = 11451400 + Math . floor ( Math . random ( ) * 114514 * 19 )
131- z -= z % 16
132- system . run ( ( ) => {
133- try {
134- overworld . runCommand ( 'execute positioned 15000000 256 ' + z + ' run gametest run 我是云梦:假人' ) ;
135- testWorldDimension = overworld
136- } catch ( e ) {
137- world . sendMessage ( '[模拟玩家] 报错了,我也不知道为什么' + e ) ;
138- }
139- } ) ;
194+ // 记分板PID初始化 写的烂 执行两次
195+ verify ( )
196+ verify ( )
197+
198+ let z = 11451400 + Math . floor ( Math . random ( ) * 114514 * 19 )
199+ z -= z % 16
200+ system . run ( ( ) => {
201+ try {
202+ overworld . runCommand ( 'execute positioned 15000000 256 ' + z + ' run gametest run 我是云梦:假人' ) ;
203+ testWorldDimension = overworld
204+ } catch ( e ) {
205+ world . sendMessage ( '[模拟玩家] 报错了,我也不知道为什么' + e ) ;
206+ }
207+ } ) ;
140208
141209
142210let say = false
143- playerMove . subscribe ( ( ) => {
211+ playerMove . subscribe ( ( ) => {
144212 if ( say ) return
145213 say = true
146214 world . sendMessage ( '[模拟玩家] 初始化完成,输入“假人创建”或“ffpp”' )
147215 //添加第二行提示
148216 world . sendMessage ( '[模拟玩家] 输入“假人帮助”以获取使用说明' )
149217} )
150218
151- // initialized.subscribe(()=> console.error('[模拟玩家]初始化完毕,加载内置插件') )
152- // initialized.subscribe(()=>
153- // {
154- // }
155- // // 'test',
156- // // 'chatSpawn',
157- // // 'command',
158- // // 'breakBlock',
159- // // 'youAreMine',
160- // // 'help',
161- // // 'task',
162- // // 'gui',
163- // // 'autoFishing',
164- // // 'killedBySimPlayer',
165- // // 'setting',
166- // // 'Deja Vu Yan Returns',
Hidden Unicode 167- // // '鱼肉 ~咕噜咕噜',
168- //
169- // )
170-
171- world . beforeEvents . chatSend . subscribe ( ( { message, sender} ) => {
219+
220+ world . beforeEvents . chatSend . subscribe ( ( { message, sender } ) => {
172221 system . run ( ( ) => {
173222 try {
174223 commandManager . execute ( message , {
@@ -185,5 +234,5 @@ world.beforeEvents.chatSend.subscribe(({message, sender}) => {
185234 } ) ;
186235} ) ;
187236
188- export { spawnSimulatedPlayer , spawnSimulatedPlayerByNameTag , testWorldLocation , testWorldDimension , GetPID }
237+ export { spawnSimulatedPlayerByNameTag , testWorldLocation , testWorldDimension , GetGlobalPID , GetCurrentPID4Player , GetPlayerPID2GlobalPID }
189238
0 commit comments