File: weapon.h

package info (click to toggle)
openmohaa 0.82.1%2Bdfsg-1
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 34,192 kB
  • sloc: cpp: 315,720; ansic: 275,789; sh: 312; xml: 246; asm: 141; makefile: 7
file content (637 lines) | stat: -rw-r--r-- 25,781 bytes parent folder | download
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
/*
===========================================================================
Copyright (C) 2025 the OpenMoHAA team

This file is part of OpenMoHAA source code.

OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.

OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
*/

// weapon.h: Header file for Weapon class.  The weapon class is the base class for
// all weapons in Sin.  Any entity created from a class derived from the weapon
// class will be usable by any Sentient (players and monsters) as a weapon.
//

#pragma once

#include "g_local.h"
#include "item.h"
#include "ammo.h"
#include "queue.h"
#include "sentient.h"
#include "../fgame/scriptmaster.h"

extern Event EV_Weapon_Shoot;
extern Event EV_Weapon_SetAmmoClipSize;
extern Event EV_Weapon_SetAmmoInClip;
extern Event EV_Weapon_FireDelay;
extern Event EV_Weapon_SetProjectile;
extern Event EV_Weapon_SetBulletDamage;
extern Event EV_Weapon_SetBulletLarge;
extern Event EV_Weapon_SetTracerSpeed;
extern Event EV_Weapon_SetBulletKnockback;
extern Event EV_Weapon_SetBulletThroughWood;
extern Event EV_Weapon_SetBulletThroughMetal;
extern Event EV_Weapon_SetBulletCount;
extern Event EV_Weapon_SetBulletRange;
extern Event EV_Weapon_SetBulletSpread;
extern Event EV_Weapon_SetTracerFrequency;
extern Event EV_Weapon_GiveStartingAmmo;
extern Event EV_Weapon_SetMeansOfDeath;

typedef enum {
    FT_NONE,
    FT_BULLET,
    FT_FAKEBULLET,
    FT_PROJECTILE,
    FT_MELEE,
    FT_SPECIAL_PROJECTILE,
    FT_CLICKITEM,
    FT_HEAVY,
    FT_LANDMINE,
    FT_DEFUSE,
} firetype_t;

typedef enum {
    WEAPON_READY,
    WEAPON_FIRING,
    WEAPON_LOWERING,
    WEAPON_RAISING,
    WEAPON_HOLSTERED,
    WEAPON_RELOADING,
    WEAPON_CHANGING
} weaponstate_t;

typedef enum {
    RANGE_SHORT,
    RANGE_MEDIUM,
    RANGE_LONG,
    RANGE_SNIPER,
    RANGE_NUM_RANGES
} AIRanges;

#define INITIALIZE_WEAPONMODE_VAR(var, value)       \
    {                                               \
        int _ii;                                    \
        for (_ii = 0; _ii < MAX_FIREMODES; _ii++) { \
            var[_ii] = value;                       \
        }                                           \
    }

static const unsigned int MAX_WEAPON_ANIM_SLOTS = 4;

class Player;

class Weapon : public Item
{
protected:
    int        m_iAnimSlot;
    qboolean   attached;            // Is this weapon attached to something?
    float      nextweaponsoundtime; // The next time this weapon should sound off
    float      m_fLastFireTime;
    firemode_t m_eLastFireMode;
    str        current_attachToTag; // The current name of the tag to attach itself to on the owner
    str        attachToTag_main;    // Tag to use when weapon is wielded in the main hand
    str        attachToTag_offhand; // ...offhand hand
    str        holster_attachToTag; // Tag to use when weapon is put away
    float      lastScale;           // Used for attaching to holster
    Vector     lastAngles;          // Used for attaching to holster
    qboolean   lastValid;           // Used for attaching to holster
    qboolean   auto_putaway;        // Weapon will put itself away when out of ammo
    qboolean   use_no_ammo;         // Weapon will be able to be used when it has no ammo
    qboolean   crosshair;           // Whether or not to display a crosshair with this weapon
    int        m_iZoom;
    float      m_fZoomSpreadMult;
    qboolean   m_bAutoZoom;
    qboolean   m_bSemiAuto;

protected:
    float         maxrange;                // maximum effective firing distance (for AI)
    float         minrange;                // minimum safe firing distance (for AI)
    str           viewmodel;               // View model of the weapon (not used in FAKK)
    weaponstate_t weaponstate;             // current state of the weapon
    int           rank;                    // rank of the weapon (relative to other weapons)
    int           order;                   // The order of this weapon in the inventory
    SentientPtr   last_owner;              // The last owner of the weapon
    float         last_owner_trigger_time; // The time when the last owner may re-pickup this weapon
    qboolean      notdroppable;            // makes the weapon not able to be dropped
    int           aimanim;                 // The aim animation to use for this weapon (so it shoots straight)
    int           aimframe;                // The aim frame to use for this weapon (so it shoots straight)
    Vector        holsterOffset;           // Angles to set the weapon to when it's holstered
    Vector        holsterAngles;           // Angles to set the weapon to when it's holstered
    float         holsterScale;            // Scale the weapon should be set to when it's holstered
    float         next_noise_time;         // next time weapon will alert actors
    float         next_noammo_time;        // next time we can play out of ammo sound
    float         next_maxmovement_time;

