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 | 2009.01.17 - 2.5.1.23 | ||||||
|   * Fixed teleport location text to display as float values instead of decimal. |   * 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: |   zr_anticamp_remove_volume <volume id> | ||||||
|     alpha_spawn    <0-255>   255         initial alpha value (0 = transparent) |     - Remove a volume. | ||||||
|     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. |  | ||||||
|    |    | ||||||
|     knockback = zr_zombie_knockback * class knockback |   zr_anticamp_list | ||||||
|  |     - List existing volumes. | ||||||
|  |  | ||||||
| * Spawn protection makes the players invisible and move faster, and cannot be | Set default classes | ||||||
|   infected during protecting time. A centered counter shows the time remaining. | ~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
| * Support for overrriding class nvgs with the zr_zombie_nvgs cvar: | Setting the default class with a cvar. Works with per-map configs. | ||||||
|   Generally, any non-zero value is considered as on. |  | ||||||
|    |    | ||||||
|     Value:    Description: |   zr_classes_default <classname> | ||||||
|     -1        no override (use value in classes.txt) / nvgs on |  | ||||||
|     0         never give nvgs |  | ||||||
|     1         always give nvgs |  | ||||||
|  |  | ||||||
| * 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> |   Class knockback | ||||||
|  |     - Fine tune a class knockback value. | ||||||
| * 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. |  | ||||||
|    |    | ||||||
|     Knockback multiplier |   Night vision settings | ||||||
|       - Fine tune the knockback multiplier. |     - Override night vision settings (explained earlier). | ||||||
|      |    | ||||||
|     Class knockback |   Infect | ||||||
|       - Fine tune a class knockback value. |     - Infect a player. Lists all players, but could be changed to only list | ||||||
|      |       humans. | ||||||
|     Night vision settings |    | ||||||
|       - Override night vision settings (explained earlier). |   Spawn players | ||||||
|      |     - Spawns all dead players (except spectactors). | ||||||
|     Infect |    | ||||||
|       - Infect a player. Lists all players, but could be changed to only list |   (more zombie admin stuff might come...) | ||||||
|         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 | Set (and get) class knockback | ||||||
|   are not saved. They will be reset on map change. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  | Set or get knockback from a class. Changes are not saved. They will be reset on | ||||||
|  | map change. | ||||||
|    |    | ||||||
|   zr_set_class_knockback <classname> <knockback> |   zr_set_class_knockback <classname> <knockback> | ||||||
|     - Sets knockback to a specified class. Useful when using per-map configs to |     - 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. |     - 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. |       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." | 		"en"		"Once a player has been infected, only zombies can use !ztele." | ||||||
| 		"ru"		"После инфицирования кого-либо, только зомби могут использовать !ztele" | 		"ru"		"После инфицирования кого-либо, только зомби могут использовать !ztele" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	"!ztele zombies restricted" | 	"!ztele zombies restricted" | ||||||
| 	{ | 	{ | ||||||
| 		"en"		"The teleporter is disabled for zombies." | 		"en"		"The teleporter is disabled for zombies." | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	"!ztele stuck" | 	"!ztele stuck" | ||||||
| 	{ | 	{ | ||||||
| 		"en"		"Tip: Use !tp to teleport away if you are stuck." | 		"en"		"Tip: Use !tp to teleport away if you are stuck." | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	"!ztele not spawned" | 	"!ztele not spawned" | ||||||
| 	{ | 	{ | ||||||
| 		"en"		"You cannot use the teleporter before you've spawned." | 		"en"		"You cannot use the teleporter before you've spawned." | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	"!ztele offline" | 	"!ztele offline" | ||||||
| 	{ | 	{ | ||||||
| 		"en"		"The teleporter is not online yet." | 		"en"		"The teleporter is not online yet." | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	"!ztele cooldown" | 	"!ztele cooldown" | ||||||
| 	{ | 	{ | ||||||
| 		"en"		"Your teleporter is still on a cooldown." | 		"en"		"Your teleporter is still on a cooldown." | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	"!ztele in progress" | 	"!ztele in progress" | ||||||
| @@ -224,6 +224,17 @@ | |||||||
| 		"en"		"Nice try n00b!" | 		"en"		"Nice try n00b!" | ||||||
| 		"ru"		"Неплохая попытка 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" | 	"DX90 not supported" | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ | |||||||
| #undef REQUIRE_PLUGIN | #undef REQUIRE_PLUGIN | ||||||
| #include <market> | #include <market> | ||||||
|  |  | ||||||
| #define VERSION "2.5.1.23" | #define VERSION "2.5.1.24" | ||||||
|  |  | ||||||
| #include "zr/zombiereloaded" | #include "zr/zombiereloaded" | ||||||
| #include "zr/global" | #include "zr/global" | ||||||
| @@ -26,6 +26,7 @@ | |||||||
| #include "zr/classes" | #include "zr/classes" | ||||||
| #include "zr/models" | #include "zr/models" | ||||||
| #include "zr/overlays" | #include "zr/overlays" | ||||||
|  | #include "zr/anticamp" | ||||||
| #include "zr/teleport" | #include "zr/teleport" | ||||||
| #include "zr/zombie" | #include "zr/zombie" | ||||||
| #include "zr/menu" | #include "zr/menu" | ||||||
| @@ -123,6 +124,13 @@ public OnMapStart() | |||||||
|             pClass[i] = classindex; |             pClass[i] = classindex; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     Anticamp_Startup(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public OnMapEnd() | ||||||
|  | { | ||||||
|  |     Anticamp_Disable(); | ||||||
| } | } | ||||||
|  |  | ||||||
| public OnConfigsExecuted() | 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_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_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_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) | public Action:Command_Infect(client, argc) | ||||||
|   | |||||||
| @@ -81,7 +81,10 @@ enum ZRSettings | |||||||
|     Handle:CVAR_INFECT_SHAKE_AMP, |     Handle:CVAR_INFECT_SHAKE_AMP, | ||||||
|     Handle:CVAR_INFECT_SHAKE_FREQUENCY, |     Handle:CVAR_INFECT_SHAKE_FREQUENCY, | ||||||
|     Handle:CVAR_INFECT_SHAKE_DURATION, |     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]; | 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_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_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_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_ENABLE], EnableHook); | ||||||
|  |     HookConVarChange(gCvars[CVAR_ANTICAMP], AnticampHook); | ||||||
|  |     HookConVarChange(gCvars[CVAR_ANTICAMP_UPDATE_INTERVAL], UpdateIntervalHook); | ||||||
|      |      | ||||||
|     AutoExecConfig(true, "zombiereloaded", "sourcemod/zombiereloaded"); |     AutoExecConfig(true, "zombiereloaded", "sourcemod/zombiereloaded"); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user