Made a anticamp feature with custom hurt volumes. Reformatted changes.txt.
This commit is contained in:
		| @@ -1,3 +1,7 @@ | ||||
| 2009.01.18 - 2.5.1.24 | ||||
|   * Created a anticamp feature that give players damage at a specified interval in custom defined volumes. Only affects humans. | ||||
|   * Re-formatted changes.txt. | ||||
|  | ||||
| 2009.01.17 - 2.5.1.23 | ||||
|   * Fixed teleport location text to display as float values instead of decimal. | ||||
|  | ||||
|   | ||||
							
								
								
									
										147
									
								
								changes.txt
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								changes.txt
									
									
									
									
									
								
							| @@ -1,60 +1,108 @@ | ||||
| Behaviour changes from version 2.5.1 | ||||
| ===================================== | ||||
| Changes from Zombie: Reloaded 2.5.1 | ||||
| ==================================== | ||||
|  | ||||
| * Support for alpha values in classes. New values in classes.txt (per class): | ||||
| Alpha values (transparency) | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Support for alpha values in classes. New values in classes.txt (per class): | ||||
|  | ||||
|   Key:           Value:    Default:    Description: | ||||
|   alpha_spawn    <0-255>   255         initial alpha value (0 = transparent) | ||||
|   alpha_damaged  <0-255>   255         alpha value when damaged | ||||
|   alpha_damage   <damage>  0           how much damage to do before | ||||
|                                        alpha_damaged take effect | ||||
|  | ||||
| Knockback multiplier | ||||
| ~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| If classes are enabled the zr_zombie_knockback cvar is used as a multiplier. | ||||
| Makes it possible to set custom knockback on maps using per-map configs. | ||||
|  | ||||
| Set zr_zombie_knockback to 1 if you use classes and want it the way it was | ||||
| before. | ||||
|  | ||||
|   knockback = zr_zombie_knockback * class knockback | ||||
|  | ||||
| Full spawn protection | ||||
| ~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Spawn protection makes the players invisible and move faster, and cannot be | ||||
| infected during protection time. | ||||
|  | ||||
| A centered counter shows the time remaining. | ||||
|  | ||||
| Overriding class night vision | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Support for overrriding class nvgs with the zr_zombie_nvgs cvar. Generally, | ||||
| any non-zero value is considered as on. | ||||
|  | ||||
|   Value:    Description: | ||||
|   -1        no override (use value in classes.txt) / nvgs on | ||||
|   0         never give nvgs | ||||
|   1         always give nvgs | ||||
|  | ||||
| Anticamp feature | ||||
| ~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Define hurt volumes in maps that gives x damage at a custom interval. | ||||
|  | ||||
| When creating volumes they should start a little bit _below_ the floor, so it | ||||
| covers the players feet. | ||||
|  | ||||
| The volume is rectangular and you only need two locations in the map to create | ||||
| it; a top corner, and the bottom corner at the oposite side. | ||||
|  | ||||
|   zr_anticamp_create_volume <damage> <interval> <x1> <y1> <z1> <x2> <y2> <z2> | ||||
|     - Create a rectangular volume between the specified locations. | ||||
|    | ||||
|     Key:           Value:    Default:    Description: | ||||
|     alpha_spawn    <0-255>   255         initial alpha value (0 = transparent) | ||||
|     alpha_damaged  <0-255>   255         alpha value when damaged | ||||
|     alpha_damage   <damage>  0           how much damage to do before | ||||
|                                          alpha_damaged take effect | ||||
|  | ||||
| * If classes are enabled the zr_zombie_knockback cvar is used as a multiplier. | ||||
|   Makes it possible to set custom knockback on maps using per-map configs. Set | ||||
|   zr_zombie_knockback to 1 if you use classes and want it the way it was before. | ||||
|   zr_anticamp_remove_volume <volume id> | ||||
|     - Remove a volume. | ||||
|    | ||||
|     knockback = zr_zombie_knockback * class knockback | ||||
|   zr_anticamp_list | ||||
|     - List existing volumes. | ||||
|  | ||||
| * Spawn protection makes the players invisible and move faster, and cannot be | ||||
|   infected during protecting time. A centered counter shows the time remaining. | ||||
| Set default classes | ||||
| ~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| * Support for overrriding class nvgs with the zr_zombie_nvgs cvar: | ||||
|   Generally, any non-zero value is considered as on. | ||||
| Setting the default class with a cvar. Works with per-map configs. | ||||
|    | ||||
|     Value:    Description: | ||||
|     -1        no override (use value in classes.txt) / nvgs on | ||||
|     0         never give nvgs | ||||
|     1         always give nvgs | ||||
|   zr_classes_default <classname> | ||||
|  | ||||
| * Setting default class with a cvar. Works with per-map configs. | ||||
| Zombie admin menu | ||||
| ~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Basic zombie admin commands like adjusting knockback, nvgs, infecting players | ||||
| and spawn everyone. | ||||
|  | ||||
| Knockback changes are applied instantly, useful for tuning knockback in-game. | ||||
|  | ||||
| Note that the changes are not saved. They will reset on map change. In a | ||||
| future version this menu might save the changes. | ||||
|  | ||||
|   Knockback multiplier | ||||
|     - Fine tune the knockback multiplier. | ||||
|    | ||||
|     zr_classes_default <classname> | ||||
|  | ||||
| * Zombie admin menu. Basic zombie admin commands like adjusting knockback, nvgs, | ||||
|   infecting players and spawn everyone. Knockback changes are applied instantly, | ||||
|   useful for fine tuning live. Note that the changes are not saved. They will be | ||||
|   reset on map change. In the future this menu might save the changes. | ||||
|   Class knockback | ||||
|     - Fine tune a class knockback value. | ||||
|    | ||||
|     Knockback multiplier | ||||
|       - Fine tune the knockback multiplier. | ||||
|      | ||||
|     Class knockback | ||||
|       - Fine tune a class knockback value. | ||||
|      | ||||
|     Night vision settings | ||||
|       - Override night vision settings (explained earlier). | ||||
|      | ||||
|     Infect | ||||
|       - Infect a player. Lists all players, but could be changed to only list | ||||
|         humans. | ||||
|      | ||||
|     Spawn players | ||||
|       - Spawns all dead players (except spectactors). | ||||
|      | ||||
|     (more zombie admin stuff might come...) | ||||
|   Night vision settings | ||||
|     - Override night vision settings (explained earlier). | ||||
|    | ||||
|   Infect | ||||
|     - Infect a player. Lists all players, but could be changed to only list | ||||
|       humans. | ||||
|    | ||||
|   Spawn players | ||||
|     - Spawns all dead players (except spectactors). | ||||
|    | ||||
|   (more zombie admin stuff might come...) | ||||
|  | ||||
| * Console commands zr_set_class_knockback and zr_get_class_knockback. Changes | ||||
|   are not saved. They will be reset on map change. | ||||
| Set (and get) class knockback | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Set or get knockback from a class. Changes are not saved. They will be reset on | ||||
| map change. | ||||
|    | ||||
|   zr_set_class_knockback <classname> <knockback> | ||||
|     - Sets knockback to a specified class. Useful when using per-map configs to | ||||
| @@ -64,4 +112,7 @@ Behaviour changes from version 2.5.1 | ||||
|     - Prints the current knockback of a class to the client/server console. | ||||
|       Using the zombie admin menu to read a knockback value is easier sometimes. | ||||
|  | ||||
| * Other minior and major bug fixes. See changelog.txt. | ||||
| More stuff | ||||
| ~~~~~~~~~~~ | ||||
|  | ||||
| Other minior and major bug fixes. See changelog.txt. | ||||
|   | ||||
| @@ -115,31 +115,31 @@ | ||||
| 	{ | ||||
| 		"en"		"Once a player has been infected, only zombies can use !ztele." | ||||
| 		"ru"		"После инфицирования кого-либо, только зомби могут использовать !ztele" | ||||
| 	} | ||||
| 	} | ||||
|  | ||||
| 	"!ztele zombies restricted" | ||||
| 	{ | ||||
| 		"en"		"The teleporter is disabled for zombies." | ||||
| 	} | ||||
|  | ||||
| 	"!ztele stuck" | ||||
| 	{ | ||||
| 		"en"		"Tip: Use !tp to teleport away if you are stuck." | ||||
| 	} | ||||
|  | ||||
| 	"!ztele not spawned" | ||||
| 	{ | ||||
| 		"en"		"You cannot use the teleporter before you've spawned." | ||||
| 	} | ||||
|  | ||||
| 	"!ztele offline" | ||||
| 	{ | ||||
| 		"en"		"The teleporter is not online yet." | ||||
| 	} | ||||
|  | ||||
| 	"!ztele cooldown" | ||||
| 	{ | ||||
| 		"en"		"Your teleporter is still on a cooldown." | ||||
|  | ||||
| 	"!ztele stuck" | ||||
| 	{ | ||||
| 		"en"		"Tip: Use !tp to teleport away if you are stuck." | ||||
| 	} | ||||
|  | ||||
| 	"!ztele not spawned" | ||||
| 	{ | ||||
| 		"en"		"You cannot use the teleporter before you've spawned." | ||||
| 	} | ||||
|  | ||||
| 	"!ztele offline" | ||||
| 	{ | ||||
| 		"en"		"The teleporter is not online yet." | ||||
| 	} | ||||
|  | ||||
| 	"!ztele cooldown" | ||||
| 	{ | ||||
| 		"en"		"Your teleporter is still on a cooldown." | ||||
| 	} | ||||
|  | ||||
| 	"!ztele in progress" | ||||
| @@ -224,6 +224,17 @@ | ||||
| 		"en"		"Nice try n00b!" | ||||
| 		"ru"		"Неплохая попытка n00b!" | ||||
| 	} | ||||
| 	 | ||||
| 	"Unfair camping" | ||||
| 	{ | ||||
| 		"en"		"This area is marked as unfair. Move, go through or die..." | ||||
| 	} | ||||
| 	 | ||||
| 	"Unfair camper slayed" | ||||
| 	{ | ||||
| 		"#format"   "{1:s},{2:d}" | ||||
| 		"en"		"Killed %s due to camping in a unfair area (id: %d)." | ||||
| 	} | ||||
|  | ||||
| 	"DX90 not supported" | ||||
| 	{ | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
| #undef REQUIRE_PLUGIN | ||||
| #include <market> | ||||
|  | ||||
| #define VERSION "2.5.1.23" | ||||
| #define VERSION "2.5.1.24" | ||||
|  | ||||
| #include "zr/zombiereloaded" | ||||
| #include "zr/global" | ||||
| @@ -26,6 +26,7 @@ | ||||
| #include "zr/classes" | ||||
| #include "zr/models" | ||||
| #include "zr/overlays" | ||||
| #include "zr/anticamp" | ||||
| #include "zr/teleport" | ||||
| #include "zr/zombie" | ||||
| #include "zr/menu" | ||||
| @@ -123,6 +124,13 @@ public OnMapStart() | ||||
|             pClass[i] = classindex; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     Anticamp_Startup(); | ||||
| } | ||||
|  | ||||
| public OnMapEnd() | ||||
| { | ||||
|     Anticamp_Disable(); | ||||
| } | ||||
|  | ||||
| public OnConfigsExecuted() | ||||
|   | ||||
							
								
								
									
										437
									
								
								src/zr/anticamp.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										437
									
								
								src/zr/anticamp.inc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,437 @@ | ||||