    qboolean m_bShouldReload;

    // Starting loadout
    Container<str> m_additionalStartAmmoTypes;
    Container<int> m_additionalStartAmmoAmounts;
    Container<str> m_startItems;

    // Each of these arrays is used to describe the properties of the weapon
    // in its primary(index 0) and alternate(index 1) mode

    float          fire_delay[MAX_FIREMODES];
    str            ammo_type[MAX_FIREMODES];          // The type of ammo used
    int            ammorequired[MAX_FIREMODES];       // The amount of ammo required to fire this weapon
    int            startammo[MAX_FIREMODES];          // The starting amount of ammo when the weapon is picked up
    str            projectileModel[MAX_FIREMODES];    // The model of the projectile fired
    float          bulletdamage[MAX_FIREMODES];       // The amount of damate a single bullet causes
    float          bulletcount[MAX_FIREMODES];        // The number of bullets the weapon fires
    int            bulletlarge[MAX_FIREMODES];        // The number of bullets the weapon fires
    float          bulletrange[MAX_FIREMODES];        // The range of the bullet
    float          bulletknockback[MAX_FIREMODES];    // The amount of knockback a bullet causes
    float          bulletthroughwood[MAX_FIREMODES];  // The amount of knockback a bullet causes
    float          bulletthroughmetal[MAX_FIREMODES]; // The amount of knockback a bullet causes
    float          projectilespeed[MAX_FIREMODES];    // The speed of the projectile fired
    Vector         bulletspread[MAX_FIREMODES];       // The amount of spread bullets can have
    Vector         bulletspreadmax[MAX_FIREMODES];    // The max amount of spread bullets can have
    firetype_t     firetype[MAX_FIREMODES];           // The type of fire (projectile or bullet)
    int            ammo_clip_size[MAX_FIREMODES];     // The amount of rounds the clip can hold
    int            ammo_in_clip[MAX_FIREMODES];       // The current amount of ammo in the clip
    float          max_charge_time[MAX_FIREMODES];    // The max amount of time the weapon may be charged.
    float          min_charge_time[MAX_FIREMODES];    // The min amount of time the weapon may be charged.
    meansOfDeath_t meansofdeath[MAX_FIREMODES];       // The means of death for this mode
    qboolean       loopfire[MAX_FIREMODES];           // The weapon loopfires and will not idle when shooting
    str            worldhitspawn[MAX_FIREMODES];      // The models to spawn when the weapon strikes the world
    int            tracerfrequency[MAX_FIREMODES];
    int            tracercount[MAX_FIREMODES];
    float          tracerspeed[MAX_FIREMODES];
    Vector         viewkickmin[MAX_FIREMODES];
    Vector         viewkickmax[MAX_FIREMODES];
    qboolean       quiet[MAX_FIREMODES];
    float          m_fFireSpreadMultAmount[MAX_FIREMODES];
    float          m_fFireSpreadMultFalloff[MAX_FIREMODES];
    float          m_fFireSpreadMultCap[MAX_FIREMODES];
    float          m_fFireSpreadMultTimeCap[MAX_FIREMODES];
    float          m_fFireSpreadMultTime[MAX_FIREMODES];
    float          m_fFireSpreadMult[MAX_FIREMODES];
    qboolean       m_bShareClip;
    qboolean       m_bCanPartialReload;

