Merge commit 'origin/master' into diabolik/weaponscale
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_uzi.qc
1 #ifdef REGISTER_WEAPON
2 REGISTER_WEAPON(UZI, w_uzi, IT_NAILS, 3, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "uzi", "uzi", "Machine Gun");
3 #else
4 // leilei's fancy muzzleflash stuff
5 void W_Uzi_Flash_Go() {
6         if (self.frame > 10){
7                 SUB_Remove();
8                 return;
9         }
10         self.frame = self.frame + 2;
11         self.alpha = self.alpha - 0.2;
12         self.think = W_Uzi_Flash_Go;
13         self.nextthink = time + 0.02;
14 };
15
16 .float uzi_bulletcounter;
17 void W_Uzi_Attack (float deathtype)
18 {
19         local entity flash;
20
21         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
22         {
23                 if (self.uzi_bulletcounter == 1)
24                         self.ammo_nails = self.ammo_nails - cvar("g_balance_uzi_first_ammo");
25                 else
26                         self.ammo_nails = self.ammo_nails - cvar("g_balance_uzi_sustained_ammo");
27         }
28         W_SetupShot (self, cvar("g_antilag_bullets") && cvar("g_balance_uzi_speed") >= cvar("g_antilag_bullets"), 0, "weapons/uzi_fire.wav", cvar("g_balance_uzi_first_damage"));
29         if (!g_norecoil)
30         {
31                 self.punchangle_x = random () - 0.5;
32                 self.punchangle_y = random () - 0.5;
33         }
34
35         // this attack_finished just enforces a cooldown at the end of a burst
36         ATTACK_FINISHED(self) = time + cvar("g_balance_uzi_first_refire") * W_WeaponRateFactor();
37
38         if (self.uzi_bulletcounter == 1)
39                 fireBallisticBullet(w_shotorg, w_shotdir, cvar("g_balance_uzi_first_spread"), cvar("g_balance_uzi_speed"), 5, cvar("g_balance_uzi_first_damage"), 0, cvar("g_balance_uzi_first_force"), deathtype, 0, 1, cvar("g_balance_uzi_bulletconstant"));
40         else
41                 fireBallisticBullet(w_shotorg, w_shotdir, cvar("g_balance_uzi_sustained_spread"), cvar("g_balance_uzi_speed"), 5, cvar("g_balance_uzi_sustained_damage"), 0, cvar("g_balance_uzi_sustained_force"), deathtype, 0, 1, cvar("g_balance_uzi_bulletconstant"));
42         endFireBallisticBullet();
43
44         pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
45
46         // muzzle flash for 1st person view
47         flash = spawn();
48         setmodel(flash, "models/uziflash.md3"); // precision set below
49         //SUB_SetFade(flash, time + 0.06, 0);
50         flash.think = W_Uzi_Flash_Go;
51         flash.nextthink = time + 0.02;
52         flash.frame = 2;
53         flash.alpha = 1;
54         flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
55         W_AttachToShotorg(flash, '5 0 0');
56
57         // casing code
58         if (cvar("g_casings") >= 2)
59                 SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
60 }
61
62 // weapon frames
63 void uzi_fire1_02()
64 {
65         if(self.weapon != self.switchweapon) // abort immediately if switching
66         {
67                 w_ready();
68                 return;
69         }
70         if (self.BUTTON_ATCK)
71         {
72                 if (!weapon_action(self.weapon, WR_CHECKAMMO2))
73                 {
74                         W_SwitchWeapon_Force(self, w_getbestweapon(self));
75                         w_ready();
76                         return;
77                 }
78                 self.uzi_bulletcounter = self.uzi_bulletcounter + 1;
79                 W_Uzi_Attack(WEP_UZI);
80                 weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), uzi_fire1_02);
81         }
82         else
83                 weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), w_ready);
84 };
85
86 void spawnfunc_weapon_machinegun(); // defined in t_items.qc
87
88 float w_uzi(float req)
89 {
90         if (req == WR_AIM)
91                 if(vlen(self.origin-self.enemy.origin) < 3000 - bound(0, skill, 10) * 200)
92                         self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, FALSE);
93                 else
94                 {
95                         self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, FALSE);
96                 }
97         else if (req == WR_THINK)
98         {
99                 if (self.BUTTON_ATCK)
100                 if (weapon_prepareattack(0, 0))
101                 {
102                         self.uzi_bulletcounter = 1;
103                         W_Uzi_Attack(WEP_UZI); // sets attack_finished
104                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), uzi_fire1_02);
105                 }
106                 if (self.BUTTON_ATCK2 && cvar("g_balance_uzi_first"))
107                 if (weapon_prepareattack(1, 0))
108                 {
109                         self.uzi_bulletcounter = 1;
110                         W_Uzi_Attack(WEP_UZI | HITTYPE_SECONDARY); // sets attack_finished
111                         weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_uzi_first_refire"), w_ready);
112                 }
113         }
114         else if (req == WR_PRECACHE)
115         {
116                 precache_model ("models/uziflash.md3");
117                 precache_model ("models/weapons/g_uzi.md3");
118                 precache_model ("models/weapons/v_uzi.md3");
119                 precache_model ("models/weapons/h_uzi.iqm");
120                 precache_sound ("weapons/uzi_fire.wav");
121         }
122         else if (req == WR_SETUP)
123                 weapon_setup(WEP_UZI);
124         else if (req == WR_CHECKAMMO1)
125                 return self.ammo_nails >= cvar("g_balance_uzi_first_ammo");
126         else if (req == WR_CHECKAMMO2)
127                 return self.ammo_nails >= cvar("g_balance_uzi_first_ammo");
128         else if (req == WR_SUICIDEMESSAGE)
129                 w_deathtypestring = "did the impossible";
130         else if (req == WR_KILLMESSAGE)
131         {
132                 if(w_deathtype & HITTYPE_SECONDARY)
133                         w_deathtypestring = "was sniped by";
134                 else
135                         w_deathtypestring = "was riddled full of holes by";
136         }
137         return TRUE;
138 };
139 #endif