5 void W_Blaster_Touch(entity this, entity toucher)
7 PROJECTILE_TOUCH(this, toucher);
9 this.event_damage = func_null;
11 RadiusDamageForSource(
13 (this.origin + (this.mins + this.maxs) * 0.5),
17 this.blaster_edgedamage,
23 this.blaster_force_zscale,
24 this.projectiledeathtype,
25 this.weaponentity_fld,
32 void W_Blaster_Think(entity this)
34 set_movetype(this, MOVETYPE_FLY);
35 setthink(this, SUB_Remove);
36 this.nextthink = time + this.blaster_lifetime;
37 CSQCProjectile(this, true, PROJECTILE_BLASTER, true);
40 void W_Blaster_Attack(
49 float atk_force_zscale,
55 vector s_forward = v_forward * cos(atk_shotangle * DEG2RAD) + v_up * sin(atk_shotangle * DEG2RAD);
57 W_SetupShot_Dir(actor, weaponentity, s_forward, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_B, atk_damage, atk_deathtype);
58 Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
60 entity missile = new(blasterbolt);
61 missile.owner = missile.realowner = actor;
62 missile.bot_dodge = true;
63 missile.bot_dodgerating = atk_damage;
64 PROJECTILE_MAKETRIGGER(missile);
66 missile.blaster_damage = atk_damage;
67 missile.blaster_edgedamage = atk_edgedamage;
68 missile.blaster_radius = atk_radius;
69 missile.blaster_force = atk_force;
70 missile.blaster_force_zscale = atk_force_zscale;
71 missile.blaster_lifetime = atk_lifetime;
73 setorigin(missile, w_shotorg);
74 setsize(missile, '0 0 0', '0 0 0');
76 W_SetupProjVelocity_Explicit(
87 missile.angles = vectoangles(missile.velocity);
89 //missile.glow_color = 250; // 244, 250
90 //missile.glow_size = 120;
92 settouch(missile, W_Blaster_Touch);
93 missile.flags = FL_PROJECTILE;
94 IL_PUSH(g_projectiles, missile);
95 IL_PUSH(g_bot_dodge, missile);
96 missile.missile_flags = MIF_SPLASH;
97 missile.projectiledeathtype = atk_deathtype;
98 missile.weaponentity_fld = weaponentity;
99 setthink(missile, W_Blaster_Think);
100 missile.nextthink = time + atk_delay;
102 MUTATOR_CALLHOOK(EditProjectile, actor, missile);
104 if (time >= missile.nextthink)
106 getthink(missile)(missile);
110 METHOD(Blaster, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
112 if(WEP_CVAR(blaster, secondary))
114 if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage))
115 { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
117 { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
120 { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
123 METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponentity, int fire))
127 if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(blaster, refire)))
133 WEP_CVAR_PRI(blaster, shotangle),
134 WEP_CVAR_PRI(blaster, damage),
135 WEP_CVAR_PRI(blaster, edgedamage),
136 WEP_CVAR_PRI(blaster, radius),
137 WEP_CVAR_PRI(blaster, force),
138 WEP_CVAR_PRI(blaster, force_zscale),
139 WEP_CVAR_PRI(blaster, speed),
140 WEP_CVAR_PRI(blaster, spread),
141 WEP_CVAR_PRI(blaster, delay),
142 WEP_CVAR_PRI(blaster, lifetime)
144 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready);
149 switch(WEP_CVAR(blaster, secondary))
151 case 0: // switch to last used weapon
153 if(actor.(weaponentity).m_switchweapon == WEP_BLASTER) // don't do this if already switching
154 W_LastWeapon(actor, weaponentity);
158 case 1: // normal projectile secondary
160 if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(blaster, refire)))
165 WEP_BLASTER.m_id | HITTYPE_SECONDARY,
166 WEP_CVAR_SEC(blaster, shotangle),
167 WEP_CVAR_SEC(blaster, damage),
168 WEP_CVAR_SEC(blaster, edgedamage),
169 WEP_CVAR_SEC(blaster, radius),
170 WEP_CVAR_SEC(blaster, force),
171 WEP_CVAR_SEC(blaster, force_zscale),
172 WEP_CVAR_SEC(blaster, speed),
173 WEP_CVAR_SEC(blaster, spread),
174 WEP_CVAR_SEC(blaster, delay),
175 WEP_CVAR_SEC(blaster, lifetime)
177 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready);
186 METHOD(Blaster, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
188 return true; // infinite ammo
191 METHOD(Blaster, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
193 return true; // blaster has infinite ammo
196 METHOD(Blaster, wr_suicidemessage, Notification(entity thiswep))
198 return WEAPON_BLASTER_SUICIDE;
201 METHOD(Blaster, wr_killmessage, Notification(entity thiswep))
203 return WEAPON_BLASTER_MURDER;
206 METHOD(OffhandBlaster, offhand_think, void(OffhandBlaster this, entity actor, bool key_pressed))
208 if (!key_pressed || (time < actor.jump_interval))
212 actor.jump_interval = time + WEP_CVAR_SEC(blaster, refire) * W_WeaponRateFactor(actor);
213 .entity weaponentity = weaponentities[1];
214 BLASTER_SECONDARY_ATTACK(blaster, actor, weaponentity);
220 METHOD(Blaster, wr_impacteffect, void(entity thiswep, entity actor))
223 org2 = w_org + w_backoff * 6;
224 pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1);
225 if(!w_issilent) { sound(actor, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); }