    qboolean   autoaim;         // Whether or not the weapon will autoaim
    float      charge_fraction; // Fraction of a charge up time
    qboolean   putaway;         // This is set to true by the state system to signal a weapon to be putaway
    firemode_t firemodeindex;
    int        weapon_class;
    const_str  m_csWeaponGroup;
    //
    // Movement speed
    //
    float m_fMovementSpeed;
    float m_fMaxFireMovement;
    float m_fZoomMovement;
    //
    // Special sounds
    //
    str m_sAmmoPickupSound;
    str m_NoAmmoSound;
    str m_sMaxMovementSound;
    // Weapon subtype
    int m_iWeaponSubtype;
    //
    // Weapon animations
    //
    int m_iNumFireAnims;
    int m_iCurrentFireAnim;
    str m_sTagBarrel;
    //
    // Cook variables
    //
    float      m_fCookTime;
    firemode_t m_eCookModeIndex;
    qboolean   m_bSecondaryAmmoInHud;

public:
    //
    // Stats variables
    //
    int             m_iNumShotsFired;
    int             m_iNumHits;
    int             m_iNumHeadShots;
    int             m_iNumTorsoShots;
    int             m_iNumLeftLegShots;
    int             m_iNumRightLegShots;
    int             m_iNumGroinShots;
    int             m_iNumLeftArmShots;
    int             m_iNumRightArmShots;
    AIRanges        mAIRange;
    SafePtr<Entity> aim_target;

protected:
    friend class Player;
    friend class PlayerBot;
    friend class Sentient;

    void SetMaxRangeEvent(Event *ev);
    void SetMinRangeEvent(Event *ev);
    void SetSecondaryAmmo(const char *type, int amount, int startamount);

    void         DetachGun(void);
    void         AttachGun(weaponhand_t hand, qboolean holstering = qfalse);
    qboolean     IsSecondaryWeapon(void);
    void         PickupWeapon(Event *ev);
    void         DoneRaising(Event *ev);
    void         DoneFiring(Event *ev);
    void         Idle(Event *ev);
    void         IdleInit(Event *ev);
    void         FillAmmoClip(Event *ev);
    void         EmptyAmmoClip(Event *ev);
    void         AddToAmmoClip(Event *ev);
    void         DoneReloading(Event *ev);
    virtual void ApplyFireKickback(const Vector& org, float kickback);
    void         SetAimAnim(Event *ev);
    virtual void Shoot(Event *ev);
    void         Secondary(Event *ev);
    void         SetFireType(Event *ev);
    void         SetAIRange(Event *ev);
    void         SetProjectile(Event *ev);
    void         SetDMProjectile(Event *ev);
    void         SetBulletDamage(Event *ev);
    void         SetBulletLarge(Event *ev); // Added in 2.0
    void         SetTracerSpeed(Event *ev); // Added in 2.0
    void         SetDMBulletDamage(Event *ev);
    void         SetBulletRange(Event *ev);
    void         SetDMBulletRange(Event *ev);
    void         SetBulletKnockback(Event *ev);
    void         SetDMBulletKnockback(Event *ev);
    void         SetBulletThroughWood(Event *ev);  // Added in 2.0
    void         SetBulletThroughMetal(Event *ev); // Added in 2.0
    void         SetBulletCount(Event *ev);
    void         SetDMBulletCount(Event *ev);
    void         SetBulletSpread(Event *ev);
    void         SetDMBulletSpread(Event *ev);
    void         SetZoomSpreadMult(Event *ev);
    void         SetDMZoomSpreadMult(Event *ev);
    void         SetFireSpreadMult(Event *ev);
    void         SetDMFireSpreadMult(Event *ev);
    void         SetTracerFrequency(Event *ev);
    void         SetAutoPutaway(Event *ev);
    void         SetRange(Event *ev);
    void         SetWeaponType(Event *ev);
    void         SetWeaponGroup(Event *ev);
    void         SetUseNoAmmo(Event *ev);
    void         MainAttachToTag(Event *ev);
    void         OffHandAttachToTag(Event *ev);
    void         HolsterAttachToTag(Event *ev);
    void         SetHolsterOffset(Event *ev);
    void         SetHolsterAngles(Event *ev);
    void         SetHolsterScale(Event *ev);
    void         SetWorldHitSpawn(Event *ev);
    void         SetViewKick(Event *ev);
    void         SetMovementSpeed(Event *ev);
    void         SetDMMovementSpeed(Event *ev);
    void         SetMaxFireMovement(Event *ev); // Added in 2.0
    void         SetZoomMovement(Event *ev);    // Added in 2.0
    void         EventAmmoPickupSound(Event *ev);
    void         EventNoAmmoSound(Event *ev);
    void         EventMaxMovementSound(Event *ev); // Added in 2.0
    //====
    // Added in 2.0
    void SetNumFireAnims(Event *ev);
    void SetWeaponSubtype(Event *ev);
    void SetCookTime(Event *ev);
    void SetCurrentFireAnim(Event *ev);
    void SetSecondaryAmmoInHud(Event *ev);
    //====
    void ShowInfo(float fDot, float fDist) override;

public:
    CLASS_PROTOTYPE(Weapon);

