X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Fweapons%2Fweapon%2Farc.qc;h=21ca117f4c4ec89980bbb60f9e34e3c4b88a549c;hp=1f6c3d40a45a154643f45ddde11a2c8228e178da;hb=95a5a2479a35e264473e8ba3fc4e584553da42b3;hpb=85a690d8a1e3eddfee959cea3dd42517484b07f4 diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index 1f6c3d40a..21ca117f4 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -1,151 +1,6 @@ #include "arc.qh" -#ifndef IMPLEMENTATION -CLASS(Arc, Weapon) -/* ammotype */ ATTRIB(Arc, ammo_field, .int, ammo_cells); -/* impulse */ ATTRIB(Arc, impulse, int, 3); -/* flags */ ATTRIB(Arc, spawnflags, int, WEP_FLAG_NORMAL); -/* rating */ ATTRIB(Arc, bot_pickupbasevalue, float, 8000); -/* color */ ATTRIB(Arc, wpcolor, vector, '1 1 1'); -/* modelname */ ATTRIB(Arc, mdl, string, "arc"); -#ifdef GAMEQC -/* model */ ATTRIB(Arc, m_model, Model, MDL_ARC_ITEM); -#endif -/* crosshair */ ATTRIB(Arc, w_crosshair, string, "gfx/crosshairhlac"); -/* crosshair */ ATTRIB(Arc, w_crosshair_size, float, 0.7); -/* wepimg */ ATTRIB(Arc, model2, string, "weaponarc"); -/* refname */ ATTRIB(Arc, netname, string, "arc"); -/* wepname */ ATTRIB(Arc, m_name, string, _("Arc")); - -#define X(BEGIN, P, END, class, prefix) \ - BEGIN(class) \ - P(class, prefix, bolt, float, NONE) \ - P(class, prefix, bolt_ammo, float, NONE) \ - P(class, prefix, bolt_damageforcescale, float, NONE) \ - P(class, prefix, bolt_damage, float, NONE) \ - P(class, prefix, bolt_edgedamage, float, NONE) \ - P(class, prefix, bolt_force, float, NONE) \ - P(class, prefix, bolt_health, float, NONE) \ - P(class, prefix, bolt_lifetime, float, NONE) \ - P(class, prefix, bolt_radius, float, NONE) \ - P(class, prefix, bolt_refire, float, NONE) \ - P(class, prefix, bolt_speed, float, NONE) \ - P(class, prefix, bolt_spread, float, NONE) \ - P(class, prefix, beam_ammo, float, NONE) \ - P(class, prefix, beam_animtime, float, NONE) \ - P(class, prefix, beam_botaimlifetime, float, NONE) \ - P(class, prefix, beam_botaimspeed, float, NONE) \ - P(class, prefix, beam_damage, float, NONE) \ - P(class, prefix, beam_degreespersegment, float, NONE) \ - P(class, prefix, beam_distancepersegment, float, NONE) \ - P(class, prefix, beam_falloff_halflifedist, float, NONE) \ - P(class, prefix, beam_falloff_maxdist, float, NONE) \ - P(class, prefix, beam_falloff_mindist, float, NONE) \ - P(class, prefix, beam_force, float, NONE) \ - P(class, prefix, beam_healing_amax, float, NONE) \ - P(class, prefix, beam_healing_aps, float, NONE) \ - P(class, prefix, beam_healing_hmax, float, NONE) \ - P(class, prefix, beam_healing_hps, float, NONE) \ - P(class, prefix, beam_heat, float, NONE) /* heat increase per second (primary) */ \ - P(class, prefix, beam_maxangle, float, NONE) \ - P(class, prefix, beam_nonplayerdamage, float, NONE) \ - P(class, prefix, beam_range, float, NONE) \ - P(class, prefix, beam_refire, float, NONE) \ - P(class, prefix, beam_returnspeed, float, NONE) \ - P(class, prefix, beam_tightness, float, NONE) \ - P(class, prefix, burst_ammo, float, NONE) \ - P(class, prefix, burst_damage, float, NONE) \ - P(class, prefix, burst_healing_aps, float, NONE) \ - P(class, prefix, burst_healing_hps, float, NONE) \ - P(class, prefix, burst_heat, float, NONE) /* heat increase per second (secondary) */ \ - P(class, prefix, cooldown, float, NONE) /* heat decrease per second when resting */ \ - P(class, prefix, cooldown_release, float, NONE) /* delay weapon re-use when releasing button */ \ - P(class, prefix, overheat_max, float, NONE) /* maximum heat before jamming */ \ - P(class, prefix, overheat_min, float, NONE) /* minimum heat to wait for cooldown */ \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, weaponreplace, string, NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ - END() - W_PROPS(X, Arc, arc) -#undef X - -ENDCLASS(Arc) -REGISTER_WEAPON(ARC, arc, NEW(Arc)); - - -#ifdef GAMEQC -const float ARC_MAX_SEGMENTS = 20; -vector arc_shotorigin[4]; -.vector beam_start; -.vector beam_dir; -.vector beam_wantdir; -.int beam_type; - -const int ARC_BT_MISS = 0x00; -const int ARC_BT_WALL = 0x01; -const int ARC_BT_HEAL = 0x02; -const int ARC_BT_HIT = 0x03; -const int ARC_BT_BURST_MISS = 0x10; -const int ARC_BT_BURST_WALL = 0x11; -const int ARC_BT_BURST_HEAL = 0x12; -const int ARC_BT_BURST_HIT = 0x13; -const int ARC_BT_BURSTMASK = 0x10; - -const int ARC_SF_SETTINGS = BIT(0); -const int ARC_SF_START = BIT(1); -const int ARC_SF_WANTDIR = BIT(2); -const int ARC_SF_BEAMDIR = BIT(3); -const int ARC_SF_BEAMTYPE = BIT(4); -const int ARC_SF_LOCALMASK = ARC_SF_START | ARC_SF_WANTDIR | ARC_SF_BEAMDIR; -#endif -#ifdef SVQC -.entity arc_beam; -.bool arc_BUTTON_ATCK_prev; // for better animation control -.float beam_prev; -.float beam_initialized; -.float beam_bursting; -.float beam_teleporttime; -.float beam_heat; // (beam) amount of heat produced -.float arc_overheat; // (dropped arc/player) time during which it's too hot -.float arc_cooldown; // (dropped arc/player) cooling speed -.float arc_heat_percent = _STAT(ARC_HEAT); -.float arc_smoke_sound; -#endif -#ifdef CSQC -.vector beam_color; -.float beam_alpha; -.float beam_thickness; -.entity beam_traileffect; -.entity beam_hiteffect; -.float beam_hitlight[4]; // 0: radius, 123: rgb -.entity beam_muzzleeffect; -.float beam_muzzlelight[4]; // 0: radius, 123: rgb -.string beam_image; - -.entity beam_muzzleentity; - -.float beam_degreespersegment; -.float beam_distancepersegment; -.float beam_usevieworigin; -.float beam_initialized; -.float beam_maxangle; -.float beam_range; -.float beam_returnspeed; -.float beam_tightness; -.vector beam_shotorigin; - -entity Draw_ArcBeam_callback_entity; -float Draw_ArcBeam_callback_last_thickness; -vector Draw_ArcBeam_callback_last_top; // NOTE: in same coordinate system as player. -vector Draw_ArcBeam_callback_last_bottom; // NOTE: in same coordinate system as player. -#endif -#endif -#ifdef IMPLEMENTATION #ifdef SVQC -spawnfunc(weapon_arc) { weapon_defaultspawnfunc(this, WEP_ARC); } bool W_Arc_Beam_Send(entity this, entity to, int sf) { @@ -175,21 +30,17 @@ bool W_Arc_Beam_Send(entity this, entity to, int sf) } if(sf & ARC_SF_START) // starting location { - WriteCoord(MSG_ENTITY, this.beam_start.x); - WriteCoord(MSG_ENTITY, this.beam_start.y); - WriteCoord(MSG_ENTITY, this.beam_start.z); + WriteVector(MSG_ENTITY, this.beam_start); } if(sf & ARC_SF_WANTDIR) // want/aim direction { - WriteCoord(MSG_ENTITY, this.beam_wantdir.x); - WriteCoord(MSG_ENTITY, this.beam_wantdir.y); - WriteCoord(MSG_ENTITY, this.beam_wantdir.z); + WriteVector(MSG_ENTITY, this.beam_wantdir); } if(sf & ARC_SF_BEAMDIR) // beam direction { - WriteCoord(MSG_ENTITY, this.beam_dir.x); - WriteCoord(MSG_ENTITY, this.beam_dir.y); - WriteCoord(MSG_ENTITY, this.beam_dir.z); + WriteAngle(MSG_ENTITY, this.beam_dir.x); + WriteAngle(MSG_ENTITY, this.beam_dir.y); + WriteAngle(MSG_ENTITY, this.beam_dir.z); } if(sf & ARC_SF_BEAMTYPE) // beam type { @@ -232,14 +83,14 @@ float Arc_GetHeat_Percent(entity player, .entity weaponentity) } void Arc_Player_SetHeat(entity player, .entity weaponentity) { - player.arc_heat_percent = Arc_GetHeat_Percent(player, weaponentity); + player.(weaponentity).arc_heat_percent = Arc_GetHeat_Percent(player, weaponentity); //dprint("Heat: ",ftos(player.arc_heat_percent*100),"%\n"); } void W_Arc_Bolt_Explode(entity this, entity directhitentity) { this.event_damage = func_null; - RadiusDamage(this, this.realowner, WEP_CVAR(arc, bolt_damage), WEP_CVAR(arc, bolt_edgedamage), WEP_CVAR(arc, bolt_radius), NULL, NULL, WEP_CVAR(arc, bolt_force), this.projectiledeathtype, directhitentity); + RadiusDamage(this, this.realowner, WEP_CVAR(arc, bolt_damage), WEP_CVAR(arc, bolt_edgedamage), WEP_CVAR(arc, bolt_radius), NULL, NULL, WEP_CVAR(arc, bolt_force), this.projectiledeathtype, this.weaponentity_fld, directhitentity); delete(this); } @@ -249,7 +100,7 @@ void W_Arc_Bolt_Explode_use(entity this, entity actor, entity trigger) W_Arc_Bolt_Explode(this, trigger); } -void W_Arc_Bolt_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +void W_Arc_Bolt_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force) { if(this.health <= 0) return; @@ -276,7 +127,7 @@ void W_Arc_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity) W_DecreaseAmmo(thiswep, actor, WEP_CVAR(arc, bolt_ammo), weaponentity); - W_SetupShot(actor, weaponentity, false, 2, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR(arc, bolt_damage)); + W_SetupShot(actor, weaponentity, false, 2, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR(arc, bolt_damage), WEP_ARC.m_id | HITTYPE_SECONDARY); Send_Effect(EFFECT_ARC_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); @@ -299,6 +150,7 @@ void W_Arc_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity) missile.nextthink = time + WEP_CVAR(arc, bolt_lifetime); PROJECTILE_MAKETRIGGER(missile); missile.projectiledeathtype = WEP_ARC.m_id | HITTYPE_SECONDARY; + missile.weaponentity_fld = weaponentity; setorigin(missile, w_shotorg); setsize(missile, '0 0 0', '0 0 0'); @@ -402,8 +254,8 @@ void W_Arc_Beam_Think(entity this) if(rootammo) { - coefficient = min(coefficient, own.(thiswep.ammo_field) / rootammo); - own.(thiswep.ammo_field) = max(0, own.(thiswep.ammo_field) - (rootammo * frametime)); + coefficient = min(coefficient, GetResourceAmount(own, thiswep.ammo_type) / rootammo); + SetResourceAmount(own, thiswep.ammo_type, max(0, GetResourceAmount(own, thiswep.ammo_type) - (rootammo * frametime))); } } float heat_speed = burst ? WEP_CVAR(arc, burst_heat) : WEP_CVAR(arc, beam_heat); @@ -419,7 +271,8 @@ void W_Arc_Beam_Think(entity this) SND_Null, 0, WEP_CVAR(arc, beam_damage) * coefficient, - WEP_CVAR(arc, beam_range) + WEP_CVAR(arc, beam_range), + WEP_ARC.m_id ); // After teleport, "lock" the beam until the teleport is confirmed. @@ -649,6 +502,7 @@ void W_Arc_Beam_Think(entity this) own, rootdamage * coefficient * falloff, WEP_ARC.m_id, + weaponentity, hitorigin, WEP_CVAR(arc, beam_force) * new_dir * coefficient * falloff ); @@ -705,12 +559,12 @@ void W_Arc_Beam(float burst, entity actor, .entity weaponentity) void Arc_Smoke(entity actor, .entity weaponentity) { makevectors(actor.v_angle); - W_SetupShot_Range(actor,weaponentity,true,0,SND_Null,0,0,0); + W_SetupShot_Range(actor,weaponentity,true,0,SND_Null,0,0,0,WEP_ARC.m_id); // TODO: probably doesn't need deathtype, since this is just a prefire effect vector smoke_origin = w_shotorg + actor.velocity*frametime; if ( actor.arc_overheat > time ) { - if ( random() < actor.arc_heat_percent ) + if ( random() < actor.(weaponentity).arc_heat_percent ) Send_Effect(EFFECT_ARC_SMOKE, smoke_origin, '0 0 0', 1 ); if ( PHYS_INPUT_BUTTON_ATCK(actor) || PHYS_INPUT_BUTTON_ATCK2(actor) ) { @@ -841,19 +695,19 @@ METHOD(Arc, wr_init, void(entity thiswep)) } METHOD(Arc, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - return ((!WEP_CVAR(arc, beam_ammo)) || (actor.(thiswep.ammo_field) > 0)); + return ((!WEP_CVAR(arc, beam_ammo)) || (GetResourceAmount(actor, thiswep.ammo_type) > 0)); } METHOD(Arc, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity)) { if(WEP_CVAR(arc, bolt)) { - float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(arc, bolt_ammo); + float ammo_amount = GetResourceAmount(actor, thiswep.ammo_type) >= WEP_CVAR(arc, bolt_ammo); ammo_amount += actor.(weaponentity).(weapon_load[WEP_ARC.m_id]) >= WEP_CVAR(arc, bolt_ammo); return ammo_amount; } else return WEP_CVAR(arc, overheat_max) > 0 && - ((!WEP_CVAR(arc, burst_ammo)) || (actor.(thiswep.ammo_field) > 0)); + ((!WEP_CVAR(arc, burst_ammo)) || (GetResourceAmount(actor, thiswep.ammo_type) > 0)); } METHOD(Arc, wr_killmessage, Notification(entity thiswep)) { @@ -1369,9 +1223,7 @@ NET_HANDLE(ENT_CLIENT_ARC_BEAM, bool isnew) if(sf & ARC_SF_START) // starting location { - this.origin_x = ReadCoord(); - this.origin_y = ReadCoord(); - this.origin_z = ReadCoord(); + this.origin = ReadVector(); } else if(this.beam_usevieworigin) // infer the location from player location { @@ -1391,16 +1243,14 @@ NET_HANDLE(ENT_CLIENT_ARC_BEAM, bool isnew) if(sf & ARC_SF_WANTDIR) // want/aim direction { - this.v_angle_x = ReadCoord(); - this.v_angle_y = ReadCoord(); - this.v_angle_z = ReadCoord(); + this.v_angle = ReadVector(); } if(sf & ARC_SF_BEAMDIR) // beam direction { - this.angles_x = ReadCoord(); - this.angles_y = ReadCoord(); - this.angles_z = ReadCoord(); + this.angles_x = ReadAngle(); + this.angles_y = ReadAngle(); + this.angles_z = ReadAngle(); } if(sf & ARC_SF_BEAMTYPE) // beam type @@ -1426,6 +1276,7 @@ NET_HANDLE(ENT_CLIENT_ARC_BEAM, bool isnew) this.beam_muzzlelight[1] = 1; this.beam_muzzlelight[2] = 1; this.beam_muzzlelight[3] = 1; + this.beam_image = "particles/lgbeam"; if(this.beam_muzzleeffect) { setmodel(flash, MDL_ARC_MUZZLEFLASH); @@ -1656,4 +1507,3 @@ NET_HANDLE(ENT_CLIENT_ARC_BEAM, bool isnew) } #endif -#endif