ScriptLib.java 13.5 KB
Newer Older
1
2
3
4
5
6
package emu.grasscutter.scripts;

import emu.grasscutter.game.dungeons.DungeonChallenge;
import emu.grasscutter.game.entity.EntityGadget;
import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.game.entity.GameEntity;
Melledy's avatar
Melledy committed
7
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
8
import emu.grasscutter.scripts.data.SceneGroup;
Melledy's avatar
Melledy committed
9
import emu.grasscutter.scripts.data.SceneRegion;
10
import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify;
11
12
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
import emu.grasscutter.server.packet.send.PacketWorktopOptionNotify;
13
14
15
16
17
18
19
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Optional;
20
21

public class ScriptLib {
22
	public static final Logger logger = LoggerFactory.getLogger(ScriptLib.class);
23
24
25
26
	private final SceneScriptManager sceneScriptManager;
	
	public ScriptLib(SceneScriptManager sceneScriptManager) {
		this.sceneScriptManager = sceneScriptManager;
Akka's avatar
Akka committed
27
		this.currentGroup = new ThreadLocal<>();
28
29
30
31
32
	}

	public SceneScriptManager getSceneScriptManager() {
		return sceneScriptManager;
	}
33
34
35
36
37
38
39
40
41
42

	private String printTable(LuaTable table){
		StringBuilder sb = new StringBuilder();
		sb.append("{");
		for(var meta : table.keys()){
			sb.append(meta).append(":").append(table.get(meta)).append(",");
		}
		sb.append("}");
		return sb.toString();
	}
Akka's avatar
Akka committed
43
44
45
46
47
48
49
50
51
52
53
	private final ThreadLocal<SceneGroup> currentGroup;
	public void setCurrentGroup(SceneGroup currentGroup){
		logger.debug("current {}", currentGroup);
		this.currentGroup.set(currentGroup);
	}
	public Optional<SceneGroup> getCurrentGroup(){
		return Optional.ofNullable(this.currentGroup.get());
	}
	public void removeCurrentGroup(){
		this.currentGroup.remove();
	}
54
	public int SetGadgetStateByConfigId(int configId, int gadgetState) {
55
56
		logger.debug("[LUA] Call SetGadgetStateByConfigId with {},{}",
				configId,gadgetState);
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
		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) {
76
77
		logger.debug("[LUA] Call SetGroupGadgetStateByConfigId with {},{},{}",
				groupId,configId,gadgetState);
78
79
80
81
		List<GameEntity> list = getSceneScriptManager().getScene().getEntities().values().stream()
												.filter(e -> e.getGroupId() == groupId).toList();
		
		for (GameEntity entity : list) {
Melledy's avatar
Melledy committed
82
83
84
85
			if (!(entity instanceof EntityGadget)) {
				continue;
			}
			
86
87
88
89
90
91
92
93
94
95
			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) {
96
97
		logger.debug("[LUA] Call SetWorktopOptionsByGroupId with {},{},{}",
				groupId,configId,options);
Melledy's avatar
Melledy committed
98
		
99
100
101
		Optional<GameEntity> entity = getSceneScriptManager().getScene().getEntities().values().stream()
				.filter(e -> e.getConfigId() == configId && e.getGroupId() == groupId).findFirst();

Melledy's avatar
Melledy committed
102
103

		if (entity.isEmpty() || !(entity.get() instanceof EntityGadget gadget)) {
104
105
			return 1;
		}
Melledy's avatar
Melledy committed
106
107

		if (!(gadget.getContent() instanceof GadgetWorktop worktop)) {
108
109
110
			return 1;
		}
		
Melledy's avatar
Melledy committed
111
		worktop.addWorktopOptions(options);
112
		getSceneScriptManager().getScene().broadcastPacket(new PacketWorktopOptionNotify(gadget));
Melledy's avatar
Melledy committed
113
		
114
115
		return 0;
	}
Akka's avatar
Akka committed
116
117
118
119
120
121

	public int SetWorktopOptions(LuaTable table){
		logger.debug("[LUA] Call SetWorktopOptions with {}", printTable(table));
		// TODO
		return 0;
	}
122
	public int DelWorktopOptionByGroupId(int groupId, int configId, int option) {
123
124
		logger.debug("[LUA] Call DelWorktopOptionByGroupId with {},{},{}",groupId,configId,option);

125
126
127
		Optional<GameEntity> entity = getSceneScriptManager().getScene().getEntities().values().stream()
				.filter(e -> e.getConfigId() == configId && e.getGroupId() == groupId).findFirst();

Melledy's avatar
Melledy committed
128
		if (entity.isEmpty() || !(entity.get() instanceof EntityGadget gadget)) {
129
130
			return 1;
		}
Melledy's avatar
Melledy committed
131
132

		if (!(gadget.getContent() instanceof GadgetWorktop worktop)) {
133
134
135
			return 1;
		}
		
Melledy's avatar
Melledy committed
136
		worktop.removeWorktopOption(option);
137
		getSceneScriptManager().getScene().broadcastPacket(new PacketWorktopOptionNotify(gadget));
Melledy's avatar
Melledy committed
138
		
139
140
141
142
		return 0;
	}
	
	// Some fields are guessed
143
144
145
146
	public int AutoMonsterTide(int challengeIndex, int groupId, Integer[] ordersConfigId, int tideCount, int sceneLimit, int param6) {
		logger.debug("[LUA] Call AutoMonsterTide with {},{},{},{},{},{}",
				challengeIndex,groupId,ordersConfigId,tideCount,sceneLimit,param6);

147
		SceneGroup group = getSceneScriptManager().getGroupById(groupId);
148

149
150
151
		if (group == null || group.monsters == null) {
			return 1;
		}
152

153
		this.getSceneScriptManager().startMonsterTideInGroup(group, ordersConfigId, tideCount, sceneLimit);
154
155
156
157
		
		return 0;
	}
	
158
	public int AddExtraGroupSuite(int groupId, int suite) {
159
160
		logger.debug("[LUA] Call AddExtraGroupSuite with {},{}",
				groupId,suite);
Melledy's avatar
Melledy committed
161
162
163
164
165
		SceneGroup group = getSceneScriptManager().getGroupById(groupId);
		
		if (group == null || group.monsters == null) {
			return 1;
		}
166

167
168
169
170
171
172
		// avoid spawn wrong monster
		if(getSceneScriptManager().getScene().getChallenge() != null)
			if(!getSceneScriptManager().getScene().getChallenge().inProgress() ||
					getSceneScriptManager().getScene().getChallenge().getGroup().id != groupId){
			return 0;
		}
Melledy's avatar
Melledy committed
173
		this.getSceneScriptManager().spawnMonstersInGroup(group, suite);
Melledy's avatar
Melledy committed
174
		
Melledy's avatar
Melledy committed
175
176
177
		return 0;
	}
	
Melledy's avatar
Melledy committed
178
	// param3 (probably time limit for timed dungeons)
179
180
181
182
	public int ActiveChallenge(int challengeId, int challengeIndex, int timeLimitOrGroupId, int groupId, int objectiveKills, int param5) {
		logger.debug("[LUA] Call ActiveChallenge with {},{},{},{},{},{}",
				challengeId,challengeIndex,timeLimitOrGroupId,groupId,objectiveKills,param5);

183
		SceneGroup group = getSceneScriptManager().getGroupById(groupId);
184
185
186
187
188
189
		var objective = objectiveKills;

		if(group == null){
			group = getSceneScriptManager().getGroupById(timeLimitOrGroupId);
			objective = groupId;
		}
190
191
192
193
		
		if (group == null || group.monsters == null) {
			return 1;
		}
194
195
196
197
198
199
200

		if(getSceneScriptManager().getScene().getChallenge() != null &&
				getSceneScriptManager().getScene().getChallenge().inProgress())
		{
			return 0;
		}

201
202
203
204
205
		DungeonChallenge challenge = new DungeonChallenge(getSceneScriptManager().getScene(),
				group, challengeId, challengeIndex, objective);
		// set if tower first stage (6-1)
		challenge.setStage(getSceneScriptManager().getVariables().getOrDefault("stage", -1) == 0);

206
		getSceneScriptManager().getScene().setChallenge(challenge);
207

208
209
210
211
		challenge.start();
		return 0;
	}
	
212
	public int GetGroupMonsterCountByGroupId(int groupId) {
213
214
		logger.debug("[LUA] Call GetGroupMonsterCountByGroupId with {}",
				groupId);
215
216
217
218
219
		return (int) getSceneScriptManager().getScene().getEntities().values().stream()
								.filter(e -> e instanceof EntityMonster && e.getGroupId() == groupId)
								.count();
	}
	
Melledy's avatar
Melledy committed
220
	public int GetGroupVariableValue(String var) {
221
222
		logger.debug("[LUA] Call GetGroupVariableValue with {}",
				var);
Melledy's avatar
Melledy committed
223
		return getSceneScriptManager().getVariables().getOrDefault(var, 0);
224
225
	}
	
226
	public int SetGroupVariableValue(String var, int value) {
227
228
		logger.debug("[LUA] Call SetGroupVariableValue with {},{}",
				var, value);
229
		getSceneScriptManager().getVariables().put(var, value);
230
231
232
233
		return 0;
	}
	
	public LuaValue ChangeGroupVariableValue(String var, int value) {
234
235
236
		logger.debug("[LUA] Call ChangeGroupVariableValue with {},{}",
				var, value);

237
		getSceneScriptManager().getVariables().put(var, getSceneScriptManager().getVariables().get(var) + value);
238
239
		return LuaValue.ZERO;
	}
240
241
242
243

	/**
	 * Set the actions and triggers to designated group
	 */
244
	public int RefreshGroup(LuaTable table) {
245
		logger.debug("[LUA] Call RefreshGroup with {}",
246
				printTable(table));
247
248
249
250
251
252
253
254
255
256
		// 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;
		}
		
257
		getSceneScriptManager().refreshGroup(group, suite);
258
		
259
260
261
		return 0;
	}
	
Melledy's avatar
Melledy committed
262
	public int GetRegionEntityCount(LuaTable table) {
263
264
		logger.debug("[LUA] Call GetRegionEntityCount with {}",
				table);
Melledy's avatar
Melledy committed
265
266
267
268
269
270
271
272
273
274
275
276
		int regionId = table.get("region_eid").toint();
		int entityType = table.get("entity_type").toint();

		SceneRegion region = this.getSceneScriptManager().getRegionById(regionId);
		
		if (region == null) {
			return 0;
		}

		return (int) region.getEntities().intStream().filter(e -> e >> 24 == entityType).count();
	}
	
277
	public void PrintContextLog(String msg) {
278
		logger.info("[LUA] " + msg);
279
	}
Akka's avatar
Akka committed
280

281
282
283
284
	public int TowerCountTimeStatus(int isDone, int var2){
		logger.debug("[LUA] Call TowerCountTimeStatus with {},{}",
				isDone,var2);
		// TODO record time
Akka's avatar
Akka committed
285
286
287
		return 0;
	}
	public int GetGroupMonsterCount(int var1){
288
289
290
291
		logger.debug("[LUA] Call GetGroupMonsterCount with {}",
				var1);

		return (int) getSceneScriptManager().getScene().getEntities().values().stream()
Akka's avatar
Akka committed
292
293
				.filter(e -> e instanceof EntityMonster &&
						e.getGroupId() == getCurrentGroup().map(sceneGroup -> sceneGroup.id).orElse(-1))
294
				.count();
Akka's avatar
Akka committed
295
296
	}
	public int SetMonsterBattleByGroup(int var1, int var2, int var3){
297
298
		logger.debug("[LUA] Call SetMonsterBattleByGroup with {},{},{}",
				var1,var2,var3);
299
		// TODO
Akka's avatar
Akka committed
300
301
302
303
		return 0;
	}

