SceneGroup.java 3.91 KB
Newer Older
1
2
package emu.grasscutter.scripts.data;

Akka's avatar
Akka committed
3
4
import emu.grasscutter.Grasscutter;
import emu.grasscutter.scripts.ScriptLoader;
5
import emu.grasscutter.utils.Position;
Akka's avatar
Akka committed
6
7
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
8

Akka's avatar
Akka committed
9
10
11
12
import javax.script.Bindings;
import javax.script.CompiledScript;
import javax.script.ScriptException;
import java.util.ArrayList;
13
14
import java.util.List;
import java.util.Map;
Akka's avatar
Akka committed
15
16
17
import java.util.stream.Collectors;

import static emu.grasscutter.Configuration.SCRIPTS_FOLDER;
18

19
public class SceneGroup {
20
21
	public transient int block_id; // Not an actual variable in the scripts but we will keep it here for reference
	
22
23
24
	public int id;
	public int refresh_id;
	public Position pos;
25
26
27
28
29

	/**
	 * ConfigId - Monster
	 */
	public Map<Integer,SceneMonster> monsters;
30
31
	public List<SceneGadget> gadgets;
	public List<SceneTrigger> triggers;
Melledy's avatar
Melledy committed
32
	public List<SceneRegion> regions;
33
34
	public List<SceneSuite> suites;
	public SceneInitConfig init_config;
Akka's avatar
Akka committed
35
36
37

	public List<SceneVar> variables;
	private transient boolean loaded; // Not an actual variable in the scripts either
38
39
40
41

	public boolean isLoaded() {
		return loaded;
	}
Melledy's avatar
Melledy committed
42
	
Akka's avatar
Akka committed
43
44
45
46
47
48
49
50
51
52
	public void setLoaded(boolean loaded) {
		this.loaded = loaded;
	}

	private transient CompiledScript script; // Not an actual variable in the scripts either

	public CompiledScript getScript() {
		return script;
	}

Melledy's avatar
Melledy committed
53
54
55
	public SceneSuite getSuiteByIndex(int index) {
		return suites.get(index - 1);
	}
Akka's avatar
Akka committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

	public SceneGroup load(int sceneId, Bindings bindings){
		if(loaded){
			return this;
		}
		// Set flag here so if there is no script, we dont call this function over and over again.
		setLoaded(true);

		CompiledScript cs = ScriptLoader.getScriptByPath(
				SCRIPTS_FOLDER + "Scene/" + sceneId + "/scene" + sceneId + "_group" + id + "." + ScriptLoader.getScriptType());

		if (cs == null) {
			return this;
		}

		this.script = cs;
		// Eval script
		try {
			cs.eval(bindings);

			// Set
			monsters = ScriptLoader.getSerializer().toList(SceneMonster.class, bindings.get("monsters")).stream()
					.collect(Collectors.toMap(x -> x.config_id, y -> y));
			gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, bindings.get("gadgets"));
			triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, bindings.get("triggers"));
			suites = ScriptLoader.getSerializer().toList(SceneSuite.class, bindings.get("suites"));
			regions = ScriptLoader.getSerializer().toList(SceneRegion.class, bindings.get("regions"));
			init_config = ScriptLoader.getSerializer().toObject(SceneInitConfig.class, bindings.get("init_config"));

			// Add variables to suite
			variables = ScriptLoader.getSerializer().toList(SceneVar.class, bindings.get("variables"));


			// Add monsters to suite TODO optimize
			Int2ObjectMap<Object> map = new Int2ObjectOpenHashMap<>();
			monsters.entrySet().forEach(m -> map.put(m.getValue().config_id, m));
			monsters.values().forEach(m -> m.groupId = id);
			gadgets.forEach(m -> map.put(m.config_id, m));
			gadgets.forEach(m -> m.groupId = id);

			for (SceneSuite suite : suites) {
				suite.sceneMonsters = new ArrayList<>(suite.monsters.size());
				suite.monsters.forEach(id -> {
					Object objEntry = map.get(id.intValue());
					if (objEntry instanceof Map.Entry<?,?> monsterEntry) {
						Object monster = monsterEntry.getValue();
						if(monster instanceof SceneMonster sceneMonster){
							suite.sceneMonsters.add(sceneMonster);
						}
					}
				});

				suite.sceneGadgets = new ArrayList<>(suite.gadgets.size());
				for (int id : suite.gadgets) {
					try {
						SceneGadget gadget = (SceneGadget) map.get(id);
						if (gadget != null) {
							suite.sceneGadgets.add(gadget);
						}
					} catch (Exception ignored) { }
				}
			}

		} catch (ScriptException e) {
			Grasscutter.getLogger().error("Error loading group " + id + " in scene " + sceneId, e);
		}
		Grasscutter.getLogger().info("group {} in scene {} is loaded successfully.", id, sceneId);
		return this;
	}
125
}