mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-02-07 02:26:43 +01:00
Copy some files from Grasscutter-Quests
NOT completely finished, nor is it completely done. Protocol issues remain! (including lack of packet IDs)
This commit is contained in:
@@ -1,53 +1,54 @@
|
||||
package emu.grasscutter.scripts;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.scripts.data.controller.EntityController;
|
||||
import lombok.val;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.CompiledScript;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static emu.grasscutter.utils.FileUtils.getScriptPath;
|
||||
|
||||
public class EntityControllerScriptManager {
|
||||
private static final Map<String, EntityController> gadgetController = new ConcurrentHashMap<>();
|
||||
|
||||
public static void load(){
|
||||
cacheGadgetControllers();
|
||||
}
|
||||
|
||||
private static void cacheGadgetControllers(){
|
||||
try {
|
||||
Files.newDirectoryStream(getScriptPath("Gadget/"), "*.lua").forEach(path -> {
|
||||
val fileName = path.getFileName().toString();
|
||||
|
||||
if(!fileName.endsWith(".lua")) return;
|
||||
|
||||
val controllerName = fileName.substring(0, fileName.length()-4);
|
||||
CompiledScript cs = ScriptLoader.getScript("Gadget/"+fileName);
|
||||
Bindings bindings = ScriptLoader.getEngine().createBindings();
|
||||
if (cs == null) return;
|
||||
|
||||
try{
|
||||
cs.eval(bindings);
|
||||
gadgetController.put(controllerName, new EntityController(cs, bindings));
|
||||
} catch (Throwable e){
|
||||
Grasscutter.getLogger().error("Error while loading gadget controller: {}", fileName);
|
||||
}
|
||||
});
|
||||
|
||||
Grasscutter.getLogger().info("Loaded {} gadget controllers", gadgetController.size());
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Error loading gadget controller luas");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static EntityController getGadgetController(String name) {
|
||||
return gadgetController.get(name);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.scripts;
|
||||
|
||||
import static emu.grasscutter.utils.FileUtils.getScriptPath;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.scripts.data.controller.EntityController;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.script.Bindings;
|
||||
import javax.script.CompiledScript;
|
||||
import lombok.val;
|
||||
|
||||
public class EntityControllerScriptManager {
|
||||
private static final Map<String, EntityController> gadgetController = new ConcurrentHashMap<>();
|
||||
|
||||
public static void load() {
|
||||
cacheGadgetControllers();
|
||||
}
|
||||
|
||||
private static void cacheGadgetControllers() {
|
||||
try {
|
||||
Files.newDirectoryStream(getScriptPath("Gadget/"), "*.lua")
|
||||
.forEach(
|
||||
path -> {
|
||||
val fileName = path.getFileName().toString();
|
||||
|
||||
if (!fileName.endsWith(".lua")) return;
|
||||
|
||||
val controllerName = fileName.substring(0, fileName.length() - 4);
|
||||
CompiledScript cs = ScriptLoader.getScript("Gadget/" + fileName);
|
||||
Bindings bindings = ScriptLoader.getEngine().createBindings();
|
||||
if (cs == null) return;
|
||||
|
||||
try {
|
||||
cs.eval(bindings);
|
||||
gadgetController.put(controllerName, new EntityController(cs, bindings));
|
||||
} catch (Throwable e) {
|
||||
Grasscutter.getLogger()
|
||||
.error("Error while loading gadget controller: {}", fileName);
|
||||
}
|
||||
});
|
||||
|
||||
Grasscutter.getLogger().info("Loaded {} gadget controllers", gadgetController.size());
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Error loading gadget controller luas");
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityController getGadgetController(String name) {
|
||||
return gadgetController.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import com.github.davidmoten.rtreemulti.RTree;
|
||||
import com.github.davidmoten.rtreemulti.geometry.Geometry;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.MonsterData;
|
||||
import emu.grasscutter.data.excels.WorldLevelData;
|
||||
import emu.grasscutter.data.excels.monster.MonsterData;
|
||||
import emu.grasscutter.data.excels.world.WorldLevelData;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
|
||||
@@ -518,7 +518,7 @@ public class ScriptLib {
|
||||
|
||||
for (var player : getSceneScriptManager().getScene().getPlayers()) {
|
||||
player.getQuestManager().triggerEvent(QuestTrigger.QUEST_COND_LUA_NOTIFY, var1);
|
||||
player.getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_LUA_NOTIFY, var1);
|
||||
player.getQuestManager().triggerEvent(QuestContent.QUEST_CONTENT_LUA_NOTIFY, var1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package emu.grasscutter.scripts.constants;
|
||||
|
||||
public enum GroupKillPolicy {
|
||||
GROUP_KILL_NONE,
|
||||
GROUP_KILL_ALL,
|
||||
GROUP_KILL_MONSTER,
|
||||
GROUP_KILL_GADGET,
|
||||
GROUP_KILL_NPC
|
||||
}
|
||||
package emu.grasscutter.scripts.constants;
|
||||
|
||||
public enum GroupKillPolicy {
|
||||
GROUP_KILL_NONE,
|
||||
GROUP_KILL_ALL,
|
||||
GROUP_KILL_MONSTER,
|
||||
GROUP_KILL_GADGET,
|
||||
GROUP_KILL_NPC
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package emu.grasscutter.scripts.constants;
|
||||
|
||||
public interface IntValueEnum {
|
||||
int getValue();
|
||||
}
|
||||
package emu.grasscutter.scripts.constants;
|
||||
|
||||
public interface IntValueEnum {
|
||||
int getValue();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package emu.grasscutter.scripts.constants;
|
||||
|
||||
public enum SealBattleType {
|
||||
NONE,
|
||||
ENERGY_CHARGE,
|
||||
KILL_MONSTER
|
||||
}
|
||||
package emu.grasscutter.scripts.constants;
|
||||
|
||||
public enum SealBattleType {
|
||||
NONE,
|
||||
ENERGY_CHARGE,
|
||||
KILL_MONSTER
|
||||
}
|
||||
|
||||
@@ -13,13 +13,10 @@ public class SceneGadget extends SceneObject {
|
||||
public int interact_id;
|
||||
public boolean isOneoff;
|
||||
public int draft_id;
|
||||
public String drop_tag;
|
||||
public boolean persistent;
|
||||
public int mark_flag;
|
||||
public int route_id;
|
||||
public Explore explore;
|
||||
public int trigger_count;
|
||||
public boolean showcutscene;
|
||||
public boolean start_route = true;
|
||||
public boolean is_use_point_array = false;
|
||||
public boolean persistent = false;
|
||||
|
||||
public void setIsOneoff(boolean isOneoff) {
|
||||
this.isOneoff = isOneoff;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package emu.grasscutter.scripts.data;
|
||||
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
@Setter
|
||||
public class SceneReplaceable {
|
||||
public boolean value;
|
||||
public int version;
|
||||
public boolean new_bin_only;
|
||||
}
|
||||
package emu.grasscutter.scripts.data;
|
||||
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
@Setter
|
||||
public class SceneReplaceable {
|
||||
public boolean value;
|
||||
public int version;
|
||||
public boolean new_bin_only;
|
||||
}
|
||||
|
||||
@@ -1,67 +1,104 @@
|
||||
package emu.grasscutter.scripts.data.controller;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.scripts.ScriptLib;
|
||||
import emu.grasscutter.scripts.ScriptLoader;
|
||||
import org.luaj.vm2.LuaError;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.CompiledScript;
|
||||
|
||||
public class EntityController {
|
||||
private transient CompiledScript entityController;
|
||||
private transient Bindings entityControllerBindings;
|
||||
|
||||
public EntityController(CompiledScript entityController, Bindings entityControllerBindings){
|
||||
this.entityController = entityController;
|
||||
this.entityControllerBindings = entityControllerBindings;
|
||||
}
|
||||
|
||||
public void onBeHurt(GameEntity entity, ElementType elementType, boolean isHost) {
|
||||
callControllerScriptFunc(entity, "OnBeHurt", LuaValue.valueOf(elementType.getValue()), LuaValue.valueOf(0), LuaValue.valueOf(isHost));
|
||||
}
|
||||
|
||||
public void onDie(GameEntity entity, ElementType elementType) {
|
||||
callControllerScriptFunc(entity, "OnDie", LuaValue.valueOf(elementType.getValue()), LuaValue.valueOf(0));
|
||||
}
|
||||
|
||||
public void onTimer(GameEntity entity, int now) {
|
||||
callControllerScriptFunc(entity, "OnTimer", LuaValue.valueOf(now));
|
||||
}
|
||||
|
||||
public int onClientExecuteRequest(GameEntity entity, int param1, int param2, int param3) {
|
||||
Grasscutter.getLogger().debug("Request on {}, {}: {}", entity.getGroupId(), param1, entity.getPosition().toString());
|
||||
LuaValue value = callControllerScriptFunc(entity, "OnClientExecuteReq", LuaValue.valueOf(param1), LuaValue.valueOf(param2), LuaValue.valueOf(param3));
|
||||
if(value.isint() && value.toint() == 1) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO actual execution should probably be handle by EntityControllerScriptManager
|
||||
private LuaValue callControllerScriptFunc(GameEntity entity, String funcName, LuaValue arg1) { return callControllerScriptFunc(entity, funcName, arg1, LuaValue.NIL, LuaValue.NIL); }
|
||||
private LuaValue callControllerScriptFunc(GameEntity entity, String funcName, LuaValue arg1, LuaValue arg2) { return callControllerScriptFunc(entity, funcName, arg1, arg2, LuaValue.NIL); }
|
||||
private LuaValue callControllerScriptFunc(GameEntity entity, String funcName, LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
||||
LuaValue funcLua = null;
|
||||
if (funcName != null && !funcName.isEmpty()) {
|
||||
funcLua = (LuaValue) entityControllerBindings.get(funcName);
|
||||
}
|
||||
|
||||
LuaValue ret = LuaValue.ONE;
|
||||
|
||||
if (funcLua != null) {
|
||||
try {
|
||||
ScriptLoader.getScriptLib().setCurrentEntity(entity);
|
||||
ret = funcLua.invoke(new LuaValue[]{ScriptLoader.getScriptLibLua(), arg1, arg2, arg3}).arg1();
|
||||
}catch (LuaError error) {
|
||||
ScriptLib.logger.error("[LUA] call function failed in gadget {} with {} {} {},{}", entity.getEntityTypeId(), funcName, arg1, arg2, arg3, error);
|
||||
ret = LuaValue.valueOf(-1);
|
||||
}
|
||||
} else if(funcName != null && !funcName.equals("OnTimer")) {
|
||||
ScriptLib.logger.error("[LUA] unknown func in gadget {} with {} {} {} {}", entity.getEntityTypeId(), funcName, arg1, arg2, arg3);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.scripts.data.controller;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.scripts.ScriptLib;
|
||||
import emu.grasscutter.scripts.ScriptLoader;
|
||||
import javax.script.Bindings;
|
||||
import javax.script.CompiledScript;
|
||||
import org.luaj.vm2.LuaError;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
public class EntityController {
|
||||
private transient CompiledScript entityController;
|
||||
private transient Bindings entityControllerBindings;
|
||||
|
||||
public EntityController(CompiledScript entityController, Bindings entityControllerBindings) {
|
||||
this.entityController = entityController;
|
||||
this.entityControllerBindings = entityControllerBindings;
|
||||
}
|
||||
|
||||
public void onBeHurt(GameEntity entity, ElementType elementType, boolean isHost) {
|
||||
callControllerScriptFunc(
|
||||
entity,
|
||||
"OnBeHurt",
|
||||
LuaValue.valueOf(elementType.getValue()),
|
||||
LuaValue.valueOf(0),
|
||||
LuaValue.valueOf(isHost));
|
||||
}
|
||||
|
||||
public void onDie(GameEntity entity, ElementType elementType) {
|
||||
callControllerScriptFunc(
|
||||
entity, "OnDie", LuaValue.valueOf(elementType.getValue()), LuaValue.valueOf(0));
|
||||
}
|
||||
|
||||
public void onTimer(GameEntity entity, int now) {
|
||||
callControllerScriptFunc(entity, "OnTimer", LuaValue.valueOf(now));
|
||||
}
|
||||
|
||||
public int onClientExecuteRequest(GameEntity entity, int param1, int param2, int param3) {
|
||||
Grasscutter.getLogger()
|
||||
.debug(
|
||||
"Request on {}, {}: {}", entity.getGroupId(), param1, entity.getPosition().toString());
|
||||
LuaValue value =
|
||||
callControllerScriptFunc(
|
||||
entity,
|
||||
"OnClientExecuteReq",
|
||||
LuaValue.valueOf(param1),
|
||||
LuaValue.valueOf(param2),
|
||||
LuaValue.valueOf(param3));
|
||||
if (value.isint() && value.toint() == 1) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO actual execution should probably be handle by EntityControllerScriptManager
|
||||
private LuaValue callControllerScriptFunc(GameEntity entity, String funcName, LuaValue arg1) {
|
||||
return callControllerScriptFunc(entity, funcName, arg1, LuaValue.NIL, LuaValue.NIL);
|
||||
}
|
||||
|
||||
private LuaValue callControllerScriptFunc(
|
||||
GameEntity entity, String funcName, LuaValue arg1, LuaValue arg2) {
|
||||
return callControllerScriptFunc(entity, funcName, arg1, arg2, LuaValue.NIL);
|
||||
}
|
||||
|
||||
private LuaValue callControllerScriptFunc(
|
||||
GameEntity entity, String funcName, LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
||||
LuaValue funcLua = null;
|
||||
if (funcName != null && !funcName.isEmpty()) {
|
||||
funcLua = (LuaValue) entityControllerBindings.get(funcName);
|
||||
}
|
||||
|
||||
LuaValue ret = LuaValue.ONE;
|
||||
|
||||
if (funcLua != null) {
|
||||
try {
|
||||
ScriptLoader.getScriptLib().setCurrentEntity(entity);
|
||||
ret =
|
||||
funcLua
|
||||
.invoke(new LuaValue[] {ScriptLoader.getScriptLibLua(), arg1, arg2, arg3})
|
||||
.arg1();
|
||||
} catch (LuaError error) {
|
||||
ScriptLib.logger.error(
|
||||
"[LUA] call function failed in gadget {} with {} {} {},{}",
|
||||
entity.getEntityTypeId(),
|
||||
funcName,
|
||||
arg1,
|
||||
arg2,
|
||||
arg3,
|
||||
error);
|
||||
ret = LuaValue.valueOf(-1);
|
||||
}
|
||||
} else if (funcName != null && !funcName.equals("OnTimer")) {
|
||||
ScriptLib.logger.error(
|
||||
"[LUA] unknown func in gadget {} with {} {} {} {}",
|
||||
entity.getEntityTypeId(),
|
||||
funcName,
|
||||
arg1,
|
||||
arg2,
|
||||
arg3);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user