    Weapon();
    Weapon(const char *file);
    ~Weapon();

    void Delete(void) override;
    int  GetRank(void);
    int  GetOrder(void);

    int GetWeaponClass(void) const;

    const_str GetWeaponGroup(void) const;

    void  SetItemSlot(int slot);
    void  SetRank(int order, int rank);
    void  SetRankEvent(Event *ev);
    float GetMaxRange(void);
    float GetMinRange(void);

    qboolean GetPutaway(void);

    void SetPutAway(qboolean p);

    void             SetMaxRange(float val);
    void             SetMinRange(float val);
    void             ForceIdle(void);
    virtual qboolean SetWeaponAnim(const char *anim, Event *ev = NULL);
    qboolean         SetWeaponAnim(const char *anim, Event& ev);
    void             SetWeaponAnimEvent(Event *ev);
    void             SetWeaponIdleAnim(void);
    void             SetWeaponIdleAnimEvent(Event *ev);
    virtual void     StopWeaponAnim(void);

    void       SetAmmoRequired(Event *ev);
    void       SetDMAmmoRequired(Event *ev);
    void       SetStartAmmo(Event *ev);
    void       SetDMStartAmmo(Event *ev);
    int        GetStartAmmo(firemode_t mode);
    int        GetMaxAmmo(firemode_t mode);
    str        GetAmmoType(firemode_t mode);
    firetype_t GetFireType(firemode_t mode);
    void       SetAmmoType(Event *ev);
    void       SetAmmoAmount(int amount, firemode_t mode);
    void       UseAmmo(int amount, firemode_t mode);
    void       SetAmmoClipSize(Event *ev);
    void       SetAmmoInClip(Event *ev);
    void       SetShareClip(Event *ev);
    void       SetTagBarrel(const char *tagBarrel); // Added in 2.0
    str        GetTagBarrel() const;                // Added in 2.0
    void       SetModels(const char *world, const char *view);
    void       SetOwner(Sentient *ent) override;
    void       SetMaxChargeTime(Event *ev);
    void       SetMinChargeTime(Event *ev);
    float      GetMinChargeTime(firemode_t);
    float      GetMaxChargeTime(firemode_t);
    int        AmmoAvailable(firemode_t mode);
    qboolean   UnlimitedAmmo(firemode_t mode);
    qboolean   HasAmmo(firemode_t mode);
    qboolean   HasAmmoInClip(firemode_t mode);
    int        GetClipSize(firemode_t mode);

    qboolean CheckReload(firemode_t mode);
    qboolean ShouldReload(void);
    void     SetShouldReload(qboolean should_reload);
    void     StartReloading(void);

    virtual qboolean ReadyToFire(firemode_t mode, qboolean playsound = qtrue);
    qboolean         MuzzleClear(void);