	public int CauseDungeonFail(int var1){
304
305
306
307
308
		logger.debug("[LUA] Call CauseDungeonFail with {}",
				var1);

		return 0;
	}
309

310
311
312
	public int GetGroupVariableValueByGroup(String name, int groupId){
		logger.debug("[LUA] Call GetGroupVariableValueByGroup with {},{}",
				name,groupId);
313

314
		return getSceneScriptManager().getVariables().getOrDefault(name, 0);
315
316
317
318
319
320
321
322
323
324
325
326
	}

	public int SetIsAllowUseSkill(int canUse, int var2){
		logger.debug("[LUA] Call SetIsAllowUseSkill with {},{}",
				canUse,var2);

		getSceneScriptManager().getScene().broadcastPacket(new PacketCanUseSkillNotify(canUse == 1));
		return 0;
	}

	public int KillEntityByConfigId(LuaTable table){
		logger.debug("[LUA] Call KillEntityByConfigId with {}",
327
				printTable(table));
328
329
330
331
332
333
334
335
336
337
		var configId = table.get("config_id");
		if(configId == LuaValue.NIL){
			return 1;
		}

		var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId.toint());
		if(entity == null){
			return 1;
		}
		getSceneScriptManager().getScene().killEntity(entity, 0);
Akka's avatar
Akka committed
338
339
		return 0;
	}
