diff options
Diffstat (limited to 'sourcemod/scripting/gokz-core/map')
| -rw-r--r-- | sourcemod/scripting/gokz-core/map/buttons.sp | 138 | ||||
| -rw-r--r-- | sourcemod/scripting/gokz-core/map/end.sp | 155 | ||||
| -rw-r--r-- | sourcemod/scripting/gokz-core/map/mapfile.sp | 502 | ||||
| -rw-r--r-- | sourcemod/scripting/gokz-core/map/prefix.sp | 48 | ||||
| -rw-r--r-- | sourcemod/scripting/gokz-core/map/starts.sp | 219 | ||||
| -rw-r--r-- | sourcemod/scripting/gokz-core/map/triggers.sp | 855 | ||||
| -rw-r--r-- | sourcemod/scripting/gokz-core/map/zones.sp | 183 |
7 files changed, 0 insertions, 2100 deletions
diff --git a/sourcemod/scripting/gokz-core/map/buttons.sp b/sourcemod/scripting/gokz-core/map/buttons.sp deleted file mode 100644 index 8923fbd..0000000 --- a/sourcemod/scripting/gokz-core/map/buttons.sp +++ /dev/null @@ -1,138 +0,0 @@ -/* - Hooks between specifically named func_buttons and GOKZ. -*/ - - - -static Regex RE_BonusStartButton; -static Regex RE_BonusEndButton; - - - -// =====[ EVENTS ]===== - -void OnPluginStart_MapButtons() -{ - RE_BonusStartButton = CompileRegex(GOKZ_BONUS_START_BUTTON_NAME_REGEX); - RE_BonusEndButton = CompileRegex(GOKZ_BONUS_END_BUTTON_NAME_REGEX); -} - -void OnEntitySpawned_MapButtons(int entity) -{ - char buffer[32]; - - GetEntityClassname(entity, buffer, sizeof(buffer)); - if (!StrEqual("func_button", buffer, false)) - { - return; - } - - if (GetEntityName(entity, buffer, sizeof(buffer)) == 0) - { - return; - } - - int course = 0; - if (StrEqual(GOKZ_START_BUTTON_NAME, buffer, false)) - { - HookSingleEntityOutput(entity, "OnPressed", OnStartButtonPress); - RegisterCourseStart(course); - } - else if (StrEqual(GOKZ_END_BUTTON_NAME, buffer, false)) - { - HookSingleEntityOutput(entity, "OnPressed", OnEndButtonPress); - RegisterCourseEnd(course); - } - else if ((course = GetStartButtonBonusNumber(entity)) != -1) - { - HookSingleEntityOutput(entity, "OnPressed", OnBonusStartButtonPress); - RegisterCourseStart(course); - } - else if ((course = GetEndButtonBonusNumber(entity)) != -1) - { - HookSingleEntityOutput(entity, "OnPressed", OnBonusEndButtonPress); - RegisterCourseEnd(course); - } -} - -public void OnStartButtonPress(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessStartButtonPress(activator, 0); -} - -public void OnEndButtonPress(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessEndButtonPress(activator, 0); -} - -public void OnBonusStartButtonPress(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetStartButtonBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessStartButtonPress(activator, course); -} - -public void OnBonusEndButtonPress(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetEndButtonBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessEndButtonPress(activator, course); -} - - - -// =====[ PRIVATE ]===== - -static void ProcessStartButtonPress(int client, int course) -{ - if (GOKZ_StartTimer(client, course)) - { - // Only calling on success is intended behaviour (and prevents virtual button exploits) - OnStartButtonPress_Teleports(client, course); - OnStartButtonPress_VirtualButtons(client, course); - } -} - -static void ProcessEndButtonPress(int client, int course) -{ - GOKZ_EndTimer(client, course); - OnEndButtonPress_VirtualButtons(client, course); -} - -static int GetStartButtonBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartButton, 1); -} - -static int GetEndButtonBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndButton, 1); -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/end.sp b/sourcemod/scripting/gokz-core/map/end.sp deleted file mode 100644 index d119084..0000000 --- a/sourcemod/scripting/gokz-core/map/end.sp +++ /dev/null @@ -1,155 +0,0 @@ -/* - Hooks between specifically named end destinations and GOKZ -*/ - - - -static Regex RE_BonusEndButton; -static Regex RE_BonusEndZone; -static CourseTimerType endType[GOKZ_MAX_COURSES]; -static float endOrigin[GOKZ_MAX_COURSES][3]; -static float endAngles[GOKZ_MAX_COURSES][3]; - - - -// =====[ EVENTS ]===== - -void OnPluginStart_MapEnd() -{ - RE_BonusEndButton = CompileRegex(GOKZ_BONUS_END_BUTTON_NAME_REGEX); - RE_BonusEndZone = CompileRegex(GOKZ_BONUS_END_ZONE_NAME_REGEX); -} - -void OnEntitySpawnedPost_MapEnd(int entity) -{ - char buffer[32]; - - GetEntityClassname(entity, buffer, sizeof(buffer)); - - if (StrEqual("trigger_multiple", buffer, false)) - { - bool isEndZone; - if (GetEntityName(entity, buffer, sizeof(buffer)) != 0) - { - if (StrEqual(GOKZ_END_ZONE_NAME, buffer, false)) - { - isEndZone = true; - StoreEnd(0, entity, CourseTimerType_ZoneNew); - } - else if (GetEndZoneBonusNumber(entity) != -1) - { - int course = GetEndZoneBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - isEndZone = true; - StoreEnd(course, entity, CourseTimerType_ZoneNew); - } - } - } - if (!isEndZone) - { - TimerButtonTrigger trigger; - if (IsTimerButtonTrigger(entity, trigger) && !trigger.isStartTimer) - { - StoreEnd(trigger.course, entity, CourseTimerType_ZoneLegacy); - } - } - } - else if (StrEqual("func_button", buffer, false)) - { - bool isEndButton; - if (GetEntityName(entity, buffer, sizeof(buffer)) != 0) - { - if (StrEqual(GOKZ_END_BUTTON_NAME, buffer, false)) - { - isEndButton = true; - StoreEnd(0, entity, CourseTimerType_Button); - } - else - { - int course = GetEndButtonBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - isEndButton = true; - StoreEnd(course, entity, CourseTimerType_Button); - } - } - } - if (!isEndButton) - { - TimerButtonTrigger trigger; - if (IsTimerButtonTrigger(entity, trigger) && !trigger.isStartTimer) - { - StoreEnd(trigger.course, entity, CourseTimerType_Button); - } - } - } -} - -void OnMapStart_MapEnd() -{ - for (int course = 0; course < GOKZ_MAX_COURSES; course++) - { - endType[course] = CourseTimerType_None; - } -} - -bool GetMapEndPosition(int course, float origin[3], float angles[3]) -{ - if (endType[course] == CourseTimerType_None) - { - return false; - } - - origin = endOrigin[course]; - angles = endAngles[course]; - - return true; -} - - - -// =====[ PRIVATE ]===== - -static void StoreEnd(int course, int entity, CourseTimerType type) -{ - // If StoreEnd is called, then there is at least an end position (even though it might not be a valid one) - if (endType[course] < CourseTimerType_Default) - { - endType[course] = CourseTimerType_Default; - } - - // Real zone is always better than "fake" zones which are better than buttons - // as the buttons found in a map with fake zones aren't meant to be visible. - if (endType[course] >= type) - { - return; - } - - float origin[3], distFromCenter[3]; - GetEntityPositions(entity, origin, endOrigin[course], endAngles[course], distFromCenter); - - // If it is a button or the center of the center of the zone is invalid - if (type == CourseTimerType_Button || !IsSpawnValid(endOrigin[course])) - { - // Attempt with various positions around the entity, pick the first valid one. - if (!FindValidPositionAroundTimerEntity(entity, endOrigin[course], endAngles[course], type == CourseTimerType_Button)) - { - endOrigin[course][2] -= 64.0; // Move the origin down so the eye position is directly on top of the button/zone. - return; - } - } - - // Only update the CourseTimerType if a valid position is found. - endType[course] = type; -} - -static int GetEndButtonBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndButton, 1); -} - -static int GetEndZoneBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndZone, 1); -} diff --git a/sourcemod/scripting/gokz-core/map/mapfile.sp b/sourcemod/scripting/gokz-core/map/mapfile.sp deleted file mode 100644 index db60e7e..0000000 --- a/sourcemod/scripting/gokz-core/map/mapfile.sp +++ /dev/null @@ -1,502 +0,0 @@ -/* - Mapping API - - Reads data from the current map file. -*/ - -static Regex RE_BonusStartButton; -static Regex RE_BonusEndButton; - -// NOTE: 4 megabyte array for entity lump reading. -static char gEntityLump[4194304]; - -// =====[ PUBLIC ]===== - -void EntlumpParse(StringMap antiBhopTriggers, StringMap teleportTriggers, StringMap timerButtonTriggers, int &mappingApiVersion) -{ - char mapPath[512]; - GetCurrentMap(mapPath, sizeof(mapPath)); - Format(mapPath, sizeof(mapPath), "maps/%s.bsp", mapPath); - - // https://developer.valvesoftware.com/wiki/Source_BSP_File_Format - - File file = OpenFile(mapPath, "rb"); - if (file != INVALID_HANDLE) - { - int identifier; - file.ReadInt32(identifier); - - if (identifier == GOKZ_BSP_HEADER_IDENTIFIER) - { - // skip version number - file.Seek(4, SEEK_CUR); - - // the entity lump info is the first lump in the array, so we don't need to seek any further. - int offset; - int length; - file.ReadInt32(offset); - file.ReadInt32(length); - - // jump to the start of the entity lump - file.Seek(offset, SEEK_SET); - - int charactersRead = file.ReadString(gEntityLump, sizeof(gEntityLump), length); - delete file; - if (charactersRead >= sizeof(gEntityLump) - 1) - { - PushMappingApiError("ERROR: Entity lump: The map's entity lump is too big! Reduce the amount of entities in your map."); - return; - } - gEntityLump[length] = '\0'; - - int index = 0; - - StringMap entity = new StringMap(); - bool gotWorldSpawn = false; - while (EntlumpParseEntity(entity, gEntityLump, index)) - { - char classname[128]; - char targetName[GOKZ_ENTLUMP_MAX_VALUE]; - entity.GetString("classname", classname, sizeof(classname)); - - if (!gotWorldSpawn && StrEqual("worldspawn", classname, false)) - { - gotWorldSpawn = true; - char versionString[32]; - if (entity.GetString("climb_mapping_api_version", versionString, sizeof(versionString))) - { - if (StringToIntEx(versionString, mappingApiVersion) == 0) - { - PushMappingApiError("ERROR: Entity lump: Couldn't parse Mapping API version from map properties: \"%s\".", versionString); - mappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE; - } - } - else - { - // map doesn't have a mapping api version. - mappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE; - } - } - else if (StrEqual("trigger_multiple", classname, false)) - { - TriggerType triggerType; - if (!gotWorldSpawn || mappingApiVersion != GOKZ_MAPPING_API_VERSION_NONE) - { - if (entity.GetString("targetname", targetName, sizeof(targetName))) - { - // get trigger properties if applicable - triggerType = GetTriggerType(targetName); - if (triggerType == TriggerType_Antibhop) - { - AntiBhopTrigger trigger; - if (GetAntiBhopTriggerEntityProperties(trigger, entity)) - { - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - antiBhopTriggers.SetArray(key, trigger, sizeof(trigger)); - } - } - else if (triggerType == TriggerType_Teleport) - { - TeleportTrigger trigger; - if (GetTeleportTriggerEntityProperties(trigger, entity)) - { - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - teleportTriggers.SetArray(key, trigger, sizeof(trigger)); - } - } - } - } - - // Tracking legacy timer triggers that press the timer buttons upon triggered. - if (triggerType == TriggerType_Invalid) - { - char touchOutput[128]; - ArrayList value; - - if (entity.GetString("OnStartTouch", touchOutput, sizeof(touchOutput))) - { - TimerButtonTriggerCheck(touchOutput, sizeof(touchOutput), entity, timerButtonTriggers); - } - else if (entity.GetValue("OnStartTouch", value)) // If there are multiple outputs, we have to check for all of them. - { - for (int i = 0; i < value.Length; i++) - { - value.GetString(i, touchOutput, sizeof(touchOutput)); - TimerButtonTriggerCheck(touchOutput, sizeof(touchOutput), entity, timerButtonTriggers); - } - } - } - } - else if (StrEqual("func_button", classname, false)) - { - char pressOutput[128]; - ArrayList value; - - if (entity.GetString("OnPressed", pressOutput, sizeof(pressOutput))) - { - TimerButtonTriggerCheck(pressOutput, sizeof(pressOutput), entity, timerButtonTriggers); - } - else if (entity.GetValue("OnPressed", value)) // If there are multiple outputs, we have to check for all of them. - { - for (int i = 0; i < value.Length; i++) - { - value.GetString(i, pressOutput, sizeof(pressOutput)); - TimerButtonTriggerCheck(pressOutput, sizeof(pressOutput), entity, timerButtonTriggers); - } - } - } - // clear for next loop - entity.Clear(); - } - delete entity; - } - delete file; - } - else - { - // TODO: do something more elegant - SetFailState("Catastrophic extreme hyperfailure! Mapping API Couldn't open the map file for reading! %s. The map file might be gone or another program is using it.", mapPath); - } -} - - -// =====[ EVENTS ]===== - -void OnPluginStart_MapFile() -{ - char buffer[64]; - char press[8]; - FormatEx(press, sizeof(press), "%s%s", CHAR_ESCAPE, "Press"); - - buffer = GOKZ_BONUS_START_BUTTON_NAME_REGEX; - ReplaceStringEx(buffer, sizeof(buffer), "$", ""); - StrCat(buffer, sizeof(buffer), press); - RE_BonusStartButton = CompileRegex(buffer); - - buffer = GOKZ_BONUS_END_BUTTON_NAME_REGEX; - ReplaceStringEx(buffer, sizeof(buffer), "$", ""); - StrCat(buffer, sizeof(buffer), press); - RE_BonusEndButton = CompileRegex(buffer); -} - - -// =====[ PRIVATE ]===== - -static void EntlumpSkipAllWhiteSpace(char[] entityLump, int &index) -{ - while (IsCharSpace(entityLump[index]) && entityLump[index] != '\0') - { - index++; - } -} - -static int EntlumpGetString(char[] result, int maxLength, int copyCount, char[] entityLump, int entlumpIndex) -{ - int finalLength; - for (int i = 0; i < maxLength - 1 && i < copyCount; i++) - { - if (entityLump[entlumpIndex + i] == '\0') - { - break; - } - result[i] = entityLump[entlumpIndex + i]; - finalLength++; - } - - result[finalLength] = '\0'; - return finalLength; -} - -static EntlumpToken EntlumpGetToken(char[] entityLump, int &entlumpIndex) -{ - EntlumpToken result; - - EntlumpSkipAllWhiteSpace(entityLump, entlumpIndex); - - switch (entityLump[entlumpIndex]) - { - case '{': - { - result.type = EntlumpTokenType_OpenBrace; - EntlumpGetString(result.string, sizeof(result.string), 1, entityLump, entlumpIndex); - entlumpIndex++; - } - case '}': - { - result.type = EntlumpTokenType_CloseBrace; - EntlumpGetString(result.string, sizeof(result.string), 1, entityLump, entlumpIndex); - entlumpIndex++; - } - case '\0': - { - result.type = EntlumpTokenType_EndOfStream; - EntlumpGetString(result.string, sizeof(result.string), 1, entityLump, entlumpIndex); - entlumpIndex++; - } - case '\"': - { - result.type = EntlumpTokenType_Identifier; - int identifierLen; - entlumpIndex++; - for (int i = 0; i < sizeof(result.string) - 1; i++) - { - // NOTE: Unterminated strings can probably never happen, since the map has to be - // loaded by the game first and the engine will fail the load before we get to it. - if (entityLump[entlumpIndex + i] == '\0') - { - result.type = EntlumpTokenType_Unknown; - break; - } - if (entityLump[entlumpIndex + i] == '\"') - { - break; - } - result.string[i] = entityLump[entlumpIndex + i]; - identifierLen++; - } - - entlumpIndex += identifierLen + 1; // +1 to skip over last quotation mark - result.string[identifierLen] = '\0'; - } - default: - { - result.type = EntlumpTokenType_Unknown; - result.string[0] = entityLump[entlumpIndex]; - result.string[1] = '\0'; - } - } - - return result; -} - -static bool EntlumpParseEntity(StringMap result, char[] entityLump, int &entlumpIndex) -{ - EntlumpToken token; - token = EntlumpGetToken(entityLump, entlumpIndex); - if (token.type == EntlumpTokenType_EndOfStream) - { - return false; - } - - // NOTE: The following errors will very very likely never happen, since the entity lump has to be - // loaded by the game first and the engine will fail the load before we get to it. - // But if there's an obscure bug in this code, then we'll know!!! - for (;;) - { - token = EntlumpGetToken(entityLump, entlumpIndex); - switch (token.type) - { - case EntlumpTokenType_OpenBrace: - { - continue; - } - case EntlumpTokenType_Identifier: - { - EntlumpToken valueToken; - valueToken = EntlumpGetToken(entityLump, entlumpIndex); - if (valueToken.type == EntlumpTokenType_Identifier) - { - char tempString[GOKZ_ENTLUMP_MAX_VALUE]; - ArrayList values; - if (result.GetString(token.string, tempString, sizeof(tempString))) - { - result.Remove(token.string); - values = new ArrayList(ByteCountToCells(GOKZ_ENTLUMP_MAX_VALUE)); - values.PushString(tempString); - values.PushString(valueToken.string); - result.SetValue(token.string, values); - } - else if (result.GetValue(token.string, values)) - { - values.PushString(valueToken.string); - } - else - { - result.SetString(token.string, valueToken.string); - } - } - else - { - PushMappingApiError("ERROR: Entity lump: Unexpected token \"%s\".", valueToken.string); - return false; - } - } - case EntlumpTokenType_CloseBrace: - { - break; - } - case EntlumpTokenType_EndOfStream: - { - PushMappingApiError("ERROR: Entity lump: Unexpected end of entity lump! Entity lump parsing failed."); - return false; - } - default: - { - PushMappingApiError("ERROR: Entity lump: Invalid token \"%s\". Entity lump parsing failed.", token.string); - return false; - } - } - } - - return true; -} - -static bool GetHammerIDFromEntityStringMap(int &result, StringMap entity) -{ - char hammerID[32]; - if (!entity.GetString("hammerid", hammerID, sizeof(hammerID)) - || StringToIntEx(hammerID, result) == 0) - { - // if we don't have the hammer id, then we can't match the entity to an existing one! - char origin[64]; - entity.GetString("origin", origin, sizeof(origin)); - PushMappingApiError("ERROR: Failed to parse \"hammerid\" keyvalue on trigger! \"%i\" origin: %s.", result, origin); - return false; - } - return true; -} - -static bool GetAntiBhopTriggerEntityProperties(AntiBhopTrigger result, StringMap entity) -{ - if (!GetHammerIDFromEntityStringMap(result.hammerID, entity)) - { - return false; - } - - char time[32]; - if (!entity.GetString("climb_anti_bhop_time", time, sizeof(time)) - || StringToFloatEx(time, result.time) == 0) - { - result.time = GOKZ_ANTI_BHOP_TRIGGER_DEFAULT_DELAY; - } - - return true; -} - -static bool GetTeleportTriggerEntityProperties(TeleportTrigger result, StringMap entity) -{ - if (!GetHammerIDFromEntityStringMap(result.hammerID, entity)) - { - return false; - } - - char buffer[64]; - if (!entity.GetString("climb_teleport_type", buffer, sizeof(buffer)) - || StringToIntEx(buffer, view_as<int>(result.type)) == 0) - { - result.type = GOKZ_TELEPORT_TRIGGER_DEFAULT_TYPE; - } - - if (!entity.GetString("climb_teleport_destination", result.tpDestination, sizeof(result.tpDestination))) - { - // We don't want triggers without destinations dangling about, so we need to tell everyone about it!!! - PushMappingApiError("ERROR: Could not find \"climb_teleport_destination\" keyvalue on a climb_teleport trigger! hammer id \"%i\".", - result.hammerID); - return false; - } - - if (!entity.GetString("climb_teleport_delay", buffer, sizeof(buffer)) - || StringToFloatEx(buffer, result.delay) == 0) - { - result.delay = GOKZ_TELEPORT_TRIGGER_DEFAULT_DELAY; - } - - if (!entity.GetString("climb_teleport_use_dest_angles", buffer, sizeof(buffer)) - || StringToIntEx(buffer, result.useDestAngles) == 0) - { - result.useDestAngles = GOKZ_TELEPORT_TRIGGER_DEFAULT_USE_DEST_ANGLES; - } - - if (!entity.GetString("climb_teleport_reset_speed", buffer, sizeof(buffer)) - || StringToIntEx(buffer, result.resetSpeed) == 0) - { - result.resetSpeed = GOKZ_TELEPORT_TRIGGER_DEFAULT_RESET_SPEED; - } - - if (!entity.GetString("climb_teleport_reorient_player", buffer, sizeof(buffer)) - || StringToIntEx(buffer, result.reorientPlayer) == 0) - { - result.reorientPlayer = GOKZ_TELEPORT_TRIGGER_DEFAULT_REORIENT_PLAYER; - } - - if (!entity.GetString("climb_teleport_relative", buffer, sizeof(buffer)) - || StringToIntEx(buffer, result.relativeDestination) == 0) - { - result.relativeDestination = GOKZ_TELEPORT_TRIGGER_DEFAULT_RELATIVE_DESTINATION; - } - - // NOTE: Clamping - if (IsBhopTrigger(result.type)) - { - result.delay = FloatMax(result.delay, GOKZ_TELEPORT_TRIGGER_BHOP_MIN_DELAY); - } - else - { - result.delay = FloatMax(result.delay, 0.0); - } - - return true; -} - -static void TimerButtonTriggerCheck(char[] touchOutput, int size, StringMap entity, StringMap timerButtonTriggers) -{ - int course = 0; - char startOutput[128]; - char endOutput[128]; - FormatEx(startOutput, sizeof(startOutput), "%s%s%s", GOKZ_START_BUTTON_NAME, CHAR_ESCAPE, "Press"); - FormatEx(endOutput, sizeof(endOutput), "%s%s%s", GOKZ_END_BUTTON_NAME, CHAR_ESCAPE, "Press"); - if (StrContains(touchOutput, startOutput, false) != -1) - { - TimerButtonTrigger trigger; - if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity)) - { - trigger.course = 0; - trigger.isStartTimer = true; - } - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - timerButtonTriggers.SetArray(key, trigger, sizeof(trigger)); - } - else if (StrContains(touchOutput, endOutput, false) != -1) - { - TimerButtonTrigger trigger; - if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity)) - { - trigger.course = 0; - trigger.isStartTimer = false; - } - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - timerButtonTriggers.SetArray(key, trigger, sizeof(trigger)); - } - else if (RE_BonusStartButton.Match(touchOutput) > 0) - { - RE_BonusStartButton.GetSubString(1, touchOutput, sizeof(size)); - course = StringToInt(touchOutput); - TimerButtonTrigger trigger; - if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity)) - { - trigger.course = course; - trigger.isStartTimer = true; - } - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - timerButtonTriggers.SetArray(key, trigger, sizeof(trigger)); - } - else if (RE_BonusEndButton.Match(touchOutput) > 0) - { - RE_BonusEndButton.GetSubString(1, touchOutput, sizeof(size)); - course = StringToInt(touchOutput); - TimerButtonTrigger trigger; - if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity)) - { - trigger.course = course; - trigger.isStartTimer = false; - } - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - timerButtonTriggers.SetArray(key, trigger, sizeof(trigger)); - } -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/prefix.sp b/sourcemod/scripting/gokz-core/map/prefix.sp deleted file mode 100644 index 3ecbf89..0000000 --- a/sourcemod/scripting/gokz-core/map/prefix.sp +++ /dev/null @@ -1,48 +0,0 @@ -/* - Mapping API - Prefix - - Detects the map's prefix. -*/ - - - -static int currentMapPrefix; - - - -// =====[ PUBLIC ]===== - -int GetCurrentMapPrefix() -{ - return currentMapPrefix; -} - - - -// =====[ LISTENERS ]===== - -void OnMapStart_Prefix() -{ - char map[PLATFORM_MAX_PATH], mapPrefix[PLATFORM_MAX_PATH]; - GetCurrentMapDisplayName(map, sizeof(map)); - - // Get all characters before the first '_' character - for (int i = 0; i < sizeof(mapPrefix); i++) - { - if (map[i] == '\0' || map[i] == '_') - { - break; - } - - mapPrefix[i] = map[i]; - } - - if (StrEqual(mapPrefix[0], "kzpro", false)) - { - currentMapPrefix = MapPrefix_KZPro; - } - else - { - currentMapPrefix = MapPrefix_Other; - } -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/starts.sp b/sourcemod/scripting/gokz-core/map/starts.sp deleted file mode 100644 index 94d5b33..0000000 --- a/sourcemod/scripting/gokz-core/map/starts.sp +++ /dev/null @@ -1,219 +0,0 @@ -/* - Hooks between start destinations and GOKZ. -*/ - - - -static Regex RE_BonusStart; -static bool startExists[GOKZ_MAX_COURSES]; -static float startOrigin[GOKZ_MAX_COURSES][3]; -static float startAngles[GOKZ_MAX_COURSES][3]; - -// Used for SearchStart -static Regex RE_BonusStartButton; -static Regex RE_BonusStartZone; -static CourseTimerType startType[GOKZ_MAX_COURSES]; -static float searchStartOrigin[GOKZ_MAX_COURSES][3]; -static float searchStartAngles[GOKZ_MAX_COURSES][3]; - -// =====[ EVENTS ]===== - -void OnPluginStart_MapStarts() -{ - RE_BonusStart = CompileRegex(GOKZ_BONUS_START_NAME_REGEX); - RE_BonusStartButton = CompileRegex(GOKZ_BONUS_START_BUTTON_NAME_REGEX); - RE_BonusStartZone = CompileRegex(GOKZ_BONUS_START_ZONE_NAME_REGEX); -} - -void OnEntitySpawned_MapStarts(int entity) -{ - char buffer[32]; - - GetEntityClassname(entity, buffer, sizeof(buffer)); - if (!StrEqual("info_teleport_destination", buffer, false)) - { - return; - } - - if (GetEntityName(entity, buffer, sizeof(buffer)) == 0) - { - return; - } - - if (StrEqual(GOKZ_START_NAME, buffer, false)) - { - StoreStart(0, entity); - } - else - { - int course = GetStartBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - StoreStart(course, entity); - } - } -} - -void OnEntitySpawnedPost_MapStarts(int entity) -{ - char buffer[32]; - GetEntityClassname(entity, buffer, sizeof(buffer)); - - if (StrEqual("trigger_multiple", buffer, false)) - { - bool isStartZone; - if (GetEntityName(entity, buffer, sizeof(buffer)) != 0) - { - if (StrEqual(GOKZ_START_ZONE_NAME, buffer, false)) - { - isStartZone = true; - StoreSearchStart(0, entity, CourseTimerType_ZoneNew); - } - else if (GetStartZoneBonusNumber(entity) != -1) - { - int course = GetStartZoneBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - isStartZone = true; - StoreSearchStart(course, entity, CourseTimerType_ZoneNew); - } - } - } - if (!isStartZone) - { - TimerButtonTrigger trigger; - if (IsTimerButtonTrigger(entity, trigger) && trigger.isStartTimer) - { - StoreSearchStart(trigger.course, entity, CourseTimerType_ZoneLegacy); - } - } - - } - else if (StrEqual("func_button", buffer, false)) - { - bool isStartButton; - if (GetEntityName(entity, buffer, sizeof(buffer)) != 0) - { - if (StrEqual(GOKZ_START_BUTTON_NAME, buffer, false)) - { - isStartButton = true; - StoreSearchStart(0, entity, CourseTimerType_Button); - } - else - { - int course = GetStartButtonBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - isStartButton = true; - StoreSearchStart(course, entity, CourseTimerType_Button); - } - } - } - if (!isStartButton) - { - TimerButtonTrigger trigger; - if (IsTimerButtonTrigger(entity, trigger) && trigger.isStartTimer) - { - StoreSearchStart(trigger.course, entity, CourseTimerType_Button); - } - } - } -} - -void OnMapStart_MapStarts() -{ - for (int course = 0; course < GOKZ_MAX_COURSES; course++) - { - startExists[course] = false; - startType[course] = CourseTimerType_None; - } -} - -bool GetMapStartPosition(int course, float origin[3], float angles[3]) -{ - if (!startExists[course]) - { - return false; - } - - origin = startOrigin[course]; - angles = startAngles[course]; - - return true; -} - -bool GetSearchStartPosition(int course, float origin[3], float angles[3]) -{ - if (startType[course] == CourseTimerType_None) - { - return false; - } - - origin = searchStartOrigin[course]; - angles = searchStartAngles[course]; - - return true; -} - -// =====[ PRIVATE ]===== - -static void StoreStart(int course, int entity) -{ - float origin[3], angles[3]; - GetEntPropVector(entity, Prop_Send, "m_vecOrigin", origin); - GetEntPropVector(entity, Prop_Data, "m_angRotation", angles); - angles[2] = 0.0; // Roll should always be 0.0 - - startExists[course] = true; - startOrigin[course] = origin; - startAngles[course] = angles; -} - -static void StoreSearchStart(int course, int entity, CourseTimerType type) -{ - // If StoreSearchStart is called, then there is at least an end position (even though it might not be a valid one) - if (startType[course] < CourseTimerType_Default) - { - startType[course] = CourseTimerType_Default; - } - - // Real zone is always better than "fake" zones which are better than buttons - // as the buttons found in a map with fake zones aren't meant to be visible. - if (startType[course] >= type) - { - return; - } - - float origin[3], distFromCenter[3]; - GetEntityPositions(entity, origin, searchStartOrigin[course], searchStartAngles[course], distFromCenter); - - // If it is a button or the center of the center of the zone is invalid - if (type == CourseTimerType_Button || !IsSpawnValid(searchStartOrigin[course])) - { - // Attempt with various positions around the entity, pick the first valid one. - if (!FindValidPositionAroundTimerEntity(entity, searchStartOrigin[course], searchStartAngles[course], type == CourseTimerType_Button)) - { - searchStartOrigin[course][2] -= 64.0; // Move the origin down so the eye position is directly on top of the button/zone. - return; - } - } - - // Only update the CourseTimerType if a valid position is found. - startType[course] = type; -} - - -static int GetStartBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStart, 1); -} - -static int GetStartButtonBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartButton, 1); -} - -static int GetStartZoneBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartZone, 1); -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/triggers.sp b/sourcemod/scripting/gokz-core/map/triggers.sp deleted file mode 100644 index 2444493..0000000 --- a/sourcemod/scripting/gokz-core/map/triggers.sp +++ /dev/null @@ -1,855 +0,0 @@ -/* - Mapping API - Triggers - - Implements trigger related features. -*/ - - - -static float lastTrigMultiTouchTime[MAXPLAYERS + 1]; -static float lastTrigTeleTouchTime[MAXPLAYERS + 1]; -static float lastTouchGroundOrLadderTime[MAXPLAYERS + 1]; -static int lastTouchSingleBhopEntRef[MAXPLAYERS + 1]; -static ArrayList lastTouchSequentialBhopEntRefs[MAXPLAYERS + 1]; -static int triggerTouchCount[MAXPLAYERS + 1]; -static int antiCpTriggerTouchCount[MAXPLAYERS + 1]; -static int antiPauseTriggerTouchCount[MAXPLAYERS + 1]; -static int antiJumpstatTriggerTouchCount[MAXPLAYERS + 1]; -static int mapMappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE; -static int bhopTouchCount[MAXPLAYERS + 1]; -static bool jumpedThisTick[MAXPLAYERS + 1]; -static float jumpOrigin[MAXPLAYERS + 1][3]; -static float jumpVelocity[MAXPLAYERS + 1][3]; -static ArrayList triggerTouchList[MAXPLAYERS + 1]; // arraylist of TouchedTrigger that the player is currently touching. this array won't ever get long (unless the mapper does something weird). -static StringMap triggerTouchCounts[MAXPLAYERS + 1]; // stringmap of int touch counts with key being a string of the entity reference. -static StringMap antiBhopTriggers; // stringmap of AntiBhopTrigger with key being a string of the m_iHammerID entprop. -static StringMap teleportTriggers; // stringmap of TeleportTrigger with key being a string of the m_iHammerID entprop. -static StringMap timerButtonTriggers; // stringmap of legacy timer zone triggers with key being a string of the m_iHammerID entprop. -static ArrayList parseErrorStrings; - - - -// =====[ PUBLIC ]===== - -bool BhopTriggersJustTouched(int client) -{ - // NOTE: This is slightly incorrect since we touch triggers in the air, but - // it doesn't matter since we can't checkpoint in the air. - if (bhopTouchCount[client] > 0) - { - return true; - } - // GetEngineTime return changes between calls. We only call it once at the beginning. - float engineTime = GetEngineTime(); - // If the player touches a teleport trigger, increase the delay required - if (engineTime - lastTouchGroundOrLadderTime[client] < GOKZ_MULT_NO_CHECKPOINT_TIME // Just touched ground or ladder - && engineTime - lastTrigMultiTouchTime[client] < GOKZ_MULT_NO_CHECKPOINT_TIME // Just touched trigger_multiple - || engineTime - lastTrigTeleTouchTime[client] < GOKZ_BHOP_NO_CHECKPOINT_TIME) // Just touched trigger_teleport - { - return true; - } - - return Movement_GetMovetype(client) == MOVETYPE_LADDER - && triggerTouchCount[client] > 0 - && engineTime - lastTrigTeleTouchTime[client] < GOKZ_LADDER_NO_CHECKPOINT_TIME; -} - -bool AntiCpTriggerIsTouched(int client) -{ - return antiCpTriggerTouchCount[client] > 0; -} - -bool AntiPauseTriggerIsTouched(int client) -{ - return antiPauseTriggerTouchCount[client] > 0; -} - -void PushMappingApiError(char[] format, any ...) -{ - char error[GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH]; - VFormat(error, sizeof(error), format, 2); - parseErrorStrings.PushString(error); -} - -TriggerType GetTriggerType(char[] targetName) -{ - TriggerType result = TriggerType_Invalid; - - if (StrEqual(targetName, GOKZ_ANTI_BHOP_TRIGGER_NAME)) - { - result = TriggerType_Antibhop; - } - else if (StrEqual(targetName, GOKZ_TELEPORT_TRIGGER_NAME)) - { - result = TriggerType_Teleport; - } - - return result; -} - -bool IsBhopTrigger(TeleportType type) -{ - return type == TeleportType_MultiBhop - || type == TeleportType_SingleBhop - || type == TeleportType_SequentialBhop; -} - -bool IsTimerButtonTrigger(int entity, TimerButtonTrigger trigger) -{ - char hammerID[32]; - bool gotHammerID = GetEntityHammerIDString(entity, hammerID, sizeof(hammerID)); - if (gotHammerID && timerButtonTriggers.GetArray(hammerID, trigger, sizeof(trigger))) - { - return true; - } - return false; -} - -// =====[ EVENTS ]===== - -void OnPluginStart_MapTriggers() -{ - parseErrorStrings = new ArrayList(ByteCountToCells(GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH)); - antiBhopTriggers = new StringMap(); - teleportTriggers = new StringMap(); - timerButtonTriggers = new StringMap(); -} - -void OnMapStart_MapTriggers() -{ - parseErrorStrings.Clear(); - antiBhopTriggers.Clear(); - teleportTriggers.Clear(); - timerButtonTriggers.Clear(); - mapMappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE; - EntlumpParse(antiBhopTriggers, teleportTriggers, timerButtonTriggers, mapMappingApiVersion); - - if (mapMappingApiVersion > GOKZ_MAPPING_API_VERSION) - { - SetFailState("Map's mapping api version is too big! Maximum supported version is %i, but map has %i. If you're not on the latest GOKZ version, then update!", - GOKZ_MAPPING_API_VERSION, mapMappingApiVersion); - } -} - -void OnClientPutInServer_MapTriggers(int client) -{ - triggerTouchCount[client] = 0; - antiCpTriggerTouchCount[client] = 0; - antiPauseTriggerTouchCount[client] = 0; - antiJumpstatTriggerTouchCount[client] = 0; - - if (triggerTouchList[client] == null) - { - triggerTouchList[client] = new ArrayList(sizeof(TouchedTrigger)); - } - else - { - triggerTouchList[client].Clear(); - } - - if (triggerTouchCounts[client] == null) - { - triggerTouchCounts[client] = new StringMap(); - } - else - { - triggerTouchCounts[client].Clear(); - } - - bhopTouchCount[client] = 0; - - if (lastTouchSequentialBhopEntRefs[client] == null) - { - lastTouchSequentialBhopEntRefs[client] = new ArrayList(); - } - else - { - lastTouchSequentialBhopEntRefs[client].Clear(); - } -} - -void OnPlayerRunCmd_MapTriggers(int client, int &buttons) -{ - int flags = GetEntityFlags(client); - MoveType moveType = GetEntityMoveType(client); - - // if the player isn't touching any bhop triggers on ground/a ladder, then - // reset the singlebhop and sequential bhop state. - if ((flags & FL_ONGROUND || moveType == MOVETYPE_LADDER) - && bhopTouchCount[client] == 0) - { - ResetBhopState(client); - } - - if (antiJumpstatTriggerTouchCount[client] > 0) - { - if (GetFeatureStatus(FeatureType_Native, "GOKZ_JS_InvalidateJump") == FeatureStatus_Available) - { - GOKZ_JS_InvalidateJump(client); - } - } - - // Check if we're touching any triggers and act accordingly. - // NOTE: Read through the touch list in reverse order, so some - // trigger behaviours will be better. Trust me! - int triggerTouchListLength = triggerTouchList[client].Length; - for (int i = triggerTouchListLength - 1; i >= 0; i--) - { - TouchedTrigger touched; - triggerTouchList[client].GetArray(i, touched); - - if (touched.triggerType == TriggerType_Antibhop) - { - TouchAntibhopTrigger(client, touched, buttons, flags); - } - else if (touched.triggerType == TriggerType_Teleport) - { - // Sometimes due to lag or whatever, the player can be - // teleported twice by the same trigger. This fixes that. - if (TouchTeleportTrigger(client, touched, flags)) - { - RemoveTriggerFromTouchList(client, EntRefToEntIndex(touched.entRef)); - i--; - triggerTouchListLength--; - } - } - } - jumpedThisTick[client] = false; -} - -void OnPlayerSpawn_MapTriggers(int client) -{ - // Print trigger errors every time a player spawns so that - // mappers and testers can very easily spot mistakes in names - // and get them fixed asap. - if (parseErrorStrings.Length > 0) - { - char errStart[] = "ERROR: Errors detected when trying to load triggers!"; - CPrintToChat(client, "{red}%s", errStart); - PrintToConsole(client, "\n%s", errStart); - - int length = parseErrorStrings.Length; - for (int err = 0; err < length; err++) - { - char error[GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH]; - parseErrorStrings.GetString(err, error, sizeof(error)); - CPrintToChat(client, "{red}%s", error); - PrintToConsole(client, error); - } - CPrintToChat(client, "{red}If the errors get clipped off in the chat, then look in your developer console!\n"); - } -} - -public void OnPlayerJump_Triggers(int client) -{ - jumpedThisTick[client] = true; - GetClientAbsOrigin(client, jumpOrigin[client]); - Movement_GetVelocity(client, jumpVelocity[client]); -} - -void OnEntitySpawned_MapTriggers(int entity) -{ - char classname[32]; - GetEntityClassname(entity, classname, sizeof(classname)); - char name[64]; - GetEntityName(entity, name, sizeof(name)); - - bool triggerMultiple = StrEqual("trigger_multiple", classname); - if (triggerMultiple) - { - char hammerID[32]; - bool gotHammerID = GetEntityHammerIDString(entity, hammerID, sizeof(hammerID)); - - if (StrEqual(GOKZ_TELEPORT_TRIGGER_NAME, name)) - { - TeleportTrigger teleportTrigger; - if (gotHammerID && teleportTriggers.GetArray(hammerID, teleportTrigger, sizeof(teleportTrigger))) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnTeleportTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnTeleportTrigTouchEnd_MapTriggers); - } - else - { - PushMappingApiError("ERROR: Couldn't match teleport trigger's Hammer ID %s with any Hammer ID from the map.", hammerID); - } - } - else if (StrEqual(GOKZ_ANTI_BHOP_TRIGGER_NAME, name)) - { - AntiBhopTrigger antiBhopTrigger; - if (gotHammerID && antiBhopTriggers.GetArray(hammerID, antiBhopTrigger, sizeof(antiBhopTrigger))) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnAntiBhopTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnAntiBhopTrigTouchEnd_MapTriggers); - } - else - { - PushMappingApiError("ERROR: Couldn't match antibhop trigger's Hammer ID %s with any Hammer ID from the map.", hammerID); - } - } - else if (StrEqual(GOKZ_BHOP_RESET_TRIGGER_NAME, name)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnBhopResetTouchStart_MapTriggers); - } - else if (StrEqual(GOKZ_ANTI_CP_TRIGGER_NAME, name, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnAntiCpTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnAntiCpTrigTouchEnd_MapTriggers); - } - else if (StrEqual(GOKZ_ANTI_PAUSE_TRIGGER_NAME, name, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnAntiPauseTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnAntiPauseTrigTouchEnd_MapTriggers); - } - else if (StrEqual(GOKZ_ANTI_JUMPSTAT_TRIGGER_NAME, name, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnAntiJumpstatTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnAntiJumpstatTrigTouchEnd_MapTriggers); - } - else - { - // NOTE: SDKHook touch hooks bypass trigger filters. We want that only with - // non mapping api triggers because it prevents checkpointing on bhop blocks. - SDKHook(entity, SDKHook_StartTouchPost, OnTrigMultTouchStart_MapTriggers); - SDKHook(entity, SDKHook_EndTouchPost, OnTrigMultTouchEnd_MapTriggers); - } - } - else if (StrEqual("trigger_teleport", classname)) - { - SDKHook(entity, SDKHook_StartTouchPost, OnTrigTeleTouchStart_MapTriggers); - SDKHook(entity, SDKHook_EndTouchPost, OnTrigTeleTouchEnd_MapTriggers); - } -} - -public void OnAntiBhopTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - int touchCount = IncrementTriggerTouchCount(other, entity); - if (touchCount <= 0) - { - // The trigger has fired a matching endtouch output before - // the starttouch output, so ignore it. - return; - } - - if (jumpedThisTick[other]) - { - TeleportEntity(other, jumpOrigin[other], NULL_VECTOR, jumpVelocity[other]); - } - - AddTriggerToTouchList(other, entity, TriggerType_Antibhop); -} - -public void OnAntiBhopTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - DecrementTriggerTouchCount(other, entity); - RemoveTriggerFromTouchList(other, entity); -} - -public void OnTeleportTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - int touchCount = IncrementTriggerTouchCount(other, entity); - if (touchCount <= 0) - { - // The trigger has fired a matching endtouch output before - // the starttouch output, so ignore it. - return; - } - - char key[32]; - GetEntityHammerIDString(entity, key, sizeof(key)); - TeleportTrigger trigger; - if (teleportTriggers.GetArray(key, trigger, sizeof(trigger)) - && IsBhopTrigger(trigger.type)) - { - bhopTouchCount[other]++; - } - - AddTriggerToTouchList(other, entity, TriggerType_Teleport); -} - -public void OnTeleportTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - DecrementTriggerTouchCount(other, entity); - - char key[32]; - GetEntityHammerIDString(entity, key, sizeof(key)); - TeleportTrigger trigger; - if (teleportTriggers.GetArray(key, trigger, sizeof(trigger)) - && IsBhopTrigger(trigger.type)) - { - bhopTouchCount[other]--; - } - - RemoveTriggerFromTouchList(other, entity); -} - -public void OnBhopResetTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - ResetBhopState(other); -} - -public void OnAntiCpTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiCpTriggerTouchCount[other]++; -} - -public void OnAntiCpTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiCpTriggerTouchCount[other]--; -} - -public void OnAntiPauseTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiPauseTriggerTouchCount[other]++; -} - -public void OnAntiPauseTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiPauseTriggerTouchCount[other]--; -} - -public void OnAntiJumpstatTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiJumpstatTriggerTouchCount[other]++; -} - -public void OnAntiJumpstatTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiJumpstatTriggerTouchCount[other]--; -} - -public void OnTrigMultTouchStart_MapTriggers(int entity, int other) -{ - if (!IsValidClient(other)) - { - return; - } - - lastTrigMultiTouchTime[other] = GetEngineTime(); - triggerTouchCount[other]++; -} - -public void OnTrigMultTouchEnd_MapTriggers(int entity, int other) -{ - if (!IsValidClient(other)) - { - return; - } - - triggerTouchCount[other]--; -} - -public void OnTrigTeleTouchStart_MapTriggers(int entity, int other) -{ - if (!IsValidClient(other)) - { - return; - } - - lastTrigTeleTouchTime[other] = GetEngineTime(); - triggerTouchCount[other]++; -} - -public void OnTrigTeleTouchEnd_MapTriggers(int entity, int other) -{ - if (!IsValidClient(other)) - { - return; - } - - triggerTouchCount[other]--; -} - -void OnStartTouchGround_MapTriggers(int client) -{ - lastTouchGroundOrLadderTime[client] = GetEngineTime(); - - for (int i = 0; i < triggerTouchList[client].Length; i++) - { - TouchedTrigger touched; - triggerTouchList[client].GetArray(i, touched); - // set the touched tick to the tick that the player touches the ground. - touched.groundTouchTick = gI_TickCount[client]; - triggerTouchList[client].SetArray(i, touched); - } -} - -void OnStopTouchGround_MapTriggers(int client) -{ - for (int i = 0; i < triggerTouchList[client].Length; i++) - { - TouchedTrigger touched; - triggerTouchList[client].GetArray(i, touched); - - if (touched.triggerType == TriggerType_Teleport) - { - char key[32]; - GetEntityHammerIDString(touched.entRef, key, sizeof(key)); - TeleportTrigger trigger; - // set last touched triggers for single and sequential bhop. - if (teleportTriggers.GetArray(key, trigger, sizeof(trigger)) - && IsBhopTrigger(trigger.type)) - { - if (trigger.type == TeleportType_SequentialBhop) - { - lastTouchSequentialBhopEntRefs[client].Push(touched.entRef); - } - // NOTE: For singlebhops, we don't care which type of bhop we last touched, because - // otherwise jumping back and forth between a multibhop and a singlebhop wouldn't work. - if (i == 0 && IsBhopTrigger(trigger.type)) - { - // We only want to set this once in this loop. - lastTouchSingleBhopEntRef[client] = touched.entRef; - } - } - } - } -} - -void OnChangeMovetype_MapTriggers(int client, MoveType newMovetype) -{ - if (newMovetype == MOVETYPE_LADDER) - { - lastTouchGroundOrLadderTime[client] = GetEngineTime(); - } -} - - - -// =====[ PRIVATE ]===== - -static void AddTriggerToTouchList(int client, int trigger, TriggerType triggerType) -{ - int triggerEntRef = EntIndexToEntRef(trigger); - - TouchedTrigger touched; - touched.triggerType = triggerType; - touched.entRef = triggerEntRef; - touched.startTouchTick = gI_TickCount[client]; - touched.groundTouchTick = -1; - if (GetEntityFlags(client) & FL_ONGROUND) - { - touched.groundTouchTick = gI_TickCount[client]; - } - - triggerTouchList[client].PushArray(touched); -} - -static void RemoveTriggerFromTouchList(int client, int trigger) -{ - int triggerEntRef = EntIndexToEntRef(trigger); - for (int i = 0; i < triggerTouchList[client].Length; i++) - { - TouchedTrigger touched; - triggerTouchList[client].GetArray(i, touched); - if (touched.entRef == triggerEntRef) - { - triggerTouchList[client].Erase(i); - break; - } - } -} - -static int IncrementTriggerTouchCount(int client, int trigger) -{ - int entref = EntIndexToEntRef(trigger); - char szEntref[64]; - FormatEx(szEntref, sizeof(szEntref), "%i", entref); - - int value = 0; - triggerTouchCounts[client].GetValue(szEntref, value); - - value += 1; - triggerTouchCounts[client].SetValue(szEntref, value); - - return value; -} - -static void DecrementTriggerTouchCount(int client, int trigger) -{ - int entref = EntIndexToEntRef(trigger); - char szEntref[64]; - FormatEx(szEntref, sizeof(szEntref), "%i", entref); - - int value = 0; - triggerTouchCounts[client].GetValue(szEntref, value); - - value -= 1; - triggerTouchCounts[client].SetValue(szEntref, value); -} - -static void TouchAntibhopTrigger(int client, TouchedTrigger touched, int &newButtons, int flags) -{ - if (!(flags & FL_ONGROUND)) - { - // Disable jump when the player is in the air. - // This is a very simple way to fix jumpbugging antibhop triggers. - newButtons &= ~IN_JUMP; - return; - } - - if (touched.groundTouchTick == -1) - { - // The player hasn't touched the ground inside this trigger yet. - return; - } - - char key[32]; - GetEntityHammerIDString(touched.entRef, key, sizeof(key)); - AntiBhopTrigger trigger; - if (antiBhopTriggers.GetArray(key, trigger, sizeof(trigger))) - { - float touchTime = CalculateGroundTouchTime(client, touched); - if (trigger.time == 0.0 || touchTime <= trigger.time) - { - // disable jump - newButtons &= ~IN_JUMP; - } - } -} - -static bool TouchTeleportTrigger(int client, TouchedTrigger touched, int flags) -{ - bool shouldTeleport = false; - - char key[32]; - GetEntityHammerIDString(touched.entRef, key, sizeof(key)); - TeleportTrigger trigger; - if (!teleportTriggers.GetArray(key, trigger, sizeof(trigger))) - { - // Couldn't get the teleport trigger from the trigger array for some reason. - return shouldTeleport; - } - - bool isBhopTrigger = IsBhopTrigger(trigger.type); - // NOTE: Player hasn't touched the ground inside this trigger yet. - if (touched.groundTouchTick == -1 && isBhopTrigger) - { - return shouldTeleport; - } - - float destOrigin[3]; - float destAngles[3]; - bool gotDestOrigin; - bool gotDestAngles; - int destinationEnt = GetTeleportDestinationAndOrientation(trigger.tpDestination, destOrigin, destAngles, gotDestOrigin, gotDestAngles); - - float triggerOrigin[3]; - bool gotTriggerOrigin = GetEntityAbsOrigin(touched.entRef, triggerOrigin); - - // NOTE: We only use the trigger's origin if we're using a relative destination, so if - // we're not using a relative destination and don't have it, then it's fine. - if (!IsValidEntity(destinationEnt) || !gotDestOrigin - || (!gotTriggerOrigin && trigger.relativeDestination)) - { - PrintToConsole(client, "[KZ] Invalid teleport destination \"%s\" on trigger with hammerID %i.", trigger.tpDestination, trigger.hammerID); - return shouldTeleport; - } - - // NOTE: Find out if we should actually teleport. - if (isBhopTrigger && (flags & FL_ONGROUND)) - { - float touchTime = CalculateGroundTouchTime(client, touched); - if (touchTime > trigger.delay) - { - shouldTeleport = true; - } - else if (trigger.type == TeleportType_SingleBhop) - { - shouldTeleport = lastTouchSingleBhopEntRef[client] == touched.entRef; - } - else if (trigger.type == TeleportType_SequentialBhop) - { - int length = lastTouchSequentialBhopEntRefs[client].Length; - for (int j = 0; j < length; j++) - { - int entRef = lastTouchSequentialBhopEntRefs[client].Get(j); - if (entRef == touched.entRef) - { - shouldTeleport = true; - break; - } - } - } - } - else if (trigger.type == TeleportType_Normal) - { - float touchTime = CalculateStartTouchTime(client, touched); - shouldTeleport = touchTime > trigger.delay || (trigger.delay == 0.0); - } - - if (!shouldTeleport) - { - return shouldTeleport; - } - - bool shouldReorientPlayer = trigger.reorientPlayer - && gotDestAngles && (destAngles[1] != 0.0); - - float zAxis[3]; - zAxis = view_as<float>({0.0, 0.0, 1.0}); - - // NOTE: Work out finalOrigin. - float finalOrigin[3]; - if (trigger.relativeDestination) - { - float playerOrigin[3]; - Movement_GetOrigin(client, playerOrigin); - - float playerOffsetFromTrigger[3]; - SubtractVectors(playerOrigin, triggerOrigin, playerOffsetFromTrigger); - - if (shouldReorientPlayer) - { - // NOTE: rotate player offset by the destination trigger's yaw. - RotateVectorAxis(playerOffsetFromTrigger, zAxis, DegToRad(destAngles[1]), playerOffsetFromTrigger); - } - - AddVectors(destOrigin, playerOffsetFromTrigger, finalOrigin); - } - else - { - finalOrigin = destOrigin; - } - - // NOTE: Work out finalPlayerAngles. - float finalPlayerAngles[3]; - Movement_GetEyeAngles(client, finalPlayerAngles); - if (shouldReorientPlayer) - { - finalPlayerAngles[1] -= destAngles[1]; - - float velocity[3]; - Movement_GetVelocity(client, velocity); - - // NOTE: rotate velocity by the destination trigger's yaw. - RotateVectorAxis(velocity, zAxis, DegToRad(destAngles[1]), velocity); - Movement_SetVelocity(client, velocity); - } - else if (!trigger.reorientPlayer && trigger.useDestAngles) - { - finalPlayerAngles = destAngles; - } - - if (shouldTeleport) - { - TeleportPlayer(client, finalOrigin, finalPlayerAngles, gotDestAngles && trigger.useDestAngles, trigger.resetSpeed); - } - - return shouldTeleport; -} - -static float CalculateGroundTouchTime(int client, TouchedTrigger touched) -{ - float result = float(gI_TickCount[client] - touched.groundTouchTick) * GetTickInterval(); - return result; -} - -static float CalculateStartTouchTime(int client, TouchedTrigger touched) -{ - float result = float(gI_TickCount[client] - touched.startTouchTick) * GetTickInterval(); - return result; -} - -static void ResetBhopState(int client) -{ - lastTouchSingleBhopEntRef[client] = INVALID_ENT_REFERENCE; - lastTouchSequentialBhopEntRefs[client].Clear(); -} - -static bool GetEntityHammerIDString(int entity, char[] buffer, int maxLength) -{ - if (!IsValidEntity(entity)) - { - return false; - } - - if (!HasEntProp(entity, Prop_Data, "m_iHammerID")) - { - return false; - } - - int hammerID = GetEntProp(entity, Prop_Data, "m_iHammerID"); - IntToString(hammerID, buffer, maxLength); - - return true; -} - -// NOTE: returns an entity reference (possibly invalid). -static int GetTeleportDestinationAndOrientation(char[] targetName, float origin[3], float angles[3] = NULL_VECTOR, bool &gotOrigin = false, bool &gotAngles = false) -{ - // NOTE: We're not caching the teleport destination because it could change. - int destination = GOKZFindEntityByName(targetName, .ignorePlayers = true); - if (!IsValidEntity(destination)) - { - return destination; - } - - gotOrigin = GetEntityAbsOrigin(destination, origin); - - if (HasEntProp(destination, Prop_Data, "m_angAbsRotation")) - { - GetEntPropVector(destination, Prop_Data, "m_angAbsRotation", angles); - gotAngles = true; - } - else - { - gotAngles = false; - } - - return destination; -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/zones.sp b/sourcemod/scripting/gokz-core/map/zones.sp deleted file mode 100644 index 684e42d..0000000 --- a/sourcemod/scripting/gokz-core/map/zones.sp +++ /dev/null @@ -1,183 +0,0 @@ -/* - Hooks between specifically named trigger_multiples and GOKZ. -*/ - - - -static Regex RE_BonusStartZone; -static Regex RE_BonusEndZone; -static bool touchedGroundSinceTouchingStartZone[MAXPLAYERS + 1]; - - - -// =====[ EVENTS ]===== - -void OnPluginStart_MapZones() -{ - RE_BonusStartZone = CompileRegex(GOKZ_BONUS_START_ZONE_NAME_REGEX); - RE_BonusEndZone = CompileRegex(GOKZ_BONUS_END_ZONE_NAME_REGEX); -} - -void OnStartTouchGround_MapZones(int client) -{ - touchedGroundSinceTouchingStartZone[client] = true; -} - -void OnEntitySpawned_MapZones(int entity) -{ - char buffer[32]; - - GetEntityClassname(entity, buffer, sizeof(buffer)); - if (!StrEqual("trigger_multiple", buffer, false)) - { - return; - } - - if (GetEntityName(entity, buffer, sizeof(buffer)) == 0) - { - return; - } - - int course = 0; - if (StrEqual(GOKZ_START_ZONE_NAME, buffer, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnStartZoneStartTouch); - HookSingleEntityOutput(entity, "OnEndTouch", OnStartZoneEndTouch); - RegisterCourseStart(course); - } - else if (StrEqual(GOKZ_END_ZONE_NAME, buffer, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnEndZoneStartTouch); - RegisterCourseEnd(course); - } - else if ((course = GetStartZoneBonusNumber(entity)) != -1) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnBonusStartZoneStartTouch); - HookSingleEntityOutput(entity, "OnEndTouch", OnBonusStartZoneEndTouch); - RegisterCourseStart(course); - } - else if ((course = GetEndZoneBonusNumber(entity)) != -1) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnBonusEndZoneStartTouch); - RegisterCourseEnd(course); - } -} - -public void OnStartZoneStartTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessStartZoneStartTouch(activator, 0); -} - -public void OnStartZoneEndTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessStartZoneEndTouch(activator, 0); -} - -public void OnEndZoneStartTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessEndZoneStartTouch(activator, 0); -} - -public void OnBonusStartZoneStartTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetStartZoneBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessStartZoneStartTouch(activator, course); -} - -public void OnBonusStartZoneEndTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetStartZoneBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessStartZoneEndTouch(activator, course); -} - -public void OnBonusEndZoneStartTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetEndZoneBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessEndZoneStartTouch(activator, course); -} - - - -// =====[ PRIVATE ]===== - -static void ProcessStartZoneStartTouch(int client, int course) -{ - touchedGroundSinceTouchingStartZone[client] = Movement_GetOnGround(client); - - GOKZ_StopTimer(client, false); - SetCurrentCourse(client, course); - - OnStartZoneStartTouch_Teleports(client, course); -} - -static void ProcessStartZoneEndTouch(int client, int course) -{ - if (!touchedGroundSinceTouchingStartZone[client]) - { - return; - } - - GOKZ_StartTimer(client, course, true); - GOKZ_ResetVirtualButtonPosition(client, true); -} - -static void ProcessEndZoneStartTouch(int client, int course) -{ - GOKZ_EndTimer(client, course); - GOKZ_ResetVirtualButtonPosition(client, false); -} - -static int GetStartZoneBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartZone, 1); -} - -static int GetEndZoneBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndZone, 1); -}
\ No newline at end of file |
