Added hitgroup API, and logging values for it. Knockback module is done.

This commit is contained in:
Greyscale 2009-04-15 03:24:02 +02:00
parent 648a875c14
commit e7ace94625
10 changed files with 236 additions and 40 deletions

View 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"
}
}

View File

@ -36,6 +36,9 @@
// Weapons // Weapons
#include "zr/weapons/weapons" #include "zr/weapons/weapons"
// Hitgroups
#include "zr/hitgroups"
// Knockback // Knockback
#include "zr/knockback" #include "zr/knockback"
@ -126,7 +129,8 @@ public OnMapStart()
// Forward event to modules. // Forward event to modules.
ClassLoad(); ClassLoad();
WeaponsOnMapStart(); WeaponsLoad();
HitgroupsLoad();
Anticamp_Startup(); Anticamp_Startup();
} }

View File

@ -240,13 +240,15 @@ public Action:PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
new index = GetClientOfUserId(GetEventInt(event, "userid")); new index = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker")); new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
new hitgroup = GetEventInt(event, "hitgroup");
new dmg_health = GetEventInt(event, "dmg_health"); new dmg_health = GetEventInt(event, "dmg_health");
decl String:weapon[32]; decl String:weapon[32];
GetEventString(event, "weapon", weapon, sizeof(weapon)); GetEventString(event, "weapon", weapon, sizeof(weapon));
// Forward event to modules. // Forward event to modules.
KnockbackPlayerHurt(index, attacker, weapon, dmg_health); KnockbackPlayerHurt(index, attacker, weapon, hitgroup, dmg_health);
// Check if the attacker is a player. // Check if the attacker is a player.
if (attacker != 0) if (attacker != 0)

104
src/zr/hitgroups.inc Normal file
View 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;
}

View File