    void         PutAway(void);
    qboolean     Drop(void) override;
    void         Fire(firemode_t mode);
    void         Charge(firemode_t mode);
    void         OnOverCookedWarning(Event *ev); // Added in 2.0
    void         OnOverCooked(Event *ev);        // Added in 2.0
    void         ReleaseFire(firemode_t mode, float chargetime);
    const char  *GetFireAnim() const; // Added in 2.0
    void         ClientFireDone(void);
    qboolean     Removable(void) override;
    qboolean     Pickupable(Entity *other) override;
    virtual void DetachFromOwner(void);
    void         AttachToOwner(weaponhand_t hand);
    void         WeaponSound(Event *ev);
    virtual void GetMuzzlePosition(
        vec3_t position, vec3_t vBarrelPos = NULL, vec3_t forward = NULL, vec3_t right = NULL, vec3_t up = NULL
    );
    qboolean      AutoChange(void);
    int           ClipAmmo(firemode_t mode);
    qboolean      IsDroppable(void);
    virtual float FireDelay(firemode_t mode);
    virtual void  SetFireDelay(Event *ev);
    void          SetDMFireDelay(Event *ev);

    weaponstate_t GetState(void);
    void          ForceState(weaponstate_t state);

    void         NotDroppableEvent(Event *ev);
    void         GiveStartingAmmoToOwner(Event *ev);
    void         AutoAim(Event *ev);
    void         Crosshair(Event *ev);
    void         DMCrosshair(Event *ev);
    void         SetZoom(Event *ev);
    void         SetSemiAuto(Event *ev);
    void         AttachToHand(Event *ev);
    void         SetCantPartialReload(Event *ev);
    void         SetDMCantPartialReload(Event *ev);
    void         AddAdditionalStartAmmo(Event *ev); // Added in 2.0
    void         AddStartItem(Event *ev);           // Added in 2.0
    void         SetQuiet(Event *ev);
    void         SetLoopFire(Event *ev);
    virtual void SpecialFireProjectile(
        Vector pos, Vector forward, Vector right, Vector up, Entity *owner, str projectileModel, float charge_fraction
    );

    virtual void AttachToHolster(weaponhand_t hand);
    str          GetCurrentAttachToTag(void);
    void         SetCurrentAttachToTag(str s);
    str          GetHolsterTag(void);
    qboolean     GetUseNoAmmo(void);

    int            GetZoom(void);
    qboolean       GetAutoZoom(void);
    void           SetMeansOfDeath(Event *ev);
    meansOfDeath_t GetMeansOfDeath(firemode_t mode);
    void           SetAimTarget(Entity *);
    void           SetIdleState(int state); // Added in 2.0
    void           WorldHitSpawn(firemode_t mode, Vector org, Vector angles, float life);
    void           MakeNoise(Event *ev);
    void           FallingAngleAdjust(Event *ev);
    float          GetMovementSpeed() const;
    qboolean       GetUseCrosshair() const;

    virtual bool IsCarryableTurret() const; // Added in 2.0

    void Archive(Archiver& arc) override;

    //
    // Added in OPM
    //
    Listener  *GetScriptOwner(void) override;
    float      GetBulletRange(firemode_t mode);
    float      GetSpreadFactor(firemode_t mode);
    float      GetChargeFraction(void) const;
    float      GetCurrentFireSpreadMult(firemode_t mode) const;
    float      GetCurrentFireSpreadMultTime(firemode_t mode) const;
    float      GetFireSpreadMultAmount(firemode_t mode) const;
    float      GetFireSpreadMultFalloff(firemode_t mode) const;
    float      GetFireSpreadMultCap(firemode_t mode) const;
    float      GetFireSpreadMultTimeCap(firemode_t mode) const;
    firemode_t GetFireMode(void);
    qboolean   IsSemiAuto(void);
    void       DoneAnimating(Event *ev);
    void       EventGetPutaway(Event *ev);

    float GetMaxFireMovementMult() const;
    float GetZoomMovement() const;
    float GetMaxFireMovement() const;
};

