|
78 | 78 | #include "s_music.h"
|
79 | 79 | #include "v_video.h"
|
80 | 80 | #include "texturemanager.h"
|
| 81 | +#include "events.h" |
81 | 82 |
|
82 | 83 | // P-codes for ACS scripts
|
83 | 84 | enum
|
@@ -4823,6 +4824,77 @@ enum EACSFunctions
|
4823 | 4824 | ACSF_SetTeamScore, // (int team, int value
|
4824 | 4825 | };
|
4825 | 4826 |
|
| 4827 | +// Op code -> minimum arg count |
| 4828 | +static TMap<int, int> HandledACSFunctions = {}; |
| 4829 | + |
| 4830 | +void SetHandledACSFunctions() |
| 4831 | +{ |
| 4832 | + // Zandronum |
| 4833 | + HandledACSFunctions[100] = 0; // ResetMap |
| 4834 | + HandledACSFunctions[101] = 1; // PlayerIsSpectator |
| 4835 | + // ConsolePlayerNumber will be intentionally left out until proper client-side |
| 4836 | + // ACS scripts are implemented. Right now it'd just leave the game prone to desyncs. |
| 4837 | + HandledACSFunctions[103] = 2; // GetTeamProperty |
| 4838 | + HandledACSFunctions[104] = 1; // GetPlayersLivesLeft |
| 4839 | + HandledACSFunctions[105] = 2; // SetPlayerLivesLeft |
| 4840 | + HandledACSFunctions[106] = 2; // KickFromGame |
| 4841 | + HandledACSFunctions[107] = 0; // GetGamemodeState |
| 4842 | + HandledACSFunctions[108] = 3; // SetDBEntry |
| 4843 | + HandledACSFunctions[109] = 2; // GetDBEntry |
| 4844 | + HandledACSFunctions[110] = 3; // SetDBEntryString |
| 4845 | + HandledACSFunctions[111] = 2; // GetDBEntryString |
| 4846 | + HandledACSFunctions[112] = 3; // IncrementDBEntry |
| 4847 | + HandledACSFunctions[113] = 1; // PlayerIsLoggedIn |
| 4848 | + HandledACSFunctions[114] = 1; // GetPlayerAccountName |
| 4849 | + HandledACSFunctions[115] = 4; // SortDBEntries |
| 4850 | + HandledACSFunctions[116] = 1; // CountDBResults |
| 4851 | + HandledACSFunctions[117] = 1; // FreeDBResults |
| 4852 | + HandledACSFunctions[118] = 2; // GetDBResultKeyString |
| 4853 | + HandledACSFunctions[119] = 2; // GetDBResultValueString |
| 4854 | + HandledACSFunctions[120] = 2; // GetDBResultValue |
| 4855 | + HandledACSFunctions[121] = 3; // GetDBEntryRank |
| 4856 | + HandledACSFunctions[122] = 4; // RequestScriptPuke |
| 4857 | + HandledACSFunctions[123] = 0; // BeginDBTransaction |
| 4858 | + HandledACSFunctions[124] = 0; // EndDBTransaction |
| 4859 | + HandledACSFunctions[125] = 1; // GetDBEntries |
| 4860 | + HandledACSFunctions[126] = 1; // NamedRequestScriptPuke |
| 4861 | + // System time functions are intentionally left out since they're prone to causing desyncs. Can be added |
| 4862 | + // in if client/server ever becomes a thing. |
| 4863 | + HandledACSFunctions[130] = 2; // SetDeadSpectator |
| 4864 | + HandledACSFunctions[131] = 1; // SetActivatorToPlayer |
| 4865 | + HandledACSFunctions[132] = 1; // SetCurrentGamemode |
| 4866 | + HandledACSFunctions[133] = 0; // GetCurrentGamemode |
| 4867 | + HandledACSFunctions[134] = 2; // SetGamemodeLimit |
| 4868 | + // Player class handling isn't implemented yet. |
| 4869 | + HandledACSFunctions[136] = 2; // SetPlayerChasecam |
| 4870 | + HandledACSFunctions[137] = 1; // GetPlayerChasecam |
| 4871 | + HandledACSFunctions[138] = 3; // SetPlayerScore |
| 4872 | + HandledACSFunctions[139] = 2; // GetPlayerScore |
| 4873 | + HandledACSFunctions[140] = 0; // InDemoMode |
| 4874 | + // Client-side scripts aren't implemented yet for ClientScript functions. |
| 4875 | + HandledACSFunctions[146] = 2; // SendNetworkString |
| 4876 | + HandledACSFunctions[147] = 2; // NamedSendNetworkString |
| 4877 | + HandledACSFunctions[148] = 2; // GetChatMessage |
| 4878 | + HandledACSFunctions[149] = 0; // GetMapRotationSize |
| 4879 | + HandledACSFunctions[150] = 2; // GetMapRotationInfo |
| 4880 | + HandledACSFunctions[151] = 0; // GetCurrentMapPosition |
| 4881 | + HandledACSFunctions[152] = 0; // GetEventResult |
| 4882 | + HandledACSFunctions[153] = 2; // GetActorSectorLocation |
| 4883 | + HandledACSFunctions[154] = 3; // ChangeTeamScore |
| 4884 | + HandledACSFunctions[155] = 2; // SetGameplaySettings |
| 4885 | + HandledACSFunctions[156] = 3; // SetCustomPlayerValue |
| 4886 | + HandledACSFunctions[157] = 2; // GetCustomPlayerValue |
| 4887 | + HandledACSFunctions[158] = 2; // ResetCustomDataToDefault |
| 4888 | + HandledACSFunctions[159] = 1; // LumpOpen |
| 4889 | + HandledACSFunctions[160] = 2; // LumpRead |
| 4890 | + HandledACSFunctions[161] = 2; // LumpReadString |
| 4891 | + HandledACSFunctions[166] = 2; // LumpGetInfo |
| 4892 | + HandledACSFunctions[167] = 1; // LumpClose |
| 4893 | + |
| 4894 | + // Eternity |
| 4895 | + HandledACSFunctions[302] = 1; // SetAirFriction |
| 4896 | +} |
| 4897 | + |
4826 | 4898 | int DLevelScript::SideFromID(int id, int side)
|
4827 | 4899 | {
|
4828 | 4900 | if (side != 0 && side != 1) return -1;
|
@@ -7249,8 +7321,28 @@ int DLevelScript::RunScript()
|
7249 | 7321 | int argCount = NEXTBYTE;
|
7250 | 7322 | int funcIndex = NEXTSHORT;
|
7251 | 7323 |
|
7252 |
| - int retval, minCount = 0; |
7253 |
| - retval = CallFunction(argCount, funcIndex, &STACK(argCount), minCount); |
| 7324 | + int retval = 0, minCount = 0; |
| 7325 | + auto undefined = HandledACSFunctions.CheckKey(funcIndex); |
| 7326 | + if (undefined != nullptr) |
| 7327 | + { |
| 7328 | + if (argCount >= *undefined || (Level->i_compatflags2 & COMPATF2_NOACSARGCHECK)) |
| 7329 | + { |
| 7330 | + TArray<int> args = {}; |
| 7331 | + auto argStart = &STACK(argCount); |
| 7332 | + for (size_t p = 0u; p < argCount; ++p) |
| 7333 | + args.Push(argStart[p]); |
| 7334 | + |
| 7335 | + retval = primaryLevel->localEventManager->ProcessACSFunction(funcIndex, &args); |
| 7336 | + } |
| 7337 | + else |
| 7338 | + { |
| 7339 | + minCount = *undefined; |
| 7340 | + } |
| 7341 | + } |
| 7342 | + else |
| 7343 | + { |
| 7344 | + retval = CallFunction(argCount, funcIndex, &STACK(argCount), minCount); |
| 7345 | + } |
7254 | 7346 | if (minCount != 0)
|
7255 | 7347 | {
|
7256 | 7348 | Printf("Called ACS function index %d with too few args: %d (need %d)\n", funcIndex, argCount, minCount);
|
|
0 commit comments