]> icculus.org git repositories - divverent/nexuiz.git/blob - attic/TeamNexuiz/game/gamec/w_hook.c
now menu qc respects g_campaign_name
[divverent/nexuiz.git] / attic / TeamNexuiz / game / gamec / w_hook.c
1 void() grapple_ready_01;\r
2 void() grapple_fire1_01;\r
3 void() grapple_deselect_01;\r
4 void() grapple_select_01;\r
5 \r
6 float() grapple_check =\r
7 {\r
8         return TRUE;\r
9 }\r
10 \r
11 void(float req) w_grapple =\r
12 {\r
13         if (req == WR_IDLE)\r
14                 grapple_ready_01();\r
15         else if (req == WR_FIRE1)\r
16                 weapon_prepareattack(grapple_check, grapple_check, grapple_fire1_01, cvar("g_balance_grapple_refire"));\r
17         else if (req == WR_RAISE)\r
18                 grapple_select_01();\r
19         else if (req == WR_UPDATECOUNTS)\r
20                 self.currentammo = 1;\r
21         else if (req == WR_DROP)\r
22                 grapple_deselect_01();\r
23         else if (req == WR_SETUP)\r
24                 weapon_setup(WEP_GRAPPLE, "w_grapple.zym", 0);\r
25         else if (req == WR_CHECKAMMO)\r
26                 weapon_hasammo = grapple_check();\r
27 }\r
28 \r
29 void RemoveGrapplingHook(entity pl)\r
30 {\r
31         if(pl.hook == world)\r
32                 return;\r
33         remove(pl.hook);\r
34         pl.hook = world;\r
35         if(pl.movetype == MOVETYPE_FLY)\r
36                 pl.movetype = MOVETYPE_WALK;\r
37 }\r
38 \r
39 void GrapplingHookThink()\r
40 {\r
41         float spd, dist, minlength, pullspeed, pullspeed2, totalmass, m1, m2, dropspd1, dropspd2;\r
42         vector dir, org, end;\r
43 \r
44         makevectors(self.owner.v_angle);\r
45         org = self.owner.origin + self.owner.view_ofs + v_forward * 15 - v_right * 5 + v_up * -12;\r
46 \r
47         traceline(self.origin, org, TRUE, self);\r
48         if(self.owner.health <= 2               // owner died\r
49                 || self.owner.hook != self      // owner fired a different hook\r
50                 || !self.owner.button0          // owner let go of button\r
51                 || trace_fraction < 1)          // owner not visible\r
52         {\r
53                 remove(self);\r
54                 return;\r
55         }\r
56 \r
57         self.nextthink = time + 0.1;\r
58         dropspd1 = cvar("sv_gravity") * 0.1; // thinks this often\r
59         dropspd2 = dropspd1;\r
60         if(self.owner.gravity)\r
61                 dropspd1 = dropspd1 * self.owner.gravity;\r
62         if(self.enemy.gravity)\r
63                 dropspd2 = dropspd2 * self.enemy.gravity;\r
64         self.owner.attack_finished = max(self.owner.attack_finished, time + cvar("g_balance_grapple_refire"));\r
65 \r
66 \r
67         // testing\r
68         self.owner.jump_pad = 1;\r
69 \r
70 \r
71         if(self.state == 1)\r
72         {\r
73                 pullspeed = cvar("g_balance_grapple_pullspeed");\r
74                 if(self.enemy != world) // pull both players toward each other at different speeds based on mass\r
75                 {\r
76                         m1 = self.owner.mass;\r
77                         m2 = self.enemy.mass;\r
78                         if(m1 <= 0)\r
79                                 m1 = 1;\r
80                         if(m2 <= 0)\r
81                                 m2 = 1;\r
82                         totalmass = m1 + m2;\r
83                         pullspeed2 = (m1 / totalmass) * pullspeed;\r
84                         pullspeed = (m2 / totalmass) * pullspeed;\r
85                 }\r
86                 minlength = 50;\r
87                 dir = self.origin - org;\r
88                 dist = vlen(dir);\r
89                 dir = normalize(dir);\r
90 \r
91                 end = self.origin - dir*minlength;\r
92                 \r
93                 dist = vlen(end - org);\r
94 \r
95                 if(dist < 200 && self.enemy == world)\r
96                         spd = dist * (pullspeed / 200);\r
97                 else\r
98                         spd = pullspeed;\r
99                 if(spd < 50)\r
100                         spd = 0;\r
101 \r
102                 if(!(dist < 200 && !self.owner.flags & FL_ONGROUND && self.enemy != world))\r
103                         self.owner.velocity = dir*spd;\r
104                 self.owner.movetype = MOVETYPE_FLY;\r
105                 self.owner.flags = self.owner.flags - (self.owner.flags & FL_ONGROUND);\r
106 \r
107                 org = org + dir*50; // get the beam out of the player's eyes\r
108 \r
109                 if(self.enemy != world)\r
110                 {\r
111                         self.origin = 0.5*(self.enemy.absmin+self.enemy.absmax) + '0 0 10'; // follow enemy's body\r
112 \r
113                         if(dist < 200)\r
114                                 spd = dist * (pullspeed2 / 200 + 150);\r
115                         else\r
116                                 spd = pullspeed2;\r
117                         if(spd < 50)\r
118                                 spd = 0;\r
119 \r
120 \r
121                         if(dist < 200 && !self.owner.flags & FL_ONGROUND)\r
122                         {\r
123                                 //self.enemy.velocity = self.enemy.velocity + '0 0 -1'*dropspd1;\r
124                                 self.owner.velocity = self.owner.velocity + '0 0 -1'*dropspd2; // fake effects of gravity, and don't pull enemy toward me\r
125                         }\r
126                         else\r
127                                 self.enemy.velocity = dir * spd * -1;\r
128 \r
129                         if(self.attack_finished < time)\r
130                         {\r
131                                 self.attack_finished = time + cvar("g_balance_grapple_hurtrate");\r
132                                 Damage (self.enemy, self, self.owner, cvar("g_balance_grapple_damage2"), WEP_GRAPPLE, self.origin, '0 0 0');\r
133                         }\r
134                         if(self.enemy.health <= 0) // gib the dead player\r
135                         {\r
136                                 Damage (self.enemy, self, self.owner, 100, WEP_GRAPPLE, self.origin, '0 0 0');\r
137                                 self.enemy = world;\r
138                                 self.owner.hook = world;\r
139                                 remove(self);\r
140                                 return;\r
141                         }\r
142                 }\r
143         }\r
144 \r
145         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);\r
146         WriteByte (MSG_BROADCAST, TE_BEAM);\r
147         WriteEntity (MSG_BROADCAST, self);\r
148         WriteCoord (MSG_BROADCAST, self.origin_x);\r
149         WriteCoord (MSG_BROADCAST, self.origin_y);\r
150         WriteCoord (MSG_BROADCAST, self.origin_z);\r
151         WriteCoord (MSG_BROADCAST, org_x);\r
152         WriteCoord (MSG_BROADCAST, org_y);\r
153         WriteCoord (MSG_BROADCAST, org_z);\r
154         //WriteCoord (MSG_BROADCAST, 0);\r
155         //WriteCoord (MSG_BROADCAST, 0);\r
156         //WriteCoord (MSG_BROADCAST, 0);\r
157 }\r
158 \r
159 void GrapplingHookTouch (void)\r
160 {\r
161         if (other == self.owner)\r
162                 return;\r
163         else if (pointcontents (self.origin) == CONTENT_SKY)\r
164         {\r
165                 RemoveGrapplingHook(self.owner);\r
166                 return;\r
167         }\r
168 \r
169         self.event_damage = SUB_Null; // fixme: ability to dislodge a player by damaging hook?\r
170         sound (self, CHAN_BODY, "weapons/laserimpact.wav", 1, ATTN_NORM);\r
171 \r
172         self.state = 1;\r
173         self.think = GrapplingHookThink;\r
174         self.nextthink = time + 0.1;\r
175         self.touch = SUB_Null;\r
176         self.velocity = '0 0 0';\r
177         self.movetype = MOVETYPE_NONE;\r
178 \r
179         if((other.classname == "player" || other.classname == "body") && other.health > 0)\r
180         {\r
181                 self.enemy = other;\r
182         }\r
183 \r
184         Damage (other, self, self.owner, cvar("g_balance_grapple_damage"), WEP_GRAPPLE, self.origin, normalize(self.velocity)*cvar("g_balance_grapple_force"));\r
185 }\r
186 \r
187 void FireGrapplingHook (void)\r
188 {\r
189 \r
190         // fixme: drop the CTF flag\r
191 \r
192 \r
193         local entity missile;\r
194         local vector org;\r
195 \r
196         makevectors(self.v_angle);\r
197 \r
198         sound (self, CHAN_WEAPON, "weapons/lasergun_fire.wav", 1, ATTN_NORM);\r
199         org = self.origin + self.view_ofs + v_forward * 15 - v_right * 5 + v_up * -12;\r
200         te_customflash(org, 160, 0.2, '1 0 0');\r
201 \r
202         missile = spawn ();\r
203         missile.owner = self;\r
204         self.hook = missile;\r
205         missile.classname = "laserbolt";\r
206 \r
207         missile.movetype = MOVETYPE_FLY;\r
208         missile.solid = SOLID_BBOX;\r
209 \r
210         setmodel (missile, "models/ebomb.mdl");//laser.mdl");\r
211         setsize (missile, '0 0 0', '0 0 0');\r
212         setorigin (missile, org);\r
213 \r
214         missile.state = 0; // not latched onto anything\r
215 \r
216         missile.velocity = v_forward * cvar("g_balance_grapple_speed");\r
217         missile.angles = vectoangles (missile.velocity);\r
218         //missile.glow_color = 250; // 244, 250\r
219         //missile.glow_size = 120;\r
220         missile.touch = GrapplingHookTouch;\r
221         missile.think = GrapplingHookThink;\r
222         missile.nextthink = time + 0.1;\r
223 \r
224         missile.effects = EF_FULLBRIGHT | EF_ADDITIVE | EF_LOWPRECISION;\r
225 }\r
226 \r
227 void GrapplingHookFrame()\r
228 {\r
229         // if I have no hook or it's not pulling yet, make sure I'm not flying!\r
230         if((self.hook == world || !self.hook.state) && self.movetype == MOVETYPE_FLY && self.health > 2)\r
231         {\r
232                 self.movetype = MOVETYPE_WALK;\r
233         }\r
234         if(!self.button0)\r
235         {\r
236                 // remove hook, reset movement type\r
237                 RemoveGrapplingHook(self);\r
238                 return;\r
239         }\r
240         // note: The hook entity does the actual pulling\r
241 }\r
242 \r
243 void()  grapple_ready_01 =      {weapon_thinkf(WFRAME_IDLE, 0.1, grapple_ready_01); self.weaponentity.state = WS_READY;};\r
244 void()  grapple_select_01 =     {weapon_thinkf(-1, cvar("g_balance_weaponswitchdelay"), w_ready); weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, '0 0 0');};\r
245 void()  grapple_deselect_01 =   {weapon_thinkf(-1, cvar("g_balance_weaponswitchdelay"), w_clear); weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, PLAYER_WEAPONSELECTION_RANGE);};\r
246 void()  grapple_fire1_01 =\r
247 {\r
248         weapon_doattack(grapple_check, grapple_check, FireGrapplingHook);\r
249         weapon_thinkf(WFRAME_FIRE1, 0.3, grapple_ready_01);\r
250 }\r