inline void Weapon::Archive(Archiver& arc)
{
    Item::Archive(arc);

    arc.ArchiveInteger(&m_iAnimSlot);
    arc.ArchiveBoolean(&attached);
    arc.ArchiveFloat(&nextweaponsoundtime);
    arc.ArchiveFloat(&m_fLastFireTime);
    ArchiveEnum(m_eLastFireMode, firemode_t);
    arc.ArchiveString(&current_attachToTag);
    arc.ArchiveString(&attachToTag_main);
    arc.ArchiveString(&attachToTag_offhand);
    arc.ArchiveString(&holster_attachToTag);
    arc.ArchiveFloat(&lastScale);
    arc.ArchiveVector(&lastAngles);
    arc.ArchiveBoolean(&lastValid);
    arc.ArchiveBoolean(&auto_putaway);
    arc.ArchiveBoolean(&use_no_ammo);
    arc.ArchiveBoolean(&crosshair);
    arc.ArchiveInteger(&m_iZoom);
    arc.ArchiveFloat(&m_fZoomSpreadMult);
    arc.ArchiveBoolean(&m_bAutoZoom);
    arc.ArchiveBoolean(&m_bSemiAuto);
    arc.ArchiveSafePointer(&aim_target);
    arc.ArchiveFloat(&maxrange);
    arc.ArchiveFloat(&minrange);
    arc.ArchiveString(&viewmodel);

    ArchiveEnum(weaponstate, weaponstate_t);

    arc.ArchiveInteger(&rank);
    arc.ArchiveInteger(&order);
    arc.ArchiveSafePointer(&last_owner);
    arc.ArchiveFloat(&last_owner_trigger_time);
    arc.ArchiveBoolean(&notdroppable);
    arc.ArchiveInteger(&aimanim);
    arc.ArchiveInteger(&aimframe);
    arc.ArchiveVector(&holsterOffset);
    arc.ArchiveVector(&holsterAngles);
    arc.ArchiveFloat(&holsterScale);
    arc.ArchiveFloat(&next_noise_time);
    arc.ArchiveFloat(&next_noammo_time);
    arc.ArchiveFloat(&next_maxmovement_time);

    arc.ArchiveBoolean(&m_bShouldReload);

    m_additionalStartAmmoTypes.Archive(arc);
    m_additionalStartAmmoTypes.Archive(arc);
    m_additionalStartAmmoAmounts.Archive(arc);

    arc.ArchiveFloat(&fire_delay[0]);
    arc.ArchiveFloat(&fire_delay[1]);
    arc.ArchiveString(&ammo_type[0]);
    arc.ArchiveString(&ammo_type[1]);
    arc.ArchiveInteger(&ammorequired[0]);
    arc.ArchiveInteger(&ammorequired[1]);
    arc.ArchiveInteger(&startammo[0]);
    arc.ArchiveInteger(&startammo[1]);
    arc.ArchiveString(&projectileModel[0]);
    arc.ArchiveString(&projectileModel[1]);
    arc.ArchiveFloat(&bulletdamage[0]);
    arc.ArchiveFloat(&bulletdamage[1]);
    arc.ArchiveInteger(&bulletlarge[0]);
    arc.ArchiveInteger(&bulletlarge[1]);
    arc.ArchiveFloat(&bulletcount[0]);
    arc.ArchiveFloat(&bulletcount[1]);
    arc.ArchiveFloat(&bulletrange[0]);
    arc.ArchiveFloat(&bulletrange[1]);
    arc.ArchiveFloat(&bulletknockback[0]);
    arc.ArchiveFloat(&bulletknockback[1]);
    arc.ArchiveFloat(&bulletthroughwood[0]);
    arc.ArchiveFloat(&bulletthroughwood[1]);
    arc.ArchiveFloat(&bulletthroughmetal[0]);
    arc.ArchiveFloat(&bulletthroughmetal[1]);
    arc.ArchiveFloat(&projectilespeed[0]);
    arc.ArchiveFloat(&projectilespeed[1]);
    arc.ArchiveVector(&bulletspread[0]);
    arc.ArchiveVector(&bulletspread[1]);
    arc.ArchiveVector(&bulletspreadmax[0]);
    arc.ArchiveVector(&bulletspreadmax[1]);
    arc.ArchiveString(&worldhitspawn[0]);
    arc.ArchiveString(&worldhitspawn[1]);
    arc.ArchiveInteger(&tracerfrequency[0]);
    arc.ArchiveInteger(&tracerfrequency[1]);
    arc.ArchiveInteger(&tracercount[0]);
    arc.ArchiveInteger(&tracercount[1]);
    arc.ArchiveFloat(&tracerspeed[0]);
    arc.ArchiveFloat(&tracerspeed[1]);
    arc.ArchiveVector(&viewkickmin[0]);
    arc.ArchiveVector(&viewkickmin[1]);
    arc.ArchiveVector(&viewkickmax[0]);
    arc.ArchiveVector(&viewkickmax[1]);
    arc.ArchiveBoolean(&quiet[0]);
    arc.ArchiveBoolean(&quiet[1]);
    arc.ArchiveFloat(&m_fFireSpreadMultAmount[0]);
    arc.ArchiveFloat(&m_fFireSpreadMultAmount[1]);
    arc.ArchiveFloat(&m_fFireSpreadMultFalloff[0]);
    arc.ArchiveFloat(&m_fFireSpreadMultFalloff[1]);
    arc.ArchiveFloat(&m_fFireSpreadMultCap[0]);
    arc.ArchiveFloat(&m_fFireSpreadMultCap[1]);
    arc.ArchiveFloat(&m_fFireSpreadMultTimeCap[0]);
    arc.ArchiveFloat(&m_fFireSpreadMultTimeCap[1]);
    arc.ArchiveFloat(&m_fFireSpreadMultTime[0]);
    arc.ArchiveFloat(&m_fFireSpreadMultTime[1]);
    arc.ArchiveFloat(&m_fFireSpreadMult[0]);
    arc.ArchiveFloat(&m_fFireSpreadMult[1]);

    ArchiveEnum(firetype[0], firetype_t);
    ArchiveEnum(firetype[1], firetype_t);

    arc.ArchiveInteger(&ammo_clip_size[0]);
    arc.ArchiveInteger(&ammo_clip_size[1]);
    arc.ArchiveInteger(&ammo_in_clip[0]);
    arc.ArchiveInteger(&ammo_in_clip[1]);
    arc.ArchiveFloat(&max_charge_time[0]);
    arc.ArchiveFloat(&max_charge_time[1]);
    arc.ArchiveFloat(&min_charge_time[0]);
    arc.ArchiveFloat(&min_charge_time[1]);

    ArchiveEnum(meansofdeath[0], meansOfDeath_t);
    ArchiveEnum(meansofdeath[1], meansOfDeath_t);

    arc.ArchiveBoolean(&loopfire[0]);
    arc.ArchiveBoolean(&loopfire[1]);
    arc.ArchiveBoolean(&m_bShareClip);
    arc.ArchiveBoolean(&m_bCanPartialReload);
    arc.ArchiveBoolean(&autoaim);
    arc.ArchiveFloat(&charge_fraction);
    arc.ArchiveBoolean(&putaway);

    ArchiveEnum(firemodeindex, firemode_t);

    arc.ArchiveInteger(&weapon_class);
    Director.ArchiveString(arc, m_csWeaponGroup);
    arc.ArchiveFloat(&m_fMovementSpeed);
    arc.ArchiveFloat(&m_fMaxFireMovement);
    arc.ArchiveFloat(&m_fZoomMovement);
    arc.ArchiveString(&m_sAmmoPickupSound);
    arc.ArchiveString(&m_NoAmmoSound);
    arc.ArchiveString(&m_sMaxMovementSound);
    arc.ArchiveInteger(&m_iNumShotsFired);
    arc.ArchiveInteger(&m_iNumHits);
    arc.ArchiveInteger(&m_iNumHeadShots);
    arc.ArchiveInteger(&m_iNumTorsoShots);
    arc.ArchiveInteger(&m_iNumLeftLegShots);
    arc.ArchiveInteger(&m_iNumRightLegShots);
    arc.ArchiveInteger(&m_iNumGroinShots);
    arc.ArchiveInteger(&m_iNumLeftArmShots);
    arc.ArchiveInteger(&m_iNumRightArmShots);
    arc.ArchiveInteger(&m_iNumFireAnims);
    arc.ArchiveInteger(&m_iCurrentFireAnim);
    arc.ArchiveString(&m_sTagBarrel);

    ArchiveEnum(mAIRange, AIRanges);

    arc.ArchiveInteger(&m_iWeaponSubtype);
    arc.ArchiveFloat(&m_fCookTime);
    ArchiveEnum(m_eCookModeIndex, firemode_t);
    arc.ArchiveBoolean(&m_bSecondaryAmmoInHud);
}

typedef SafePtr<Weapon> WeaponPtr;