15 float drawlocal = ((to == this.
owner) || ((to.enemy == this.
owner) &&
IS_SPEC(to)));
51 if(!player.(weaponentity).arc_beam)
53 player.(weaponentity).
arc_beam.beam_dir = forward;
60 if (
WEP_CVAR(WEP_ARC, overheat_max) <= 0 ||
WEP_CVAR(WEP_ARC, overheat_max) <= 0 )
62 player.arc_overheat = 0;
66 if ( player.(weaponentity).arc_beam )
67 return player.(weaponentity).
arc_beam.beam_heat/
WEP_CVAR(WEP_ARC, overheat_max);
69 if ( player.arc_overheat >
time )
71 return (player.arc_overheat-
time) /
WEP_CVAR(WEP_ARC, overheat_max)
72 * player.arc_cooldown;
125 if(
WEP_CVAR(WEP_ARC, bolt_bounce_explode))
132 if(this.
cnt == 1 &&
WEP_CVAR(WEP_ARC, bolt_bounce_lifetime))
143 entity missile =
new(missile);
144 missile.owner = missile.realowner = actor;
145 missile.bot_dodge =
true;
147 missile.bot_dodgerating =
WEP_CVAR(WEP_ARC, bolt_damage);
151 missile.damageforcescale =
WEP_CVAR(WEP_ARC, bolt_damageforcescale);
153 missile.damagedbycontents =
true;
160 missile.nextthink =
time +
WEP_CVAR(WEP_ARC, bolt_lifetime);
163 missile.weaponentity_fld = weaponentity;
165 setsize(missile,
'0 0 0',
'0 0 0');
179 actor.(weaponentity).
misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
180 if(actor.(weaponentity).misc_bulletcounter == 0)
195 if(
this != own.(weaponentity).arc_beam)
214 || own.(weaponentity).m_switchweapon != WEP_ARC
218 if (
WEP_CVAR(WEP_ARC, cooldown) > 0 )
220 float cooldown_speed = 0;
223 cooldown_speed =
WEP_CVAR(WEP_ARC, cooldown);
237 if ( cooldown_speed )
239 if (
WEP_CVAR(WEP_ARC, cooldown_release) || overheat)
241 own.arc_cooldown = cooldown_speed;
246 if(
this == own.(weaponentity).arc_beam) { own.(weaponentity).
arc_beam =
NULL; }
263 { rootammo =
WEP_CVAR(WEP_ARC, burst_ammo); }
265 { rootammo =
WEP_CVAR(WEP_ARC, beam_ammo); }
285 WEP_CVAR(WEP_ARC, beam_damage) * coefficient,
328 float max_blendfactor = 1;
340 if(
WEP_CVAR(WEP_ARC, beam_distancepersegment))
346 if(
WEP_CVAR(WEP_ARC, beam_degreespersegment))
349 segments =
bound(1, segments, max_allowed_segments);
354 float beam_controlpoint_dist =
WEP_CVAR(WEP_ARC, beam_range) *
bound(0.001, 1 -
WEP_CVAR(WEP_ARC, beam_tightness), 1);
357 int new_beam_type = 0;
359 vector last_origin_prev =
'0 0 0';
360 for(
int i = 1; i <= segments; ++i)
383 last_origin_prev = last_origin;
408 float roothealth = ((burst) ?
WEP_CVAR(WEP_ARC, burst_healing_hps) :
WEP_CVAR(WEP_ARC, beam_healing_hps));
409 float rootarmor = ((burst) ?
WEP_CVAR(WEP_ARC, burst_healing_aps) :
WEP_CVAR(WEP_ARC, beam_healing_aps));
421 if(roothealth || rootarmor)
424 else if(
trace_ent.takedamage && (is_player ||
WEP_CVAR(WEP_ARC, beam_nonplayerdamage)))
432 WEP_CVAR(WEP_ARC, beam_falloff_mindist),
433 WEP_CVAR(WEP_ARC, beam_falloff_maxdist),
434 WEP_CVAR(WEP_ARC, beam_falloff_halflifedist),
442 rootdamage =
WEP_CVAR(WEP_ARC, burst_damage);
444 rootdamage =
WEP_CVAR(WEP_ARC, beam_damage);
447 rootdamage =
WEP_CVAR(WEP_ARC, beam_nonplayerdamage);
460 rootdamage * coefficient *
falloff,
475 new_beam_type |= burst;
491 if(
time - actor.(weaponentity).beam_prev > 1)
495 beam.weaponentity_fld = weaponentity;
500 beam.bot_dodge =
true;
502 beam.bot_dodgerating =
WEP_CVAR(WEP_ARC, beam_damage);
503 beam.beam_bursting =
boolean(burst);
510 if(!actor.(weaponentity).arc_beam || wasfreed(actor.(weaponentity).arc_beam))
512 w_ready(thiswep, actor, weaponentity, fire);
520 actor.(weaponentity).
wframe = WFRAME_FIRE1;
530 w_shotorg = actor.origin + actor.view_ofs + dv;
534 if ( actor.arc_overheat >
time )
536 if (
random() < actor.(weaponentity).arc_heat_percent )
537 Send_Effect(EFFECT_ARC_SMOKE, smoke_origin,
'0 0 0', 1 );
538 if ( fire & (1 | 2) )
541 if ( !actor.arc_smoke_sound )
543 actor.arc_smoke_sound =
true;
548 else if ( actor.(weaponentity).arc_beam &&
WEP_CVAR(WEP_ARC, overheat_max) > 0 &&
549 actor.(weaponentity).arc_beam.beam_heat >
WEP_CVAR(WEP_ARC, overheat_min) )
551 if (
random() < (actor.(weaponentity).arc_beam.beam_heat-
WEP_CVAR(WEP_ARC, overheat_min)) /
553 Send_Effect(EFFECT_ARC_SMOKE, smoke_origin,
'0 0 0', 1 );
557 bool stop_smoke_sound = actor.arc_overheat <=
time || !attacking;
558 if ((actor.arc_smoke_sound && stop_smoke_sound) || actor.(weaponentity).m_switchweapon != thiswep)
560 actor.arc_smoke_sound =
false;
567 if(
WEP_CVAR(WEP_ARC, beam_botaimspeed))
572 WEP_CVAR(WEP_ARC, beam_botaimspeed),
574 WEP_CVAR(WEP_ARC, beam_botaimlifetime),
593 Arc_Smoke(thiswep, actor, weaponentity, fire);
595 bool beam_fire2 = ((fire & 2) && !
WEP_CVAR(WEP_ARC, bolt));
597 if (
time >= actor.arc_overheat)
598 if ((fire & 1) || beam_fire2 || actor.(weaponentity).arc_beam.beam_bursting)
601 if(actor.(weaponentity).arc_BUTTON_ATCK_prev)
604 if(actor.animstate_startframe == actor.anim_shoot.x && actor.animstate_numframes == actor.anim_shoot.y)
605 weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime,
w_ready);
612 if((!actor.(weaponentity).arc_beam) || wasfreed(actor.(weaponentity).arc_beam))
616 W_Arc_Beam(
boolean(beam_fire2), actor, weaponentity);
618 if(!actor.(weaponentity).arc_BUTTON_ATCK_prev)
620 actor.(weaponentity).
wframe = WFRAME_FIRE1;
633 if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
637 w_ready(thiswep, actor, weaponentity, fire);
640 int to_shoot =
WEP_CVAR(WEP_ARC, bolt_count);
643 float ammo_available =
GetResource(actor, thiswep.ammo_type);
646 float burst_fraction =
min(1, ammo_available /
WEP_CVAR(WEP_ARC, bolt_ammo));
647 to_shoot =
floor(to_shoot * burst_fraction);
650 int to_use =
min(
WEP_CVAR(WEP_ARC, bolt_ammo), ammo_available);
660 if(actor.(weaponentity).arc_BUTTON_ATCK_prev)
670 if(
weapon_prepareattack(thiswep, actor, weaponentity,
true, autocvar_g_balance_arc_secondary_refire))
673 actor.arc_count = autocvar_g_balance_arc_secondary_count;
674 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack);
682 return WEAPON_ARC_SUICIDE_BOLT;
684 return WEAPON_THINKING_WITH_PORTALS;
706 ammo_amount += actor.(weaponentity).(
weapon_load[WEP_ARC.m_id]) >=
WEP_CVAR(WEP_ARC, bolt_ammo);
710 return WEP_CVAR(WEP_ARC, overheat_max) > 0 &&
716 return WEAPON_ARC_MURDER_SPRAY;
718 return WEAPON_ARC_MURDER;
724 actor.arc_overheat = 0;
725 actor.arc_cooldown = 0;
739 actor.arc_overheat = 0;
740 actor.arc_cooldown = 0;
749 actor.arc_overheat = 0;
750 actor.arc_cooldown = 0;
780 hitorigin = start + (Draw_ArcBeam_callback_new_dir * Draw_ArcBeam_callback_segmentdist *
trace_fraction);
791 float thickness = beam.beam_thickness;
802 vector top = hitorigin + (thickdir * thickness);
803 vector bottom = hitorigin - (thickdir * thickness);
812 '0 0.5 0' + (
'0 0.5 0' * (thickness / beam.beam_thickness)),
830 '0 0.5 0' * (1 - (thickness / beam.beam_thickness)),
846 if(beam.beam_traileffect)
856 e.beam_initialized =
false;
859 e.beam_initialized =
false;
866 this.move_time =
time;
867 if(dt <= 0) {
return; }
900 vector forward, right, up;
912 { start_pos = this.
origin; }
914 vector start_pos_saved = start_pos;
919 start_pos =
gettaginfo(wepent, v_shot_idx) -
'0 0 2';
928 start_pos_saved = start_pos;
935 start_pos_saved + forward *
WEP_CVAR(WEP_ARC, beam_range),
948 vector origin_offset =
'0 0 0';
957 start_pos = start_pos + origin_offset;
964 if (
vdist(end_pos - start_pos, >, 0.001))
965 wantdir =
normalize(end_pos - start_pos);
986 float max_blendfactor = 1;
989 float blendfactor =
bound(0, (1 - (
WEP_CVAR(WEP_ARC, beam_returnspeed) * dt)), max_blendfactor);
994 if(
WEP_CVAR(WEP_ARC, beam_distancepersegment))
996 max_allowed_segments = 1 + (
vlen(wantdir /
WEP_CVAR(WEP_ARC, beam_distancepersegment)));
1000 if(
WEP_CVAR(WEP_ARC, beam_degreespersegment))
1003 segments =
bound(1, segments, max_allowed_segments);
1024 if(beamdir != wantdir)
1030 if(
WEP_CVAR(WEP_ARC, beam_distancepersegment))
1032 max_allowed_segments = 1 + (
vlen(wantdir /
WEP_CVAR(WEP_ARC, beam_distancepersegment)));
1036 if(
WEP_CVAR(WEP_ARC, beam_degreespersegment))
1039 segments =
bound(1, segments, max_allowed_segments);
1044 setorigin(
this, start_pos);
1047 vector beam_endpos = (start_pos + (beamdir *
WEP_CVAR(WEP_ARC, beam_range)));
1048 float beam_controlpoint_dist =
WEP_CVAR(WEP_ARC, beam_range) *
bound(0.001, 1 -
WEP_CVAR(WEP_ARC, beam_tightness), 1);
1049 vector beam_controlpoint = start_pos + wantdir * beam_controlpoint_dist;
1059 vector last_origin = start_pos;
1060 vector original_start_pos = start_pos;
1062 for(
int i = 1; i <= segments; ++i)
1131 original_start_pos + wantdir * 20,
1139 original_start_pos + wantdir * 20,
1186 flash =
new(arc_flash);
1191 flash.avelocity_z = 5000;
1192 setattachment(flash,
this,
"");
1193 setorigin(flash,
'0 0 0');
1242 setorigin(
this, this.
origin);
1258 vector beamcolor =
'1 1 1';
1283 setmodel(flash, MDL_ARC_MUZZLEFLASH);
1309 setmodel(flash, MDL_ARC_MUZZLEFLASH);
1335 setmodel(flash, MDL_ARC_MUZZLEFLASH);
1361 setmodel(flash, MDL_ARC_MUZZLEFLASH);
1387 setmodel(flash, MDL_ARC_MUZZLEFLASH);
1413 setmodel(flash, MDL_ARC_MUZZLEFLASH);
1439 setmodel(flash, MDL_ARC_MUZZLEFLASH);
1465 setmodel(flash, MDL_ARC_MUZZLEFLASH);
1493 setmodel(flash, MDL_ARC_MUZZLEFLASH);
1518 PAR(_(
"The %s fires a continuous beam of electricity, steadily dealing damage to any enemies that cross its path."),
COLORED_NAME(
this));
1519 PAR(_(
"The secondary fire rapidly shoots electric bolts forward, exploding on impact and dealing some splash damage."));
1520 PAR(_(
"It consumes %s ammo, steadily churning through your supply to maintain the stream."),
COLORED_NAME(ITEM_Cells));
1521 PAR(_(
"The %s is quite a versatile weapon, however it is more effective at close to medium ranges, since the stream is not instantaneous."),
COLORED_NAME(
this));
void accuracy_add(entity this, Weapon w, float fired, float hit, float real)
update accuracy stats
bool accuracy_isgooddamage(entity attacker, entity targ)
does this damage count towards accuracy stats?
void WarpZone_traceline_antilag(entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
#define ANTILAG_LATENCY(e)
bool bot_aim(entity this,.entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, float applygravity, bool shot_accurate)
IntrusiveList g_bot_dodge
void W_Arc_Beam(bool burst, entity actor,.entity weaponentity)
bool autocvar_cl_arcbeam_simple
void Arc_Smoke(Weapon thiswep, entity actor,.entity weaponentity, int fire)
void Remove_ArcBeam(entity this)
bool W_Arc_Beam_Send(entity this, entity to, int sf)
void Draw_ArcBeam_callback(vector start, vector hit, vector end)
void W_Arc_Bolt_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
void W_Arc_Attack_Bolt(Weapon thiswep, entity actor,.entity weaponentity, int fire)
void W_Arc_Bolt_Explode_use(entity this, entity actor, entity trigger)
void W_Arc_Beam_Think(entity this)
void W_Arc_Attack(Weapon thiswep, entity actor,.entity weaponentity, int fire)
float Arc_GetHeat_Percent(entity player,.entity weaponentity)
void Draw_ArcBeam(entity this)
void W_Arc_Bolt_Touch(entity this, entity toucher)
void W_Arc_Bolt_Explode(entity this, entity directhitentity)
void Arc_Player_SetHeat(entity player,.entity weaponentity)
vector Draw_ArcBeam_callback_last_top
const int ARC_SF_LOCALMASK
const float ARC_MAX_SEGMENTS
const int ARC_SF_BEAMTYPE
bool arc_BUTTON_ATCK_prev
const int ARC_BT_BURST_HEAL
vector Draw_ArcBeam_callback_last_bottom
entity Draw_ArcBeam_callback_entity
const int ARC_BT_BURST_MISS
const int ARC_BT_BURST_WALL
float beam_muzzlelight[4]
const int ARC_BT_BURST_HIT
float Draw_ArcBeam_callback_last_thickness
const int ARC_BT_BURSTMASK
#define MUTATOR_CALLHOOK(id,...)
int W_GunAlign(entity this, int preferred_align)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
void SetResource(entity e, Resource res_type, float amount)
Sets the current amount of resource the given entity will have.
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Resource ammo_type
M: ammotype : main ammo type.
virtual void wr_checkammo1()
(SERVER) checks ammo for weapon primary
IntrusiveList g_drawables
#define colormapPaletteColor(c, isPants)
#define COLORED_NAME(this)
const int IT_UNLIMITED_AMMO
#define setmodel(this, m)
#define PHYS_INPUT_BUTTON_ATCK(s)
#define PHYS_INPUT_BUTTON_ATCK2(s)
float W_WeaponRateFactor(entity this)
void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float theAlpha, float drawflag, vector vieworg)
const float DRAWFLAG_NORMAL
const float MOVE_NOMONSTERS
const float EF_FULLBRIGHT
float trace_dphitq3surfaceflags
float Q3SURFACEFLAG_NOIMPACT
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
bool Heal(entity targ, entity inflictor, float amount, float limit)
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
IntrusiveList g_damagedbycontents
void W_SwitchWeapon_Force(Player this, Weapon w,.entity weaponentity)
const int HITTYPE_SECONDARY
#define MAKE_VECTORS(angles, forward, right, up)
Same as the makevectors builtin but uses the provided locals instead of the v_* globals.
#define pointparticles(effect, org, vel, howmany)
#define trailparticles(e, effect, org, vel)
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
#define entcs_receiver(...)
int entcs_GetClientColors(int i)
void InterpolateOrigin_Undo(entity this)
snap origin to iorigin2 (actual origin)
void InterpolateOrigin_Note(entity this)
void InterpolateOrigin_Do(entity this)
set origin based on iorigin1 (old pos), iorigin2 (desired pos), and time
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define NET_HANDLE(id, param)
#define ReadAngleVector()
#define WriteHeader(to, id)
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
vector warpzone_save_view_origin
vector warpzone_save_view_angles
void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent, entity zone, WarpZone_trace_callback_t cb)
void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
vector WarpZone_TransformVelocity(entity wz, vector v)
vector WarpZone_UnTransformOrigin(entity wz, vector v)
vector WarpZone_TransformOrigin(entity wz, vector v)
entity WarpZone_trace_transform
ERASEABLE float ExponentialFalloff(float mindist, float maxdist, float halflifedist, float d)
ERASEABLE vector bezier_quadratic_getpoint(vector a, vector b, vector c, float t)
void set_movetype(entity this, int mt)
const int MOVETYPE_BOUNCEMISSILE
entity Notification
always last
#define METHOD(cname, name, prototype)
void loopsound(entity e, int ch, Sound samp, float vol, float attn)
const int PROJECTILE_ARC_BOLT
bool client_hasweapon(entity this, Weapon wpn,.entity weaponentity, float andammo, bool complain)
void W_SwitchToOtherWeapon(entity this,.entity weaponentity)
#define w_getbestweapon(ent, wepent)
float W_CheckProjectileDamage(entity inflictor, entity projowner, int deathtype, float exception)
void W_PrepareExplosionByDamage(entity this, entity attacker, void(entity this) explode)
void adaptor_think2use_hittype_splash(entity this)
#define PROJECTILE_TOUCH(e, t)
IntrusiveList g_projectiles
#define PROJECTILE_MAKETRIGGER(e)
const int CH_SHOTS_SINGLE
#define sound(e, c, s, v, a)
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
void GiveResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
Gives an entity some resource but not more than a limit.
float autocvar_g_balance_pause_armor_rot
#define W_SetupProjVelocity_PRE(ent, wep, prefix)
#define W_SetupShot_Range(ent, wepent, antilag, recoil, snd, chan, maxdamage, range, deathtype)
#define W_SetupShot(ent, wepent, antilag, recoil, snd, chan, maxdamage, deathtype)
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
int autocvar_chase_active
bool autocvar_r_drawviewmodel
bool autocvar_cl_lockview
entity viewmodels[MAX_WEAPONSLOTS]
string W_Guide_Keybinds(Weapon wep)
void W_MuzzleFlash(Weapon thiswep, entity actor,.entity weaponentity, vector shotorg, vector shotdir)
string W_Guide_DPS_primaryDPS(string name, string pri, string sec)
vector shotorg_adjust(vector vecs, bool y_is_right, bool visual, int algn)
#define WEP_CVAR(wep, name)
const int MAX_WEAPONSLOTS
entity weaponentities[MAX_WEAPONSLOTS]
int autocvar_cl_tracers_teamcolor
int weaponslot(.entity weaponentity)
void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use,.entity weaponentity)
void weapon_thinkf(entity actor,.entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,.entity weaponentity, int fire) func)
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
vector CL_Weapon_GetShotOrg(int wpn)
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)
bool weapon_prepareattack_check(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
entity weapon_dropevent_item
#define ATTACK_FINISHED(ent, w)
float weapon_load[REGISTRY_MAX(Weapons)]