diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 6ccf7339d0..18ab347eba 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4127,6 +4127,11 @@ enum EACSFunctions ACSF_LineAttack, ACSF_PlaySound, ACSF_StopSound, + ACSF_strcmp, + ACSF_stricmp, + ACSF_StrLeft, + ACSF_StrRight, + ACSF_StrMid, // ZDaemon ACSF_GetTeamScore = 19620, // (int team) @@ -4951,6 +4956,75 @@ doplaysound: if (!looping) } break; + case ACSF_strcmp: + case ACSF_stricmp: + if (argCount >= 2) + { + const char *a, *b; + a = FBehavior::StaticLookupString(args[0]); + b = FBehavior::StaticLookupString(args[1]); + + // Don't crash on invalid strings. + if (a == NULL) a = ""; + if (b == NULL) b = ""; + + if (argCount > 2) + { + int n = args[2]; + return (funcIndex == ACSF_strcmp) ? strncmp(a, b, n) : strnicmp(a, b, n); + } + else + { + return (funcIndex == ACSF_strcmp) ? strcmp(a, b) : stricmp(a, b); + } + } + break; + + case ACSF_StrLeft: + case ACSF_StrRight: + if (argCount >= 2) + { + const char *oldstr = FBehavior::StaticLookupString(args[0]); + if (oldstr == NULL || *oldstr == '\0') + { + return GlobalACSStrings.AddString(""); + } + size_t oldlen = strlen(oldstr); + size_t newlen = args[1]; + + if (oldlen < newlen) + { + newlen = oldlen; + } + FString newstr(funcIndex == ACSF_StrLeft ? oldstr : oldstr + oldlen - newlen, newlen); + return GlobalACSStrings.AddString(newstr); + } + break; + + case ACSF_StrMid: + if (argCount >= 3) + { + const char *oldstr = FBehavior::StaticLookupString(args[0]); + if (oldstr == NULL || *oldstr == '\0') + { + return GlobalACSStrings.AddString(""); + } + size_t oldlen = strlen(oldstr); + size_t pos = args[1]; + size_t newlen = args[2]; + + if (pos >= oldlen) + { + return GlobalACSStrings.AddString(""); + } + if (pos + newlen > oldlen || pos + newlen < pos) + { + newlen = oldlen - pos; + } + return GlobalACSStrings.AddString(FString(oldstr + pos, newlen)); + } + break; + default: break; }