Transifex autosync
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / vehicles / vehicle / raptor_weapons.qc
1 #include "raptor_weapons.qh"
2
3 #ifdef SVQC
4
5 METHOD(RaptorCannon, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) {
6     bool isPlayer = IS_PLAYER(actor);
7     entity player = isPlayer ? actor : actor.owner;
8     entity veh = player.vehicle;
9     // 1 [wait] 1 [wait] 2 [wait] 2 [wait] [wait]
10     float t = autocvar_g_vehicle_raptor_cannon_refire * (1 + veh.misc_bulletcounter == 4);
11     if (fire & 1)
12     if (weapon_prepareattack(thiswep, player, weaponentity, false, t)) {
13         if (isPlayer) W_SetupShot_Dir(player, weaponentity, v_forward, false, 0, SND_Null, CH_WEAPON_B, 0, DEATH_VH_RAPT_CANNON.m_id);
14         vector org = w_shotorg;
15         vector dir = w_shotdir;
16         if (veh) {
17             veh.misc_bulletcounter += 1;
18             org = (veh.misc_bulletcounter <= 2) ? gettaginfo(veh.gun1, gettagindex(veh.gun1, "fire1"))
19               : (((veh.misc_bulletcounter == 4) ? veh.misc_bulletcounter = 0 : 0), gettaginfo(veh.gun2, gettagindex(veh.gun2, "fire1")));
20             dir = v_forward;
21             veh.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost;
22             actor.cnt = time;
23         }
24         vehicles_projectile(veh, EFFECT_RAPTOR_MUZZLEFLASH.eent_eff_name, SND_LASERGUN_FIRE,
25                                org, normalize(dir + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed,
26                                autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force,  0,
27                                DEATH_VH_RAPT_CANNON.m_id, PROJECTILE_RAPTORCANNON, 0, true, true, player);
28         weapon_thinkf(player, weaponentity, WFRAME_FIRE1, 0, w_ready);
29     }
30 }
31 METHOD(RaptorCannon, wr_checkammo1, bool(RacerAttack thiswep, entity actor, .entity weaponentity)) {
32     bool isPlayer = IS_PLAYER(actor);
33     entity player = isPlayer ? actor : actor.owner;
34     entity veh = player.vehicle;
35     return isPlayer || veh.vehicle_energy >= autocvar_g_vehicle_raptor_cannon_cost;
36 }
37
38
39 void raptor_bombdrop(entity this);
40 METHOD(RaptorBomb, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) {
41     bool isPlayer = IS_PLAYER(actor);
42     entity player = isPlayer ? actor : actor.owner;
43     entity veh = player.vehicle;
44     if (fire & 2)
45     if (!isPlayer || weapon_prepareattack(thiswep, player, weaponentity, true, autocvar_g_vehicle_raptor_bombs_refire)) {
46         entity e = (veh) ? veh : player;
47         raptor_bombdrop(e);
48         weapon_thinkf(player, weaponentity, WFRAME_FIRE2, 0, w_ready);
49     }
50 }
51
52 void raptor_flare_think(entity this);
53 void raptor_flare_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force);
54 void raptor_flare_touch(entity this, entity toucher);
55
56 METHOD(RaptorFlare, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) {
57     bool isPlayer = IS_PLAYER(actor);
58     entity player = isPlayer ? actor : actor.owner;
59     entity veh = player.vehicle;
60     if (fire & 2)
61     if (!isPlayer || weapon_prepareattack(thiswep, player, weaponentity, true, autocvar_g_vehicle_raptor_flare_refire)) {
62         for(int i = 0; i < 3; ++i) {
63             entity _flare = spawn();
64             setmodel(_flare, MDL_VEH_RAPTOR_FLARE);
65             _flare.effects = EF_LOWPRECISION | EF_FLAME;
66             _flare.scale = 0.5;
67             setorigin(_flare, actor.origin - '0 0 16');
68             set_movetype(_flare, MOVETYPE_TOSS);
69             _flare.gravity = 0.15;
70             _flare.velocity = 0.25 * actor.velocity + (v_forward + randomvec() * 0.25)* -500;
71             setthink(_flare, raptor_flare_think);
72             _flare.nextthink = time;
73             _flare.owner = veh ? veh : player;
74             _flare.solid = SOLID_CORPSE;
75             _flare.takedamage = DAMAGE_YES;
76             _flare.event_damage = raptor_flare_damage;
77             SetResourceExplicit(_flare, RES_HEALTH, 20);
78             _flare.tur_impacttime = time + autocvar_g_vehicle_raptor_flare_lifetime;
79             settouch(_flare, raptor_flare_touch);
80         }
81         weapon_thinkf(player, weaponentity, WFRAME_FIRE2, 0, w_ready);
82     }
83 }
84
85
86 void raptor_bomblet_boom(entity this)
87 {
88     RadiusDamage (this, this.realowner, autocvar_g_vehicle_raptor_bomblet_damage,
89                                     autocvar_g_vehicle_raptor_bomblet_edgedamage,
90                                     autocvar_g_vehicle_raptor_bomblet_radius, NULL, NULL,
91                                     autocvar_g_vehicle_raptor_bomblet_force, DEATH_VH_RAPT_BOMB.m_id, DMG_NOWEP, NULL);
92     delete(this);
93 }
94
95 void raptor_bomblet_touch(entity this, entity toucher)
96 {
97     if(toucher == this.owner)
98         return;
99
100     PROJECTILE_TOUCH(this, toucher);
101     setthink(this, raptor_bomblet_boom);
102     this.nextthink = time + random() * autocvar_g_vehicle_raptor_bomblet_explode_delay;
103 }
104
105 void raptor_bomb_burst(entity this)
106 {
107     if(this.cnt > time)
108     if(autocvar_g_vehicle_raptor_bomblet_alt)
109     {
110         this.nextthink = time;
111         traceline(this.origin, this.origin + (normalize(this.velocity) * autocvar_g_vehicle_raptor_bomblet_alt), MOVE_NORMAL, this);
112         if((trace_fraction == 1.0) || (vdist(this.origin - this.owner.origin, <, autocvar_g_vehicle_raptor_bomblet_radius)))
113         {
114             UpdateCSQCProjectile(this);
115             return;
116         }
117     }
118
119     entity bomblet;
120     float i;
121
122     Damage_DamageInfo(this.origin, 0, 0, 0, '0 0 0', DEATH_VH_RAPT_FRAGMENT.m_id, 0, this);
123
124     for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i)
125     {
126         bomblet = spawn();
127         setorigin(bomblet, this.origin);
128
129         set_movetype(bomblet, MOVETYPE_TOSS);
130         settouch(bomblet, raptor_bomblet_touch);
131         setthink(bomblet, raptor_bomblet_boom);
132         bomblet.nextthink   = time + 5;
133         bomblet.owner      = this.owner;
134         bomblet.realowner   = this.realowner;
135         bomblet.velocity        = normalize(normalize(this.velocity) + (randomvec() * autocvar_g_vehicle_raptor_bomblet_spread)) * vlen(this.velocity);
136
137         PROJECTILE_MAKETRIGGER(bomblet);
138         CSQCProjectile(bomblet, true, PROJECTILE_RAPTORBOMBLET, true);
139     }
140
141     delete(this);
142 }
143
144 void raptor_bomb_touch(entity this, entity toucher)
145 {
146         raptor_bomb_burst(this);
147 }
148
149 void raptor_bombdrop(entity this)
150 {
151     entity bomb_1, bomb_2;
152
153     bomb_1 = spawn();
154     bomb_2 = spawn();
155
156     vector org = gettaginfo(this, gettagindex(this, "bombmount_left"));
157     setorigin(bomb_1, org);
158     org = gettaginfo(this, gettagindex(this, "bombmount_right"));
159     setorigin(bomb_2, org);
160
161     set_movetype(bomb_1, MOVETYPE_BOUNCE);
162     set_movetype(bomb_2, MOVETYPE_BOUNCE);
163     bomb_1.velocity      = bomb_2.velocity   = this.velocity;
164     settouch(bomb_1, raptor_bomb_touch);
165     settouch(bomb_2, raptor_bomb_touch);
166     setthink(bomb_1, raptor_bomb_burst);
167     setthink(bomb_2, raptor_bomb_burst);
168     bomb_1.cnt            = bomb_2.cnt          = time + 10;
169
170     if(autocvar_g_vehicle_raptor_bomblet_alt)
171         bomb_1.nextthink = bomb_2.nextthink  = time;
172     else
173         bomb_1.nextthink = bomb_2.nextthink  = time + autocvar_g_vehicle_raptor_bomblet_time;
174
175     bomb_1.owner         = bomb_2.owner   = this;
176     bomb_1.realowner = bomb_2.realowner  = this.owner;
177     bomb_1.solid         = bomb_2.solid   = SOLID_BBOX;
178     bomb_1.gravity   = bomb_2.gravity   = 1;
179
180     PROJECTILE_MAKETRIGGER(bomb_1);
181     PROJECTILE_MAKETRIGGER(bomb_2);
182
183     CSQCProjectile(bomb_1, true, PROJECTILE_RAPTORBOMB, true);
184     CSQCProjectile(bomb_2, true, PROJECTILE_RAPTORBOMB, true);
185 }
186
187 void raptor_flare_touch(entity this, entity toucher)
188 {
189     delete(this);
190 }
191
192 void raptor_flare_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
193 {
194     TakeResource(this, RES_HEALTH, damage);
195     if(GetResource(this, RES_HEALTH) <= 0)
196         delete(this);
197 }
198
199 void raptor_flare_think(entity this)
200 {
201     this.nextthink = time + 0.1;
202     IL_EACH(g_projectiles, it.enemy == this.owner,
203     {
204         if(vdist(this.origin - it.origin, <, autocvar_g_vehicle_raptor_flare_range))
205         if(random() > autocvar_g_vehicle_raptor_flare_chase)
206             it.enemy = this;
207     });
208
209     if(this.tur_impacttime < time)
210         delete(this);
211 }
212
213 #endif
214
215 #ifdef CSQC
216
217 void RaptorCBShellfragDraw(entity this)
218 {
219     if(wasfreed(this))
220         return;
221
222     Movetype_Physics_MatchTicrate(this, autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
223     this.avelocity += randomvec() * 15;
224     this.renderflags = 0;
225
226     if(this.cnt < time)
227         this.alpha = bound(0, this.nextthink - time, 1);
228
229     if(this.alpha < ALPHA_MIN_VISIBLE)
230         delete(this);
231 }
232
233 void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
234 {
235     entity sfrag = spawn();
236     setmodel(sfrag, MDL_VEH_RAPTOR_CB_FRAGMENT);
237     setorigin(sfrag, _org);
238
239     set_movetype(sfrag, MOVETYPE_BOUNCE);
240     sfrag.gravity = 0.15;
241     sfrag.solid = SOLID_CORPSE;
242
243     sfrag.draw = RaptorCBShellfragDraw;
244     IL_PUSH(g_drawables, sfrag);
245
246     sfrag.velocity = _vel;
247     sfrag.avelocity = prandomvec() * vlen(sfrag.velocity);
248     sfrag.angles = _ang;
249
250     sfrag.move_time = time;
251     sfrag.damageforcescale = 4;
252
253     sfrag.nextthink = time + 3;
254     sfrag.cnt = time + 2;
255     sfrag.alpha = 1;
256     sfrag.drawmask = MASK_NORMAL;
257 }
258
259 #endif