@ -6,29 +6,14 @@
* ==================== * ====================
*/ */
/**
* @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 /** Player hurt event
* @param client The victim index. (zombie) * @param client The victim index. (zombie)
* @param attacker The attacker index. (human) * @param attacker The attacker index. (human)
* @param weapon The weapon used. * @param weapon The weapon used.
* @param hitgroup Hitgroup attacker has damaged.
* @param dmg_health Damage done. * @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. // Check if the attacker is a player.
if (attacker != 0) if (attacker != 0)
@ -68,14 +53,15 @@ KnockbackPlayerHurt(client, attacker, const String:weapon[], dmg_health)
TR_GetEndPosition(clientloc); TR_GetEndPosition(clientloc);
} }
// Apply damage knockback multiplier
knockback *= float(dmg_health);
// Retrieve weapon knockback boost. // Retrieve weapon knockback boost.
new Float:boostWeapon = WeaponGetWeaponKnockback(weapon); new Float:boostWeapon = WeaponGetWeaponKnockback(weapon);
// Apply weapon knockback multiplier. // Retrieve hitgroup knockback boost.
knockback *= boostWeapon; 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. // Apply knockback.
KnockbackSetVelocity(client, attackerloc, clientloc, knockback); KnockbackSetVelocity(client, attackerloc, clientloc, knockback);

View File

@ -126,14 +126,16 @@ RestrictDefaultRestrictions()
*/ */
RestrictValidateWeaponGroups() 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)) if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
{ {
return; return;
} }
// Reset keygroup's traversal stack.
KvRewind(kvWeaponGroups); KvRewind(kvWeaponGroups);
// Traverse into the keygroup. (weapon groups level)
if (KvGotoFirstSubKey(kvWeaponGroups)) if (KvGotoFirstSubKey(kvWeaponGroups))
{ {
decl String:weapongroup[WEAPONS_MAX_LENGTH]; decl String:weapongroup[WEAPONS_MAX_LENGTH];
@ -143,12 +145,14 @@ RestrictValidateWeaponGroups()
{ {
KvGetSectionName(kvWeaponGroups, weapongroup, sizeof(weapongroup)); KvGetSectionName(kvWeaponGroups, weapongroup, sizeof(weapongroup));
// Traverse into the keygroup. (weapons level)
if (KvGotoFirstSubKey(kvWeaponGroups)) if (KvGotoFirstSubKey(kvWeaponGroups))
{ {
do do
{ {
KvGetSectionName(kvWeaponGroups, groupweapon, sizeof(groupweapon)); KvGetSectionName(kvWeaponGroups, groupweapon, sizeof(groupweapon));
// If weapon is invalid, then log it.
if (!WeaponsIsValidWeapon(groupweapon)) 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); 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); KvGoBack(kvWeaponGroups);
} }
// If it couldn't traverse to the weapons, then log no weapons within group.
else else
{ {
ZR_LogMessageFormatted(-1, "Weapon Restrict", "Config Validation", "No weapons listed in weapon group \"%s\" in weapongroups.txt.", LOG_FORMAT_TYPE_ERROR, weapongroup); ZR_LogMessageFormatted(-1, "Weapon Restrict", "Config Validation", "No weapons listed in weapon group \"%s\" in weapongroups.txt.", LOG_FORMAT_TYPE_ERROR, weapongroup);

View File

@ -50,7 +50,7 @@ WeaponsClearData()
/** /**
* Loads weapon data from file. * Loads weapon data from file.
*/ */
WeaponsOnMapStart() WeaponsLoad()
{ {
// Clear weapon data // Clear weapon data
WeaponsClearData(); WeaponsClearData();
@ -73,13 +73,13 @@ WeaponsOnMapStart()
} }
// Validate weapons config // Validate weapons config
WeaponsValidateWeaponsConfig(); WeaponsValidateConfig();
// Forward event to sub-module // Forward event to sub-module
RestrictOnMapStart(); RestrictOnMapStart();
} }
WeaponsValidateWeaponsConfig() WeaponsValidateConfig()
{ {
// If log flag check fails, don't log // If log flag check fails, don't log
if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS)) if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))

View File

@ -11,10 +11,9 @@ new curMenuClass[MAXPLAYERS + 1];
bool:ZRAdminMenu(client) bool:ZRAdminMenu(client)
{ {
if (!GetAdminFlag(GetUserAdmin(client), Admin_Generic)) if (!IsClientAdmin(client))
{ {
ZR_PrintToChat(client, "Must be admin"); ZR_PrintToChat(client, "Must be admin");
return false; return false;
} }
@ -520,6 +519,7 @@ ZRLogFlagsMenu(client)
decl String:z_log_module_teleport[64]; decl String:z_log_module_teleport[64];
decl String:z_log_module_classes[64]; decl String:z_log_module_classes[64];
decl String:z_log_module_weapons[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_commands[64];
decl String:z_log_module_anticamp[64]; decl String:z_log_module_anticamp[64];
decl String:z_log_module_damagecontrol[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_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_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_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_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_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)); 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); 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) if (action == MenuAction_Select)
{ {
@ -666,20 +667,25 @@ public ZRLogFlagsMenuHandle(Handle:menu_log_flags , MenuAction:action, client, s
} }
case 17: case 17:
{ {
ToggleLogFlag(LOG_MODULE_COMMANDS); ToggleLogFlag(LOG_MODULE_HITGROUPS);
ZRLogFlagsMenu(client); ZRLogFlagsMenu(client);
} }
case 18: case 18:
{ {
ToggleLogFlag(LOG_MODULE_ANTICAMP); ToggleLogFlag(LOG_MODULE_COMMANDS);
ZRLogFlagsMenu(client); ZRLogFlagsMenu(client);
} }
case 19: case 19:
{ {
ToggleLogFlag(LOG_MODULE_DAMAGECONTROL); ToggleLogFlag(LOG_MODULE_ANTICAMP);
ZRLogFlagsMenu(client); ZRLogFlagsMenu(client);
} }
case 20: case 20:
{
ToggleLogFlag(LOG_MODULE_DAMAGECONTROL);
ZRLogFlagsMenu(client);
}
case 21:
{ {
ToggleLogFlag(LOG_MODULE_OFFSETS); ToggleLogFlag(LOG_MODULE_OFFSETS);
ZRLogFlagsMenu(client); ZRLogFlagsMenu(client);
@ -695,7 +701,7 @@ public ZRLogFlagsMenuHandle(Handle:menu_log_flags , MenuAction:action, client, s
} }
if (action == MenuAction_End) if (action == MenuAction_End)
{ {
CloseHandle(menu_log_flags ); CloseHandle(menu_log_flags);
} }
} }

View File

@ -55,9 +55,10 @@ enum ZTeam
#define LOG_MODULE_OVERLAYS 65536 /** overlays.inc */ #define LOG_MODULE_OVERLAYS 65536 /** overlays.inc */
#define LOG_MODULE_TELEPORT 131072 /** teleport.inc */ #define LOG_MODULE_TELEPORT 131072 /** teleport.inc */
#define LOG_MODULE_WEAPONS 262144 /** Weapons module - weapons/ *.inc */ #define LOG_MODULE_WEAPONS 262144 /** Weapons module - weapons/ *.inc */
#define LOG_MODULE_ANTICAMP 524288 /** anticamp.inc */ #define LOG_MODULE_HITGROUPS 524288 /** hitgroups.inc */
#define LOG_MODULE_DAMAGECONTROL 1048576 /** damagecontrol.inc */ #define LOG_MODULE_ANTICAMP 1048576 /** anticamp.inc */
#define LOG_MODULE_OFFSETS 2097152 /** offsets.inc */ #define LOG_MODULE_DAMAGECONTROL 2097152 /** damagecontrol.inc */
#define LOG_MODULE_OFFSETS 4194304 /** offsets.inc */
/* /*
* @endsection * @endsection
*/ */
@ -248,3 +249,21 @@ bool:IsClientPlayer(client)
return false; 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;
}
}