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
#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();
}

View File

@ -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
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
* @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);

View File

@ -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);

View File

@ -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))

View File

@ -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));
@ -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);

View File

@ -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;
}
}