Menu

Beyond 48 weapons, help is needed.

2014-05-10
2023-08-20
  • ChaosEsqueTeam

    ChaosEsqueTeam - 2014-05-10

    The current code allows up to 48 weapons. With the addition of the morgenstern 48 weapons have been reached (no, weapons will not be removed to make way for others).

    Divverent, of Xonotic, Nexuiz, and Darkplaces fame, created the macro code to support 48 weapons. This was an extension of the previous 24 weapon code. When I last talked to him he said that a further extension was trivial, simply follow the pattern of the existing macro code and extend it.

    The problem comes from a simple fact that I, and perhaps others, have come to realize is unbreachable: I, your host, am simply not very smart. There are many things I cannot fathom. I get by by sticking to one thing and hammering away at it untill I understand it enough. It took me four years to learn quake C sufficiently to effortlessly move around the code without frustration. Four years.

    That is a long time for learning a programming language.

    The code that needs to be extended resides in the common directory of the quake C source, specifically the items header file:
    qcsrc/common/items.qh

    (accessable by web git if you wish here: http://chaosesqueanthology.git.sourceforge.net/git/gitweb.cgi?p=chaosesqueanthology/xonotic-data.pk3dir;a=blob_plain;f=qcsrc/common/items.qh;hb=HEAD )

    The code block in question starts at line 93, but note, the code that the anthology uses starts at line 127, note the maxcount 48 (we are using two weapon sets here, we need to extend it to three to add more weapons):

    [quote]

    define WEP_FIRST 1

    float WEP_COUNT;
    float WEP_LAST;

    if 0

    define WEP_MAXCOUNT 24

    // default storage
    .float _WS_weapons;

    define WEPSET_BIT(a) power2of((a) - WEP_FIRST)

    define WEPSET_DECLARE_A(a) float WS##a

    define WEPSET_CLEAR_E(e) ((e)._WS_weapons = 0)

    define WEPSET_CLEAR_A(a) (WS##a = 0)

    define WEPSET_EMPTY_E(e) ((e)._WS_weapons == 0)

    define WEPSET_EMPTY_A(a) (WS##a == 0)

    define WEPSET_COPY_AS(a) (WS##a = getstati(STAT_WEAPONS))

    define WEPSET_ADDSTAT() addstat(STAT_WEAPONS, AS_INT, _WS_weapons)

    define WEPSET_WRITE_E(dest,a) WriteInt24_t(dest, (a)._WS_weapons)

    define WEPSET_WRITE_A(dest,a) WriteInt24_t(dest, WS##a)

    define WEPSET_WRITE_W(dest,a) WriteInt24_t(dest, WEPSET_BIT(a))

    define WEPSET_READ_E(a) (a)._WS_weapons = ReadInt24_t()

    define WEPSET_READ_A(a) (WS##a) = ReadInt24_t()

    define WEPSET_OP1_EE(a,b,mergeop,x) ((a)._WS_weapons x (b)._WS_weapons)

    define WEPSET_OP2_EE(a,b,mergeop,x,y) ((a)._WS_weapons x (b)._WS_weapons y (a)._WS_weapons)

    define WEPSET_OP1_EA(a,b,mergeop,x) ((a).WS_weapons x _WS##b)

    define WEPSET_OP2_EA(a,b,mergeop,x,y) ((a).WS_weapons x _WS##b y (a)._WS_weapons)

    define WEPSET_OP1_EW(a,b,mergeop,x) ((a)._WS_weapons x WEPSET_BIT(b))

    define WEPSET_OP2_EW(a,b,mergeop,x,y) ((a)._WS_weapons x WEPSET_BIT(b) y (a)._WS_weapons)

    define WEPSET_OP1_AE(a,b,mergeop,x) (WS##a x (b)._WS_weapons)

    define WEPSET_OP2_AE(a,b,mergeop,x,y) (WS##a x (b).WS_weapons y _WS##a)

    define WEPSET_OP1_AA(a,b,mergeop,x) (WS##a x WS##b)

    define WEPSET_OP2_AA(a,b,mergeop,x,y) (WS##a x WS##b y WS##a)

    define WEPSET_OP1_AW(a,b,mergeop,x) (WS##a x WEPSET_BIT(b))

    define WEPSET_OP2_AW(a,b,mergeop,x,y) (WS##a x WEPSET_BIT(b) y WS##a)

    else

    define WEP_MAXCOUNT 48

    define WEP_FIRST2 25

    .float _WS1_weapons;
    .float _WS2_weapons;

    define WEPSET_BIT1(a) (((a) < WEP_FIRST2) ? power2of((a) - WEP_FIRST) : 0)

    define WEPSET_BIT2(a) (((a) >= WEP_FIRST2) ? power2of((a) - WEP_FIRST2) : 0)

    define WEPSET_DECLARE_A(a) float WS1##a, WS2##a

    define WEPSET_CLEAR_E(e) ((e)._WS1_weapons = (e)._WS2_weapons = 0)

    define WEPSET_CLEAR_A(a) ((WS1##a) = (WS2##a) = 0)

    define WEPSET_EMPTY_E(e) ((e)._WS1_weapons == 0 && (e)._WS2_weapons == 0)

    define WEPSET_EMPTY_A(a) ((WS1##a) == 0 && (WS2##a) == 0)

    define WEPSET_COPY_AS(a) ((WS1##a) = getstati(STAT_WEAPONS), (WS2##a) = getstati(STAT_WEAPONS2))

    define WEPSET_ADDSTAT() addstat(STAT_WEAPONS, AS_INT, _WS1_weapons); addstat(STAT_WEAPONS2, AS_INT, _WS2_weapons)

    define WEPSET_WRITE_E(dest,a) WriteInt24_t(dest, (a)._WS1_weapons); WriteInt24_t(dest, (a)._WS2_weapons)

    define WEPSET_WRITE_A(dest,a) WriteInt24_t(dest, WS1##a); WriteInt24_t(dest, WS2##a)

    define WEPSET_WRITE_W(dest,a) WriteInt24_t(dest, WEPSET_BIT1(a)); WriteInt24_t(dest, WEPSET_BIT2(a))

    define WEPSET_READ_E(a) (a)._WS1_weapons = ReadInt24_t(); (a)._WS2_weapons = ReadInt24_t()

    define WEPSET_READ_A(a) (WS1##a) = ReadInt24_t(); (WS2##a) = ReadInt24_t()

    define WEPSET_OP1_EE(a,b,mergeop,x) (((a)._WS1_weapons x (b)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons))

    define WEPSET_OP2_EE(a,b,mergeop,x,y) (((a)._WS1_weapons x (b)._WS1_weapons y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons y (a)._WS2_weapons))

    define WEPSET_OP1_EA(a,b,mergeop,x) (((a).WS1_weapons x _WS1##b) mergeop ((a).WS2_weapons x _WS2##b))

    define WEPSET_OP2_EA(a,b,mergeop,x,y) (((a).WS1_weapons x _WS1##b y (a).WS1_weapons) mergeop ((a)._WS2_weapons x _WS2##b y (a)._WS2_weapons))

    define WEPSET_OP1_EW(a,b,mergeop,x) (((a)._WS1_weapons x WEPSET_BIT1(b)) mergeop ((a)._WS2_weapons x WEPSET_BIT2(b)))

    define WEPSET_OP2_EW(a,b,mergeop,x,y) (((a)._WS1_weapons x WEPSET_BIT1(b) y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x WEPSET_BIT2(b) y (a)._WS2_weapons))

    define WEPSET_OP1_AE(a,b,mergeop,x) ((WS1##a x (b).WS1_weapons) mergeop (_WS2##a x (b)._WS2_weapons))

    define WEPSET_OP2_AE(a,b,mergeop,x,y) ((WS1##a x (b).WS1_weapons y _WS1##a) mergeop (WS2##a x (b).WS2_weapons y _WS2##a))

    define WEPSET_OP1_AA(a,b,mergeop,x) ((WS1##a x WS1##b) mergeop (WS2##a x WS2##b))

    define WEPSET_OP2_AA(a,b,mergeop,x,y) ((WS1##a x WS1##b y WS1##a) mergeop (WS2##a x WS2##b y WS2##a))

    define WEPSET_OP1_AW(a,b,mergeop,x) ((WS1##a x WEPSET_BIT1(b)) mergeop (WS2##a x WEPSET_BIT2(b)))

    define WEPSET_OP2_AW(a,b,mergeop,x,y) ((WS1##a x WEPSET_BIT1(b) y WS1##a) mergeop (WS2##a x WEPSET_BIT2(b) y WS2##a))

    endif

    define XX ,

    define WEPSET_COPY_EE(a,b) WEPSET_OP1_EE(a,b,XX,=)

    define WEPSET_EQ_EE(a,b) WEPSET_OP1_EE(a,b,&&,==)

    define WEPSET_OR_EE(a,b) WEPSET_OP1_EE(a,b,XX,|=)

    define WEPSET_AND_EE(a,b) WEPSET_OP2_EE(a,b,XX,=,&)

    define WEPSET_ANDNOT_EE(a,b) WEPSET_OP1_EE(a,b,XX,&~=)

    define WEPSET_CONTAINS_ANY_EE(a,b) !!(WEPSET_OP1_EE(a,b,||,&))

    define WEPSET_CONTAINS_ALL_EE(a,b) WEPSET_OP2_EE(b,a,&&,==,&)

    define WEPSET_COPY_EA(a,b) WEPSET_OP1_EA(a,b,XX,=)

    define WEPSET_EQ_EA(a,b) WEPSET_OP1_EA(a,b,&&,==)

    define WEPSET_OR_EA(a,b) WEPSET_OP1_EA(a,b,XX,|=)

    define WEPSET_AND_EA(a,b) WEPSET_OP2_EA(a,b,XX,=,&)

    define WEPSET_ANDNOT_EA(a,b) WEPSET_OP1_EA(a,b,XX,&~=)

    define WEPSET_CONTAINS_ANY_EA(a,b) !!(WEPSET_OP1_EA(a,b,||,&))

    define WEPSET_CONTAINS_ALL_EA(a,b) WEPSET_OP2_EA(b,a,&&,==,&)

    define WEPSET_COPY_EW(a,b) WEPSET_OP1_EW(a,b,XX,=)

    define WEPSET_EQ_EW(a,b) WEPSET_OP1_EW(a,b,&&,==)

    define WEPSET_OR_EW(a,b) WEPSET_OP1_EW(a,b,XX,|=)

    define WEPSET_AND_EW(a,b) WEPSET_OP2_EW(a,b,XX,=,&)

    define WEPSET_ANDNOT_EW(a,b) WEPSET_OP1_EW(a,b,XX,&~=)

    define WEPSET_CONTAINS_EW(a,b) !!(WEPSET_OP1_EW(a,b,||,&))

    define WEPSET_COPY_AE(a,b) WEPSET_OP1_AE(a,b,XX,=)

    define WEPSET_EQ_AE(a,b) WEPSET_OP1_AE(a,b,&&,==)

    define WEPSET_OR_AE(a,b) WEPSET_OP1_AE(a,b,XX,|=)

    define WEPSET_AND_AE(a,b) WEPSET_OP2_AE(a,b,XX,=,&)

    define WEPSET_ANDNOT_AE(a,b) WEPSET_OP1_AE(a,b,XX,&~=)

    define WEPSET_CONTAINS_ANY_AE(a,b) !!(WEPSET_OP1_AE(a,b,||,&))

    define WEPSET_CONTAINS_ALL_AE(a,b) WEPSET_OP2_AE(b,a,&&,==,&)

    define WEPSET_COPY_AA(a,b) WEPSET_OP1_AA(a,b,XX,=)

    define WEPSET_EQ_AA(a,b) WEPSET_OP1_AA(a,b,&&,==)

    define WEPSET_OR_AA(a,b) WEPSET_OP1_AA(a,b,XX,|=)

    define WEPSET_AND_AA(a,b) WEPSET_OP2_AA(a,b,XX,=,&)

    define WEPSET_ANDNOT_AA(a,b) WEPSET_OP1_AA(a,b,XX,&~=)

    define WEPSET_CONTAINS_ANY_AA(a,b) !!(WEPSET_OP1_AA(a,b,||,&))

    define WEPSET_CONTAINS_ALL_AA(a,b) WEPSET_OP2_AA(b,a,&&,==,&)

    define WEPSET_COPY_AW(a,b) WEPSET_OP1_AW(a,b,XX,=)

    define WEPSET_EQ_AW(a,b) WEPSET_OP1_AW(a,b,&&,==)

    define WEPSET_OR_AW(a,b) WEPSET_OP1_AW(a,b,XX,|=)

    define WEPSET_AND_AW(a,b) WEPSET_OP2_AW(a,b,XX,=,&)

    define WEPSET_ANDNOT_AW(a,b) WEPSET_OP1_AW(a,b,XX,&~=)

    define WEPSET_CONTAINS_AW(a,b) !!(WEPSET_OP1_AW(a,b,||,&))

    WEPSET_DECLARE_A(WEPBIT_ALL);
    WEPSET_DECLARE_A(WEPBIT_SUPERWEAPONS);
    // note: the fabs call is just there to hide "if result is constant" warning
    #define REGISTER_WEAPON_2(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
    float id; \
    float func(float); \
    void RegisterWeapons_##id() \
    { \
    WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
    WEPSET_OR_AW(WEPBIT_ALL, id); \
    if(fabs(weapontype & WEP_FLAG_SUPERWEAPON)) \
    WEPSET_OR_AW(WEPBIT_SUPERWEAPONS, id); \
    ++WEP_COUNT; \
    register_weapon(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname); \
    } \
    ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)

    ifdef MENUQC

    #define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
    REGISTER_WEAPON_2(WEP_##id,w_null,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname)

    else

    #define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
    REGISTER_WEAPON_2(WEP_##id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname)

    endif

    include "../server/w_all.qc"

    undef REGISTER_WEAPON

    ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done)

    string W_FixWeaponOrder(string order, float complete);
    string W_NumberWeaponOrder(string order);
    string W_NameWeaponOrder(string order);
    string W_FixWeaponOrder_BuildImpulseList(string o);
    string W_FixWeaponOrder_AllowIncomplete(string order);
    string W_FixWeaponOrder_ForceComplete(string order);

    void W_RandomWeapons(entity e, float n);
    [/quote]

    How? I don't know, but if you do, please tell!

     
    • ChaosEsqueTeam

      ChaosEsqueTeam - 2014-05-18

      Another file that will need to be edited is the file with the weapon reload code it seems:
      near the end of string W_ThrowNewWeapon( in
      (line 278 on)
      qcsrc/server/cl_weapons.qc
      [code]
      else if(doreduce)
      {
      for(i = 0, j = 1; i < 24; ++i, j *= 2)
      {
      if(wa & j)
      {
      ammofield = Item_CounterField(j);

                      // if our weapon is loaded, give its load back to the player
                      if(self.(weapon_load[self.weapon]) > 0)
                      {
                          own.ammofield += self.(weapon_load[self.weapon]);
                          self.(weapon_load[self.weapon]) = -1; // schedule the weapon for reloading
                      }
      
                      thisammo = min(own.ammofield, wep.ammofield);
                      wep.ammofield = thisammo;
                      own.ammofield -= thisammo;
                      s = strcat(s, " and ", ftos(thisammo), " ", Item_CounterFieldName(j));
                  }
              }
              s = substring(s, 5, -1);
          }
      

      [/code]

      the i < 24 stuff, will probably need an aditionally i < 48 if that's possile in qc for loops

       
  • ChaosEsqueTeam

    ChaosEsqueTeam - 2014-05-18
     
  • ChaosEsqueTeam

    ChaosEsqueTeam - 2014-06-17

    I would like to add a katana, shriukens, and a desert eagle to the game,
    however more weapons slots are needed. Last time I talked to the German main
    developer of Nexuiz and Xonotic he said to extend the system, when needed
    was not difficult.

    However it is beyond me because I am not terribly smart. I can work within
    a system, but cannot surpass even the simplest of limits. That is in everything.

    The programmer that originated the bitshifting weapon code is Divverent of Nexuiz
    and Xonotic. He is often busy with his job and family so it is difficult to
    contact him (I've only been able to maybe once a year these days).

    (The bitshifting code is needed for compatability with fteqcc quake C compiler)

    Other people who might be able to figure it out and how to extend the code
    reside on the anynet.org irc server in #qc and #darkplaces. And on the quakenet.org
    irc server on various #xonotic channels (maybe #nexuiz too). Also any channel
    associated with fte quake engine might also be useful.

    Could some of you, here, perhaps ask them. My scheduel is such that I and they are
    rarely on at the same time so I can't communicate with them effectivly.

    I very much wish to add more weapons.

     
  • ChaosEsqueTeam

    ChaosEsqueTeam - 2014-07-10

    Divverent came through. We now have a third weaponset, and the knowlege to extend it when we need to.

    The third weaponset gives us a max weapons of 72.

    Just added a katana as the 49th weapon.

     
  • Anonymous

    Anonymous - 2023-08-20

    Sirs where to find camel porn

     

Anonymous
Anonymous

Add attachments
Cancel





MongoDB Logo MongoDB