←  Pytania

AMXX.pl: Support AMX Mod X i SourceMod

»

TakeDamage_Pre - sprawdzenie funkcji

  • +
  • -
DEADP00L - zdjęcie 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!

Odpowiedz

  • +
  • -
Robiin - zdjęcie 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.

Odpowiedz

  • +
  • -
DEADP00L - zdjęcie 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

Odpowiedz

  • +
  • -
DEADP00L - zdjęcie 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 ;)

Odpowiedz

  • +
  • -
Robiin - zdjęcie 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ć

Odpowiedz

  • +
  • -
Hard D'RING - zdjęcie 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 :) 

Odpowiedz