diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index b4bccb225..5ddb96f45 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -65,6 +65,7 @@ char gS_ZoneNames[][] = enum struct zone_cache_t { bool bZoneInitialized; + bool bPrebuilt; // comes from mod_zone_* entities int iZoneType; int iZoneTrack; // 0 - main, 1 - bonus etc int iEntityID; @@ -118,7 +119,6 @@ float gV_WallSnap[MAXPLAYERS+1][3]; bool gB_Button[MAXPLAYERS+1]; bool gB_InsideZone[MAXPLAYERS+1][ZONETYPES_SIZE][TRACKS_SIZE]; bool gB_InsideZoneID[MAXPLAYERS+1][MAX_ZONES]; -float gF_PrebuiltZones[TRACKS_SIZE][2][3]; float gF_CustomSpawn[TRACKS_SIZE][3]; int gI_ZoneTrack[MAXPLAYERS+1]; int gI_ZoneDatabaseID[MAXPLAYERS+1]; @@ -313,6 +313,11 @@ public void OnPluginStart() } } + for(int i = 0; i < sizeof(gI_EntityZone); i++) + { + gI_EntityZone[i] = -1; + } + for(int i = 1; i <= MaxClients; i++) { if(IsClientConnected(i) && IsClientInGame(i)) @@ -753,7 +758,6 @@ public void OnMapStart() GetMapDisplayName(gS_Map, gS_Map, 160); gI_MapZones = 0; - ReloadPrebuiltZones(); UnloadZones(0); RefreshZones(); LoadStageZones(); @@ -770,7 +774,6 @@ public void OnMapStart() PrecacheModel("models/props/cs_office/vending_machine.mdl"); } - // draw // start drawing mapzones here if(gH_DrawEverything == null) { @@ -832,6 +835,15 @@ public void OnEntityCreated(int entity, const char[] classname) } } +public void OnEntityDestroyed(int entity) +{ + if (gI_EntityZone[entity] > -1) + { + KillZoneEntity(gI_EntityZone[entity]); + ClearZone(gI_EntityZone[entity]); + } +} + public void Frame_HookButton(any data) { int entity = EntRefToEntIndex(data); @@ -893,12 +905,8 @@ public void Frame_HookTrigger(any data) return; } - if (StrContains(sName, "checkpoint") != -1) - { - return; // TODO - } - int zone = -1; + int zonedata = 0; int track = Track_Main; if(StrContains(sName, "start") != -1) @@ -911,43 +919,75 @@ public void Frame_HookTrigger(any data) zone = Zone_End; } - if(StrContains(sName, "bonus") != -1) + if(StrContains(sName, "bonus") != -1 || StrContains(sName, "checkpoint") != -1) { - // Parse out the X in mod_zone_bonus_X_start and mod_zone_bonus_X_end - char sections[8][8]; - ExplodeString(sName, "_", sections, 8, 8, false); - track = StringToInt(sections[3]); // 0 on failure to parse. 0 is less than Track_Bonus + char sections[8][12]; + ExplodeString(sName, "_", sections, 8, 12, false); + + int iCheckpointIndex = 3; // mod_zone_checkpoint_X - if (track < Track_Bonus || track > Track_Bonus_Last) + if (StrContains(sName, "bonus") != -1) { - // Just ignore because there's either too many bonuses or X can be 0 and nobody told me - return; + iCheckpointIndex = 5; // mod_zone_bonus_X_checkpoint_X + track = StringToInt(sections[3]); // 0 on failure to parse. 0 is less than Track_Bonus + + if (track < Track_Bonus || track > Track_Bonus_Last) + { + LogError("invalid track in prebuilt map zone (%s) on %s", sName, gS_Map); + return; + } + } + + if (StrContains(sName, "checkpoint") != -1) + { + zone = Zone_Stage; + zonedata = StringToInt(sections[iCheckpointIndex]); + + // TODO stop hardcoding stage number limit + if (zonedata <= 0 || zonedata > 40) + { + LogError("invalid stage number in prebuilt map zone (%s) on %s", sName, gS_Map); + return; + } } } if(zone != -1) { - gI_KZButtons[track][zone] = entity; - Shavit_MarkKZMap(); + if (zone == Zone_Start || zone == Zone_End) + { + gI_KZButtons[track][zone] = entity; + Shavit_MarkKZMap(); + } - float maxs[3]; + float maxs[3], mins[3], origin[3]; GetEntPropVector(entity, Prop_Send, "m_vecMaxs", maxs); - - float origin[3]; + GetEntPropVector(entity, Prop_Send, "m_vecMins", mins); GetEntPropVector(entity, Prop_Send, "m_vecOrigin", origin); - origin[2] -= (maxs[2] - 2.0); // so you don't get stuck in the ground - - gF_PrebuiltZones[track][zone] = origin; + gI_EntityZone[entity] = gI_MapZones; + gA_ZoneCache[gI_MapZones].iEntityID = entity; - for(int i = 1; i <= MaxClients; i++) - { - gB_InsideZone[i][zone][track] = false; - } + //origin[2] -= (maxs[2] - 2.0); // so you don't get stuck in the ground + origin[2] += 1.0; // so you don't get stuck in the ground - SDKHook(entity, SDKHook_StartTouchPost, StartTouchPost_Trigger); - SDKHook(entity, SDKHook_EndTouchPost, EndTouchPost_Trigger); - SDKHook(entity, SDKHook_TouchPost, TouchPost_Trigger); + AddZoneToCache( + zone, + origin[0]+mins[0], origin[1]+mins[1], origin[2]+mins[2], // corner1_xyz + origin[0]+maxs[0], origin[1]+maxs[1], origin[2]+maxs[2], // corner2_xyz + 0.0, 0.0, 0.0, // destination_xyz (Zone_Teleport/Zone_Stage) + track, + -1, // iDatabaseID + 0, // iZoneFlags + zonedata, + true // bPrebuilt + ); + + SDKHook(entity, SDKHook_StartTouchPost, StartTouchPost); + SDKHook(entity, SDKHook_EndTouchPost, EndTouchPost); + SDKHook(entity, SDKHook_TouchPost, TouchPost); + + gB_ZonesCreated = true; } } @@ -972,6 +1012,7 @@ void ClearZone(int index) } gA_ZoneCache[index].bZoneInitialized = false; + gA_ZoneCache[index].bPrebuilt = false; gA_ZoneCache[index].iZoneType = -1; gA_ZoneCache[index].iZoneTrack = -1; gA_ZoneCache[index].iEntityID = -1; @@ -991,7 +1032,7 @@ void KillZoneEntity(int index) { int entity = gA_ZoneCache[index].iEntityID; - if(entity > MaxClients && IsValidEntity(entity)) + if(entity > MaxClients) { for(int i = 1; i <= MaxClients; i++) { @@ -1003,16 +1044,19 @@ void KillZoneEntity(int index) gB_InsideZoneID[i][index] = false; } - char sTargetname[32]; - GetEntPropString(entity, Prop_Data, "m_iName", sTargetname, 32); + gI_EntityZone[gA_ZoneCache[index].iEntityID] = -1; - if(StrContains(sTargetname, "shavit_zones_") == -1) + if (!IsValidEntity(entity)) { return; } UnhookEntity(entity); - AcceptEntityInput(entity, "Kill"); + + if (!gA_ZoneCache[index].bPrebuilt) + { + AcceptEntityInput(entity, "Kill"); + } } } @@ -1036,31 +1080,14 @@ void UnloadZones(int zone) } ClearCustomSpawn(-1); - - if(zone == 0) - { - gB_ZonesCreated = false; - - char sTargetname[32]; - int iEntity = INVALID_ENT_REFERENCE; - - while((iEntity = FindEntityByClassname(iEntity, "trigger_multiple")) != INVALID_ENT_REFERENCE) - { - GetEntPropString(iEntity, Prop_Data, "m_iName", sTargetname, 32); - - if(StrContains(sTargetname, "shavit_zones_") != -1) - { - AcceptEntityInput(iEntity, "Kill"); - } - } - } - - return; } } void RefreshZones() { + gI_MapZones = 0; + ReloadPrebuiltZones(); + char sQuery[512]; FormatEx(sQuery, 512, "SELECT type, corner1_x, corner1_y, corner1_z, corner2_x, corner2_y, corner2_z, destination_x, destination_y, destination_z, track, %s, flags, data FROM %smapzones WHERE map = '%s';", @@ -1078,8 +1105,6 @@ public void SQL_RefreshZones_Callback(Database db, DBResultSet results, const ch return; } - gI_MapZones = 0; - while(results.FetchRow()) { int type = results.FetchInt(0); @@ -1092,42 +1117,57 @@ public void SQL_RefreshZones_Callback(Database db, DBResultSet results, const ch gF_CustomSpawn[track][1] = results.FetchFloat(8); gF_CustomSpawn[track][2] = results.FetchFloat(9); } - else { - gV_MapZones[gI_MapZones][0][0] = gV_MapZones_Visual[gI_MapZones][0][0] = results.FetchFloat(1); - gV_MapZones[gI_MapZones][0][1] = gV_MapZones_Visual[gI_MapZones][0][1] = results.FetchFloat(2); - gV_MapZones[gI_MapZones][0][2] = gV_MapZones_Visual[gI_MapZones][0][2] = results.FetchFloat(3); - gV_MapZones[gI_MapZones][1][0] = gV_MapZones_Visual[gI_MapZones][7][0] = results.FetchFloat(4); - gV_MapZones[gI_MapZones][1][1] = gV_MapZones_Visual[gI_MapZones][7][1] = results.FetchFloat(5); - gV_MapZones[gI_MapZones][1][2] = gV_MapZones_Visual[gI_MapZones][7][2] = results.FetchFloat(6); + AddZoneToCache( + type, + results.FetchFloat(1), results.FetchFloat(2), results.FetchFloat(3), // corner1_xyz + results.FetchFloat(4), results.FetchFloat(5), results.FetchFloat(6), // corner2_xyz + results.FetchFloat(7), results.FetchFloat(8), results.FetchFloat(9), // destination_xyz (Zone_Teleport/Zone_Stage) + results.FetchInt(10), // track + results.FetchInt(11), // iDatabaseID + results.FetchInt(12), // iZoneFlags + results.FetchInt(13), // iZoneData + false // bPrebuilt + ); + } + } - CreateZonePoints(gV_MapZones_Visual[gI_MapZones], gCV_Offset.FloatValue); + CreateZoneEntities(); +} - gV_ZoneCenter[gI_MapZones][0] = (gV_MapZones[gI_MapZones][0][0] + gV_MapZones[gI_MapZones][1][0]) / 2.0; - gV_ZoneCenter[gI_MapZones][1] = (gV_MapZones[gI_MapZones][0][1] + gV_MapZones[gI_MapZones][1][1]) / 2.0; - gV_ZoneCenter[gI_MapZones][2] = (gV_MapZones[gI_MapZones][0][2] + gV_MapZones[gI_MapZones][1][2]) / 2.0; +public void AddZoneToCache(int type, float corner1_x, float corner1_y, float corner1_z, float corner2_x, float corner2_y, float corner2_z, float destination_x, float destination_y, float destination_z, int track, int id, int flags, int data, bool prebuilt) +{ + gV_MapZones[gI_MapZones][0][0] = gV_MapZones_Visual[gI_MapZones][0][0] = corner1_x; + gV_MapZones[gI_MapZones][0][1] = gV_MapZones_Visual[gI_MapZones][0][1] = corner1_y; + gV_MapZones[gI_MapZones][0][2] = gV_MapZones_Visual[gI_MapZones][0][2] = corner1_z; + gV_MapZones[gI_MapZones][1][0] = gV_MapZones_Visual[gI_MapZones][7][0] = corner2_x; + gV_MapZones[gI_MapZones][1][1] = gV_MapZones_Visual[gI_MapZones][7][1] = corner2_y; + gV_MapZones[gI_MapZones][1][2] = gV_MapZones_Visual[gI_MapZones][7][2] = corner2_z; - if(type == Zone_Teleport || type == Zone_Stage) - { - gV_Destinations[gI_MapZones][0] = results.FetchFloat(7); - gV_Destinations[gI_MapZones][1] = results.FetchFloat(8); - gV_Destinations[gI_MapZones][2] = results.FetchFloat(9); - } + CreateZonePoints(gV_MapZones_Visual[gI_MapZones], gCV_Offset.FloatValue); - gA_ZoneCache[gI_MapZones].bZoneInitialized = true; - gA_ZoneCache[gI_MapZones].iZoneType = type; - gA_ZoneCache[gI_MapZones].iZoneTrack = results.FetchInt(10); - gA_ZoneCache[gI_MapZones].iDatabaseID = results.FetchInt(11); - gA_ZoneCache[gI_MapZones].iZoneFlags = results.FetchInt(12); - gA_ZoneCache[gI_MapZones].iZoneData = results.FetchInt(13); - gA_ZoneCache[gI_MapZones].iEntityID = -1; + gV_ZoneCenter[gI_MapZones][0] = (gV_MapZones[gI_MapZones][0][0] + gV_MapZones[gI_MapZones][1][0]) / 2.0; + gV_ZoneCenter[gI_MapZones][1] = (gV_MapZones[gI_MapZones][0][1] + gV_MapZones[gI_MapZones][1][1]) / 2.0; + gV_ZoneCenter[gI_MapZones][2] = (gV_MapZones[gI_MapZones][0][2] + gV_MapZones[gI_MapZones][1][2]) / 2.0; - gI_MapZones++; - } + if(type == Zone_Teleport || type == Zone_Stage) + { + gV_Destinations[gI_MapZones][0] = destination_x; + gV_Destinations[gI_MapZones][1] = destination_y; + gV_Destinations[gI_MapZones][2] = destination_z; } - CreateZoneEntities(); + gA_ZoneCache[gI_MapZones].bZoneInitialized = true; + gA_ZoneCache[gI_MapZones].bPrebuilt = prebuilt; + gA_ZoneCache[gI_MapZones].iZoneType = type; + gA_ZoneCache[gI_MapZones].iZoneTrack = track; + gA_ZoneCache[gI_MapZones].iDatabaseID = id; + gA_ZoneCache[gI_MapZones].iZoneFlags = flags; + gA_ZoneCache[gI_MapZones].iZoneData = data; + gA_ZoneCache[gI_MapZones].iEntityID = -1; + + gI_MapZones++; } public void OnClientPutInServer(int client) @@ -1528,12 +1568,6 @@ void ClearCustomSpawn(int track) void ReloadPrebuiltZones() { - for(int i = 0; i < TRACKS_SIZE; i++) - { - gF_PrebuiltZones[i][Zone_Start] = NULL_VECTOR; - gF_PrebuiltZones[i][Zone_End] = NULL_VECTOR; - } - char sTargetname[32]; int iEntity = INVALID_ENT_REFERENCE; @@ -2781,11 +2815,11 @@ public Action Timer_DrawEverything(Handle Timer) gA_ZoneSettings[type][track].iBeam, gA_ZoneSettings[type][track].iHalo); } - } - if(++iCycle % iMaxZonesPerFrame == 0) - { - return Plugin_Continue; + if(++iCycle % iMaxZonesPerFrame == 0) + { + return Plugin_Continue; + } } } @@ -3041,12 +3075,6 @@ public void Shavit_OnRestart(int client, int track) TeleportEntity(client, fCenter, gB_HasSetStart[client][track] ? gF_StartAng[client][track] : NULL_VECTOR, view_as({0.0, 0.0, 0.0})); } - // prebuilt map zones - else if(!EmptyVector(gF_PrebuiltZones[track][Zone_Start])) - { - TeleportEntity(client, gF_PrebuiltZones[track][Zone_Start], NULL_VECTOR, view_as({0.0, 0.0, 0.0})); - } - // kz buttons else if(Shavit_IsKZMap() && !EmptyVector(gF_ClimbButtonCache[client][track][0]) && !EmptyVector(gF_ClimbButtonCache[client][track][1])) { @@ -3078,11 +3106,6 @@ public void Shavit_OnEnd(int client, int track) TeleportEntity(client, fCenter, NULL_VECTOR, view_as({0.0, 0.0, 0.0})); } - - else if(!EmptyVector(gF_PrebuiltZones[track][Zone_End])) - { - TeleportEntity(client, gF_PrebuiltZones[track][Zone_End], NULL_VECTOR, view_as({0.0, 0.0, 0.0})); - } } } @@ -3125,12 +3148,24 @@ public void Round_Start(Event event, const char[] name, bool dontBroadcast) gB_ZonesCreated = false; - RequestFrame(Frame_CreateZoneEntities); -} + for (int i = 0; i <= MaxClients; i++) + { + for (int j = 0; j < ZONETYPES_SIZE; j++) + { + for (int k = 0; k < TRACKS_SIZE; k++) + { + gB_InsideZone[i][j][k] = false; + } + } -public void Frame_CreateZoneEntities(any data) -{ - CreateZoneEntities(); + for (int x = 0; x < MAX_ZONES; x++) + { + gB_InsideZoneID[i][x] = false; + } + } + + gI_MapZones = 0; + RequestFrame(CreateZoneEntities); } float Abs(float input) @@ -3152,6 +3187,11 @@ public void CreateZoneEntities() for(int i = 0; i < gI_MapZones; i++) { + if(gA_ZoneCache[i].bPrebuilt) + { + continue; + } + for(int j = 1; j <= MaxClients; j++) { for(int k = 0; k < TRACKS_SIZE; k++) @@ -3448,102 +3488,3 @@ public void UsePost(int entity, int activator, int caller, UseType type, float v Shavit_FinishMap(activator, track); } } - -public void StartTouchPost_Trigger(int entity, int other) -{ - if(other < 1 || other > MaxClients || IsFakeClient(other)) - { - return; - } - - int zone = -1; - int track = Track_Main; - - GetButtonInfo(entity, zone, track); - - if(zone == -1 || GetZoneIndex(zone, track) != -1) - { - return; - } - - TimerStatus status = Shavit_GetTimerStatus(other); - - if(zone == Zone_End && !Shavit_IsPaused(other) && status != Timer_Stopped && Shavit_GetClientTrack(other) == track) - { - Shavit_FinishMap(other, track); - } - - gB_InsideZone[other][zone][track] = true; - - Call_StartForward(gH_Forwards_EnterZone); - Call_PushCell(other); - Call_PushCell(zone); - Call_PushCell(track); - Call_PushCell(0); - Call_PushCell(entity); - Call_Finish(); -} - -public void EndTouchPost_Trigger(int entity, int other) -{ - if(other < 1 || other > MaxClients || IsFakeClient(other)) - { - return; - } - - int zone = -1; - int track = Track_Main; - - GetButtonInfo(entity, zone, track); - - if(zone == -1 || GetZoneIndex(zone, track) != -1) - { - return; - } - - gB_InsideZone[other][zone][track] = false; - - Call_StartForward(gH_Forwards_LeaveZone); - Call_PushCell(other); - Call_PushCell(zone); - Call_PushCell(track); - Call_PushCell(0); - Call_PushCell(entity); - Call_Finish(); -} - -public void TouchPost_Trigger(int entity, int other) -{ - if(other < 1 || other > MaxClients || IsFakeClient(other)) - { - return; - } - - int zone = -1; - int track = Track_Main; - - GetButtonInfo(entity, zone, track); - - if(zone == -1 || GetZoneIndex(zone, track) != -1) - { - return; - } - - if(zone == Zone_Start) - { - if(GetEntPropEnt(other, Prop_Send, "m_hGroundEntity") == -1) - { - return; - } - - if(Shavit_GetTimerStatus(other) == Timer_Stopped || Shavit_GetClientTrack(other) != Track_Main) - { - Shavit_StartTimer(other, track); - } - - else if(track == Track_Main) - { - Shavit_StartTimer(other, Track_Main); - } - } -}