]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/cl_weaponsystem.c
made cl_client.c compile again - you can not assign a string to a float field without...
[divverent/nexuiz.git] / qcsrc / gamec / cl_weaponsystem.c
1 /*
2 ===========================================================================
3
4   CLIENT WEAPONSYSTEM CODE
5   Bring back W_Weaponframe
6
7 ===========================================================================
8 */
9
10 void() CL_Weaponentity_Think =
11 {
12         self.nextthink = time;
13         if (self.owner.weaponentity != self)
14         {
15                 remove(self);
16                 return;
17         }
18 };
19
20 // spawning weaponentity for client
21 void() CL_SpawnWeaponentity =
22 {
23         if (self.weaponentity)
24         {
25                 w_clear();
26                 return;
27         }
28         self.weaponentity = spawn();
29         self.weaponentity.solid = SOLID_NOT;
30         self.weaponentity.owner = self;
31         self.weaponentity.weaponentity = self.weaponentity;
32         setmodel(self.weaponentity, "");
33         self.weaponentity.origin = '0 0 0';
34         self.weaponentity.angles = '0 0 0';
35         self.weaponentity.viewmodelforclient = self;
36         self.weaponentity.flags = 0;
37         self.weaponentity.think = CL_Weaponentity_Think;
38         self.weaponentity.nextthink = time;
39 };
40
41 // convertion from index (= impulse) to flag in .items
42 float(float index) weapon_translateindextoflag =
43 {
44         if (index == WEP_LASER)
45                 return IT_LASER;
46         else if (index == WEP_SHOTGUN)
47                 return IT_SHOTGUN;
48         else if (index == WEP_UZI)
49                 return IT_UZI;
50         else if (index == WEP_GRENADE_LAUNCHER)
51                 return IT_GRENADE_LAUNCHER;
52         else if (index == WEP_ELECTRO)
53                 return IT_ELECTRO;
54         else if (index == WEP_CRYLINK)
55                 return IT_CRYLINK;
56         else if (index == WEP_NEX)
57                 return IT_NEX;
58         else if (index == WEP_HAGAR)
59                 return IT_HAGAR;
60         else if (index == WEP_ROCKET_LAUNCHER)
61                 return IT_ROCKET_LAUNCHER;
62         return IT_LASER;
63 };
64
65 float(entity cl, float wpn, float andammo) client_hasweapon =
66 {
67         local float itemcode;
68         local entity oldself;
69
70         weapon_hasammo = TRUE;
71         if (wpn < WEP_FIRST || wpn > WEP_LAST)
72                 return FALSE;
73         itemcode = weapon_translateindextoflag(wpn);
74         if (cl.items & itemcode)
75         {
76                 if (andammo)
77                 {
78                         oldself = self;
79                         self = cl;
80                         weapon_action(wpn, WR_CHECKAMMO);
81                         self = oldself;
82                         if (weapon_hasammo)
83                                 return TRUE;
84                         return FALSE;
85                 }
86                 return TRUE;
87         }
88         return FALSE;
89 };
90
91 // Weapon subs
92 void() w_clear =
93 {
94         weapon_action(self.weapon, WR_CLEAR);
95         if (self.weapon != -1)
96                 self.weapon = 0;
97         if (self.weaponentity)
98         {
99                 self.weaponentity.state = WS_CLEAR;
100                 setmodel(self.weaponentity, "");
101                 self.weaponentity.effects = 0;
102         }
103 };
104
105 void() w_ready =
106 {
107         self.weaponentity.state = WS_READY;
108         weapon_action(self.weapon, WR_IDLE);
109 };
110
111 // FIXME: add qw-style client-custom weaponrating (cl_weaponrating)?
112 float(entity e) w_getbestweapon
113 {// add new weapons here
114         if (client_hasweapon(e, WEP_ROCKET_LAUNCHER, TRUE))
115                 return WEP_ROCKET_LAUNCHER;
116         else if (client_hasweapon(e, WEP_NEX, TRUE))
117                 return WEP_NEX;
118         else if (client_hasweapon(e, WEP_HAGAR, TRUE))
119                 return WEP_HAGAR;
120         else if (client_hasweapon(e, WEP_GRENADE_LAUNCHER, TRUE))
121                 return WEP_GRENADE_LAUNCHER;
122         else if (client_hasweapon(e, WEP_ELECTRO, TRUE))
123                 return WEP_ELECTRO;
124         else if (client_hasweapon(e, WEP_CRYLINK, TRUE))
125                 return WEP_CRYLINK;
126         else if (client_hasweapon(e, WEP_UZI, TRUE))
127                 return WEP_UZI;
128         else if (client_hasweapon(e, WEP_SHOTGUN, TRUE))
129                 return WEP_SHOTGUN;
130         else
131         {
132                 weapon_hasammo = TRUE;
133                 return WEP_LASER;
134         }
135 };
136
137 // Setup weapon for client (after this raise frame will be launched)
138 void(float windex, string wmodel, float hudammo) weapon_setup =
139 {
140         local string wdir, weaponmdl;
141
142         self.items = self.items - (self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS));
143         self.items = self.items | hudammo;
144
145         self.weapon = windex;
146
147         if (wmodel != "")
148         {
149                 weaponmdl = strzone(strcat("models/weapons/", wmodel));
150                 setmodel(self.weaponentity, weaponmdl);
151         }
152         // VorteX: update visible weapon
153         // CL_ViswepUpdate();
154 };
155
156 // shot direction
157 float WEAPON_MAXRELX = 14; // if more, shot can be spawned after wall surface (in empty worldspace) or inside other entity if client stands close to it
158 void(float x, float y, float z) weapon_shotdir =
159 {
160         makevectors(self.v_angle);
161         self.shotorg  = self.origin + self.view_ofs + v_forward*bound(0, x, WEAPON_MAXRELX) + v_right*(y + self.weaponentity.view_ofs_y) + v_up*z;
162         self.shotdir = aim(self, 1000);
163 };
164
165 // perform weapon to attack (weaponstate and attack_finished check is here)
166 void(float() checkfunc1, float() checkfunc2, void() firefunc, float atktime) weapon_prepareattack =
167 {
168         // Change to best weapon if failed
169         if (!(game & GAME_INSTAGIB) && !(game & GAME_ROCKET_ARENA))
170         {
171                 if (!checkfunc1())
172                 {
173                         if (!checkfunc2())
174                                 self.switchweapon = w_getbestweapon(self);
175                         return;
176                 }
177         }
178         // Don't do shot if previos attack  not finished
179         if (!(game & GAME_INSANE))
180                 if (time < self.attack_finished)
181                         return;
182         // Can't do shot if changing weapon
183         if (!(game & GAME_INSANE))
184                 if (self.weaponentity.state != WS_READY)
185                         return;
186
187         self.attack_finished = time + atktime;
188         firefunc();
189 };
190
191 // perform weapon attack
192 void(float() checkfunc1, float() checkfunc2, void() firefunc) weapon_doattack
193 {
194         // Change to best weapon if failed
195         if (!(game & GAME_INSTAGIB) && !(game & GAME_ROCKET_ARENA))
196         {
197                 if (!checkfunc1())
198                 {
199                         if (!checkfunc2())
200                                 self.switchweapon = w_getbestweapon(self);
201                         return;
202                 }
203         }
204         self.weaponentity.state = WS_INUSE;
205         firefunc();
206         weapon_action(self.weapon, WR_UPDATECOUNTS); // update ammo now
207 };
208
209 void(entity ent, float recoil) weapon_recoil =
210 {
211         ent.punchangle = (randomvec() + '-1 0 0')*recoil;
212         ent.punchangle_z = 0; // don't want roll
213         if (recoil > 3) // push back if large recoil
214                 ent.velocity = ent.velocity - normalize(ent.shotdir)*recoil*25;
215 };
216
217 void(float fr, float t, void() func) weapon_thinkf =
218 {
219         if (fr >= 0)
220                 if (self.weaponentity != world)
221                         self.weaponentity.frame = fr;
222         // VorteX: haste can be added here
223         self.weapon_nextthink = time + t;
224         self.weapon_think = func;
225 };
226
227 void(float spd, vector org) weapon_boblayer1 =
228 {
229         // VorteX: haste can be added here
230         self.weaponentity.pos1 =org;
231         self.weaponentity.lip = spd;
232 };