]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/w_hotbombs.c
now menu qc respects g_campaign_name
[divverent/nexuiz.git] / TeamNexuiz / game / gamec / w_hotbombs.c
1 void() hotbombs_ready_01;\r
2 void() hotbombs_fire1_01;\r
3 void() hotbombs_fire2_01;\r
4 void() hotbombs_deselect_01;\r
5 void() hotbombs_select_01;\r
6 \r
7 float   AMMO_COST_HOTBOMBS = 5;\r
8 \r
9 float() hotbombs_check =\r
10 {\r
11         return TRUE;\r
12 }\r
13 \r
14 float() hotbombs_check2 =\r
15 {\r
16         if (self.ammo_cells >= AMMO_COST_HOTBOMBS)\r
17                 return TRUE;\r
18         return FALSE;\r
19 }\r
20 \r
21 void(float req) w_hotbombs =\r
22 {\r
23         if (req == WR_IDLE)\r
24                 hotbombs_ready_01();\r
25         else if (req == WR_FIRE1 || req == WR_FIRE2)\r
26         {\r
27                 if(req == WR_FIRE2)\r
28                         weapon_prepareattack(hotbombs_check, hotbombs_check, hotbombs_fire2_01, cvar("g_balance_hotbombs_refire"));\r
29                 else\r
30                         weapon_prepareattack(hotbombs_check, hotbombs_check, hotbombs_fire1_01, cvar("g_balance_hotbombs_refire2"));\r
31         }\r
32         else if (req == WR_RAISE)\r
33                 hotbombs_select_01();\r
34         else if (req == WR_UPDATECOUNTS)\r
35                 self.currentammo = floor(self.ammo_cells/AMMO_COST_HOTBOMBS);\r
36         else if (req == WR_DROP)\r
37                 hotbombs_deselect_01();\r
38         else if (req == WR_SETUP)\r
39         {\r
40                 weapon_setup(WEP_BOMBLETTS, "w_hotbombs.zym", IT_ROCKETS);\r
41                 //self.weaponentity.colormod = '0 4 0';\r
42                 //self.weaponentity.scale = 0.65;\r
43         }\r
44         else if (req == WR_CHECKAMMO)\r
45                 weapon_hasammo = hotbombs_check();\r
46 }\r
47 \r
48 void W_Hotbomb_Explode (void)\r
49 {\r
50         vector  org2;\r
51         entity head;\r
52 \r
53         float flametime, flamedmg, flamerate, flameedge, flameradius, distratio;\r
54 \r
55         flameradius =   cvar("g_balance_hotbombs_burnradius");\r
56         flamedmg =              cvar("g_balance_hotbombs_burndamage");\r
57         flamerate =             cvar("g_balance_hotbombs_burnrate");\r
58         flametime =             cvar("g_balance_hotbombs_burntime");\r
59         flameedge =             cvar("g_balance_hotbombs_burnedge_ratio");\r
60 \r
61         org2 = findbetterlocation (self.origin);\r
62         te_explosion (org2);\r
63         if(random() > 0.5)\r
64         {\r
65                 effect (org2, "models/sprites/grenadeexplosion.spr32", 0, 20, 30);\r
66                 sound (self, CHAN_BODY, "weapons/grenade_impact.wav", 1, ATTN_NORM);\r
67         }\r
68         else\r
69         {\r
70                 effect (org2, "models/sprites/rocketexplosion.spr32", 0, 20, 40);\r
71                 sound (self, CHAN_BODY, "weapons/rocket_impact.wav", 1, ATTN_NORM);\r
72         }\r
73 \r
74 \r
75         self.event_damage = SUB_Null;\r
76         RadiusDamage (self, self.owner, cvar("g_balance_hotbombs_damage"), cvar("g_balance_hotbombs_edgedamage"), cvar("g_balance_hotbombs_radius"), world, cvar("g_balance_hotbombs_force"), WEP_HOTBOMBS);\r
77 \r
78         // fixme: need better way to set on fire...\r
79         head = findradius(self.origin, flameradius);\r
80         while(head)\r
81         {\r
82                 if(head.takedamage == DAMAGE_AIM)//head.classname == "player" || head.classname == "turret")\r
83                 {\r
84                         traceline(self.origin, head.origin, TRUE, self);\r
85                         if(trace_fraction >= 1)\r
86                         {\r
87                                 distratio = 1 - (vlen(head.origin - self.origin) / flameradius);\r
88                                 IgniteTarget(head, self.owner,\r
89                                         (flametime*flameedge) + (flametime - flameedge)*distratio,\r
90                                         flamedmg,\r
91                                         flamerate,\r
92                                         TRUE);\r
93                         }\r
94                 }\r
95                 head = head.chain;\r
96         }\r
97 \r
98         \r
99         remove (self);\r
100 }\r
101 \r
102 void W_Hotbomb_Detonate (entity gren)\r
103 {\r
104         gren.classname = "hotbombdet";\r
105         gren.takedamage = 0;\r
106         gren.think = W_Hotbomb_Explode;\r
107         gren.nextthink = time + random()*0.1;\r
108         gren.movetype = MOVETYPE_TOSS;\r
109 }\r
110 \r
111 void W_HotbombThink ()\r
112 {\r
113         self.nextthink = time + 1;\r
114         if(self.owner.class != CLASS_PYRO)\r
115         {\r
116                 remove(self);\r
117                 return;\r
118         }\r
119         if(self.movetype == MOVETYPE_WALK)\r
120         {\r
121                 if(!self.flags & FL_ONGROUND)\r
122                 {\r
123                         self.movetype = MOVETYPE_TOSS;\r
124                         //self.think = SUB_Null;\r
125                         //self.nextthink = -1;\r
126                 }\r
127 \r
128                 self.velocity = self.velocity*0.9;\r
129 \r
130                 if(vlen(self.velocity) < 25)\r
131                 {\r
132                         self.velocity = '0 0 0';\r
133                         self.movetype = MOVETYPE_TOSS;\r
134                         self.ltime = time + 0.5; // don't bounce or start over on accident\r
135                 }\r
136                 else\r
137                         self.nextthink = time + 0.1;\r
138         }\r
139 }\r
140 \r
141 void W_Hotbombs_Touch (void)\r
142 {\r
143         if(self.think != W_HotbombThink)\r
144         {\r
145                 if(self.ltime > time)\r
146                         return;\r
147                 sound (self, CHAN_IMPACT, "weapons/grenade_bounce.wav", 1, ATTN_NORM);\r
148                 if(self.flags & FL_ONGROUND)\r
149                 {\r
150                         self.movetype = MOVETYPE_WALK;\r
151                         self.think = W_HotbombThink;\r
152                         self.nextthink = time + 0.1;\r
153                 }\r
154         }\r
155 }\r
156 \r
157 void W_Hotbombs_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)\r
158 {\r
159         self.health = self.health - damage;\r
160         if (self.health <= 0 || deathtype == DEATH_BURNING)\r
161         {\r
162                 W_Hotbomb_Detonate(self);\r
163                 //self.think = W_Hotbombs_Explode;\r
164                 //self.nextthink = time + random()*0.1;\r
165                 //self.takedamage = 0;\r
166                 //self.classname = "hotbombdet";\r
167                 //self.movetype = MOVETYPE_TOSS;\r
168         }\r
169 }\r
170 \r
171 void W_Hotbombs_Attack (void)\r
172 {\r
173         local entity gren;\r
174         local vector org;\r
175 \r
176         // only allow a limited number of hotbombs\r
177         W_LimitNumEnts("hotbomb", cvar("g_balance_hotbombs_allowed") - 1, SUB_Remove);\r
178 \r
179 \r
180         //sound (self, CHAN_WEAPON, "weapons/grenade_fire.wav", 1, ATTN_NORM);\r
181         self.punchangle_x = -4;\r
182         org = self.origin + self.view_ofs + v_forward * 15 + v_right * 5 + v_up * -12;\r
183         self.ammo_cells = self.ammo_cells - AMMO_COST_HOTBOMBS;\r
184 \r
185         gren = spawn ();\r
186         gren.create_time = time; // for W_LimitNumEnts\r
187         gren.owner = self;\r
188         gren.classname = "hotbomb";\r
189         gren.movetype = MOVETYPE_WALK;\r
190         gren.solid = SOLID_BBOX;\r
191         setmodel(gren, "models/grenademodel.md3");\r
192         setsize(gren, '-6 -6 -3', '6 6 3');\r
193         setorigin(gren, org);\r
194 \r
195         gren.nextthink = time + 100;\r
196         gren.think = W_Hotbomb_Explode;\r
197         gren.touch = W_Hotbombs_Touch;\r
198         gren.takedamage = DAMAGE_YES;\r
199         gren.health = 40; // a bit harder to destroy\r
200         gren.damageforcescale = 4;\r
201         gren.event_damage = W_Hotbombs_Damage;\r
202         gren.velocity = v_forward * cvar("g_balance_hotbombs_speed");\r
203 \r
204         gren.angles = vectoangles (gren.velocity);\r
205         gren.angles_x = -90;\r
206 \r
207         gren.scale = 2;\r
208         //gren.colormod = '0.5 0.5 0.5';\r
209 }\r
210 \r
211 void W_Hotbombs_Attack2 (void)\r
212 {\r
213         local entity gren;\r
214         gren = world;\r
215         do\r
216         {\r
217                 gren = find(gren, classname, "hotbomb");\r
218                 if(gren.owner == self)\r
219                 {\r
220                         W_Hotbomb_Detonate(gren);\r
221                 }\r
222         }while(gren);\r
223 }\r
224 \r
225 float W_Hotbombs_CheckEmpty ()\r
226 {\r
227         local entity gren;\r
228 \r
229         if(hotbombs_check2())\r
230                 return FALSE; // I still have ammo, don't auto switch\r
231 \r
232         gren = world;\r
233         do\r
234         {\r
235                 gren = find(gren, classname, "hotbomb");\r
236                 if(gren.owner == self)\r
237                 {\r
238                         return FALSE; // I still have a grenade I can explode, don't auto switch\r
239                 }\r
240         }while(gren);\r
241 \r
242         self.switchweapon = w_getbestweapon(self);\r
243         return TRUE;\r
244 }\r
245 \r
246 // weapon frames\r
247 \r
248 void()  hotbombs_ready_01 =     {weapon_thinkf(WFRAME_IDLE, 0.1, hotbombs_ready_01); self.weaponentity.state = WS_READY;};\r
249 void()  hotbombs_select_01 =    {weapon_thinkf(-1, cvar("g_balance_weaponswitchdelay"), w_ready); weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, '0 0 0');};\r
250 void()  hotbombs_deselect_01 =  {weapon_thinkf(-1, cvar("g_balance_weaponswitchdelay"), w_clear); weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, PLAYER_WEAPONSELECTION_RANGE);};\r
251 void()  hotbombs_fire1_01 =\r
252 {\r
253         if(W_Hotbombs_CheckEmpty())\r
254                 return; // auto-switch weapons and leave\r
255         if(!hotbombs_check2())\r
256                 return; // can't use primary, but alt-fire will still work\r
257         weapon_doattack(hotbombs_check, hotbombs_check, W_Hotbombs_Attack);\r
258         weapon_thinkf(WFRAME_FIRE1, 0.3, hotbombs_ready_01);\r
259 };\r
260 \r
261 void()  hotbombs_fire2_01 =\r
262 {\r
263         if(W_Hotbombs_CheckEmpty())\r
264                 return; // out of ammo and no bombs to detonate\r
265         weapon_doattack(hotbombs_check, hotbombs_check, W_Hotbombs_Attack2);\r
266         weapon_thinkf(WFRAME_IDLE, 0.1, hotbombs_ready_01);\r
267 };\r