1
1
using HarmonyLib ;
2
+ using KarlsonMapEditor . Scripting_API ;
2
3
using Loadson ;
3
4
using LoadsonAPI ;
4
5
using SevenZip . Compression . LZMA ;
@@ -23,11 +24,19 @@ public static class LevelPlayer
23
24
public static string currentLevel { get ; private set ; } = "" ;
24
25
public static void ExitedLevel ( ) => currentLevel = "" ;
25
26
private static LevelData levelData ;
27
+ private static Automata . Backbone . FunctionRunner mainFunction = null ;
28
+ public static ScriptRunner currentScript { get ; private set ; } = null ;
26
29
27
30
public static void LoadLevel ( string levelPath )
28
31
{
29
32
currentLevel = Path . GetFileName ( levelPath ) ;
30
33
levelData = new LevelData ( File . ReadAllBytes ( levelPath ) ) ;
34
+ if ( levelData . AutomataScript . Trim ( ) . Length > 0 )
35
+ { // load level script
36
+ var tokens = Automata . Parser . Tokenizer . Tokenize ( Automata . Parser . ProgramCleaner . CleanProgram ( levelData . AutomataScript ) ) ;
37
+ var program = new Automata . Parser . ProgramParser ( tokens ) . ParseProgram ( ) ;
38
+ mainFunction = new Automata . Backbone . FunctionRunner ( new List < ( Automata . Backbone . VarResolver , Automata . Backbone . BaseValue . ValueType ) > { } , program ) ;
39
+ }
31
40
SceneManager . sceneLoaded += LoadLevelData ;
32
41
UnityEngine . Object . FindObjectOfType < Lobby > ( ) . LoadMap ( "4Escape0" ) ;
33
42
}
@@ -69,6 +78,7 @@ void ReplicateObjectGroup(LevelData.ObjectGroup group, GameObject parentObject)
69
78
if ( obj . IsPrefab )
70
79
{
71
80
go = LevelData . MakePrefab ( obj . PrefabId ) ;
81
+ go . name = obj . Name ;
72
82
go . transform . parent = objGroup . transform ;
73
83
go . transform . localPosition = obj . Position ;
74
84
go . transform . localRotation = Quaternion . Euler ( obj . Rotation ) ;
@@ -96,11 +106,11 @@ void ReplicateObjectGroup(LevelData.ObjectGroup group, GameObject parentObject)
96
106
if ( obj . Glass )
97
107
{
98
108
go = LoadsonAPI . PrefabManager . NewGlass ( ) ;
109
+ // fix collider
110
+ go . GetComponent < BoxCollider > ( ) . size = Vector3 . one ;
99
111
if ( obj . DisableTrigger )
100
112
{
101
- // fix collider
102
113
go . GetComponent < BoxCollider > ( ) . isTrigger = false ;
103
- go . GetComponent < BoxCollider > ( ) . size = Vector3 . one ;
104
114
UnityEngine . Object . Destroy ( go . GetComponent < Glass > ( ) ) ;
105
115
}
106
116
}
@@ -122,10 +132,22 @@ void ReplicateObjectGroup(LevelData.ObjectGroup group, GameObject parentObject)
122
132
go . GetComponent < MeshRenderer > ( ) . material . color = obj . _Color ;
123
133
if ( obj . Bounce )
124
134
go . GetComponent < BoxCollider > ( ) . material = LoadsonAPI . PrefabManager . BounceMaterial ( ) ;
135
+ go . name = obj . Name ;
125
136
go . transform . parent = objGroup . transform ;
126
137
go . transform . localPosition = obj . Position ;
127
138
go . transform . localRotation = Quaternion . Euler ( obj . Rotation ) ;
128
139
go . transform . localScale = obj . Scale ;
140
+ if ( obj . Glass )
141
+ {
142
+ // fix particle system
143
+ var ps = go . GetComponent < Glass > ( ) . glass . GetComponent < ParticleSystem > ( ) ;
144
+ var shape = ps . shape ;
145
+ shape . scale = go . transform . lossyScale ;
146
+ var volume = ( shape . scale . x * shape . scale . y * shape . scale . z ) ;
147
+ var main = ps . main ;
148
+ main . maxParticles = Math . Max ( ( int ) ( 1000f * volume / 160f ) , 1 ) ;
149
+ main . startSpeed = 0.5f ;
150
+ }
129
151
}
130
152
foreach ( var grp in group . Groups )
131
153
ReplicateObjectGroup ( grp , objGroup ) ;
@@ -155,6 +177,12 @@ IEnumerator enemyFix()
155
177
}
156
178
}
157
179
Coroutines . StartCoroutine ( enemyFix ( ) ) ;
180
+
181
+ // load script
182
+ if ( mainFunction != null )
183
+ currentScript = new ScriptRunner ( mainFunction ) ;
184
+ else
185
+ currentScript = null ;
158
186
}
159
187
160
188
void LoadLevelData_v2 ( )
@@ -251,33 +279,6 @@ public class LevelData
251
279
252
280
public LevelData ( byte [ ] _data )
253
281
{
254
- ObjectGroup ReadObjectGroup ( byte [ ] group )
255
- {
256
- ObjectGroup objGroup = new ObjectGroup ( ) ;
257
- using ( BinaryReader br = new BinaryReader ( new MemoryStream ( group ) ) )
258
- {
259
- objGroup . Name = br . ReadString ( ) ;
260
- objGroup . Position = br . ReadVector3 ( ) ;
261
- objGroup . Rotation = br . ReadVector3 ( ) ;
262
- objGroup . Scale = br . ReadVector3 ( ) ;
263
- int count = br . ReadInt32 ( ) ;
264
- while ( count -- > 0 )
265
- {
266
- bool prefab = br . ReadBoolean ( ) ;
267
- string name = br . ReadString ( ) ;
268
- if ( prefab )
269
- objGroup . Objects . Add ( new LevelObject ( br . ReadInt32 ( ) , br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadVector3 ( ) , name , br . ReadInt32 ( ) ) ) ;
270
- else
271
- objGroup . Objects . Add ( new LevelObject ( br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadInt32 ( ) , br . ReadColor ( ) , name , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) ) ) ;
272
- Loadson . Console . Log ( objGroup . Objects . Last ( ) . ToString ( ) ) ;
273
- }
274
- count = br . ReadInt32 ( ) ;
275
- while ( count -- > 0 )
276
- objGroup . Groups . Add ( ReadObjectGroup ( br . ReadByteArray ( ) ) ) ;
277
- return objGroup ;
278
- }
279
- }
280
-
281
282
// decompress
282
283
byte [ ] data = SevenZipHelper . Decompress ( _data ) ;
283
284
using ( BinaryReader br = new BinaryReader ( new MemoryStream ( data ) ) )
@@ -288,27 +289,10 @@ ObjectGroup ReadObjectGroup(byte[] group)
288
289
LoadLevel_Version1 ( br ) ;
289
290
else if ( version == 2 )
290
291
LoadLevel_Version2 ( br ) ;
291
- else if ( version == 3 )
292
- {
293
- isKMEv2 = true ;
294
- gridAlign = br . ReadSingle ( ) ;
295
- startingGun = br . ReadInt32 ( ) ;
296
- startPosition = br . ReadVector3 ( ) ;
297
- startOrientation = br . ReadSingle ( ) ;
298
- int _len ;
299
- List < Texture2D > list = new List < Texture2D > ( ) ;
300
- int _texl = br . ReadInt32 ( ) ;
301
- while ( _texl -- > 0 )
302
- {
303
- string _name = br . ReadString ( ) ;
304
- _len = br . ReadInt32 ( ) ;
305
- list . Add ( new Texture2D ( 1 , 1 ) ) ;
306
- list . Last ( ) . LoadImage ( br . ReadBytes ( _len ) ) ;
307
- list . Last ( ) . name = _name ;
308
- }
309
- Textures = list . ToArray ( ) ;
310
- GlobalObject = ReadObjectGroup ( br . ReadByteArray ( ) ) ;
311
- }
292
+ else if ( version == 3 )
293
+ LoadLevel_Version3 ( br ) ;
294
+ else if ( version == 4 )
295
+ LoadLevel_Version4 ( br ) ;
312
296
else
313
297
{
314
298
Loadson . Console . Log ( "<color=red>Unknown level version " + version + "</color>" ) ;
@@ -317,6 +301,33 @@ ObjectGroup ReadObjectGroup(byte[] group)
317
301
}
318
302
}
319
303
304
+ ObjectGroup ReadObjectGroup_v3 ( byte [ ] group )
305
+ {
306
+ ObjectGroup objGroup = new ObjectGroup ( ) ;
307
+ using ( BinaryReader br = new BinaryReader ( new MemoryStream ( group ) ) )
308
+ {
309
+ objGroup . Name = br . ReadString ( ) ;
310
+ objGroup . Position = br . ReadVector3 ( ) ;
311
+ objGroup . Rotation = br . ReadVector3 ( ) ;
312
+ objGroup . Scale = br . ReadVector3 ( ) ;
313
+ int count = br . ReadInt32 ( ) ;
314
+ while ( count -- > 0 )
315
+ {
316
+ bool prefab = br . ReadBoolean ( ) ;
317
+ string name = br . ReadString ( ) ;
318
+ if ( prefab )
319
+ objGroup . Objects . Add ( new LevelObject ( br . ReadInt32 ( ) , br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadVector3 ( ) , name , br . ReadInt32 ( ) ) ) ;
320
+ else
321
+ objGroup . Objects . Add ( new LevelObject ( br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadInt32 ( ) , br . ReadColor ( ) , name , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) ) ) ;
322
+ Loadson . Console . Log ( objGroup . Objects . Last ( ) . ToString ( ) ) ;
323
+ }
324
+ count = br . ReadInt32 ( ) ;
325
+ while ( count -- > 0 )
326
+ objGroup . Groups . Add ( ReadObjectGroup_v3 ( br . ReadByteArray ( ) ) ) ;
327
+ return objGroup ;
328
+ }
329
+ }
330
+
320
331
private void LoadLevel_Version1 ( BinaryReader br )
321
332
{
322
333
isKMEv2 = false ;
@@ -349,6 +360,7 @@ private void LoadLevel_Version1(BinaryReader br)
349
360
objects . Add ( new LevelObject ( br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadInt32 ( ) , br . ReadColor ( ) , name , group , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) , false ) ) ;
350
361
}
351
362
Objects = objects . ToArray ( ) ;
363
+ AutomataScript = "" ;
352
364
}
353
365
354
366
private void LoadLevel_Version2 ( BinaryReader br )
@@ -383,6 +395,53 @@ private void LoadLevel_Version2(BinaryReader br)
383
395
objects . Add ( new LevelObject ( br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadVector3 ( ) , br . ReadInt32 ( ) , br . ReadColor ( ) , name , group , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) , br . ReadBoolean ( ) ) ) ;
384
396
}
385
397
Objects = objects . ToArray ( ) ;
398
+ AutomataScript = "" ;
399
+ }
400
+
401
+ private void LoadLevel_Version3 ( BinaryReader br )
402
+ {
403
+ isKMEv2 = true ;
404
+ gridAlign = br . ReadSingle ( ) ;
405
+ startingGun = br . ReadInt32 ( ) ;
406
+ startPosition = br . ReadVector3 ( ) ;
407
+ startOrientation = br . ReadSingle ( ) ;
408
+ int _len ;
409
+ List < Texture2D > list = new List < Texture2D > ( ) ;
410
+ int _texl = br . ReadInt32 ( ) ;
411
+ while ( _texl -- > 0 )
412
+ {
413
+ string _name = br . ReadString ( ) ;
414
+ _len = br . ReadInt32 ( ) ;
415
+ list . Add ( new Texture2D ( 1 , 1 ) ) ;
416
+ list . Last ( ) . LoadImage ( br . ReadBytes ( _len ) ) ;
417
+ list . Last ( ) . name = _name ;
418
+ }
419
+ Textures = list . ToArray ( ) ;
420
+ GlobalObject = ReadObjectGroup_v3 ( br . ReadByteArray ( ) ) ;
421
+ AutomataScript = "" ;
422
+ }
423
+
424
+ private void LoadLevel_Version4 ( BinaryReader br )
425
+ {
426
+ isKMEv2 = true ;
427
+ gridAlign = br . ReadSingle ( ) ;
428
+ startingGun = br . ReadInt32 ( ) ;
429
+ startPosition = br . ReadVector3 ( ) ;
430
+ startOrientation = br . ReadSingle ( ) ;
431
+ int _len ;
432
+ List < Texture2D > list = new List < Texture2D > ( ) ;
433
+ int _texl = br . ReadInt32 ( ) ;
434
+ while ( _texl -- > 0 )
435
+ {
436
+ string _name = br . ReadString ( ) ;
437
+ _len = br . ReadInt32 ( ) ;
438
+ list . Add ( new Texture2D ( 1 , 1 ) ) ;
439
+ list . Last ( ) . LoadImage ( br . ReadBytes ( _len ) ) ;
440
+ list . Last ( ) . name = _name ;
441
+ }
442
+ Textures = list . ToArray ( ) ;
443
+ AutomataScript = br . ReadString ( ) ;
444
+ GlobalObject = ReadObjectGroup_v3 ( br . ReadByteArray ( ) ) ;
386
445
}
387
446
388
447
public bool isKMEv2 ;
@@ -395,6 +454,8 @@ private void LoadLevel_Version2(BinaryReader br)
395
454
public LevelObject [ ] Objects ;
396
455
public ObjectGroup GlobalObject ;
397
456
457
+ public string AutomataScript ;
458
+
398
459
public class LevelObject
399
460
{
400
461
// kme v2 removed group names
@@ -586,4 +647,33 @@ static void Postfix()
586
647
SceneManager . sceneLoaded -= LevelPlayer . LoadLevelData ;
587
648
}
588
649
}
650
+
651
+ [ HarmonyPatch ( typeof ( Glass ) , "OnTriggerEnter" ) ]
652
+ class Hook_Glass_OnTriggerEnter
653
+ {
654
+ static bool Prefix ( Glass __instance , Collider other )
655
+ {
656
+ if ( LevelPlayer . currentLevel == "" ) return true ;
657
+ if ( LevelPlayer . currentScript == null ) return true ;
658
+ // determine break reason
659
+ if ( other . gameObject . layer == LayerMask . NameToLayer ( "Ground" ) )
660
+ return false ; // collide with ground, ignore
661
+ int reason = 0 ;
662
+ if ( other . gameObject . layer == LayerMask . NameToLayer ( "Player" ) )
663
+ reason = 1 ;
664
+ if ( other . gameObject . layer == LayerMask . NameToLayer ( "Bullet" ) )
665
+ {
666
+ if ( other . gameObject . name == "Damage" )
667
+ reason = 3 ;
668
+ else
669
+ reason = 2 ;
670
+ }
671
+ var ret = LevelPlayer . currentScript . InvokeFunction ( "onbreak" , __instance , other , reason ) ;
672
+ if ( ! ret . HoldsTrue ( ) || ret . Type != Automata . Backbone . BaseValue . ValueType . Number ) return true ; // continue normal execution
673
+ var retN = ( double ) ret . Value ;
674
+ if ( retN > 0 ) // insta-break
675
+ UnityEngine . Object . Destroy ( __instance . gameObject ) ;
676
+ return false ;
677
+ }
678
+ }
589
679
}
0 commit comments