mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-05-15 11:42:32 +08:00
100 lines
3.9 KiB
Java
100 lines
3.9 KiB
Java
package emu.grasscutter.game.ability.actions;
|
|
|
|
import com.google.protobuf.ByteString;
|
|
import emu.grasscutter.Grasscutter;
|
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
|
import emu.grasscutter.game.ability.Ability;
|
|
import emu.grasscutter.game.entity.GameEntity;
|
|
import emu.grasscutter.scripts.ScriptLoader;
|
|
import javax.script.Bindings;
|
|
import org.luaj.vm2.LuaFunction;
|
|
import org.luaj.vm2.LuaValue;
|
|
|
|
@AbilityAction(AbilityModifierAction.Type.ServerLuaCall)
|
|
public final class ActionServerLuaCall extends AbilityActionHandler {
|
|
@Override
|
|
public boolean execute(
|
|
Ability ability, AbilityModifierAction action, ByteString abilityData, GameEntity target) {
|
|
var scene = target.getScene();
|
|
var scriptManager = scene.getScriptManager();
|
|
|
|
var functionName = action.funcName;
|
|
|
|
// Set the script library's manager.
|
|
var scriptLib = ScriptLoader.getScriptLib();
|
|
scriptLib.setCurrentEntity(target);
|
|
scriptLib.setSceneScriptManager(scriptManager);
|
|
|
|
// Attempt to call the function.
|
|
return switch (action.luaCallType) {
|
|
default -> false;
|
|
case FromGroup -> {
|
|
var groupId = target.getGroupId();
|
|
var group = scriptManager.getGroupById(groupId);
|
|
var script = group.getBindings();
|
|
|
|
// Set the script library's group.
|
|
scriptLib.setCurrentGroup(group);
|
|
|
|
yield ActionServerLuaCall.callFunction(script, functionName, ability, action);
|
|
}
|
|
case SpecificGroup -> {
|
|
var groupId = action.callParamList[0];
|
|
var group = scriptManager.getGroupById(groupId);
|
|
var script = group.getBindings();
|
|
|
|
// Set the script library's group.
|
|
scriptLib.setCurrentGroup(group);
|
|
|
|
yield ActionServerLuaCall.callFunction(script, functionName, ability, action);
|
|
}
|
|
case Gadget -> {
|
|
var controller = target.getEntityController();
|
|
if (controller == null || functionName.isBlank()) yield false;
|
|
|
|
// Hand off the function handling to the controller.
|
|
controller.callControllerScriptFunc(target, functionName, ability, action);
|
|
|
|
yield true;
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Handles fetching and calling a function.
|
|
*
|
|
* @param bindings The bindings to fetch the function from.
|
|
* @param functionName The name of the function to call.
|
|
* @param ability The ability data.
|
|
* @param action The ability action data.
|
|
* @return Whether the function was called successfully.
|
|
*/
|
|
private static boolean callFunction(
|
|
Bindings bindings, String functionName, Ability ability, AbilityModifierAction action) {
|
|
try {
|
|
// Resolve the function from the script.
|
|
var function = bindings.get(functionName);
|
|
if (!(function instanceof LuaFunction luaFunction))
|
|
throw new Exception("Function is not a LuaFunction.");
|
|
|
|
// Convert parameters to Lua values.
|
|
var lParam1 = LuaValue.valueOf(action.param1.getInt(ability));
|
|
var lParam2 = LuaValue.valueOf(action.param2.getInt(ability));
|
|
var lParam3 = LuaValue.valueOf(action.param3.getInt(ability));
|
|
|
|
// Invoke the function with the parameters.
|
|
switch (action.paramNum) {
|
|
case 1 -> luaFunction.invoke(new LuaValue[] {lParam1});
|
|
case 2 -> luaFunction.invoke(new LuaValue[] {lParam1, lParam2});
|
|
case 3 -> luaFunction.invoke(new LuaValue[] {lParam1, lParam2, lParam3});
|
|
default -> luaFunction.invoke(new LuaValue[] {ScriptLoader.getScriptLibLua()});
|
|
}
|
|
|
|
return true;
|
|
} catch (Exception exception) {
|
|
Grasscutter.getLogger().warn("Unable to invoke {}.", functionName, exception);
|
|
return false;
|
|
}
|
|
}
|
|
}
|