public static TRet Call <TRet>(this ISquirrelApi squirrelApi, AnsiString functionName, params object[] parameters) { if (squirrelApi == null) { throw new ArgumentNullException(nameof(squirrelApi)); } if (functionName == null) { throw new ArgumentNullException(nameof(functionName)); } if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } // Get the stack top index int top = squirrelApi.SqGetTop(); try { // Get the function squirrelApi.SqPushRootTable(); squirrelApi.SqPushString(functionName.Unmanaged, functionName.Length); if (!squirrelApi.SqGet(-2)) { throw new SquirrelException( $"The gothic online server function '{functionName}' could not be found in the root table", squirrelApi); } // Call the function squirrelApi.SqPushRootTable(); foreach (var parameter in parameters) { squirrelApi.PushValue(parameter); } if (!squirrelApi.SqCall(parameters.Length + 1, true, false)) { throw new SquirrelException($"The call to the '{functionName}' function failed", squirrelApi); } if (typeof(TRet) == typeof(string)) { string value; squirrelApi.SqGetString(squirrelApi.SqGetTop(), out value); return((TRet)(object)value); } else if (typeof(TRet) == typeof(int)) { int value; squirrelApi.SqGetInteger(squirrelApi.SqGetTop(), out value); return((TRet)(object)value); } else if (typeof(TRet) == typeof(float)) { float value; squirrelApi.SqGetFloat(squirrelApi.SqGetTop(), out value); return((TRet)(object)value); } else if (typeof(TRet) == typeof(bool)) { bool value; squirrelApi.SqGetBool(squirrelApi.SqGetTop(), out value); return((TRet)(object)value); } else if (typeof(TRet) == typeof(IntPtr)) { IntPtr value; squirrelApi.SqGetUserPointer(squirrelApi.SqGetTop(), out value); return((TRet)(object)value); } else { throw new NotSupportedException( $"The given type argument '{typeof(TRet).Name}' is not supported as the return value of a squirrel function."); } } finally { // Set back top squirrelApi.SqSetTop(top); } }