Added hitgroup API, and logging values for it. Knockback module is done.
This commit is contained in:
		
							
								
								
									
										70
									
								
								cstrike/addons/sourcemod/configs/zr/hitgroups.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								cstrike/addons/sourcemod/configs/zr/hitgroups.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| // Hitgroups | ||||
| // | ||||
| // Format | ||||
| // | ||||
| // "hitgroup index" // Index of the hitgroup (listed below) | ||||
| // { | ||||
| //	"name"			"name of hitgroup" // Redundant as of now, used for readability. | ||||
| //	"knockback"		"1.0" (default) // The knockback multiplier for the hitgroup | ||||
| // } | ||||
| // | ||||
| // Notes: | ||||
| // | ||||
| // A missing config setting will be assumed to be its default value (documented above). | ||||
|  | ||||
| "hitgroups" // Counter-Strike: Source hitgroups | ||||
| { | ||||
| 	"0" | ||||
| 	{ | ||||
| 		"name"		"Generic" | ||||
| 		"knockback"	"1.0" | ||||
| 	} | ||||
|  | ||||
| 	"1" | ||||
| 	{ | ||||
| 		"name"		"Head" | ||||
| 		"knockback"	"2.0" | ||||
| 	} | ||||
|  | ||||
| 	"2" | ||||
| 	{ | ||||
| 		"name"		"Chest" | ||||
| 		"knockback"	"1.3" | ||||
| 	} | ||||
|  | ||||
| 	"3" | ||||
| 	{ | ||||
| 		"name"		"Stomach" | ||||
| 		"knockback"	"1.2" | ||||
| 	} | ||||
|  | ||||
| 	"4" | ||||
| 	{ | ||||
| 		"name"		"Left Arm" | ||||
| 		"knockback"	"1.0" | ||||
| 	} | ||||
|  | ||||
| 	"5" | ||||
| 	{ | ||||
| 		"name"		"Right Arm" | ||||
| 		"knockback"	"1.0" | ||||
| 	} | ||||
|  | ||||
| 	"6" | ||||
| 	{ | ||||
| 		"name"		"Left Leg" | ||||
| 		"knockback"	"0.9" | ||||
| 	} | ||||
|  | ||||
| 	"7" | ||||
| 	{ | ||||
| 		"name"		"Right Leg" | ||||
| 		"knockback"	"0.9" | ||||
| 	} | ||||
|  | ||||
| 	"10" | ||||
| 	{ | ||||
| 		"name"		"Gear" | ||||
| 		"knockback"	"1.0" | ||||
| 	} | ||||
| } | ||||
| @@ -1,3 +1,3 @@ | ||||
| // =============================== | ||||
| // Zombie:Reloaded External API | ||||
| // =============================== | ||||
| // Zombie:Reloaded External API | ||||
| // =============================== | ||||
| @@ -36,6 +36,9 @@ | ||||
| // Weapons | ||||
| #include "zr/weapons/weapons" | ||||
|  | ||||
| // Hitgroups | ||||
| #include "zr/hitgroups" | ||||
|  | ||||
| // Knockback | ||||
| #include "zr/knockback" | ||||
|  | ||||
| @@ -126,7 +129,8 @@ public OnMapStart() | ||||
|      | ||||
|     // Forward event to modules. | ||||
|     ClassLoad(); | ||||
|     WeaponsOnMapStart(); | ||||
|     WeaponsLoad(); | ||||
|     HitgroupsLoad(); | ||||
|     Anticamp_Startup(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -240,13 +240,15 @@ public Action:PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast) | ||||
|     new index = GetClientOfUserId(GetEventInt(event, "userid")); | ||||
|     new attacker = GetClientOfUserId(GetEventInt(event, "attacker")); | ||||
|      | ||||
|     new hitgroup = GetEventInt(event, "hitgroup"); | ||||
|      | ||||
|     new dmg_health = GetEventInt(event, "dmg_health"); | ||||
|      | ||||
|     decl String:weapon[32]; | ||||
|     GetEventString(event, "weapon", weapon, sizeof(weapon)); | ||||
|      | ||||
|     // Forward event to modules. | ||||
|     KnockbackPlayerHurt(index, attacker, weapon, dmg_health); | ||||
|     KnockbackPlayerHurt(index, attacker, weapon, hitgroup, dmg_health); | ||||
|      | ||||
|     // Check if the attacker is a player. | ||||
|     if (attacker != 0) | ||||
|   | ||||
							
								
								
									
										104
									
								
								src/zr/hitgroups.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/zr/hitgroups.inc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| /* | ||||
|  * ============================================================================ | ||||
|  * | ||||
|  *   Zombie:Reloaded | ||||
|  * | ||||
|  *   File:        hitgroup.inc | ||||
|  *   Description: API for loading hitgroup specific settings. | ||||
|  *   Author:      Greyscale, Richard Helgeby | ||||
|  * | ||||
|  * ============================================================================ | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Array to store keyvalue data. | ||||
|  */ | ||||
| new Handle:kvHitgroups = INVALID_HANDLE; | ||||
|  | ||||
| /** | ||||
|  * @section Player hitgroup values. | ||||
|  */ | ||||
| #define	HITGROUP_GENERIC    0 | ||||
| #define	HITGROUP_HEAD       1 | ||||
| #define	HITGROUP_CHEST      2 | ||||
| #define	HITGROUP_STOMACH    3 | ||||
| #define HITGROUP_LEFTARM    4 | ||||
| #define HITGROUP_RIGHTARM   5 | ||||
| #define HITGROUP_LEFTLEG    6 | ||||
| #define HITGROUP_RIGHTLEG   7 | ||||
| #define HITGROUP_GEAR       10 | ||||
| /** | ||||
|  * @endsection | ||||
|  */ | ||||
|  | ||||
| HitgroupsClearData() | ||||
| { | ||||
|     // Load hitgroup data | ||||
|     if (kvHitgroups != INVALID_HANDLE) | ||||
|     { | ||||
|         CloseHandle(kvHitgroups); | ||||
|     } | ||||
|      | ||||
|     kvHitgroups = CreateKeyValues("hitgroups"); | ||||
| } | ||||
|  | ||||
| HitgroupsLoad() | ||||
| { | ||||
|     // Clear hitgroup data | ||||
|     HitgroupsClearData(); | ||||
|      | ||||
|     decl String:path[PLATFORM_MAX_PATH]; | ||||
|     BuildPath(Path_SM, path, sizeof(path), "configs/zr/hitgroups.txt"); | ||||
|      | ||||
|     // If file isn't found, stop plugin | ||||
|     if (!FileToKeyValues(kvHitgroups, path)) | ||||
|     { | ||||
|         if (LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_HITGROUPS)) | ||||
|         { | ||||
|             ZR_LogMessageFormatted(-1, "Hitgroups", "Config Validation", "Missing file hitgroups.txt, disabling hitgroup-based modules.", LOG_FORMAT_TYPE_FULL); | ||||
|         } | ||||
|          | ||||
|         return; | ||||
|     } | ||||
|      | ||||
|     // Validate hitgroups config | ||||
|     HitgroupsValidateConfig(); | ||||
| } | ||||
|  | ||||
| HitgroupsValidateConfig() | ||||
| { | ||||
|     // If log flag check fails, don't log | ||||
|     if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_HITGROUPS)) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|      | ||||
|     KvRewind(kvHitgroups); | ||||
|     if (!KvGotoFirstSubKey(kvHitgroups)) | ||||
|     { | ||||
|         ZR_LogMessageFormatted(-1, "Hitgroups", "Config Validation", "No hitgroups listed in hitgroups.txt, disabling hitgroup-based modules.", LOG_FORMAT_TYPE_FULL); | ||||
|     } | ||||
| } | ||||
|  | ||||
| Float:HitgroupsGetHitgroupKnockback(hitgroup) | ||||
| { | ||||
|     // Reset keyvalue's traversal stack. | ||||
|     KvRewind(kvHitgroups); | ||||
|     if (KvGotoFirstSubKey(kvHitgroups)) | ||||
|     { | ||||
|         decl String:sHitgroup[4]; | ||||
|          | ||||
|         do | ||||
|         { | ||||
|             KvGetSectionName(kvHitgroups, sHitgroup, sizeof(sHitgroup)); | ||||
|              | ||||
|             // If this is the right hitgroup, then return knockback for it. | ||||
|             if (hitgroup == StringToInt(sHitgroup)) | ||||
|             { | ||||
|                 return KvGetFloat(kvHitgroups, "knockback", 1.0); | ||||
|             } | ||||
|         } while (KvGotoNextKey(kvHitgroups)); | ||||
|     } | ||||
|      | ||||
|     return 1.0; | ||||
| } | ||||
| @@ -5,30 +5,15 @@ | ||||
|  *   Author: Greyscale | ||||
|  * ====================  | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * @section Player hitgroup values. | ||||
|  */ | ||||
| #define	HITGROUP_GENERIC    0 | ||||
| #define	HITGROUP_HEAD       1 | ||||
| #define	HITGROUP_CHEST      2 | ||||
| #define	HITGROUP_STOMACH    3 | ||||
| #define HITGROUP_LEFTARM    4 | ||||
| #define HITGROUP_RIGHTARM   5 | ||||
| #define HITGROUP_LEFTLEG    6 | ||||
| #define HITGROUP_RIGHTLEG   7 | ||||
| #define HITGROUP_GEAR       10 | ||||
| /** | ||||
|  * @endsection | ||||
|  */ | ||||
|    | ||||
| /** Player hurt event | ||||
|  * @param client        The victim index. (zombie) | ||||
|  * @param attacker      The attacker index. (human) | ||||
|  * @param weapon        The weapon used. | ||||
|  * @param hitgroup      Hitgroup attacker has damaged.  | ||||
|  * @param dmg_health    Damage done. | ||||
|  */  | ||||
| KnockbackPlayerHurt(client, attacker, const String:weapon[], dmg_health) | ||||
| KnockbackPlayerHurt(client, attacker, const String:weapon[], hitgroup, dmg_health) | ||||
| { | ||||
|     // Check if the attacker is a player. | ||||
|     if (attacker != 0) | ||||
| @@ -68,14 +53,15 @@ KnockbackPlayerHurt(client, attacker, const String:weapon[], dmg_health) | ||||
|                 TR_GetEndPosition(clientloc); | ||||
|             } | ||||
|              | ||||
|             // Apply damage knockback multiplier | ||||
|             knockback *= float(dmg_health); | ||||
|              | ||||
|             // Retrieve weapon knockback boost. | ||||
|             new Float:boostWeapon = WeaponGetWeaponKnockback(weapon); | ||||
|              | ||||
|             // Apply weapon knockback multiplier. | ||||
|             knockback *= boostWeapon; | ||||
|             // Retrieve hitgroup knockback boost. | ||||
|             new Float:boostHitgroup = HitgroupsGetHitgroupKnockback(hitgroup); | ||||
|              | ||||
|             // Apply all knockback multipliers | ||||
|             PrintToChatAll("Multipliers %f * %f * %f * %f", knockback, float(dmg_health), boostWeapon, boostHitgroup); | ||||
|             knockback *= float(dmg_health) * boostWeapon * boostHitgroup; | ||||
|              | ||||
|             // Apply knockback. | ||||
|             KnockbackSetVelocity(client, attackerloc, clientloc, knockback); | ||||
|   | ||||
| @@ -126,14 +126,16 @@ RestrictDefaultRestrictions() | ||||
|  */  | ||||
| RestrictValidateWeaponGroups() | ||||
| { | ||||
|     // If log flag check fails, don't log | ||||
|     // If log flag check fails, don't log. | ||||
|     if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS)) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|      | ||||
|     // Reset keygroup's traversal stack. | ||||
|     KvRewind(kvWeaponGroups); | ||||
|      | ||||
|     // Traverse into the keygroup. (weapon groups level) | ||||
|     if (KvGotoFirstSubKey(kvWeaponGroups)) | ||||
|     { | ||||
|         decl String:weapongroup[WEAPONS_MAX_LENGTH]; | ||||
| @@ -143,12 +145,14 @@ RestrictValidateWeaponGroups() | ||||
|         { | ||||
|             KvGetSectionName(kvWeaponGroups, weapongroup, sizeof(weapongroup)); | ||||
|              | ||||
|             // Traverse into the keygroup. (weapons level) | ||||
|             if (KvGotoFirstSubKey(kvWeaponGroups)) | ||||
|             { | ||||
|                 do | ||||
|                 { | ||||
|                     KvGetSectionName(kvWeaponGroups, groupweapon, sizeof(groupweapon)); | ||||
|                      | ||||
|                     // If weapon is invalid, then log it. | ||||
|                     if (!WeaponsIsValidWeapon(groupweapon)) | ||||
|                     { | ||||
|                         ZR_LogMessageFormatted(-1, "Weapon Restrict", "Config Validation", "Invalid weapon \"%s\" in group \"%s\" configured in weapongroups.txt.", LOG_FORMAT_TYPE_ERROR, groupweapon, weapongroup); | ||||
| @@ -157,6 +161,7 @@ RestrictValidateWeaponGroups() | ||||
|                  | ||||
|                 KvGoBack(kvWeaponGroups); | ||||
|             } | ||||
|             // If it couldn't traverse to the weapons, then log no weapons within group. | ||||
|             else | ||||
|             { | ||||
|                 ZR_LogMessageFormatted(-1, "Weapon Restrict", "Config Validation", "No weapons listed in weapon group \"%s\" in weapongroups.txt.", LOG_FORMAT_TYPE_ERROR, weapongroup); | ||||
|   | ||||
| @@ -50,7 +50,7 @@ WeaponsClearData() | ||||
| /** | ||||
|  * Loads weapon data from file. | ||||
|  */ | ||||
| WeaponsOnMapStart() | ||||
| WeaponsLoad() | ||||
| { | ||||
|     // Clear weapon data | ||||
|     WeaponsClearData(); | ||||
| @@ -73,13 +73,13 @@ WeaponsOnMapStart() | ||||
|     } | ||||
|      | ||||
|     // Validate weapons config | ||||
|     WeaponsValidateWeaponsConfig(); | ||||
|     WeaponsValidateConfig(); | ||||
|      | ||||
|     // Forward event to sub-module | ||||
|     RestrictOnMapStart(); | ||||
| } | ||||
|  | ||||
| WeaponsValidateWeaponsConfig() | ||||
| WeaponsValidateConfig() | ||||
| { | ||||
|     // If log flag check fails, don't log | ||||
|     if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS)) | ||||
|   | ||||
| @@ -11,10 +11,9 @@ new curMenuClass[MAXPLAYERS + 1]; | ||||
|  | ||||
| bool:ZRAdminMenu(client) | ||||
| { | ||||
|     if (!GetAdminFlag(GetUserAdmin(client), Admin_Generic)) | ||||
|     if (!IsClientAdmin(client)) | ||||
|     { | ||||
|         ZR_PrintToChat(client, "Must be admin"); | ||||
|          | ||||
|         return false; | ||||
|     } | ||||
|      | ||||
| @@ -520,6 +519,7 @@ ZRLogFlagsMenu(client) | ||||
|     decl String:z_log_module_teleport[64]; | ||||
|     decl String:z_log_module_classes[64]; | ||||
|     decl String:z_log_module_weapons[64]; | ||||
|     decl String:z_log_module_hitgroups[64]; | ||||
|     decl String:z_log_module_commands[64]; | ||||
|     decl String:z_log_module_anticamp[64]; | ||||
|     decl String:z_log_module_damagecontrol[64]; | ||||
| @@ -542,6 +542,7 @@ ZRLogFlagsMenu(client) | ||||
|     Format(z_log_module_teleport, sizeof(z_log_module_teleport), "Teleporter (%d)", LogHasFlag(LOG_MODULE_TELEPORT)); | ||||
|     Format(z_log_module_classes, sizeof(z_log_module_classes), "Classes (%d)", LogHasFlag(LOG_MODULE_CLASSES)); | ||||
|     Format(z_log_module_weapons, sizeof(z_log_module_weapons), "Weapons (%d)", LogHasFlag(LOG_MODULE_WEAPONS)); | ||||
|     Format(z_log_module_hitgroups, sizeof(z_log_module_hitgroups), "Hitgroups (%d)", LogHasFlag(LOG_MODULE_HITGROUPS)); | ||||
|     Format(z_log_module_commands, sizeof(z_log_module_commands), "Admin commands (%d)", LogHasFlag(LOG_MODULE_COMMANDS)); | ||||
|     Format(z_log_module_anticamp, sizeof(z_log_module_anticamp), "Anticamp (%d)", LogHasFlag(LOG_MODULE_ANTICAMP)); | ||||
|     Format(z_log_module_damagecontrol, sizeof(z_log_module_damagecontrol), "Damage control (suicides) (%d)", LogHasFlag(LOG_MODULE_DAMAGECONTROL)); | ||||
| @@ -573,7 +574,7 @@ ZRLogFlagsMenu(client) | ||||
|     DisplayMenu(menu_log_flags, client, MENU_TIME_FOREVER); | ||||
| } | ||||
|  | ||||
| public ZRLogFlagsMenuHandle(Handle:menu_log_flags , MenuAction:action, client, slot) | ||||
| public ZRLogFlagsMenuHandle(Handle:menu_log_flags, MenuAction:action, client, slot) | ||||
| { | ||||
|     if (action == MenuAction_Select) | ||||
|     { | ||||
| @@ -666,20 +667,25 @@ public ZRLogFlagsMenuHandle(Handle:menu_log_flags , MenuAction:action, client, s | ||||
|             } | ||||
|             case 17: | ||||
|             { | ||||
|                 ToggleLogFlag(LOG_MODULE_COMMANDS); | ||||
|                 ToggleLogFlag(LOG_MODULE_HITGROUPS); | ||||
|                 ZRLogFlagsMenu(client); | ||||
|             } | ||||
|             case 18: | ||||
|             { | ||||
|                 ToggleLogFlag(LOG_MODULE_ANTICAMP); | ||||
|                 ToggleLogFlag(LOG_MODULE_COMMANDS); | ||||
|                 ZRLogFlagsMenu(client); | ||||
|             } | ||||
|             case 19: | ||||
|             { | ||||
|                 ToggleLogFlag(LOG_MODULE_DAMAGECONTROL); | ||||
|                 ToggleLogFlag(LOG_MODULE_ANTICAMP); | ||||
|                 ZRLogFlagsMenu(client); | ||||
|             } | ||||
|             case 20: | ||||
|             { | ||||
|                 ToggleLogFlag(LOG_MODULE_DAMAGECONTROL); | ||||
|                 ZRLogFlagsMenu(client); | ||||
|             } | ||||
|             case 21: | ||||
|             { | ||||
|                 ToggleLogFlag(LOG_MODULE_OFFSETS); | ||||
|                 ZRLogFlagsMenu(client); | ||||
| @@ -695,7 +701,7 @@ public ZRLogFlagsMenuHandle(Handle:menu_log_flags , MenuAction:action, client, s | ||||
|     } | ||||
|     if (action == MenuAction_End) | ||||
|     { | ||||
|         CloseHandle(menu_log_flags ); | ||||
|         CloseHandle(menu_log_flags); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -55,9 +55,10 @@ enum ZTeam | ||||
| #define LOG_MODULE_OVERLAYS         65536       /** overlays.inc */ | ||||
| #define LOG_MODULE_TELEPORT         131072      /** teleport.inc */ | ||||
| #define LOG_MODULE_WEAPONS          262144      /** Weapons module - weapons/ *.inc */ | ||||
| #define LOG_MODULE_ANTICAMP         524288      /** anticamp.inc */ | ||||
| #define LOG_MODULE_DAMAGECONTROL    1048576     /** damagecontrol.inc */ | ||||
| #define LOG_MODULE_OFFSETS          2097152     /** offsets.inc */ | ||||
| #define LOG_MODULE_HITGROUPS        524288      /** hitgroups.inc */ | ||||
| #define LOG_MODULE_ANTICAMP         1048576     /** anticamp.inc */ | ||||
| #define LOG_MODULE_DAMAGECONTROL    2097152     /** damagecontrol.inc */ | ||||
| #define LOG_MODULE_OFFSETS          4194304     /** offsets.inc */ | ||||
| /* | ||||
|  * @endsection | ||||
|  */ | ||||
| @@ -248,3 +249,21 @@ bool:IsClientPlayer(client) | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns whether a player is a generic admin or not. | ||||
|  * | ||||
|  * @param client    The client index. | ||||
|  * @return          True if generic admin, false otherwise. | ||||
|  */ | ||||
| bool:IsClientAdmin(client) | ||||
| { | ||||
|     if (GetAdminFlag(GetUserAdmin(client), Admin_Generic)) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user