Skip to content

Commit

Permalink
fix(ActionServerLuaCall.java): Handle Lua function parameter passing
Browse files Browse the repository at this point in the history
  • Loading branch information
KingRainbow44 committed Sep 29, 2024
1 parent 5b9d386 commit 10423db
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 8 deletions.
13 changes: 10 additions & 3 deletions src/main/java/emu/grasscutter/data/binout/AbilityModifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ public enum Type {
public DynamicFloat valueRangeMax;
public String overrideMapKey;

public int paramNum;
public DynamicFloat
param1 = DynamicFloat.ZERO,
param2 = DynamicFloat.ZERO,
Expand All @@ -359,12 +360,18 @@ public enum Type {
public String content;

public enum LuaCallType {
Gadget,
@SerializedName(value = "OwnerGadegt", alternate = "OwnerGadget")
OwnerGadget,
FromGroup,
CurGalleryControlGroup,
CurChallengeGroup,
OwnerFromGroup,
SpecificGroup,
CurScenePlay,
CurChallengeGroup,
CurRogueBossGroup,
CurGalleryControlGroup,
AbilityGroupSourceGroup,
CurScenePlay
LevelBankZoneContainsGroup
}

public enum DropType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
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 {
Expand All @@ -16,12 +17,14 @@ 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;
Expand All @@ -33,7 +36,7 @@ public boolean execute(
// Set the script library's group.
scriptLib.setCurrentGroup(group);

yield ActionServerLuaCall.callFunction(script, functionName);
yield ActionServerLuaCall.callFunction(script, functionName, ability, action);
}
case SpecificGroup -> {
var groupId = action.callParamList[0];
Expand All @@ -43,7 +46,16 @@ public boolean execute(
// Set the script library's group.
scriptLib.setCurrentGroup(group);

yield ActionServerLuaCall.callFunction(script, functionName);
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;
}
};
}
Expand All @@ -53,17 +65,32 @@ public boolean execute(
*
* @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) {
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.");

// Attempt to invoke the function.
luaFunction.call(ScriptLoader.getScriptLibLua());
// 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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package emu.grasscutter.scripts.data.controller;

import emu.grasscutter.*;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
import emu.grasscutter.game.ability.Ability;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.props.ElementType;
import emu.grasscutter.scripts.*;
Expand Down Expand Up @@ -58,6 +60,30 @@ public int onClientExecuteRequest(GameEntity entity, int param1, int param2, int
return 0;
}

/**
* Invoked from {@link emu.grasscutter.game.ability.actions.ActionServerLuaCall} to call an entity controller function.
*
* @param entity The entity which called the function.
* @param funcName The name of the function to call.
* @param ability The ability that is calling the function.
* @param action The action that is calling the function.
* @return The return value of the function.
*/
public LuaValue callControllerScriptFunc(
GameEntity entity, String funcName,
Ability ability, AbilityModifierAction action) {
var lParam1 = LuaValue.valueOf(action.param1.getInt(ability));
var lParam2 = LuaValue.valueOf(action.param2.getInt(ability));
var lParam3 = LuaValue.valueOf(action.param3.getInt(ability));

return switch (action.paramNum) {
case 1 -> this.callControllerScriptFunc(entity, funcName, lParam1);
case 2 -> this.callControllerScriptFunc(entity, funcName, lParam1, lParam2);
case 3 -> this.callControllerScriptFunc(entity, funcName, lParam1, lParam2, lParam3);
default -> this.callControllerScriptFunc(entity, funcName, LuaValue.NIL);
};
}

// 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);
Expand Down

0 comments on commit 10423db

Please sign in to comment.