| /** | ||||
|  * ==================== | ||||
|  *   Zombie:Reloaded | ||||
|  *   File: anticamp.inc | ||||
|  *   Authors: Richard Helgeby | ||||
|  * ====================  | ||||
|  */ | ||||
|  | ||||
| #define MAX_VOLUMES 32 | ||||
|  | ||||
| enum volume | ||||
| { | ||||
|     Float:x_min, | ||||
|     Float:x_max, | ||||
|     Float:y_min, | ||||
|     Float:y_max, | ||||
|     Float:z_min, | ||||
|     Float:z_max, | ||||
|     volume_damage, | ||||
|     Float:volume_interval, | ||||
|     Handle:volume_timer, | ||||
|     bool:volume_in_use | ||||
| } | ||||
|  | ||||
| new volumes[MAX_VOLUMES][volume]; | ||||
| new volume_count; | ||||
|  | ||||
| new Float:player_loc[MAXPLAYERS][3]; | ||||
|  | ||||
| new Handle:hUpdateTimer; | ||||
|  | ||||
| Anticamp_Startup(bool:no_reset = false) | ||||
| { | ||||
|     new Float:interval = GetConVarFloat(gCvars[CVAR_ANTICAMP_UPDATE_INTERVAL]); | ||||
|      | ||||
|     // Create timer for updating player locations. | ||||
|     if (hUpdateTimer != INVALID_HANDLE) | ||||
|     { | ||||
|         KillTimer(hUpdateTimer); | ||||
|         hUpdateTimer = INVALID_HANDLE; | ||||
|     } | ||||
|  | ||||
|     if (interval > 0.0) | ||||
|     { | ||||
|         hUpdateTimer = CreateTimer(interval, Event_UpdatePlayerLocations, 0, TIMER_REPEAT); | ||||
|     } | ||||
|      | ||||
|     if (no_reset) | ||||
|     { | ||||
|         // Start existing hurt timers. | ||||
|         for (new vol_index = 0; vol_index < MAX_VOLUMES; vol_index++) | ||||
|         { | ||||
|             if (volumes[vol_index][volume_in_use]) | ||||
|             { | ||||
|                 if (volumes[vol_index][volume_timer] != INVALID_HANDLE) | ||||
|                 { | ||||
|                     KillTimer(volumes[vol_index][volume_timer]); | ||||
|                 } | ||||
|                 volumes[vol_index][volume_timer] = CreateTimer(volumes[vol_index][volume_interval], Event_HurtPlayers, vol_index, TIMER_REPEAT); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         ResetVolumes(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| Anticamp_Disable() | ||||
| { | ||||
|     // Kill update timer. | ||||
|     if (hUpdateTimer != INVALID_HANDLE) | ||||
|     { | ||||
|         KillTimer(hUpdateTimer); | ||||
|         hUpdateTimer = INVALID_HANDLE; | ||||
|     } | ||||
|      | ||||
|     // Kill hurt timers. | ||||
|     for (new vol = 0; vol < MAX_VOLUMES; vol++) | ||||
|     { | ||||
|         if (volumes[vol][volume_timer] != INVALID_HANDLE) | ||||
|         { | ||||
|             KillTimer(volumes[vol][volume_timer]); | ||||
|             volumes[vol][volume_timer] = INVALID_HANDLE; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| public UpdateIntervalHook(Handle:convar, const String:oldValue[], const String:newValue[]) | ||||
| { | ||||
|     new Float:interval = StringToFloat(newValue); | ||||
|     if (hUpdateTimer != INVALID_HANDLE) | ||||
|     { | ||||
|         KillTimer(hUpdateTimer); | ||||
|         hUpdateTimer  = INVALID_HANDLE; | ||||
|     } | ||||
|      | ||||
|     if (interval > 0.0) | ||||
|     { | ||||
|         hUpdateTimer = CreateTimer(interval, Event_UpdatePlayerLocations, 0, TIMER_REPEAT); | ||||
|     } | ||||
| } | ||||
|  | ||||
| public AnticampHook(Handle:convar, const String:oldValue[], const String:newValue[]) | ||||
| { | ||||
|     new anticamp_enabled = StringToInt(newValue); | ||||
|     if (anticamp_enabled) | ||||
|     { | ||||
|         Anticamp_Startup(true); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Anticamp_Disable(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| public Action:Command_AnticampCreateVolume(client, argc) | ||||
| { | ||||
|     // Get a unused volume index. | ||||
|     new vol_index = GetFreeVolumeIndex(); | ||||
|     if (vol_index == -1) | ||||
|     { | ||||
|         ReplyToCommand(client, "Maximum volumes reached. Max: %d", MAX_VOLUMES); | ||||
|         return Plugin_Handled; | ||||
|     } | ||||
|      | ||||
|     // Check arguments. | ||||
|     if (argc < 8) | ||||
|     { | ||||
|         ReplyToCommand(client, "Too few parameters specified. Usage: zr_anticamp_create_volume <damage> <interval> <x1> <y1> <z1> <x2> <y2> <z2>"); | ||||
|         return Plugin_Handled; | ||||
|     } | ||||
|      | ||||
|     decl String:arg_buffer[32]; | ||||
|      | ||||
|     new vol_damage; | ||||
|     new Float:vol_interval; | ||||
|     new Float:x1; | ||||
|     new Float:y1; | ||||
|     new Float:z1; | ||||
|     new Float:x2; | ||||
|     new Float:y2; | ||||
|     new Float:z2; | ||||
|      | ||||
|     // Get arguments. | ||||
|     GetCmdArg(1, arg_buffer, sizeof(arg_buffer)); | ||||
|     vol_damage = StringToInt(arg_buffer); | ||||
|      | ||||
|     GetCmdArg(2, arg_buffer, sizeof(arg_buffer)); | ||||
|     vol_interval = StringToFloat(arg_buffer); | ||||
|      | ||||
|     GetCmdArg(3, arg_buffer, sizeof(arg_buffer)); | ||||
|     x1 = StringToFloat(arg_buffer); | ||||
|      | ||||
|     GetCmdArg(4, arg_buffer, sizeof(arg_buffer)); | ||||
|     y1 = StringToFloat(arg_buffer); | ||||
|      | ||||
|     GetCmdArg(5, arg_buffer, sizeof(arg_buffer)); | ||||
|     z1 = StringToFloat(arg_buffer); | ||||
|      | ||||
|     GetCmdArg(6, arg_buffer, sizeof(arg_buffer)); | ||||
|     x2 = StringToFloat(arg_buffer); | ||||
|      | ||||
|     GetCmdArg(7, arg_buffer, sizeof(arg_buffer)); | ||||
|     y2 = StringToFloat(arg_buffer); | ||||
|      | ||||
|     GetCmdArg(8, arg_buffer, sizeof(arg_buffer)); | ||||
|     z2 = StringToFloat(arg_buffer); | ||||
|  | ||||
|     // Check damage. | ||||
|     if (vol_damage == 0) | ||||
|     { | ||||
|         ReplyToCommand(client, "The damage specified is zero or invalid."); | ||||
|         return Plugin_Handled; | ||||
|     } | ||||
|      | ||||
|     // Check interval. | ||||
|     if (vol_interval <= 0.0) | ||||
|     { | ||||
|         ReplyToCommand(client, "The interval specified is zero or invalid."); | ||||
|         return Plugin_Handled; | ||||
|     } | ||||
|      | ||||
|     // Check if both locations are equal. | ||||
|     if (FloatCompare(x1, x2) == 0) | ||||
|     { | ||||
|         if (FloatCompare(y1, y2) == 0) | ||||
|         { | ||||
|             if (FloatCompare(z1, z2) == 0) | ||||
|             { | ||||
|                 ReplyToCommand(client, "Cannot add hurt volume. Both locations are equal."); | ||||
|                 return Plugin_Handled; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Sort out max and min values. | ||||
|     if (FloatCompare(x1, x2) == 1) | ||||
|     { | ||||
|         volumes[vol_index][x_max] = x1; | ||||
|         volumes[vol_index][x_min] = x2; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         volumes[vol_index][x_max] = x2; | ||||
|         volumes[vol_index][x_min] = x1; | ||||
|     } | ||||
|      | ||||
|     if (FloatCompare(y1, y2) == 1) | ||||
|     { | ||||
|         volumes[vol_index][y_max] = y1; | ||||
|         volumes[vol_index][y_min] = y2; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         volumes[vol_index][y_max] = y2; | ||||
|         volumes[vol_index][y_min] = y1; | ||||
|     } | ||||
|      | ||||
|     if (FloatCompare(z1, z2) == 1) | ||||
|     { | ||||
|         volumes[vol_index][z_max] = z1; | ||||
|         volumes[vol_index][z_min] = z2; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         volumes[vol_index][z_max] = z2; | ||||
|         volumes[vol_index][z_min] = z1; | ||||
|     } | ||||
|      | ||||
|     volumes[vol_index][volume_damage] = vol_damage; | ||||
|     volumes[vol_index][volume_interval] = vol_interval; | ||||
|     volumes[vol_index][volume_timer] = CreateTimer(vol_interval, Event_HurtPlayers, vol_index, TIMER_REPEAT); | ||||
|     volumes[vol_index][volume_in_use] = true; | ||||
|      | ||||
|     ReplyToCommand(client, "Volume created:\nid: %d\nx min:%f\ny min:%f\nz min:%f\nx max:%f\ny max:%f\nz max:%f", | ||||
|         vol_index, | ||||
|         volumes[vol_index][x_min], | ||||
|         volumes[vol_index][y_min], | ||||
|         volumes[vol_index][z_min], | ||||
|         volumes[vol_index][x_max], | ||||
|         volumes[vol_index][y_max], | ||||
|         volumes[vol_index][z_max]); | ||||
|      | ||||
|     volume_count++; | ||||
|      | ||||
|     return Plugin_Handled; | ||||
| } | ||||
|  | ||||
| public Action:Command_AnticampRemoveVolume(client, argc) | ||||
| { | ||||
|     new vol_index; | ||||
|     decl String:arg_buffer[32]; | ||||
|     new Handle:vol_timer; | ||||
|      | ||||
|     if (argc < 1) | ||||
|     { | ||||
|         ReplyToCommand(client, "Volume ID not specified. Usage: zr_anticamp_remove_volume <volume id>"); | ||||
|         return Plugin_Handled; | ||||
|     } | ||||
|      | ||||
|     GetCmdArg(1, arg_buffer, sizeof(arg_buffer)); | ||||
|     vol_index = StringToInt(arg_buffer); | ||||
|      | ||||
|     if (IsValidVolume(vol_index)) | ||||
|     { | ||||
|         vol_timer = volumes[vol_index][volume_timer]; | ||||
|         if (vol_timer != INVALID_HANDLE) | ||||
|         { | ||||
|             KillTimer(vol_timer); | ||||
|             volumes[vol_index][volume_timer] = INVALID_HANDLE; | ||||
|         } | ||||
|         volumes[vol_index][volume_in_use] = false; | ||||
|         ReplyToCommand(client, "Removed volume %d.", vol_index); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         ReplyToCommand(client, "Invalid volume ID."); | ||||
|         return Plugin_Handled; | ||||
|     } | ||||
|      | ||||
|     return Plugin_Handled; | ||||
| } | ||||
|  | ||||
| public Action:Command_AnticampList(client, argc) | ||||
| { | ||||
|     decl String:buffer[2048]; | ||||
|     decl String:line[192]; | ||||
|     buffer[0] = 0; | ||||
|      | ||||
|     StrCat(buffer, sizeof(buffer), "id damage interval x_min y_min z_min x_max y_max z_max\n"); | ||||
|      | ||||
|     for (new vol_index = 0; vol_index < MAX_VOLUMES; vol_index++) | ||||
|     { | ||||
|         if (volumes[vol_index][volume_in_use]) | ||||
|         { | ||||
|             Format(line, sizeof(line), "%d %d %f %f %f %f %f %f %f\n", | ||||
|                 vol_index, | ||||
|                 volumes[vol_index][volume_damage], | ||||
|                 volumes[vol_index][volume_interval], | ||||
|                 volumes[vol_index][x_min], | ||||
|                 volumes[vol_index][y_min], | ||||
|                 volumes[vol_index][z_min], | ||||
|                 volumes[vol_index][x_max], | ||||
|                 volumes[vol_index][y_max], | ||||
|                 volumes[vol_index][y_max]); | ||||
|             StrCat(buffer, sizeof(buffer), line); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     ReplyToCommand(client, buffer); | ||||
| } | ||||
|  | ||||
| UpdatePlayerLocations() | ||||
| { | ||||
|     new client; | ||||
|     for (client = 1; client <= maxclients; client++) | ||||
|     { | ||||
|         if (IsClientConnected(client) && IsClientInGame(client)) | ||||
|         { | ||||
|             GetClientAbsOrigin(client, player_loc[client]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| HurtPlayersInVolume(volume_index) | ||||
| { | ||||
|     new client; | ||||
|     new client_health; | ||||
|     decl String:client_name[64]; | ||||
|     decl String:buffer[192]; | ||||
|     new anticamp_echo = GetConVarBool(gCvars[CVAR_ANTICAMP_ECHO]); | ||||
|      | ||||
|     for (client = 1; client <= maxclients; client++) | ||||
|     { | ||||
|         if (IsClientConnected(client) && | ||||
|             IsClientInGame(client) && | ||||
|             IsPlayerAlive(client) && | ||||
|             IsPlayerHuman(client)) | ||||
|         { | ||||
|             if (IsPlayerInVolume(client, volume_index)) | ||||
|             { | ||||
|                 ZR_PrintToChat(client, "Unfair camping"); | ||||
|                 client_health = GetClientHealth(client) - volumes[volume_index][volume_damage]; | ||||
|                 if (client_health > 0) | ||||
|                 { | ||||
|                     SetEntityHealth(client, client_health); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     ForcePlayerSuicide(client); | ||||
|                      | ||||
|                     GetClientName(client, client_name, sizeof(client_name)); | ||||
|                     SetGlobalTransTarget(client); | ||||
|                     Format(buffer, sizeof(buffer), "%T", "Unfair camper slayed", LANG_SERVER, client_name, volume_index); | ||||
|                      | ||||
|                     LogAction(client, client, buffer); | ||||
|                     if (anticamp_echo) | ||||
|                     { | ||||
|                         FormatTextString(buffer, sizeof(buffer)); | ||||
|                         ZR_PrintToAdminChat(buffer); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool:IsPlayerInVolume(client, volume_index) | ||||
| { | ||||
|     new Float:player_loc_x = player_loc[client][0]; | ||||
|     new Float:player_loc_y = player_loc[client][1]; | ||||
|     new Float:player_loc_z = player_loc[client][2]; | ||||
|     new debug_flags = GetConVarInt(gCvars[CVAR_DEBUG]); | ||||
|      | ||||
|     if ((player_loc_x >= volumes[volume_index][x_min]) && (player_loc_x <= volumes[volume_index][x_max])) | ||||
|     { | ||||
|         if (debug_flags & 4) PrintToChatAll("[ZR] Debug, Anticamp -- IsPlayerInVolume: Client %d matches X values.", client); | ||||
|         if ((player_loc_y >= volumes[volume_index][y_min]) && (player_loc_y <= volumes[volume_index][y_max])) | ||||
|         { | ||||
|             if (debug_flags & 4) PrintToChatAll("[ZR] Debug, Anticamp -- IsPlayerInVolume: Client %d matches Y values.", client); | ||||
|             if ((player_loc_z >= volumes[volume_index][z_min]) && (player_loc_z <= volumes[volume_index][z_max])) | ||||
|             { | ||||
|                 if (debug_flags & 4) PrintToChatAll("[ZR] Debug, Anticamp -- IsPlayerInVolume: Client %d matches Z values.", client); | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| GetFreeVolumeIndex() | ||||
| { | ||||
|     for(new vol_index = 0; vol_index < MAX_VOLUMES; vol_index++) | ||||
|     { | ||||
|         if (!volumes[vol_index][volume_in_use]) | ||||
|         { | ||||
|             return vol_index; | ||||
|         } | ||||
|     } | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
| bool:IsValidVolume(vol_index) | ||||
| { | ||||
|     if (vol_index >= 0 && vol_index < MAX_VOLUMES) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| ResetVolumes() | ||||
| { | ||||
|     for (new vol_index = 0; vol_index < MAX_VOLUMES; vol_index++) | ||||
|     { | ||||
|         volumes[vol_index][volume_in_use] = false; | ||||
|         if (volumes[vol_index][volume_timer] != INVALID_HANDLE) | ||||
|         { | ||||
|             KillTimer(volumes[vol_index][volume_timer]); | ||||
|             volumes[vol_index][volume_timer] = INVALID_HANDLE; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| public Action:Event_UpdatePlayerLocations(Handle:Timer) | ||||
| { | ||||
|     UpdatePlayerLocations(); | ||||
| } | ||||
|  | ||||
| public Action:Event_HurtPlayers(Handle:Timer, any:volume_index) | ||||
| { | ||||
|     HurtPlayersInVolume(volume_index); | ||||
| } | ||||
| @@ -25,6 +25,10 @@ CreateCommands() | ||||
|     RegAdminCmd("zr_admin", Command_AdminMenu, ADMFLAG_GENERIC, "Displays the admin menu for Zombie: Reloaded."); | ||||
|     RegAdminCmd("zr_knockback_m", Command_KnockbackMMenu, ADMFLAG_GENERIC, "Displays the knockback multiplier menu."); | ||||
|     RegAdminCmd("zr_teleadmin", Command_TeleMenu, ADMFLAG_GENERIC, "Displays the teleport admin menu for Zombie: Reloaded."); | ||||
|      | ||||
|     RegAdminCmd("zr_anticamp_create_volume", Command_AnticampCreateVolume, ADMFLAG_GENERIC, "Creates a rectangular hurt volume between two points. Usage: ht_create_volume <damage> <interval> <x1> <y1> <z1> <x2> <y2> <z2>"); | ||||
|     RegAdminCmd("zr_anticamp_remove_volume", Command_AnticampRemoveVolume, ADMFLAG_GENERIC, "Removes a volume. Use zr_anticamp_list to list volumes. Usage: zr_anticamp_remove_volume <volume index>"); | ||||
|     RegAdminCmd("zr_anticamp_list", Command_AnticampList, ADMFLAG_GENERIC, "List current volumes."); | ||||
| } | ||||
|  | ||||
| public Action:Command_Infect(client, argc) | ||||
|   | ||||
| @@ -81,7 +81,10 @@ enum ZRSettings | ||||
|     Handle:CVAR_INFECT_SHAKE_AMP, | ||||
|     Handle:CVAR_INFECT_SHAKE_FREQUENCY, | ||||
|     Handle:CVAR_INFECT_SHAKE_DURATION, | ||||
|     Handle:CVAR_INFECT_ANTISTICK_FORCE | ||||
|     Handle:CVAR_INFECT_ANTISTICK_FORCE, | ||||
|     Handle:CVAR_ANTICAMP, | ||||
|     Handle:CVAR_ANTICAMP_UPDATE_INTERVAL, | ||||
|     Handle:CVAR_ANTICAMP_ECHO | ||||
| } | ||||
|  | ||||
| new gCvars[ZRSettings]; | ||||
| @@ -162,8 +165,13 @@ CreateCvars() | ||||
|     gCvars[CVAR_INFECT_SHAKE_FREQUENCY]    =    CreateConVar("zr_infect_shake_frequency", "1.0", "Frequency of the shake, when zr_infect_shake is 1"); | ||||
|     gCvars[CVAR_INFECT_SHAKE_DURATION]     =    CreateConVar("zr_infect_shake_duration", "5.0", "Duration of the shake, when zr_infect_shake is 1"); | ||||
|     gCvars[CVAR_INFECT_ANTISTICK_FORCE]    =    CreateConVar("zr_infect_antistick_force", "-160.0", "Force to push away players from eachother on infection. Negative values push away, positive values pull. (0: Disable)"); | ||||
|     gCvars[CVAR_ANTICAMP]                  =    CreateConVar("zr_anticamp", "1", "Enables or disables hurt volumes for preventing unfair camping. (0: Disable)"); | ||||
|     gCvars[CVAR_ANTICAMP_UPDATE_INTERVAL]  =    CreateConVar("zr_anticamp_update_interval", "1", "How often to update player locations (in seconds)."); | ||||
|     gCvars[CVAR_ANTICAMP_ECHO]             =    CreateConVar("zr_anticamp_echo", "1", "Log kills done by anticamp to admin chat."); | ||||
|      | ||||
|     HookConVarChange(gCvars[CVAR_ENABLE], EnableHook); | ||||
|     HookConVarChange(gCvars[CVAR_ANTICAMP], AnticampHook); | ||||
|     HookConVarChange(gCvars[CVAR_ANTICAMP_UPDATE_INTERVAL], UpdateIntervalHook); | ||||
|      | ||||
|     AutoExecConfig(true, "zombiereloaded", "sourcemod/zombiereloaded"); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user