340

341
342
343
344
	public int SetGroupVariableValueByGroup(String key, int value, int groupId){
		logger.debug("[LUA] Call SetGroupVariableValueByGroup with {},{},{}",
				key,value,groupId);

345
346
347
348
349
350
351
352
353
354
		getSceneScriptManager().getVariables().put(key, value);
		return 0;
	}

	public int CreateMonster(LuaTable table){
		logger.debug("[LUA] Call CreateMonster with {}",
				printTable(table));
		var configId = table.get("config_id").toint();
		var delayTime = table.get("delay_time").toint();

Akka's avatar
Akka committed
355
356
357
358
359
		if(getCurrentGroup().isEmpty()){
			return 1;
		}

		getSceneScriptManager().spawnMonstersByConfigId(getCurrentGroup().get(), configId, delayTime);
360
361
362
363
364
365
366
		return 0;
	}

	public int TowerMirrorTeamSetUp(int team, int var1) {
		logger.debug("[LUA] Call TowerMirrorTeamSetUp with {},{}",
				team,var1);

367
		getSceneScriptManager().unloadCurrentMonsterTide();
368
369
		getSceneScriptManager().getScene().getPlayers().get(0).getTowerManager().mirrorTeamSetUp(team-1);

370
371
372
		return 0;
	}

