return;
}
- float burst = 0;
+ int burst = 0;
- if( (PHYS_INPUT_BUTTON_ATCK2(own) && !WEP_CVAR(arc, bolt)) || this.beam_bursting)
+ if( (PHYS_INPUT_BUTTON_ATCK2(own) && !WEP_CVAR(WEP_ARC, bolt)) || this.beam_bursting)
{
if(!this.beam_bursting)
this.beam_bursting = true;
if(this.beam_dir != w_shotdir)
{
// calculate how much we're going to move the end of the beam to the want position
- // WEAPONTODO (server and client):
- // blendfactor never actually becomes 0 in this situation, which is a problem
- // regarding precision... this means that this.beam_dir and w_shotdir approach
- // eachother, however they never actually become the same value with this method.
- // Perhaps we should do some form of rounding/snapping?
float angle = vlen(w_shotdir - this.beam_dir) * RAD2DEG;
- float max_blendfactor = 1;
- if(angle && (angle > WEP_CVAR(WEP_ARC, beam_maxangle)))
- max_blendfactor = WEP_CVAR(WEP_ARC, beam_maxangle) / angle;
- float blendfactor = bound(0, (1 - (WEP_CVAR(WEP_ARC, beam_returnspeed) * frametime)), max_blendfactor);
- if(vdist(this.beam_dir - w_shotdir, <, 0.01))
- this.beam_dir = w_shotdir;
+ if (angle < 0.01) // snap only when very close so it's impossible to notice
+ this.beam_dir = w_shotdir; // snap otherwise vectors will never actually be the same
else
- if(angle && (angle > WEP_CVAR(arc, beam_maxangle)))
- max_blendfactor = WEP_CVAR(arc, beam_maxangle) / angle;
- float blendfactor = bound(0, (1 - (WEP_CVAR(arc, beam_returnspeed) * frametime)), max_blendfactor);
+ {
+ float max_blendfactor = 1;
++ if(angle && (angle > WEP_CVAR(WEP_ARC, beam_maxangle)))
++ max_blendfactor = WEP_CVAR(WEP_ARC, beam_maxangle) / angle;
++ float blendfactor = bound(0, (1 - (WEP_CVAR(WEP_ARC, beam_returnspeed) * frametime)), max_blendfactor);
this.beam_dir = normalize((w_shotdir * (1 - blendfactor)) + (this.beam_dir * blendfactor));
+ }
// network information: beam direction
this.SendFlags |= ARC_SF_BEAMDIR;
}
}
- vector beam_endpos = (w_shotorg + (this.beam_dir * WEP_CVAR(arc, beam_range)));
- float beam_controlpoint_dist = WEP_CVAR(arc, beam_range) * bound(0.001, 1 - WEP_CVAR(arc, beam_tightness), 1);
+ vector beam_endpos = (w_shotorg + (this.beam_dir * WEP_CVAR(WEP_ARC, beam_range)));
- vector beam_controlpoint = w_shotorg + w_shotdir * (WEP_CVAR(WEP_ARC, beam_range) * (1 - WEP_CVAR(WEP_ARC, beam_tightness)));
++ float beam_controlpoint_dist = WEP_CVAR(WEP_ARC, beam_range) * bound(0.001, 1 - WEP_CVAR(WEP_ARC, beam_tightness), 1);
+ vector beam_controlpoint = w_shotorg + w_shotdir * beam_controlpoint_dist;
- float i;
- float new_beam_type = 0;
+ int new_beam_type = 0;
vector last_origin = w_shotorg;
- for(i = 1; i <= segments; ++i)
+ vector last_origin_prev = '0 0 0';
+ for(int i = 1; i <= segments; ++i)
{
// WEAPONTODO (client):
// In order to do nice fading and pointing on the starting segment, we must always
// we collided with an entity
bool is_player = (IS_PLAYER(trace_ent) || trace_ent.classname == "body" || IS_MONSTER(trace_ent));
- if(SAME_TEAM(own, trace_ent))
+ if(trace_ent != own && SAME_TEAM(own, trace_ent))
{
- float roothealth = ((burst) ? WEP_CVAR(arc, burst_healing_hps) : WEP_CVAR(arc, beam_healing_hps));
- float rootarmor = ((burst) ? WEP_CVAR(arc, burst_healing_aps) : WEP_CVAR(arc, beam_healing_aps));
- float hplimit = ((IS_PLAYER(trace_ent)) ? WEP_CVAR(arc, beam_healing_hmax) : RES_LIMIT_NONE);
+ float roothealth = ((burst) ? WEP_CVAR(WEP_ARC, burst_healing_hps) : WEP_CVAR(WEP_ARC, beam_healing_hps));
+ float rootarmor = ((burst) ? WEP_CVAR(WEP_ARC, burst_healing_aps) : WEP_CVAR(WEP_ARC, beam_healing_aps));
+ float hplimit = ((IS_PLAYER(trace_ent)) ? WEP_CVAR(WEP_ARC, beam_healing_hmax) : RES_LIMIT_NONE);
Heal(trace_ent, own, (roothealth * coefficient), hplimit);
if(IS_PLAYER(trace_ent) && rootarmor
- && GetResource(trace_ent, RES_ARMOR) <= WEP_CVAR(arc, beam_healing_amax))
+ && GetResource(trace_ent, RES_ARMOR) <= WEP_CVAR(WEP_ARC, beam_healing_amax))
{
- GiveResourceWithLimit(trace_ent, RES_ARMOR, (rootarmor * coefficient), WEP_CVAR(arc, beam_healing_amax));
+ GiveResourceWithLimit(trace_ent, RES_ARMOR, (rootarmor * coefficient), WEP_CVAR(WEP_ARC, beam_healing_amax));
trace_ent.pauserotarmor_finished = max(
trace_ent.pauserotarmor_finished,
time + autocvar_g_balance_pause_armor_rot
WEP_ARC.m_id,
weaponentity,
hitorigin,
- WEP_CVAR(arc, beam_force) * coefficient * falloff * new_dir
- WEP_CVAR(WEP_ARC, beam_force) * new_dir * coefficient * falloff
++ WEP_CVAR(WEP_ARC, beam_force) * coefficient * falloff * new_dir
);
new_beam_type = ARC_BT_HIT;
set_movetype(beam, MOVETYPE_NONE);
beam.bot_dodge = true;
IL_PUSH(g_bot_dodge, beam);
- beam.bot_dodgerating = WEP_CVAR(arc, beam_damage);
+ beam.bot_dodgerating = WEP_CVAR(WEP_ARC, beam_damage);
- beam.beam_bursting = burst;
+ beam.beam_bursting = boolean(burst);
Net_LinkEntity(beam, false, 0, W_Arc_Beam_Send);
getthink(beam)(beam);
// trace forward with an estimation
WarpZone_TraceLine(
start_pos_saved,
- start_pos_saved + forward * WEP_CVAR(arc, beam_range),
- start_pos_saved + forward * this.beam_range,
++ start_pos_saved + forward * WEP_CVAR(WEP_ARC, beam_range),
MOVE_NOMONSTERS,
this
);
if(this.beam_dir != wantdir)
{
// calculate how much we're going to move the end of the beam to the want position
- // WEAPONTODO (server and client):
- // blendfactor never actually becomes 0 in this situation, which is a problem
- // regarding precision... this means that this.beam_dir and w_shotdir approach
- // eachother, however they never actually become the same value with this method.
- // Perhaps we should do some form of rounding/snapping?
float angle = vlen(wantdir - this.beam_dir) * RAD2DEG;
- float max_blendfactor = 1;
- if(angle && (angle > this.beam_maxangle))
- max_blendfactor = this.beam_maxangle / angle;
- float blendfactor = bound(0, (1 - (this.beam_returnspeed * dt)), max_blendfactor);
- this.beam_dir = normalize((wantdir * (1 - blendfactor)) + (this.beam_dir * blendfactor));
-
- // calculate how many segments are needed
- float max_allowed_segments = ARC_MAX_SEGMENTS;
- if(this.beam_distancepersegment)
+ if (angle < 0.01) // snap only when very close so it's impossible to notice
+ this.beam_dir = wantdir; // snap otherwise vectors will never actually be the same
+ else
{
- max_allowed_segments = 1 + (vlen(wantdir / this.beam_distancepersegment));
- max_allowed_segments = bound(1, max_allowed_segments, ARC_MAX_SEGMENTS);
- }
+ float max_blendfactor = 1;
- if(angle && (angle > WEP_CVAR(arc, beam_maxangle)))
- max_blendfactor = WEP_CVAR(arc, beam_maxangle) / angle;
- float blendfactor = bound(0, (1 - (WEP_CVAR(arc, beam_returnspeed) * dt)), max_blendfactor);
++ if(angle && (angle > WEP_CVAR(WEP_ARC, beam_maxangle)))
++ max_blendfactor = WEP_CVAR(WEP_ARC, beam_maxangle) / angle;
++ float blendfactor = bound(0, (1 - (WEP_CVAR(WEP_ARC, beam_returnspeed) * dt)), max_blendfactor);
+ this.beam_dir = normalize((wantdir * (1 - blendfactor)) + (this.beam_dir * blendfactor));
+
+ // calculate how many segments are needed
+ float max_allowed_segments = ARC_MAX_SEGMENTS;
- if(WEP_CVAR(arc, beam_distancepersegment))
++ if(WEP_CVAR(WEP_ARC, beam_distancepersegment))
+ {
- max_allowed_segments = 1 + (vlen(wantdir / WEP_CVAR(arc, beam_distancepersegment)));
++ max_allowed_segments = 1 + (vlen(wantdir / WEP_CVAR(WEP_ARC, beam_distancepersegment)));
+ max_allowed_segments = bound(1, max_allowed_segments, ARC_MAX_SEGMENTS);
+ }
- if(WEP_CVAR(arc, beam_degreespersegment))
- if(this.beam_degreespersegment)
- {
- segments = min(angle, this.beam_maxangle) / this.beam_degreespersegment;
- segments = bound(1, segments, max_allowed_segments);
++ if(WEP_CVAR(WEP_ARC, beam_degreespersegment))
+ {
- segments = min(angle, WEP_CVAR(arc, beam_maxangle)) / WEP_CVAR(arc, beam_degreespersegment);
++ segments = min(angle, WEP_CVAR(WEP_ARC, beam_maxangle)) / WEP_CVAR(WEP_ARC, beam_degreespersegment);
+ segments = bound(1, segments, max_allowed_segments);
+ }
}
}
// calculate how many segments are needed
float max_allowed_segments = ARC_MAX_SEGMENTS;
- if(WEP_CVAR(arc, beam_distancepersegment))
- if(this.beam_distancepersegment)
++ if(WEP_CVAR(WEP_ARC, beam_distancepersegment))
{
- max_allowed_segments = 1 + (vlen(wantdir / WEP_CVAR(arc, beam_distancepersegment)));
- max_allowed_segments = 1 + (vlen(wantdir / this.beam_distancepersegment));
++ max_allowed_segments = 1 + (vlen(wantdir / WEP_CVAR(WEP_ARC, beam_distancepersegment)));
max_allowed_segments = bound(1, max_allowed_segments, ARC_MAX_SEGMENTS);
}
- if(WEP_CVAR(arc, beam_degreespersegment))
- if(this.beam_degreespersegment)
++ if(WEP_CVAR(WEP_ARC, beam_degreespersegment))
{
- segments = min(angle, WEP_CVAR(arc, beam_maxangle)) / WEP_CVAR(arc, beam_degreespersegment);
- segments = min(angle, this.beam_maxangle) / this.beam_degreespersegment;
++ segments = min(angle, WEP_CVAR(WEP_ARC, beam_maxangle)) / WEP_CVAR(WEP_ARC, beam_degreespersegment);
segments = bound(1, segments, max_allowed_segments);
}
}
setorigin(this, start_pos);
this.beam_muzzleentity.angles_z = random() * 360; // WEAPONTODO: use avelocity instead?
- vector beam_endpos = (start_pos + (beamdir * WEP_CVAR(arc, beam_range)));
- float beam_controlpoint_dist = WEP_CVAR(arc, beam_range) * bound(0.001, 1 - WEP_CVAR(arc, beam_tightness), 1);
- vector beam_endpos = (start_pos + (beamdir * this.beam_range));
- vector beam_controlpoint = start_pos + wantdir * (this.beam_range * (1 - this.beam_tightness));
++ vector beam_endpos = (start_pos + (beamdir * WEP_CVAR(WEP_ARC, beam_range)));
++ float beam_controlpoint_dist = WEP_CVAR(WEP_ARC, beam_range) * bound(0.001, 1 - WEP_CVAR(WEP_ARC, beam_tightness), 1);
+ vector beam_controlpoint = start_pos + wantdir * beam_controlpoint_dist;
Draw_ArcBeam_callback_entity = this;
- Draw_ArcBeam_callback_last_thickness = 0;
- Draw_ArcBeam_callback_last_top = start_pos;
- Draw_ArcBeam_callback_last_bottom = start_pos;
+ if(!autocvar_cl_arcbeam_simple)
+ {
+ Draw_ArcBeam_callback_last_thickness = 0;
+ Draw_ArcBeam_callback_last_top = start_pos;
+ Draw_ArcBeam_callback_last_bottom = start_pos;
+ }
vector last_origin = start_pos;
vector original_start_pos = start_pos;