TakeDamage_Pre - sprawdzenie funkcji
DEADP00L
28.05.2023
Witam,
Chciałbym zapoznać się z waszymi opiniami czy według was jest to stabilna forma zmiany obrażeń poszczególnej broni:
#define IsPlayer(%1) (1 <= %1 <= g_iMaxPlayers) new g_iMaxPlayers; new const Float:hit_area[][] = { { 1.0, 1.0, 1.0 }, // HIT_GENERIC { 50.0, 10.0, 30.0 }, // HIT_HEAD { 25.0, 8.0, 15.0 }, // HIT_CHEST { 20.25, 6.25, 12.25 }, // HIT_STOMACH { 10.0, 4.0, 8.0 }, // HIT_LEFTARM { 10.0, 4.0, 8.0 }, // HIT_RIGHTARM { 8.75, 2.75, 5.75 }, // HIT_LEFTLEG { 8.75, 2.75, 5.75 }, // HIT_RIGHTLEG { 0.0, 0.0, 0.0 } // HIT_SHIELD } public plugin_init() { RegisterHam(Ham_TakeDamage, "player", "Ham_CBasePlayer_TakeDamage_Pre", 0); g_iMaxPlayers = get_maxplayers(); } public Ham_CBasePlayer_TakeDamage_Pre(id, iInflictor, iAttacker, Float:flDamage, bitsDamageType) { if(id != iAttacker && is_user_connected(iAttacker) && IsPlayer(iAttacker)) { const XTRA_OFS_PLAYER = 5; const m_LastHitGroup = 75; const m_iTeam = 114; new weapon = get_user_weapon(iAttacker), hitbox = get_pdata_int(id, m_LastHitGroup, XTRA_OFS_PLAYER); switch(weapon) { case CSW_KNIFE: if(bitsDamageType & DMG_BULLET && get_pdata_int(id, m_iTeam, XTRA_OFS_PLAYER) != get_pdata_int(iAttacker, m_iTeam, XTRA_OFS_PLAYER)) SetHamParamFloat(4, hit_area[hitbox][0]) case CSW_FIVESEVEN: if(bitsDamageType & DMG_BULLET && get_pdata_int(id, m_iTeam, XTRA_OFS_PLAYER) != get_pdata_int(iAttacker, m_iTeam, XTRA_OFS_PLAYER)) SetHamParamFloat(4, hit_area[hitbox][1]) case CSW_M4A1: if(bitsDamageType & DMG_BULLET && get_pdata_int(id, m_iTeam, XTRA_OFS_PLAYER) != get_pdata_int(iAttacker, m_iTeam, XTRA_OFS_PLAYER)) SetHamParamFloat(4, hit_area[hitbox][2]) } return HAM_OVERRIDE } return HAM_IGNORED }
Dodam, że łącznie będzie tam 24 case'ów z każdą bronią
Czy według was jest to dobrze zoptymalizowane?
Z góry dziękuję za wszelkie sugestie!
Robiin
28.05.2023
Czym są te floaty w hit_area?
Generalnie zamiast robić switcha to pewnie dałoby radę zrobić to z jednym ifem:
if(bitsDamageType & DMG_BULLET && get_pdata_int(id, m_iTeam, XTRA_OFS_PLAYER) != get_pdata_int(iAttacker, m_iTeam, XTRA_OFS_PLAYER)) SetHamParamFloat(4, hit_area[hitbox][id_based_on_weapon_id]);
Zakładając, że id_based_on_weapon_id będzie jakoś sensownie wyznaczany.
No i jeszcze kwestia HE, bo tam pewnie jest DMG_* inne, więc nie złapałby go if.
DEADP00L
28.05.2023
Czym są te floaty w hit_area?
Obrażenia w zależności od tego czy trafiliśmy w głowe, klate, noge itp
Dałem tam przykład pod 3 bronie, FiveSeven, M4A1 oraz Knife
DEADP00L
28.05.2023
Czym są te floaty w hit_area?
Generalnie zamiast robić switcha to pewnie dałoby radę zrobić to z jednym ifem:
if(bitsDamageType & DMG_BULLET && get_pdata_int(id, m_iTeam, XTRA_OFS_PLAYER) != get_pdata_int(iAttacker, m_iTeam, XTRA_OFS_PLAYER)) SetHamParamFloat(4, hit_area[hitbox][id_based_on_weapon_id]);Zakładając, że id_based_on_weapon_id będzie jakoś sensownie wyznaczany.
No i jeszcze kwestia HE, bo tam pewnie jest DMG_* inne, więc nie złapałby go if.
Zrobiłem to w taki sposób, tak jak napisałeś wyżej:
#define IsPlayer(%1) (1 <= %1 <= g_iMaxPlayers) new g_iMaxPlayers; new const Float:hit_area[][] = { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, 0.0 }, // HIT_GENERIC { 0.0, 5.0, 0.0, 5.0, 0.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 20.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 10.0, 5.0 }, // HIT_HEAD { 0.0, 5.0, 0.0, 5.0, 0.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 10.0, 5.0 }, // HIT_CHEST { 0.0, 5.0, 0.0, 5.0, 0.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 10.0, 5.0 }, // HIT_STOMACH { 0.0, 5.0, 0.0, 5.0, 0.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 10.0, 5.0 }, // HIT_LEFTARM { 0.0, 5.0, 0.0, 5.0, 0.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 10.0, 5.0 }, // HIT_RIGHTARM { 0.0, 5.0, 0.0, 5.0, 0.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 10.0, 5.0 }, // HIT_LEFTLEG { 0.0, 5.0, 0.0, 5.0, 0.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 10.0, 5.0 }, // HIT_RIGHTLEG { 0.0, 5.0, 0.0, 5.0, 0.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 10.0, 5.0 } // HIT_SHIELD } public plugin_init() { RegisterHam(Ham_TakeDamage, "player", "Ham_CBasePlayer_TakeDamage_Pre", 0); g_iMaxPlayers = get_maxplayers(); } public Ham_CBasePlayer_TakeDamage_Pre(id, iInflictor, iAttacker, Float:flDamage, bitsDamageType) { if(id != iAttacker && IsPlayer(iAttacker)) { const XTRA_OFS_PLAYER = 5; const m_LastHitGroup = 75; const m_iTeam = 114; new wid, weapon = GetUserWeapon(iAttacker,wid), hitbox = get_pdata_int(id, m_LastHitGroup, XTRA_OFS_PLAYER); if(bitsDamageType & DMG_BULLET && get_pdata_int(id, m_iTeam, XTRA_OFS_PLAYER) != get_pdata_int(iAttacker, m_iTeam, XTRA_OFS_PLAYER)) SetHamParamFloat(4, hit_area[hitbox][weapon]); return HAM_OVERRIDE } return HAM_IGNORED } GetUserWeapon(id,&wid=0) { const m_pActiveItem = 373 const m_iId = 43 if(!is_user_alive(id) || pev_valid((wid = get_pdata_cbase(id,m_pActiveItem,5))) != 2) return 0 return get_pdata_int(wid,m_iId,4) }
Ponumerowałem sobie ID broni od 0 do 30, tak abym potem wiedział w której broni zmieniam DMG.
Co do *HE_, to to akurat nie będzie mi potrzebne dlatego ustawiłem przy każdym granacie float 0.0, tak samo jak i przy C4.
Ten plugin jest uruchomiony na Zombie Modzie, gdzie nie ma standardowych granatów wybuchających tylko podpalających.
Daj znać czy teraz plugin jest bardziej zoptymalizowany
Robiin
30.05.2023
Proponowałbym zrobić jakiś config do tego. Przykładowy syntax:
m4a1: head: 50.0 generic: 25.0 chest: 20.0 stomach: 20.0 left_arm: 15.0 right_arm: 15.0 left_leg: 15.0 right_leg: 15.0 shield: 0.0
I potem względem tego wybierać damage. W ten sposób masz ładną i przejrzystą konfigurację i nie musisz rekompilować pluginu za każdym razem kiedy chcesz zmienić którąś z wartości.
Dodatkowo, jeśli używasz amxxa >= 1.9, to IsPlayer może użyć stałej dostępnej we wszystkich pluginach, które używają include "amxmodx" (czyli w praktycznie każdym); MAX_PLAYERS:
#define IsPlayer(%1) (1 <= %1 <= MAX_PLAYERS)
Reszta wygląda solidnie, ale już nie pamiętam kiedy ostatni raz pisałem coś w amxxie, więc mogę po prostu krzywo patrzeć
Hard D'RING
05.06.2023
if(id != iAttacker && IsPlayer(iAttacker))
zamień na
if(id != iAttacker && IsPlayer(iAttacker) && bitsDamageType & DMG_BULLET && get_pdata_int(id, m_iTeam, XTRA_OFS_PLAYER) != get_pdata_int(iAttacker, m_iTeam, XTRA_OFS_PLAYER))
będzie optymalniej