373
374
375
376
377
	public int CreateGadget(LuaTable table){
		logger.debug("[LUA] Call CreateGadget with {}",
				printTable(table));
		var configId = table.get("config_id").toint();

Akka's avatar
Akka committed
378
		var group = getCurrentGroup();
379
380
		
		if (group.isEmpty()) {
Akka's avatar
Akka committed
381
382
			return 1;
		}
383
		
Akka's avatar
Akka committed
384
385
		var gadget = group.get().gadgets.get(configId);
		var entity = getSceneScriptManager().createGadget(group.get().id, group.get().block_id, gadget);
386
		
Akka's avatar
Akka committed
387
		getSceneScriptManager().addEntity(entity);
388

Akka's avatar
Akka committed
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
		return 0;
	}
	public int CheckRemainGadgetCountByGroupId(LuaTable table){
		logger.debug("[LUA] Call CheckRemainGadgetCountByGroupId with {}",
				printTable(table));
		var groupId = table.get("group_id").toint();

		var count = getSceneScriptManager().getScene().getEntities().values().stream()
				.filter(g -> g instanceof EntityGadget entityGadget && entityGadget.getGroupId() == groupId)
				.count();
		return (int)count;
	}

	public int GetGadgetStateByConfigId(int groupId, int configId){
		logger.debug("[LUA] Call GetGadgetStateByConfigId with {},{}",
				groupId, configId);
		var gadget = getSceneScriptManager().getScene().getEntities().values().stream()
				.filter(g -> g instanceof EntityGadget entityGadget && entityGadget.getGroupId() == groupId)
				.filter(g -> g.getConfigId() == configId)
				.findFirst();
		if(gadget.isEmpty()){
Akka's avatar
Akka committed
410
			return 1;
Akka's avatar
Akka committed
411
		}
Akka's avatar
Akka committed
412
		return ((EntityGadget)gadget.get()).getState();
Akka's avatar
Akka committed
413
	}
Akka's avatar
Akka committed
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

	public int MarkPlayerAction(int var1, int var2, int var3, int var4){
		logger.debug("[LUA] Call MarkPlayerAction with {},{}",
				var1, var2);

		return 0;
	}

	public int AddQuestProgress(String var1){
		logger.debug("[LUA] Call AddQuestProgress with {}",
				var1);

		return 0;
	}

	/**
	 * change the state of gadget
	 */
	public int ChangeGroupGadget(LuaTable table){
		logger.debug("[LUA] Call ChangeGroupGadget with {}",
				printTable(table));
		var configId = table.get("config_id").toint();
		var state = table.get("state").toint();

		var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId);
		if(entity == null){
			return 1;
		}

443
444
		if (entity instanceof EntityGadget entityGadget) {
			entityGadget.updateState(state);
Akka's avatar
Akka committed
445
		}
Akka's avatar
Akka committed
446

447
448
		return 0;
	}
449
}