//lightcolor 1 0.9 0.7
//lightshadow 1
-// heal ray muzzleflash
+
++// heal ray muzzleflash
+ effect healray_muzzleflash
+ countabsolute 1
+ type smoke
+ color 0x283880 0x283880 // 0x202020 0x404040
+ tex 65 65
+ size 20 20
+ alpha 256 256 512
+ originjitter 1.5 1.5 1.5
+ velocityjitter 6 6 6
+ sizeincrease -10
+ velocitymultiplier 0.01
+ lightradius 200
+ lightradiusfade 2000
+ lightcolor 1.5 3 6
+
+ effect healray_muzzleflash
+ count 22
+ type spark
+ tex 71 73
+ color 0xD9FDFF 0x00f0ff
+ size 1 15
+ sizeincrease 3
+ alpha 50 150 1924
+ originjitter 1 1 1
+ velocityjitter 150 150 150
+ velocitymultiplier 0.4
+ airfriction 5
+ stretchfactor 3.9
+
+ effect healray_muzzleflash
+ count 4
+ type spark
+ tex 70 70
+ color 0xD9FDFF 0x00f0ff
+ size 1 1
+ alpha 110 228 4024
+ originjitter 1 1 1
+ velocityjitter 650 650 650
+ velocitymultiplier 1.1
+ stretchfactor 0.2
+
+
+
+ //healray impact
+
+ effect healray_impact
+ countabsolute 1
+ type decal
+ tex 59 59
+ size 32 32
+ alpha 256 256 0
+ color 0xd800ff 0xd800ff
+ originjitter 17 17 17
+ lightradius 125
+ lightradiusfade 450
+ lightcolor 0 4.375 0
+ // shockwave
+ effect healray_impact
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 32 32
+ sizeincrease 1400
+ color 0x00ff00 0x84c52f
+ alpha 40 40 350
+ velocitymultiplier 44
+ // cloud of bouncing sparks
+ effect healray_impact
+ count 30
+ type spark
+ tex 70 70
+ color 0x00ff00 0x84c52f
+ size 1 2
+ alpha 156 300 1024
+ gravity 2
+ airfriction 6
+ originjitter 1 1 1
+ velocityjitter 1112 1112 1112
+ // inner cloud of smoke
+ effect healray_impact
+ count 15
+ type smoke
+ color 0x00ff00 0x84c52f
+ tex 40 40
+ size 2 3
+ alpha 200 456 512
+ airfriction 3
+ gravity -2
+ velocityjitter 120 120 420
+ rotate -180 180 -90 90
+
+
+
+
+ // big plasma muzzle flash
+
+ effect bigplasma_muzzleflash
+ countabsolute 1
+ type smoke
+ color 0x283880 0x283880 // 0x202020 0x404040
+ tex 65 65
+ size 50 50
+ alpha 256 256 812
+ originjitter 1.5 1.5 1.5
+ velocityjitter 6 6 6
+ sizeincrease -10
+ velocitymultiplier 0.01
+ lightradius 200
+ lightradiusfade 2000
+ lightcolor 1.5 3 6
+
+ effect bigplasma_muzzleflash
+ countabsolute 1
+ type smoke
+ color 0x00f0ff 0x00f0ff
+ tex 74 74
+ size 20 20
+ alpha 56 56 1112
+ sizeincrease 300
+
+ effect bigplasma_muzzleflash
+ count 14
+ type spark
+ tex 51 55
+ color 0xD9FDFF 0x00f0ff
+ size 5 10
+ sizeincrease 135
+ alpha 50 150 1924
+ originjitter 1 1 1
+ velocityjitter 350 350 350
+ velocitymultiplier 0.4
+ airfriction 5
+ stretchfactor 1.9
+
+ effect bigplasma_muzzleflash
+ count 4
+ type spark
+ tex 70 70
+ color 0xD9FDFF 0x00f0ff
+ size 20 20
+ alpha 110 228 4024
+ originjitter 1 1 1
+ velocityjitter 650 650 650
+ velocitymultiplier 1.1
+ stretchfactor 0.2
+
+
+ // big plasma impact
+
+ effect bigplasma_impact
+ countabsolute 1
+ type decal
+ tex 59 59
+ size 32 32
+ alpha 256 256 0
+ originjitter 17 17 17
+ lightradius 125
+ lightradiusfade 450
+ lightcolor 3.125 4.375 10
+ // shockwave
+ effect bigplasma_impact
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 32 32
+ sizeincrease 1400
+ color 0x80C0FF 0x80C0FF
+ alpha 40 40 350
+ velocitymultiplier 44
+ // cloud of bouncing sparks
+ effect bigplasma_impact
+ count 30
+ type spark
+ tex 70 70
+ color 0x629dff 0x0018ff
+ size 1 2
+ alpha 156 300 1024
+ gravity 2
+ airfriction 6
+ originjitter 1 1 1
+ velocityjitter 1512 1512 1512
+ // inner cloud of smoke
+ effect bigplasma_impact
+ count 15
+ type smoke
+ color 0x629dff 0x0018ff
+ tex 48 55
+ size 20 24
+ sizeincrease 555
+ alpha 200 456 1512
+ airfriction 30
+ originjitter 20 20 20
+ velocityjitter 320 320 320
+ rotate -180 180 -9 9
+ // smoke
+ effect bigplasma_impact
+ type smoke
+ count 16
+ blend alpha
+ tex 0 7
+ size 60 30
+ color 0x222222 0x000000
+ alpha 128 328 390
+ rotate -180 180 2 -2
+ velocityjitter 100 100 200
+ velocityoffset 0 0 180
+ originjitter 80 80 10
+ sizeincrease 30
+ airfriction 0.04
+ gravity 0.4
+ // smoke in the middle
+ effect bigplasma_impact
+ type alphastatic
+ count 10
+ tex 0 7
+ size 60 70
+ color 0x222222 0x000000
+ alpha 128 328 310
+ rotate -180 180 20 -20
+ velocityjitter 10 10 10
+ originjitter 80 80 80
+ sizeincrease -10
+ airfriction 0.04
-gravity -0.2
++gravity -0.2
++
++
+// laser_shockwave_attack
+// used nowhere in code
+effect laser_shockwave_attack
+// glow and light
+//countabsolute 1
+//type smoke
+//color 0xcc0000 0xff0000
+//tex 65 65
+//size 10 15
+//alpha 256 512 6280
+//airfriction 10
+//sizeincrease 1.5
+//stretchfactor 2
+//lightradius 200
+//lightradiusfade 2000
+//lightcolor 3 0.1 0.1
+// electricity
+effect laser_shockwave_attack
+count 1
+type spark
+color 0xb44215 0xff0000
+tex 43 43
+size 5 7
+bounce 0
+alpha 4096 4096 20000
+airfriction 1
+originjitter 2 2 2
+velocityjitter 10 10 10
+velocitymultiplier 10
+sizeincrease 1.5
+stretchfactor 2.3
+rotate -180 180 4000 -4000
+// fire
+effect laser_shockwave_attack
+count 1
+type spark
+color 0xff4200 0xff0000
+tex 8 15
+size 7 9
+bounce 0
+alpha 4096 4096 20000
+airfriction 1
+originjitter 2 2 2
+velocityjitter 10 10 10
+velocitymultiplier 10
+sizeincrease 1.5
+stretchfactor 2
+
+// new_laser_impact
+// used nowhere in code
+// decal
+effect new_laser_impact
+countabsolute 1
+type decal
+tex 8 16
+size 72 72
+alpha 256 256 0
+originjitter 2 2 2
+// flare effect
+//effect new_laser_impact
+//countabsolute 1
+//type static
+//tex 39 39
+//color 0xFF2010 0xFF2010
+//alpha 256 256 1024
+//size 24 24
+// sparks that rapidly expand and rapidly slow down to form an interesting spherical effect
+effect new_laser_impact
+count 128
+type spark
+color 0x800000 0xFF8020
+alpha 256 256 1024
+size 4 4
+bounce 1.5
+gravity 0.5
+airfriction 1
+liquidfriction 1
+originjitter 20 20 20
- velocityjitter 256 256 256
++velocityjitter 256 256 256
void CSQC_Init(void)
{
prvm_language = cvar_string("prvm_language");
-
+ cl_simple_items = autocvar_cl_simple_items;
#ifdef USE_FTE
#pragma target ID
__engine_check = checkextension("DP_SV_WRITEPICTURE");
case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
case ENT_CLIENT_TURRET: ent_turret(); break;
- case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break;
+ case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break;
+ case ENT_CLIENT_ITEM: ItemRead(bIsNewEntity); break;
default:
//error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
error(sprintf(_("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n"), self.enttype, num_for_edict(self), self.classname));
cl_notice_read();
bHandled = true;
break;
+ case TE_CSQC_SHOCKWAVEPARTICLE:
+ Net_ReadShockwaveParticle();
+ bHandled = true;
+ break;
default:
// No special logic for this temporary entity; return 0 so the engine can handle it
bHandled = false;
const float TE_CSQC_LIGHTNINGARC = 105;
const float TE_CSQC_TEAMNAGGER = 106;
const float TE_CSQC_PINGPLREPORT = 107;
+const float TE_CSQC_SHOCKWAVEPARTICLE = 121;
const float TE_CSQC_ANNOUNCE = 110;
const float TE_CSQC_TARGET_MUSIC = 111;
const float TE_CSQC_KILLNOTIFY = 112;
const float ENT_CLIENT_SHOWNAMES = 31;
const float ENT_CLIENT_WARPZONE_TELEPORTED = 32;
const float ENT_CLIENT_MODEL = 33;
+ const float ENT_CLIENT_ITEM = 34;
const float ENT_CLIENT_TURRET = 40;
const float ENT_CLIENT_AUXILIARYXHAIR = 50;
float PROJECTILE_WAKIROCKET = 28;
float PROJECTILE_WAKICANNON = 29;
+ float PROJECTILE_BUMBLE_GUN = 30;
+ float PROJECTILE_BUMBLE_BEAM = 31;
+
float SPECIES_HUMAN = 0;
float SPECIES_ROBOT_SOLID = 1;
float SPECIES_ALIEN = 2;
float DEATH_RAPTOR_CANNON = 10037;
float DEATH_RAPTOR_BOMB = 10038;
float DEATH_RAPTOR_BOMB_SPLIT = 10039;
- float DEATH_RAPTOR_DEATH = 10040;
- float DEATH_VHLAST = 10040;
+ float DEATH_RAPTOR_DEATH = 10040;
+ float DEATH_BUMB_GUN = 10041;
+ float DEATH_BUMB_RAY = 10042;
+ float DEATH_BUMB_RAY_HEAL = 10043;
+ float DEATH_BUMB_DEATH = 10044;
+ float DEATH_VHLAST = 10044;
#define DEATH_ISVEHICLE(t) ((t) >= DEATH_VHFIRST && (t) <= DEATH_VHLAST)
float DEATH_GENERIC = 10050;
float autocvar_g_balance_laser_primary_force_other_scale;
float autocvar_g_balance_laser_primary_force_velocitybias;
float autocvar_g_balance_laser_primary_force_zscale;
+var float autocvar_g_balance_laser_primary_jumpradius = 150;
float autocvar_g_balance_laser_primary_lifetime;
float autocvar_g_balance_laser_primary_radius;
float autocvar_g_balance_laser_primary_refire;
float autocvar_g_balance_laser_primary_shotangle;
float autocvar_g_balance_laser_primary_speed;
+var float autocvar_g_balance_laser_primary_spread = 0.15;
float autocvar_g_balance_laser_secondary;
float autocvar_g_balance_laser_secondary_animtime;
float autocvar_g_balance_laser_secondary_damage;
float autocvar_g_full_getstatus_responses;
float autocvar_g_fullbrightitems;
float autocvar_g_fullbrightplayers;
- string autocvar_g_ghost_items_color;
#define autocvar_g_grappling_hook cvar("g_grappling_hook")
float autocvar_g_grappling_hook_tarzan;
float autocvar_g_hitplots;
entity e;
e = spawn();
setorigin(e, org);
- RadiusDamage(e, world, g_touchexplode_damage, g_touchexplode_edgedamage, g_touchexplode_radius, world, g_touchexplode_force, DEATH_TOUCHEXPLODE, world);
+ RadiusDamage(e, world, g_touchexplode_damage, g_touchexplode_edgedamage, g_touchexplode_radius, world, world, g_touchexplode_force, DEATH_TOUCHEXPLODE, world);
remove(e);
}
self.minelayer_mines = spectatee.minelayer_mines;
self.punchangle = spectatee.punchangle;
self.view_ofs = spectatee.view_ofs;
- self.v_angle = spectatee.v_angle;
self.velocity = spectatee.velocity;
self.dmg_take = spectatee.dmg_take;
self.dmg_save = spectatee.dmg_save;
self.dmg_inflictor = spectatee.dmg_inflictor;
+ self.v_angle = spectatee.v_angle;
self.angles = spectatee.v_angle;
if(!self.BUTTON_USE)
self.fixangle = TRUE;
setorigin(self, spectatee.origin);
setsize(self, spectatee.mins, spectatee.maxs);
SetZoomState(spectatee.zoomstate);
-
- anticheat_spectatecopy(spectatee);
-
- //self.vehicle = spectatee.vehicle;
-
+
+ anticheat_spectatecopy(spectatee);
self.hud = spectatee.hud;
if(spectatee.vehicle)
{
- setorigin(self, spectatee.origin);
- self.velocity = spectatee.vehicle.velocity;
- self.v_angle += spectatee.vehicle.angles;
- //self.v_angle_x *= -1;
+ self.fixangle = FALSE;
+ //self.velocity = spectatee.vehicle.velocity;
self.vehicle_health = spectatee.vehicle_health;
self.vehicle_shield = spectatee.vehicle_shield;
self.vehicle_energy = spectatee.vehicle_energy;
self.vehicle_ammo2 = spectatee.vehicle_ammo2;
self.vehicle_reload1 = spectatee.vehicle_reload1;
self.vehicle_reload2 = spectatee.vehicle_reload2;
-
+
msg_entity = self;
- WriteByte (MSG_ONE, SVC_SETVIEWPORT);
- WriteEntity(MSG_ONE, spectatee);
- //self.tur_head = spectatee.vehicle.vehicle_viewport;
+
+ WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
+ WriteAngle(MSG_ONE, spectatee.v_angle_x);
+ WriteAngle(MSG_ONE, spectatee.v_angle_y);
+ WriteAngle(MSG_ONE, spectatee.v_angle_z);
+
+ //WriteByte (MSG_ONE, SVC_SETVIEW);
+ // WriteEntity(MSG_ONE, self);
+ //makevectors(spectatee.v_angle);
+ //setorigin(self, spectatee.origin - v_forward * 400 + v_up * 300);*/
}
}
self.enemy = other;
if(self.enemy.classname == "player") {
- if(self.enemy.vehicle)
+ /*if(self.enemy.vehicle)
{
+
msg_entity = self;
- WriteByte(MSG_ONE, SVC_SETVIEWPORT);
+ WriteByte(MSG_ONE, SVC_SETVIEW);
WriteEntity(MSG_ONE, self.enemy);
//stuffcmd(self, "set viewsize $tmpviewsize \n");
+
self.movetype = MOVETYPE_NONE;
accuracy_resend(self);
}
else
- {
+ {*/
msg_entity = self;
WriteByte(MSG_ONE, SVC_SETVIEW);
WriteEntity(MSG_ONE, self.enemy);
if(!SpectateUpdate())
PutObserverInServer();
- }
+ //}
return 1;
} else {
return 0;
}
float RadiusDamage_running;
-float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype, entity directhitentity)
+float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, float deathtype, entity directhitentity)
// Returns total damage applies to creatures
{
entity targ;
- vector blastorigin;
vector force;
float total_damage_to_creatures;
entity next;
tfloordmg = autocvar_g_throughfloor_damage;
tfloorforce = autocvar_g_throughfloor_force;
- blastorigin = (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5);
total_damage_to_creatures = 0;
if(deathtype != (WEP_HOOK | HITTYPE_SECONDARY | HITTYPE_BOUNCE)) // only send gravity bomb damage once
if(DEATH_WEAPONOF(deathtype) != WEP_TUBA) // do not send tuba damage (bandwidth hog)
{
- force = inflictor.velocity;
+ force = inflictorvelocity;
if(vlen(force) == 0)
force = '0 0 -1';
else
force = normalize(force);
if(forceintensity >= 0)
- Damage_DamageInfo(blastorigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
+ Damage_DamageInfo(inflictororigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
else
- Damage_DamageInfo(blastorigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
+ Damage_DamageInfo(inflictororigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
}
stat_damagedone = 0;
- targ = WarpZone_FindRadius (blastorigin, rad + MAX_DAMAGEEXTRARADIUS, FALSE);
+ targ = WarpZone_FindRadius (inflictororigin, rad + MAX_DAMAGEEXTRARADIUS, FALSE);
while (targ)
{
next = targ.chain;
- if (targ != inflictor)
- if (ignore != targ) if(targ.takedamage)
+ if ((targ != inflictor) || inflictorselfdamage)
+ if (((cantbe != targ) && !mustbe) || (mustbe == targ))
+ if (targ.takedamage)
+ {
+ vector nearest;
+ vector diff;
+ float power;
+
+ // LordHavoc: measure distance to nearest point on target (not origin)
+ // (this guarentees 100% damage on a touch impact)
+ nearest = targ.WarpZone_findradius_nearest;
+ diff = targ.WarpZone_findradius_dist;
+ // round up a little on the damage to ensure full damage on impacts
+ // and turn the distance into a fraction of the radius
+ power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
+ //bprint(" ");
+ //bprint(ftos(power));
+ //if (targ == attacker)
+ // print(ftos(power), "\n");
+ if (power > 0)
{
- vector nearest;
- vector diff;
- float power;
-
- // LordHavoc: measure distance to nearest point on target (not origin)
- // (this guarentees 100% damage on a touch impact)
- nearest = targ.WarpZone_findradius_nearest;
- diff = targ.WarpZone_findradius_dist;
- // round up a little on the damage to ensure full damage on impacts
- // and turn the distance into a fraction of the radius
- power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
- //bprint(" ");
- //bprint(ftos(power));
- //if (targ == attacker)
- // print(ftos(power), "\n");
- if (power > 0)
+ float finaldmg;
+ if (power > 1)
+ power = 1;
+ finaldmg = coredamage * power + edgedamage * (1 - power);
+ if (finaldmg > 0)
{
- float finaldmg;
- if (power > 1)
- power = 1;
- finaldmg = coredamage * power + edgedamage * (1 - power);
- if (finaldmg > 0)
- {
- float a;
- float c;
- vector hitloc;
- vector myblastorigin;
- vector center;
+ float a;
+ float c;
+ vector hitloc;
+ vector myblastorigin;
+ vector center;
- myblastorigin = WarpZone_TransformOrigin(targ, blastorigin);
+ myblastorigin = WarpZone_TransformOrigin(targ, inflictororigin);
- // if it's a player, use the view origin as reference
- if (targ.classname == "player")
- center = targ.origin + targ.view_ofs;
- else
- center = targ.origin + (targ.mins + targ.maxs) * 0.5;
+ // if it's a player, use the view origin as reference
+ if (targ.classname == "player")
+ center = targ.origin + targ.view_ofs;
+ else
+ center = targ.origin + (targ.mins + targ.maxs) * 0.5;
- force = normalize(center - myblastorigin);
- force = force * (finaldmg / coredamage) * forceintensity;
- hitloc = nearest;
+ force = normalize(center - myblastorigin);
+ force = force * (finaldmg / coredamage) * forceintensity;
+ hitloc = nearest;
- if(targ != directhitentity)
- {
- float hits;
- float total;
- float hitratio;
- float mininv_f, mininv_d;
+ if(targ != directhitentity)
+ {
+ float hits;
+ float total;
+ float hitratio;
+ float mininv_f, mininv_d;
- // test line of sight to multiple positions on box,
- // and do damage if any of them hit
- hits = 0;
+ // test line of sight to multiple positions on box,
+ // and do damage if any of them hit
+ hits = 0;
- // we know: max stddev of hitratio = 1 / (2 * sqrt(n))
- // so for a given max stddev:
- // n = (1 / (2 * max stddev of hitratio))^2
+ // we know: max stddev of hitratio = 1 / (2 * sqrt(n))
+ // so for a given max stddev:
+ // n = (1 / (2 * max stddev of hitratio))^2
- mininv_d = (finaldmg * (1-tfloordmg)) / autocvar_g_throughfloor_damage_max_stddev;
- mininv_f = (vlen(force) * (1-tfloorforce)) / autocvar_g_throughfloor_force_max_stddev;
+ mininv_d = (finaldmg * (1-tfloordmg)) / autocvar_g_throughfloor_damage_max_stddev;
+ mininv_f = (vlen(force) * (1-tfloorforce)) / autocvar_g_throughfloor_force_max_stddev;
- if(autocvar_g_throughfloor_debug)
- print(sprintf("THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg, vlen(force), mininv_d, mininv_f));
+ if(autocvar_g_throughfloor_debug)
+ print(sprintf("THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg, vlen(force), mininv_d, mininv_f));
- total = 0.25 * pow(max(mininv_f, mininv_d), 2);
+ total = 0.25 * pow(max(mininv_f, mininv_d), 2);
- if(autocvar_g_throughfloor_debug)
- print(sprintf(" steps=%f", total));
+ if(autocvar_g_throughfloor_debug)
+ print(sprintf(" steps=%f", total));
- if (targ.classname == "player")
- total = ceil(bound(autocvar_g_throughfloor_min_steps_player, total, autocvar_g_throughfloor_max_steps_player));
- else
- total = ceil(bound(autocvar_g_throughfloor_min_steps_other, total, autocvar_g_throughfloor_max_steps_other));
+ if (targ.classname == "player")
+ total = ceil(bound(autocvar_g_throughfloor_min_steps_player, total, autocvar_g_throughfloor_max_steps_player));
+ else
+ total = ceil(bound(autocvar_g_throughfloor_min_steps_other, total, autocvar_g_throughfloor_max_steps_other));
- if(autocvar_g_throughfloor_debug)
- print(sprintf(" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 * sqrt(total)), vlen(force) * (1-tfloorforce) / (2 * sqrt(total))));
+ if(autocvar_g_throughfloor_debug)
+ print(sprintf(" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 * sqrt(total)), vlen(force) * (1-tfloorforce) / (2 * sqrt(total))));
- for(c = 0; c < total; ++c)
+ for(c = 0; c < total; ++c)
+ {
+ //traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
+ WarpZone_TraceLine(inflictororigin, WarpZone_UnTransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
+ if (trace_fraction == 1 || trace_ent == targ)
{
- //traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
- WarpZone_TraceLine(blastorigin, WarpZone_UnTransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
- if (trace_fraction == 1 || trace_ent == targ)
- {
- ++hits;
- if (hits > 1)
- hitloc = hitloc + nearest;
- else
- hitloc = nearest;
- }
- nearest_x = targ.origin_x + targ.mins_x + random() * targ.size_x;
- nearest_y = targ.origin_y + targ.mins_y + random() * targ.size_y;
- nearest_z = targ.origin_z + targ.mins_z + random() * targ.size_z;
+ ++hits;
+ if (hits > 1)
+ hitloc = hitloc + nearest;
+ else
+ hitloc = nearest;
}
+ nearest_x = targ.origin_x + targ.mins_x + random() * targ.size_x;
+ nearest_y = targ.origin_y + targ.mins_y + random() * targ.size_y;
+ nearest_z = targ.origin_z + targ.mins_z + random() * targ.size_z;
+ }
- nearest = hitloc * (1 / max(1, hits));
- hitratio = (hits / total);
- a = bound(0, tfloordmg + (1-tfloordmg) * hitratio, 1);
- finaldmg = finaldmg * a;
- a = bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1);
- force = force * a;
+ nearest = hitloc * (1 / max(1, hits));
+ hitratio = (hits / total);
+ a = bound(0, tfloordmg + (1-tfloordmg) * hitratio, 1);
+ finaldmg = finaldmg * a;
+ a = bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1);
+ force = force * a;
- if(autocvar_g_throughfloor_debug)
- print(sprintf(" D=%f F=%f\n", finaldmg, vlen(force)));
- }
+ if(autocvar_g_throughfloor_debug)
+ print(sprintf(" D=%f F=%f\n", finaldmg, vlen(force)));
+ }
- // laser force adjustments :P
- if(DEATH_WEAPONOF(deathtype) == WEP_LASER)
+ // laser force adjustments :P
+ if(DEATH_WEAPONOF(deathtype) == WEP_LASER)
+ {
+ if (targ == attacker)
{
- if (targ == attacker)
+ vector vel;
+
+ float force_zscale;
+ float force_velocitybiasramp;
+ float force_velocitybias;
+
+ force_velocitybiasramp = autocvar_sv_maxspeed;
+ if(deathtype & HITTYPE_SECONDARY)
{
- vector vel;
-
- float force_zscale;
- float force_velocitybiasramp;
- float force_velocitybias;
-
- force_velocitybiasramp = autocvar_sv_maxspeed;
- if(deathtype & HITTYPE_SECONDARY)
- {
- force_zscale = autocvar_g_balance_laser_secondary_force_zscale;
- force_velocitybias = autocvar_g_balance_laser_secondary_force_velocitybias;
- }
- else
- {
- force_zscale = autocvar_g_balance_laser_primary_force_zscale;
- force_velocitybias = autocvar_g_balance_laser_primary_force_velocitybias;
- }
-
- vel = targ.velocity;
- vel_z = 0;
- vel = normalize(vel) * bound(0, vlen(vel) / force_velocitybiasramp, 1) * force_velocitybias;
- force =
- vlen(force)
- *
- normalize(normalize(force) + vel);
-
- force_z *= force_zscale;
+ force_zscale = autocvar_g_balance_laser_secondary_force_zscale;
+ force_velocitybias = autocvar_g_balance_laser_secondary_force_velocitybias;
}
else
{
- if(deathtype & HITTYPE_SECONDARY)
- {
- force *= autocvar_g_balance_laser_secondary_force_other_scale;
- }
- else
- {
- force *= autocvar_g_balance_laser_primary_force_other_scale;
- }
+ force_zscale = autocvar_g_balance_laser_primary_force_zscale;
+ force_velocitybias = autocvar_g_balance_laser_primary_force_velocitybias;
}
- }
- //if (targ == attacker)
- //{
- // print("hits ", ftos(hits), " / ", ftos(total));
- // print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
- // print(" (", ftos(a), ")\n");
- //}
- if(finaldmg || vlen(force))
+ vel = targ.velocity;
+ vel_z = 0;
+ vel = normalize(vel) * bound(0, vlen(vel) / force_velocitybiasramp, 1) * force_velocitybias;
+ force =
+ vlen(force)
+ *
+ normalize(normalize(force) + vel);
+
+ force_z *= force_zscale;
+ }
+ else
{
- if(targ.iscreature)
+ if(deathtype & HITTYPE_SECONDARY)
{
- total_damage_to_creatures += finaldmg;
-
- if(accuracy_isgooddamage(attacker, targ))
- stat_damagedone += finaldmg;
+ force *= autocvar_g_balance_laser_secondary_force_other_scale;
}
-
- if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
- Damage (targ, inflictor, attacker, finaldmg, deathtype, nearest, force);
else
- Damage (targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, nearest, force);
+ {
+ force *= autocvar_g_balance_laser_primary_force_other_scale;
+ }
}
}
+
+ //if (targ == attacker)
+ //{
+ // print("hits ", ftos(hits), " / ", ftos(total));
+ // print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
+ // print(" (", ftos(a), ")\n");
+ //}
+ if(finaldmg || vlen(force))
+ {
+ if(targ.iscreature)
+ {
+ total_damage_to_creatures += finaldmg;
+
+ if(accuracy_isgooddamage(attacker, targ))
+ stat_damagedone += finaldmg;
+ }
+
+ if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
+ Damage (targ, inflictor, attacker, finaldmg, deathtype, nearest, force);
+ else
+ Damage (targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, nearest, force);
+ }
}
}
+ }
targ = next;
}
return total_damage_to_creatures;
}
+float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, float deathtype, entity directhitentity)
+{
+ return RadiusDamageForSource (inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, cantbe, mustbe, FALSE, forceintensity, deathtype, directhitentity);
+}
+
.float fire_damagepersec;
.float fire_endtime;
.float fire_deathtype;
// LEMMA:
// Look at:
- // totaldamage = min(mindamage + d, maxdamage * maxdps)
+ // totaldamage = min(mindamage + d, maxtime * maxdps)
// We see:
- // totaldamage <= maxdamage * maxdps
+ // totaldamage <= maxtime * maxdps
// ==> totaldamage / maxdps <= maxtime.
// We also see:
// totaldamage / mindps = min(mindamage / mindps + d, maxtime * maxdps / mindps)
#ifdef TURRET_DEBUG
float d;
- d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, self.owner.shot_force, self.totalfrags, world);
+ d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
#else
- RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, self.owner.shot_force, self.totalfrags, world);
+ RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
#endif
remove(self);
}
pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
proj.think = turret_flac_projectile_think_explode;
proj.nextthink = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
-
+ proj.missile_flags = MIF_SPLASH | MIF_PROXY;
+
self.tur_head.frame = self.tur_head.frame + 1;
if (self.tur_head.frame >= 4)
self.tur_head.frame = 0;
}
void walker_rocket_explode()
{
- RadiusDamage (self, self.owner, autocvar_g_turrets_unit_walker_std_rocket_dmg, 0, autocvar_g_turrets_unit_walker_std_rocket_radius, self, autocvar_g_turrets_unit_walker_std_rocket_force, DEATH_TURRET_WALKER_ROCKET, world);
+ RadiusDamage (self, self.owner, autocvar_g_turrets_unit_walker_std_rocket_dmg, 0, autocvar_g_turrets_unit_walker_std_rocket_radius, self, world, autocvar_g_turrets_unit_walker_std_rocket_force, DEATH_TURRET_WALKER_ROCKET, world);
remove (self);
}
rocket.tur_shotorg = randomvec() * 512;
rocket.cnt = time + 1;
rocket.enemy = self.enemy;
-
+
if (random() < 0.01)
rocket.think = walker_rocket_loop;
else
rocket.flags = FL_PROJECTILE;
rocket.solid = SOLID_BBOX;
rocket.tur_health = time + 9;
-
+ rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
+
CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
}
player.vehicle_reload1 = bound(0, 100 * ((time - racer.lip) / (racer.delay - racer.lip)), 100);
if(racer.vehicle_flags & VHF_SHIELDREGEN)
- vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime);
+ vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime, TRUE);
if(racer.vehicle_flags & VHF_HEALTHREGEN)
- vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime);
+ vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime, FALSE);
if(racer.vehicle_flags & VHF_ENERGYREGEN)
- vehicles_regen(wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime);
+ vehicles_regen(wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime, FALSE);
VEHICLE_UPDATE_PLAYER(health, racer);
self.deadflag = DEAD_DEAD;
self.vehicle_exit(VHEF_NORMAL);
- RadiusDamage (self, self, autocvar_g_vehicle_racer_blowup_coredamage,
+ RadiusDamage (self, self.enemy, autocvar_g_vehicle_racer_blowup_coredamage,
autocvar_g_vehicle_racer_blowup_edgedamage,
- autocvar_g_vehicle_racer_blowup_radius, world,
+ autocvar_g_vehicle_racer_blowup_radius, world, world,
autocvar_g_vehicle_racer_blowup_forceintensity,
DEATH_WAKIBLOWUP, world);
racer_frame,
racer_enter, racer_exit,
racer_die, racer_think,
- TRUE))
+ TRUE,
+ autocvar_g_vehicle_racer_health))
{
remove(self);
return;
- #ifdef SVQC
+ #define RSM_FIRST 0
+ #define RSM_BOMB 0
+ #define RSM_FLARE 1
+ #define RSM_LAST 1
+
#define RAPTOR_MIN '-80 -80 0'
#define RAPTOR_MAX '80 80 70'
+ #ifdef SVQC
float autocvar_g_vehicle_raptor_respawntime;
+ float autocvar_g_vehicle_raptor_takeofftime;
float autocvar_g_vehicle_raptor_movestyle;
float autocvar_g_vehicle_raptor_turnspeed;
float autocvar_g_vehicle_raptor_bomblet_explode_delay;
float autocvar_g_vehicle_raptor_bombs_refire;
+ float autocvar_g_vehicle_raptor_flare_refire;
+ float autocvar_g_vehicle_raptor_flare_lifetime;
+ float autocvar_g_vehicle_raptor_flare_chase;
+ float autocvar_g_vehicle_raptor_flare_range;
+
float autocvar_g_vehicle_raptor_cannon_turnspeed;
float autocvar_g_vehicle_raptor_cannon_turnlimit;
float autocvar_g_vehicle_raptor_cannon_pitchlimit_up;
{
RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_bomblet_damage,
autocvar_g_vehicle_raptor_bomblet_edgedamage,
- autocvar_g_vehicle_raptor_bomblet_radius, world,
+ autocvar_g_vehicle_raptor_bomblet_radius, world, world,
autocvar_g_vehicle_raptor_bomblet_force, DEATH_RAPTOR_BOMB, world);
remove(self);
}
if(self.owner.flagcarried)
setorigin(self.owner.flagcarried, '-20 0 96');
-
+
+ CSQCVehicleSetup(self.owner, 0);
}
void raptor_land()
// Takeoff sequense
if(raptor.frame < 25)
{
- raptor.frame += 0.25;
+ raptor.frame += 25 / (autocvar_g_vehicle_raptor_takeofftime / sys_frametime);
raptor.velocity_z = min(raptor.velocity_z * 1.5, 256);
self.bomb1.gun1.avelocity_y = 90 + ((raptor.frame / 25) * 25000);
self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y;
player.PlayerPhysplug = raptor_frame;
if(self.vehicle_flags & VHF_SHIELDREGEN)
- vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime);
+ vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime, TRUE);
if(self.vehicle_flags & VHF_HEALTHREGEN)
- vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime);
+ vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime, FALSE);
if(self.vehicle_flags & VHF_ENERGYREGEN)
- vehicles_regen(cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime);
+ vehicles_regen(cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime, FALSE);
raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip);
return 1;
}
+ void raptor_flare_touch()
+ {
+ remove(self);
+ }
+
+ void raptor_flare_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+ {
+ self.health -= damage;
+ if(self.health <= 0)
+ remove(self);
+ }
+
+ void raptor_flare_think()
+ {
+ self.nextthink = time + 0.1;
+ entity _missile = findchainentity(enemy, self.owner);
+ while(_missile)
+ {
+ if(_missile.flags & FL_PROJECTILE)
+ if(vlen(self.origin - _missile.origin) < autocvar_g_vehicle_raptor_flare_range)
+ if(random() > autocvar_g_vehicle_raptor_flare_chase)
+ _missile.enemy = self;
+ _missile = _missile.chain;
+ }
+
+ if(self.tur_impacttime < time)
+ remove(self);
+ }
+
float raptor_frame()
{
entity player, raptor;
- float ftmp = 0, ftmp2;
+ float ftmp = 0;
vector df;
if(intermission_running)
}
}
- // Aim the gunz
- ftmp2 = autocvar_g_vehicle_raptor_cannon_turnspeed * frametime;
- ftmp = -ftmp2;
-
- // Gun1
- df = gettaginfo(raptor.gun1, gettagindex(raptor.gun1, "fire1"));
- //ad = df;
- //vf = v_forward;
- df = vectoangles(normalize(trace_endpos - df)); // Find the direction & angle
- df = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(raptor.angles), AnglesTransform_FromAngles(df))) - raptor.gun1.angles;
- df = shortangle_vxy(df, raptor.gun1.angles);
-
- // Bind to aimspeed
- df_x = bound(ftmp, df_x, ftmp2);
- df_y = bound(ftmp, df_y, ftmp2);
- // Bind to limts
- raptor.gun1.angles_x = bound(-autocvar_g_vehicle_raptor_cannon_pitchlimit_down, df_x + raptor.gun1.angles_x, autocvar_g_vehicle_raptor_cannon_pitchlimit_up);
- raptor.gun1.angles_y = bound(-autocvar_g_vehicle_raptor_cannon_turnlimit, df_y + raptor.gun1.angles_y, autocvar_g_vehicle_raptor_cannon_turnlimit);
-
- // Gun2
- df = gettaginfo(raptor.gun2, gettagindex(raptor.gun2, "fire1"));
- //ad += df;
- //vf += v_forward;
- df = vectoangles(normalize(trace_endpos - df)); // Find the direction & angle
- df = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(raptor.angles), AnglesTransform_FromAngles(df))) - raptor.gun2.angles;
- df = shortangle_vxy(df, raptor.gun2.angles);
-
- // Bind to aimspeed
- df_x = bound(ftmp, df_x, ftmp2);
- df_y = bound(ftmp, df_y, ftmp2);
- // Bind to limts
- raptor.gun2.angles_x = bound(-autocvar_g_vehicle_raptor_cannon_pitchlimit_down, df_x + raptor.gun2.angles_x, autocvar_g_vehicle_raptor_cannon_pitchlimit_up);
- raptor.gun2.angles_y = bound(-autocvar_g_vehicle_raptor_cannon_turnlimit, df_y + raptor.gun2.angles_y, autocvar_g_vehicle_raptor_cannon_turnlimit);
+
+ vehicle_aimturret(raptor, trace_endpos, raptor.gun1, "fire1",
+ autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1, autocvar_g_vehicle_raptor_cannon_pitchlimit_up,
+ autocvar_g_vehicle_raptor_cannon_turnlimit * -1, autocvar_g_vehicle_raptor_cannon_turnlimit, autocvar_g_vehicle_raptor_cannon_turnspeed);
+
+ vehicle_aimturret(raptor, trace_endpos, raptor.gun2, "fire1",
+ autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1, autocvar_g_vehicle_raptor_cannon_pitchlimit_up,
+ autocvar_g_vehicle_raptor_cannon_turnlimit * -1, autocvar_g_vehicle_raptor_cannon_turnlimit, autocvar_g_vehicle_raptor_cannon_turnspeed);
/*
ad = ad * 0.5;
}
if(self.vehicle_flags & VHF_SHIELDREGEN)
- vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime);
+ vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime, TRUE);
if(self.vehicle_flags & VHF_HEALTHREGEN)
- vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime);
+ vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime, FALSE);
if(self.vehicle_flags & VHF_ENERGYREGEN)
- vehicles_regen(cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime);
-
+ vehicles_regen(cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime, FALSE);
- if(time > raptor.delay)
- if(player.BUTTON_ATCK2)
+ if(raptor.vehicle_weapon2mode == RSM_BOMB)
{
- raptor_bombdrop();
- raptor.delay = time + autocvar_g_vehicle_raptor_bombs_refire;
- raptor.lip = time;
+ if(time > raptor.lip + autocvar_g_vehicle_raptor_bombs_refire)
+ if(player.BUTTON_ATCK2)
+ {
+ raptor_bombdrop();
+ raptor.delay = time + autocvar_g_vehicle_raptor_bombs_refire;
+ raptor.lip = time;
+ }
}
-
+ else
+ {
+ if(time > raptor.lip + autocvar_g_vehicle_raptor_flare_refire)
+ if(player.BUTTON_ATCK2)
+ {
+ float i;
+ entity _flare;
+
+ for(i = 0; i < 3; ++i)
+ {
+ _flare = spawn();
+ setmodel(_flare, "models/runematch/rune.mdl");
+ _flare.effects = EF_LOWPRECISION | EF_FLAME;
+ _flare.scale = 0.5;
+ setorigin(_flare, self.origin - '0 0 16');
+ _flare.movetype = MOVETYPE_TOSS;
+ _flare.gravity = 0.15;
+ _flare.velocity = 0.25 * raptor.velocity + (v_forward + randomvec() * 0.25)* -500;
+ _flare.think = raptor_flare_think;
+ _flare.nextthink = time;
+ _flare.owner = raptor;
+ _flare.solid = SOLID_CORPSE;
+ _flare.takedamage = DAMAGE_YES;
+ _flare.event_damage = raptor_flare_damage;
+ _flare.health = 20;
+ _flare.tur_impacttime = time + autocvar_g_vehicle_raptor_flare_lifetime;
+ _flare.touch = raptor_flare_touch;
+ }
+ raptor.delay = time + autocvar_g_vehicle_raptor_flare_refire;
+ raptor.lip = time;
+ }
+ }
+
raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip);
player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100);
+ if(self.bomb1.cnt < time)
+ {
+ entity _missile = findchainentity(enemy, raptor);
+ float _incomming = 0;
+ while(_missile)
+ {
+ if(_missile.flags & FL_PROJECTILE)
+ if(MISSILE_IS_TRACKING(_missile))
+ if(vlen(self.origin - _missile.origin) < 2 * autocvar_g_vehicle_raptor_flare_range)
+ ++_incomming;
+
+ _missile = _missile.chain;
+ }
+
+ if(_incomming)
+ sound(self, CH_PAIN_SINGLE, "vehicles/missile_alarm.wav", VOL_BASE, ATTN_NONE);
+
+ self.bomb1.cnt = time + 1;
+ }
+
+
VEHICLE_UPDATE_PLAYER(health, raptor);
VEHICLE_UPDATE_PLAYER(energy, raptor);
if(self.vehicle_flags & VHF_HASSHIELD)
{
self.deadflag = DEAD_DEAD;
self.vehicle_exit(VHEF_NORMAL);
- RadiusDamage (self, self, 250, 15, 250, world, world, 250, DEATH_WAKIBLOWUP, world);
- RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_WAKIBLOWUP, world);
++
++ RadiusDamage (self, self.enemy, 250, 15, 250, world, world, 250, DEATH_WAKIBLOWUP, world);
self.alpha = -1;
self.movetype = MOVETYPE_NONE;
self.gun2.angles_y = anglemods(self.gun2.angles_y);
self.nextthink = time + 15;
}
+ float raptor_impulse(float _imp)
+ {
+ switch(_imp)
+ {
+ case 10:
+ case 15:
+ case 18:
+ self.vehicle.vehicle_weapon2mode += 1;
+ if(self.vehicle.vehicle_weapon2mode > RSM_LAST)
+ self.vehicle.vehicle_weapon2mode = RSM_FIRST;
+
+ CSQCVehicleSetup(self, 0);
+ return TRUE;
+ case 12:
+ case 16:
+ case 19:
+ self.vehicle.vehicle_weapon2mode -= 1;
+ if(self.vehicle.vehicle_weapon2mode < RSM_FIRST)
+ self.vehicle.vehicle_weapon2mode = RSM_LAST;
+
+ CSQCVehicleSetup(self, 0);
+ return TRUE;
+
+ /*
+ case 17: // toss gun, could be used to exit?
+ break;
+ case 20: // Manual minigun reload?
+ break;
+ */
+ }
+ return FALSE;
+ }
void raptor_dinit()
{
raptor_frame,
raptor_enter, raptor_exit,
raptor_die, raptor_think,
- FALSE))
+ FALSE,
+ autocvar_g_vehicle_raptor_health))
{
remove(self);
return;
//FIXME: Camera is in a bad place in HUD model.
//setorigin(self.vehicle_viewport, '25 0 5');
-
+
+ self.vehicles_impusle = raptor_impulse;
+
self.frame = 0;
self.bomb1 = spawn();
setattachment(self.tur_head, self,"root");
- // FIXME Guns mounts to angled bones
+ // FIXMODEL Guns mounts to angled bones
self.bomb1.angles = self.angles;
self.angles = '0 0 0';
// This messes up gun-aim, so work arround it.
precache_sound ("vehicles/raptor_fly.wav");
precache_sound ("vehicles/raptor_speed.wav");
+ precache_sound ("vehicles/missile_alarm.wav");
self.think = raptor_dinit;
float autocvar_g_vehicle_spiderbot_speed_strafe;
float autocvar_g_vehicle_spiderbot_speed_walk;
float autocvar_g_vehicle_spiderbot_turnspeed;
+ float autocvar_g_vehicle_spiderbot_turnspeed_strafe;
float autocvar_g_vehicle_spiderbot_movement_inertia;
float autocvar_g_vehicle_spiderbot_springlength;
float autocvar_g_vehicle_spiderbot_springup;
float autocvar_g_vehicle_spiderbot_springblend;
+ float autocvar_g_vehicle_spiderbot_tiltlimit;
float autocvar_g_vehicle_spiderbot_head_pitchlimit_down;
float autocvar_g_vehicle_spiderbot_head_pitchlimit_up;
- float autocvar_g_vehicle_spiderbot_head_pitchspeed;
float autocvar_g_vehicle_spiderbot_head_turnlimit;
float autocvar_g_vehicle_spiderbot_head_turnspeed;
float autocvar_g_vehicle_spiderbot_minigun_ammo_max;
float autocvar_g_vehicle_spiderbot_minigun_ammo_regen;
float autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause;
+ float autocvar_g_vehicle_spiderbot_minigun_force;
+ float autocvar_g_vehicle_spiderbot_minigun_speed;
+ float autocvar_g_vehicle_spiderbot_minigun_bulletconstant;
float autocvar_g_vehicle_spiderbot_rocket_damage;
float autocvar_g_vehicle_spiderbot_rocket_force;
float autocvar_g_vehicle_spiderbot_rocket_radius;
float autocvar_g_vehicle_spiderbot_rocket_speed;
+ float autocvar_g_vehicle_spiderbot_rocket_spread;
float autocvar_g_vehicle_spiderbot_rocket_refire;
+ float autocvar_g_vehicle_spiderbot_rocket_refire2;
float autocvar_g_vehicle_spiderbot_rocket_reload;
float autocvar_g_vehicle_spiderbot_rocket_health;
float autocvar_g_vehicle_spiderbot_rocket_noise;
void spiderbot_exit(float eject);
void spiderbot_enter();
void spiderbot_spawn();
+ #define SBRM_FIRST 0
+ #define SBRM_VOLLY 0
+ #define SBRM_GUIDE 1
+ #define SBRM_ARTILLERY 2
+ #define SBRM_LAST 2
+
+ void spiderbot_rocket_artillery()
+ {
+ self.nextthink = time;
+ UpdateCSQCProjectile(self);
+ }
void spiderbot_rocket_unguided()
{
}
}
+ float spiberbot_calcartillery_flighttime;
+ vector spiberbot_calcartillery(vector org, vector tgt, float ht)
+ {
+ float grav, sdist, zdist, vs, vz, jumpheight;
+ vector sdir;
+
+ grav = autocvar_sv_gravity;
+ zdist = tgt_z - org_z;
+ sdist = vlen(tgt - org - zdist * '0 0 1');
+ sdir = normalize(tgt - org - zdist * '0 0 1');
+
+ // how high do we need to go?
+ jumpheight = fabs(ht);
+ if(zdist > 0)
+ jumpheight = jumpheight + zdist;
+
+ // push so high...
+ vz = sqrt(2 * grav * jumpheight); // NOTE: sqrt(positive)!
+
+ // we start with downwards velocity only if it's a downjump and the jump apex should be outside the jump!
+ if(ht < 0)
+ if(zdist < 0)
+ vz = -vz;
+
+ vector solution;
+ solution = solve_quadratic(0.5 * grav, -vz, zdist); // equation "z(ti) = zdist"
+ // ALWAYS solvable because jumpheight >= zdist
+ if(!solution_z)
+ solution_y = solution_x; // just in case it is not solvable due to roundoff errors, assume two equal solutions at their center (this is mainly for the usual case with ht == 0)
+ if(zdist == 0)
+ solution_x = solution_y; // solution_x is 0 in this case, so don't use it, but rather use solution_y (which will be sqrt(0.5 * jumpheight / grav), actually)
+
+ if(zdist < 0)
+ {
+ // down-jump
+ if(ht < 0)
+ {
+ // almost straight line type
+ // jump apex is before the jump
+ // we must take the larger one
+ spiberbot_calcartillery_flighttime = solution_y;
+ }
+ else
+ {
+ // regular jump
+ // jump apex is during the jump
+ // we must take the larger one too
+ spiberbot_calcartillery_flighttime = solution_y;
+ }
+ }
+ else
+ {
+ // up-jump
+ if(ht < 0)
+ {
+ // almost straight line type
+ // jump apex is after the jump
+ // we must take the smaller one
+ spiberbot_calcartillery_flighttime = solution_x;
+ }
+ else
+ {
+ // regular jump
+ // jump apex is during the jump
+ // we must take the larger one
+ spiberbot_calcartillery_flighttime = solution_y;
+ }
+ }
+ vs = sdist / spiberbot_calcartillery_flighttime;
+
+ // finally calculate the velocity
+ return sdir * vs + '0 0 1' * vz;
+ }
+
void spiderbot_rocket_do()
{
vector v;
entity rocket;
- if (self.owner.BUTTON_ATCK2)
- {
- if (self.wait == 1)
- if (self.tur_head.frame == 9 || self.tur_head.frame == 1)
+ if (self.wait != -10)
+ {
+ if (self.owner.BUTTON_ATCK2 && self.vehicle_weapon2mode == SBRM_GUIDE)
{
- if(self.gun2.cnt < time && self.tur_head.frame == 9)
- self.tur_head.frame = 1;
+ if (self.wait == 1)
+ if (self.tur_head.frame == 9 || self.tur_head.frame == 1)
+ {
+ if(self.gun2.cnt < time && self.tur_head.frame == 9)
+ self.tur_head.frame = 1;
- return;
+ return;
+ }
+ self.wait = 1;
}
- self.wait = 1;
- }
- else
- {
- if(self.wait)
- spiderbot_guide_release();
+ else
+ {
+ if(self.wait)
+ spiderbot_guide_release();
- self.wait = 0;
+ self.wait = 0;
+ }
}
-
+
if(self.gun2.cnt > time)
return;
if (self.tur_head.frame >= 9)
+ {
self.tur_head.frame = 1;
+ self.wait = 0;
+ }
+
+ if (self.wait != -10)
+ if not (self.owner.BUTTON_ATCK2)
+ return;
- if not (self.owner.BUTTON_ATCK2)
- return;
-
- crosshair_trace(self.owner);
v = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
- rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav",
- v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
- autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
- DEATH_SBROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, FALSE);
-
- rocket.cnt = time + 15;
+
+ switch(self.vehicle_weapon2mode)
+ {
+ case SBRM_VOLLY:
+ rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav",
+ v, normalize(randomvec() * autocvar_g_vehicle_spiderbot_rocket_spread + v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
+ autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
+ DEATH_SBROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, TRUE);
+ crosshair_trace(self.owner);
+ float _dist = (random() * autocvar_g_vehicle_spiderbot_rocket_radius) + vlen(v - trace_endpos);
+ _dist -= (random() * autocvar_g_vehicle_spiderbot_rocket_radius) ;
+ rocket.nextthink = time + (_dist / autocvar_g_vehicle_spiderbot_rocket_speed);
+ rocket.think = vehicles_projectile_explode;
+
+ if(self.owner.BUTTON_ATCK2 && self.tur_head.frame == 1)
+ self.wait = -10;
+ break;
+ case SBRM_GUIDE:
+ rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav",
+ v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
+ autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
+ DEATH_SBROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, FALSE);
+ crosshair_trace(self.owner);
+ rocket.pos1 = trace_endpos;
+ rocket.nextthink = time;
+ rocket.think = spiderbot_rocket_guided;
+
+
+ break;
+ case SBRM_ARTILLERY:
+ rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav",
+ v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
+ autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
+ DEATH_SBROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, TRUE);
+
+ crosshair_trace(self.owner);
+ rocket.pos1 = trace_endpos + randomvec() * (0.75 * autocvar_g_vehicle_spiderbot_rocket_radius);
+ rocket.pos1_z = trace_endpos_z;
+ traceline(v, v + '0 0 1' * MAX_SHOT_DISTANCE, MOVE_WORLDONLY, self);
+
+ rocket.velocity = spiberbot_calcartillery(v, rocket.pos1, (0.75 * vlen(v - trace_endpos)));
+ rocket.movetype = MOVETYPE_TOSS;
+ rocket.gravity = 1;
+ //rocket.think = spiderbot_rocket_artillery;
+ break;
+ }
rocket.classname = "spiderbot_rocket";
- rocket.pos1 = trace_endpos;
- rocket.think = spiderbot_rocket_guided;
- rocket.nextthink = time;
- rocket.cnt = time + autocvar_g_vehicle_spiderbot_rocket_lifetime;
-
+
+ rocket.cnt = time + autocvar_g_vehicle_spiderbot_rocket_lifetime;
+
self.tur_head.frame += 1;
if (self.tur_head.frame == 9)
self.attack_finished_single = autocvar_g_vehicle_spiderbot_rocket_reload;
else
- self.attack_finished_single = autocvar_g_vehicle_spiderbot_rocket_refire;
+ self.attack_finished_single = ((self.vehicle_weapon2mode == SBRM_VOLLY) ? autocvar_g_vehicle_spiderbot_rocket_refire2 : autocvar_g_vehicle_spiderbot_rocket_refire);
self.gun2.cnt = time + self.attack_finished_single;
}
player.BUTTON_CROUCH = 0;
player.switchweapon = 0;
+ if(player.impulse == 12)
+ {
+ dprint("WOOOOOOOOOOOtotototototOOOOOOOOOOOOttt\n");
+ }
+
+
#if 1 // 0 to enable per-gun impact aux crosshairs
// Avarage gun impact point's -> aux cross
ad = gettaginfo(spider.tur_head, gettagindex(spider.tur_head, "tag_hardpoint01"));
//UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload2) + ('0 1 0' * (1 - player.vehicle_reload2)), 2);
// Rotate head
- ftmp = autocvar_g_vehicle_spiderbot_head_turnspeed * sys_frametime;
+ ftmp = autocvar_g_vehicle_spiderbot_head_turnspeed * sys_frametime;
ad_y = bound(-ftmp, ad_y, ftmp);
spider.tur_head.angles_y = bound(autocvar_g_vehicle_spiderbot_head_turnlimit * -1, spider.tur_head.angles_y + ad_y, autocvar_g_vehicle_spiderbot_head_turnlimit);
// Pitch head
- ftmp = autocvar_g_vehicle_spiderbot_head_pitchspeed * sys_frametime;
ad_x = bound(ftmp * -1, ad_x, ftmp);
spider.tur_head.angles_x = bound(autocvar_g_vehicle_spiderbot_head_pitchlimit_down, spider.tur_head.angles_x + ad_x, autocvar_g_vehicle_spiderbot_head_pitchlimit_up);
- // Turn Body
- ftmp = autocvar_g_vehicle_spiderbot_turnspeed * sys_frametime;
- ftmp = bound(-ftmp, spider.tur_head.angles_y, ftmp);
//fixedmakevectors(spider.angles);
makevectors(spider.angles + '-2 0 0' * spider.angles_x);
- movelib_groundalign4point(autocvar_g_vehicle_spiderbot_springlength, autocvar_g_vehicle_spiderbot_springup, autocvar_g_vehicle_spiderbot_springblend);
+ movelib_groundalign4point(autocvar_g_vehicle_spiderbot_springlength, autocvar_g_vehicle_spiderbot_springup, autocvar_g_vehicle_spiderbot_springblend, autocvar_g_vehicle_spiderbot_tiltlimit);
if(spider.flags & FL_ONGROUND)
{
}
else
{
+ // Turn Body
+ if(player.movement_x == 0 && player.movement_y != 0)
+ ftmp = autocvar_g_vehicle_spiderbot_turnspeed_strafe * sys_frametime;
+ else
+ ftmp = autocvar_g_vehicle_spiderbot_turnspeed * sys_frametime;
+
+ ftmp = bound(-ftmp, spider.tur_head.angles_y, ftmp);
spider.angles_y = anglemods(spider.angles_y + ftmp);
spider.tur_head.angles_y -= ftmp;
}
}
- self.angles_x = bound(-45, self.angles_x, 45);
- self.angles_z = bound(-45, self.angles_z, 45);
+ self.angles_x = bound(-autocvar_g_vehicle_spiderbot_tiltlimit, self.angles_x, autocvar_g_vehicle_spiderbot_tiltlimit);
+ self.angles_z = bound(-autocvar_g_vehicle_spiderbot_tiltlimit, self.angles_z, autocvar_g_vehicle_spiderbot_tiltlimit);
if(player.BUTTON_ATCK)
{
v_forward = normalize(v_forward);
v += v_forward * 50;
- fireBullet (v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_damage,
- autocvar_g_vehicle_spiderbot_minigun_spread, DEATH_SBMINIGUN, 0);
+ //void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float headshotbonus, float force, float dtype, float tracereffects, float gravityfactor, float bulletconstant)
+
+ fireBallisticBullet(v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_speed,
+ 5, autocvar_g_vehicle_spiderbot_minigun_damage, 0, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_SBMINIGUN, 0, 1, autocvar_g_vehicle_spiderbot_minigun_bulletconstant);
+ endFireBallisticBullet();
+
+ // fireBullet (v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_damage,
+ // autocvar_g_vehicle_spiderbot_minigun_spread, DEATH_SBMINIGUN, 0);
sound (gun, CH_WEAPON_A, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
- trailparticles(self, particleeffectnum("spiderbot_minigun_trail"), v, trace_endpos);
+ //trailparticles(self, particleeffectnum("spiderbot_minigun_trail"), v, trace_endpos);
pointparticles(particleeffectnum("spiderbot_minigun_muzzleflash"), v, v_forward * 2500, 1);
self = spider;
else
vehicles_regen(cnt, vehicle_ammo1, autocvar_g_vehicle_spiderbot_minigun_ammo_max,
autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause,
- autocvar_g_vehicle_spiderbot_minigun_ammo_regen, frametime);
+ autocvar_g_vehicle_spiderbot_minigun_ammo_regen, frametime, FALSE);
spiderbot_rocket_do();
if(self.vehicle_flags & VHF_SHIELDREGEN)
- vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_spiderbot_shield, autocvar_g_vehicle_spiderbot_shield_regen_pause, autocvar_g_vehicle_spiderbot_shield_regen, frametime);
+ vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_spiderbot_shield, autocvar_g_vehicle_spiderbot_shield_regen_pause, autocvar_g_vehicle_spiderbot_shield_regen, frametime, TRUE);
if(self.vehicle_flags & VHF_HEALTHREGEN)
- vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_spiderbot_health, autocvar_g_vehicle_spiderbot_health_regen_pause, autocvar_g_vehicle_spiderbot_health_regen, frametime);
+ vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_spiderbot_health, autocvar_g_vehicle_spiderbot_health_regen_pause, autocvar_g_vehicle_spiderbot_health_regen, frametime, FALSE);
player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
player.vehicle_ammo2 = spider.tur_head.frame;
void spiderbot_enter()
{
self.movetype = MOVETYPE_WALK;
-
+ CSQCVehicleSetup(self.owner, 0);
self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_spiderbot_health) * 100;
self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_spiderbot_shield) * 100;
SUB_SetFade(g1, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10));
SUB_SetFade(g2, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10));
- RadiusDamage (self, self, 250, 15, 250, world, world, 250, DEATH_SBBLOWUP, world);
- RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_SBBLOWUP, world);
++ RadiusDamage (self, self.enemy, 250, 15, 250, world, world, 250, DEATH_SBBLOWUP, world);
self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = -1;
self.movetype = MOVETYPE_NONE;
self.movetype = MOVETYPE_TOSS;
}
+ float spiderbot_impulse(float _imp)
+ {
+ switch(_imp)
+ {
+ case 10:
+ case 15:
+ case 18:
+ self.vehicle.vehicle_weapon2mode += 1;
+ if(self.vehicle.vehicle_weapon2mode > SBRM_LAST)
+ self.vehicle.vehicle_weapon2mode = SBRM_FIRST;
+
+ //centerprint(self, strcat("Rocket mode is ", ftos(self.vehicle.vehicle_weapon2mode)));
+ CSQCVehicleSetup(self, 0);
+ return TRUE;
+ case 12:
+ case 16:
+ case 19:
+ self.vehicle.vehicle_weapon2mode -= 1;
+ if(self.vehicle.vehicle_weapon2mode < SBRM_FIRST)
+ self.vehicle.vehicle_weapon2mode = SBRM_LAST;
+
+ //centerprint(self, strcat("Rocket mode is ", ftos(self.vehicle.vehicle_weapon2mode)));
+ CSQCVehicleSetup(self, 0);
+ return TRUE;
+
+ /*
+ case 17: // toss gun, could be used to exit?
+ break;
+ case 20: // Manual minigun reload?
+ break;
+ */
+ }
+ return FALSE;
+ }
+
void vewhicle_spiderbot_dinit()
{
if not (vehicle_initialize(
spiderbot_frame,
spiderbot_enter, spiderbot_exit,
spiderbot_die, spiderbot_think,
- FALSE))
+ FALSE,
+ autocvar_g_vehicle_spiderbot_health))
{
remove(self);
return;
self.gun1 = spawn();
self.gun2 = spawn();
-
+
+ self.vehicles_impusle = spiderbot_impulse;
+
setmodel(self.gun1, "models/vehicles/spiderbot_barrels.dpm");
setmodel(self.gun2, "models/vehicles/spiderbot_barrels.dpm");
float autocvar_g_vehicles_delayspawn_jitter;
float autocvar_g_vehicles_allow_flagcarry;
+ float autocvar_g_vehicles_nex_damagerate = 0.5;
+ float autocvar_g_vehicles_uzi_damagerate = 0.5;
+ float autocvar_g_vehicles_rifle_damagerate = 0.75;
+ float autocvar_g_vehicles_minstanex_damagerate = 0.001;
+
+
void vehicles_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
void vehicles_return();
void vehicles_enter();
WriteByte(MSG_ONE, SVC_TEMPENTITY);
WriteByte(MSG_ONE, TE_CSQC_VEHICLESETUP);
- WriteByte(MSG_ONE, vehicle_id);
+ if(vehicle_id != 0)
+ WriteByte(MSG_ONE, vehicle_id);
+ else
+ WriteByte(MSG_ONE, 1 + own.vehicle.vehicle_weapon2mode + HUD_VEHICLE_LAST);
}
/** vehicles_locktarget
}
return self.origin;
}
+
+ #if 0
void targetdrone_think();
void targetdrone_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
void targetdrone_renwe()
{
self.nextthink = time + 0.1;
- if(self.enemy)
- if(self.enemy.deadflag != DEAD_NO)
- self.enemy = targetdrone_getfear();
+ if(self.wp00)
+ if(self.wp00.deadflag != DEAD_NO)
+ self.wp00 = targetdrone_getfear();
- if(!self.enemy)
- self.enemy = targetdrone_getfear();
+ if(!self.wp00)
+ self.wp00 = targetdrone_getfear();
vector newdir;
- if(self.enemy)
- newdir = steerlib_push(self.enemy.origin) + randomvec() * 0.75;
+ if(self.wp00)
+ newdir = steerlib_push(self.wp00.origin) + randomvec() * 0.75;
else
newdir = randomvec() * 0.75;
newdir = newdir * 0.5 + normalize(self.velocity) * 0.5;
- if(self.enemy)
- self.velocity = normalize(newdir) * (500 + (1024 / min(vlen(self.enemy.origin - self.origin), 1024)) * 700);
+ if(self.wp00)
+ self.velocity = normalize(newdir) * (500 + (1024 / min(vlen(self.wp00.origin - self.origin), 1024)) * 700);
else
self.velocity = normalize(newdir) * 750;
drone.nextthink = time + 0.1;
drone.cnt = _autorenew;
}
+ #endif
void vehicles_locktarget(float incr, float decr, float _lock_time)
{
self.think = self.use;
self.nextthink = time;
}
-
}
void vehicles_projectile_explode()
PROJECTILE_TOUCH;
self.event_damage = SUB_Null;
- RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, self.shot_force, self.totalfrags, other);
+ RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, world, self.shot_force, self.totalfrags, other);
remove (self);
}
}
- void vehicles_regen(.float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time)
+ void vehicles_regen(.float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale)
{
if(self.regen_field < field_max)
if(self.timer + rpause < time)
{
+ if(_healthscale)
+ regen = regen * (self.vehicle_health / self.tur_health);
+
self.regen_field = min(self.regen_field + regen * delta_time, field_max);
if(self.owner)
void vehicles_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
self.dmg_time = time;
-
+
+ if(DEATH_ISWEAPON(deathtype, WEP_NEX))
+ damage *= autocvar_g_vehicles_nex_damagerate;
+
+ if(DEATH_ISWEAPON(deathtype, WEP_UZI))
+ damage *= autocvar_g_vehicles_uzi_damagerate;
+
+ if(DEATH_ISWEAPON(deathtype, WEP_RIFLE))
+ damage *= autocvar_g_vehicles_rifle_damagerate;
+
+ if(DEATH_ISWEAPON(deathtype, WEP_MINSTANEX))
+ damage *= autocvar_g_vehicles_minstanex_damagerate;
+
+ self.enemy = attacker;
+
if((self.vehicle_flags & VHF_HASSHIELD) && (self.vehicle_shield > 0))
{
if (wasfreed(self.vehicle_shieldent) || self.vehicle_shieldent == world)
ret = findchain(classname, "vehicle_return");
while(ret)
{
- if(ret.enemy == self)
+ if(ret.wp00 == self)
{
ret.classname = "";
ret.think = SUB_Remove;
void vehicles_return()
{
- pointparticles(particleeffectnum("teleport"), self.enemy.origin + '0 0 64', '0 0 0', 1);
+ pointparticles(particleeffectnum("teleport"), self.wp00.origin + '0 0 64', '0 0 0', 1);
- self.enemy.think = vehicles_spawn;
- self.enemy.nextthink = time;
+ self.wp00.think = vehicles_spawn;
+ self.wp00.nextthink = time;
if(self.waypointsprite_attached)
WaypointSprite_Kill(self.waypointsprite_attached);
oldself = self;
self = spawn();
setmodel(self, "null");
- self.team = oldself.enemy.team;
- self.enemy = oldself.enemy;
- setorigin(self, oldself.enemy.pos1);
+ self.team = oldself.wp00.team;
+ self.wp00 = oldself.wp00;
+ setorigin(self, oldself.wp00.pos1);
self.nextthink = time + 5;
self.think = vehicles_showwp_goaway;
WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, TRUE, RADARICON_POWERUP, rgb);
if(self.waypointsprite_attached)
{
- WaypointSprite_UpdateRule(self.waypointsprite_attached, self.enemy.team, SPRITERULE_DEFAULT);
+ WaypointSprite_UpdateRule(self.waypointsprite_attached, self.wp00.team, SPRITERULE_DEFAULT);
if(oldself == world)
WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, self.nextthink);
WaypointSprite_Ping(self.waypointsprite_attached);
ret = spawn();
ret.classname = "vehicle_return";
- ret.enemy = self;
+ ret.wp00 = self;
ret.team = self.team;
ret.think = vehicles_showwp;
void(float extflag) exitfunc,
void() dieproc,
void() thinkproc,
- float use_csqc)
+ float use_csqc,
+ float _max_health)
{
addstat(STAT_HUD, AS_INT, hud);
addstat(STAT_VEHICLESTAT_HEALTH, AS_INT, vehicle_health);
self.iscreature = TRUE;
self.damagedbycontents = TRUE;
self.hud = vhud;
-
+ self.tur_health = _max_health;
self.vehicle_die = dieproc;
self.vehicle_exit = exitfunc;
self.vehicle_enter = enterproc;
return TRUE;
}
+ void vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname,
+ float _pichlimit_min, float _pichlimit_max,
+ float _rotlimit_min, float _rotlimit_max, float _aimspeed)
+ {
+ vector vtmp;
+ float ftmp;
+
+ vtmp = vectoangles(normalize(_target - gettaginfo(_turrret, gettagindex(_turrret, _tagname))));
+ vtmp = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(_vehic.angles), AnglesTransform_FromAngles(vtmp))) - _turrret.angles;
+ vtmp = AnglesTransform_Normalize(vtmp, TRUE);
+
+ ftmp = _aimspeed * sys_frametime;
+ vtmp_y = bound(-ftmp, vtmp_y, ftmp);
+ vtmp_x = bound(-ftmp, vtmp_x, ftmp);
+ _turrret.angles_y = bound(_rotlimit_min, _turrret.angles_y + vtmp_y, _rotlimit_max);
+ _turrret.angles_x = bound(_pichlimit_min, _turrret.angles_x + vtmp_x, _pichlimit_max);
+ }
+
+
void bugmenot()
{
self.vehicle_exit = self.vehicle_exit;
// create a small explosion to throw gibs around (if applicable)
//setorigin (explosion, hitloc);
- //RadiusDamage (explosion, self, 10, 0, 50, world, 300, deathtype);
+ //RadiusDamage (explosion, self, 10, 0, 50, world, world, 300, deathtype);
ent.railgunhitloc = '0 0 0';
ent.railgunhitsolidbackup = SOLID_NOT;
void W_BallisticBullet_Touch (void)
{
- float density;
+ //float density;
if(self.think == W_BallisticBullet_LeaveSolid_think) // skip this!
return;
void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float headshotbonus, float force, float dtype, float tracereffects, float gravityfactor, float bulletconstant)
{
- float lag, dt, savetime, density;
+ float lag, dt, savetime; //, density;
entity pl, oldself;
float antilagging;
e.realowner.crylink_lastgroup = world;
if(e.projectiledeathtype & HITTYPE_SECONDARY)
- RadiusDamage (e, e.realowner, autocvar_g_balance_crylink_secondary_damage * a, autocvar_g_balance_crylink_secondary_edgedamage * a, autocvar_g_balance_crylink_secondary_radius, world, autocvar_g_balance_crylink_secondary_force * a, e.projectiledeathtype, other);
+ RadiusDamage (e, e.realowner, autocvar_g_balance_crylink_secondary_damage * a, autocvar_g_balance_crylink_secondary_edgedamage * a, autocvar_g_balance_crylink_secondary_radius, world, world, autocvar_g_balance_crylink_secondary_force * a, e.projectiledeathtype, other);
else
- RadiusDamage (e, e.realowner, autocvar_g_balance_crylink_primary_damage * a, autocvar_g_balance_crylink_primary_edgedamage * a, autocvar_g_balance_crylink_primary_radius, world, autocvar_g_balance_crylink_primary_force * a, e.projectiledeathtype, other);
+ RadiusDamage (e, e.realowner, autocvar_g_balance_crylink_primary_damage * a, autocvar_g_balance_crylink_primary_edgedamage * a, autocvar_g_balance_crylink_primary_radius, world, world, autocvar_g_balance_crylink_primary_force * a, e.projectiledeathtype, other);
W_Crylink_LinkExplode(e.queuenext, e2);
n = n / autocvar_g_balance_crylink_secondary_shots;
RadiusDamage (e, e.realowner, autocvar_g_balance_crylink_secondary_joinexplode_damage * n,
autocvar_g_balance_crylink_secondary_joinexplode_edgedamage * n,
- autocvar_g_balance_crylink_secondary_joinexplode_radius * n, e.realowner,
+ autocvar_g_balance_crylink_secondary_joinexplode_radius * n, e.realowner, world,
autocvar_g_balance_crylink_secondary_joinexplode_force * n, e.projectiledeathtype, other);
pointparticles(particleeffectnum("crylink_joinexplode"), self.origin, '0 0 0', n);
n = n / autocvar_g_balance_crylink_primary_shots;
RadiusDamage (e, e.realowner, autocvar_g_balance_crylink_primary_joinexplode_damage * n,
autocvar_g_balance_crylink_primary_joinexplode_edgedamage * n,
- autocvar_g_balance_crylink_primary_joinexplode_radius * n, e.realowner,
+ autocvar_g_balance_crylink_primary_joinexplode_radius * n, e.realowner, world,
autocvar_g_balance_crylink_primary_joinexplode_force * n, e.projectiledeathtype, other);
pointparticles(particleeffectnum("crylink_joinexplode"), self.origin, '0 0 0', n);
f = autocvar_g_balance_crylink_primary_bouncedamagefactor;
if(a)
f *= a;
- if (RadiusDamage (self, self.realowner, autocvar_g_balance_crylink_primary_damage * f, autocvar_g_balance_crylink_primary_edgedamage * f, autocvar_g_balance_crylink_primary_radius, world, autocvar_g_balance_crylink_primary_force * f, self.projectiledeathtype, other) && autocvar_g_balance_crylink_primary_linkexplode)
+ if (RadiusDamage (self, self.realowner, autocvar_g_balance_crylink_primary_damage * f, autocvar_g_balance_crylink_primary_edgedamage * f, autocvar_g_balance_crylink_primary_radius, world, world, autocvar_g_balance_crylink_primary_force * f, self.projectiledeathtype, other) && autocvar_g_balance_crylink_primary_linkexplode)
{
if(self == self.realowner.crylink_lastgroup)
self.realowner.crylink_lastgroup = world;
f = autocvar_g_balance_crylink_secondary_bouncedamagefactor;
if(a)
f *= a;
- if (RadiusDamage (self, self.realowner, autocvar_g_balance_crylink_secondary_damage * f, autocvar_g_balance_crylink_secondary_edgedamage * f, autocvar_g_balance_crylink_secondary_radius, world, autocvar_g_balance_crylink_secondary_force * f, self.projectiledeathtype, other) && autocvar_g_balance_crylink_secondary_linkexplode)
+ if (RadiusDamage (self, self.realowner, autocvar_g_balance_crylink_secondary_damage * f, autocvar_g_balance_crylink_secondary_edgedamage * f, autocvar_g_balance_crylink_secondary_radius, world, world, autocvar_g_balance_crylink_secondary_force * f, self.projectiledeathtype, other) && autocvar_g_balance_crylink_secondary_linkexplode)
{
if(self == self.realowner.crylink_lastgroup)
self.realowner.crylink_lastgroup = world;
//proj.glow_size = 20;
proj.flags = FL_PROJECTILE;
-
+ proj.missile_flags = MIF_SPLASH;
+
CSQCProjectile(proj, TRUE, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), TRUE);
other = proj; MUTATOR_CALLHOOK(EditProjectile);
//proj.glow_size = 20;
proj.flags = FL_PROJECTILE;
-
+ proj.missile_flags = MIF_SPLASH;
+
CSQCProjectile(proj, TRUE, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), TRUE);
other = proj; MUTATOR_CALLHOOK(EditProjectile);
self.takedamage = DAMAGE_NO;
if (self.movetype == MOVETYPE_BOUNCE)
{
- RadiusDamage (self, self.realowner, autocvar_g_balance_electro_secondary_damage, autocvar_g_balance_electro_secondary_edgedamage, autocvar_g_balance_electro_secondary_radius, world, autocvar_g_balance_electro_secondary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_electro_secondary_damage, autocvar_g_balance_electro_secondary_edgedamage, autocvar_g_balance_electro_secondary_radius, world, world, autocvar_g_balance_electro_secondary_force, self.projectiledeathtype, other);
}
else
{
W_Plasma_TriggerCombo(self.origin, autocvar_g_balance_electro_primary_comboradius, self.realowner);
- RadiusDamage (self, self.realowner, autocvar_g_balance_electro_primary_damage, autocvar_g_balance_electro_primary_edgedamage, autocvar_g_balance_electro_primary_radius, world, autocvar_g_balance_electro_primary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_electro_primary_damage, autocvar_g_balance_electro_primary_edgedamage, autocvar_g_balance_electro_primary_radius, world, world, autocvar_g_balance_electro_primary_force, self.projectiledeathtype, other);
}
remove (self);
W_Plasma_TriggerCombo(self.origin, autocvar_g_balance_electro_combo_comboradius, self.realowner);
self.event_damage = SUB_Null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_electro_combo_damage, autocvar_g_balance_electro_combo_edgedamage, autocvar_g_balance_electro_combo_radius, world, autocvar_g_balance_electro_combo_force, WEP_ELECTRO | HITTYPE_BOUNCE, world); // use THIS type for a combo because primary can't bounce
+ RadiusDamage (self, self.realowner, autocvar_g_balance_electro_combo_damage, autocvar_g_balance_electro_combo_edgedamage, autocvar_g_balance_electro_combo_radius, world, world, autocvar_g_balance_electro_combo_force, WEP_ELECTRO | HITTYPE_BOUNCE, world); // use THIS type for a combo because primary can't bounce
remove (self);
}
proj.touch = W_Plasma_TouchExplode;
setsize(proj, '0 0 -3', '0 0 -3');
proj.flags = FL_PROJECTILE;
+ proj.missile_flags = MIF_SPLASH;
CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO_BEAM, TRUE);
proj.bouncefactor = autocvar_g_balance_electro_secondary_bouncefactor;
proj.bouncestop = autocvar_g_balance_electro_secondary_bouncestop;
+ proj.missile_flags = MIF_SPLASH | MIF_ARC;
#if 0
entity p2;
// 1. dist damage
d = (self.realowner.health + self.realowner.armorvalue);
- RadiusDamage (self, self.realowner, autocvar_g_balance_fireball_primary_damage, autocvar_g_balance_fireball_primary_edgedamage, autocvar_g_balance_fireball_primary_radius, world, autocvar_g_balance_fireball_primary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_fireball_primary_damage, autocvar_g_balance_fireball_primary_edgedamage, autocvar_g_balance_fireball_primary_radius, world, world, autocvar_g_balance_fireball_primary_force, self.projectiledeathtype, other);
if(self.realowner.health + self.realowner.armorvalue >= d)
if(!self.cnt)
{
proj.touch = W_Fireball_TouchExplode;
setsize(proj, '-16 -16 -16', '16 16 16');
proj.flags = FL_PROJECTILE;
-
+ proj.missile_flags = MIF_SPLASH | MIF_PROXY;
+
CSQCProjectile(proj, TRUE, PROJECTILE_FIREBALL, TRUE);
other = proj; MUTATOR_CALLHOOK(EditProjectile);
proj.angles = vectoangles(proj.velocity);
proj.flags = FL_PROJECTILE;
-
+ proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
+
CSQCProjectile(proj, TRUE, PROJECTILE_FIREMINE, TRUE);
other = proj; MUTATOR_CALLHOOK(EditProjectile);
if(self.movetype == MOVETYPE_NONE)
self.velocity = self.oldvelocity;
- RadiusDamage (self, self.realowner, autocvar_g_balance_grenadelauncher_primary_damage, autocvar_g_balance_grenadelauncher_primary_edgedamage, autocvar_g_balance_grenadelauncher_primary_radius, world, autocvar_g_balance_grenadelauncher_primary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_grenadelauncher_primary_damage, autocvar_g_balance_grenadelauncher_primary_edgedamage, autocvar_g_balance_grenadelauncher_primary_radius, world, world, autocvar_g_balance_grenadelauncher_primary_force, self.projectiledeathtype, other);
remove (self);
}
if(self.movetype == MOVETYPE_NONE)
self.velocity = self.oldvelocity;
- RadiusDamage (self, self.realowner, autocvar_g_balance_grenadelauncher_secondary_damage, autocvar_g_balance_grenadelauncher_secondary_edgedamage, autocvar_g_balance_grenadelauncher_secondary_radius, world, autocvar_g_balance_grenadelauncher_secondary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_grenadelauncher_secondary_damage, autocvar_g_balance_grenadelauncher_secondary_edgedamage, autocvar_g_balance_grenadelauncher_secondary_radius, world, world, autocvar_g_balance_grenadelauncher_secondary_force, self.projectiledeathtype, other);
remove (self);
}
gren.damageforcescale = autocvar_g_balance_grenadelauncher_primary_damageforcescale;
gren.event_damage = W_Grenade_Damage;
gren.damagedbycontents = TRUE;
+ gren.missile_flags = MIF_SPLASH | MIF_ARC;
W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_primary);
gren.angles = vectoangles (gren.velocity);
gren.damageforcescale = autocvar_g_balance_grenadelauncher_secondary_damageforcescale;
gren.event_damage = W_Grenade_Damage;
gren.damagedbycontents = TRUE;
+ gren.missile_flags = MIF_SPLASH | MIF_ARC;
W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_secondary);
gren.angles = vectoangles (gren.velocity);
void W_Hagar_Explode (void)
{
self.event_damage = SUB_Null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_primary_damage, autocvar_g_balance_hagar_primary_edgedamage, autocvar_g_balance_hagar_primary_radius, world, autocvar_g_balance_hagar_primary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_primary_damage, autocvar_g_balance_hagar_primary_edgedamage, autocvar_g_balance_hagar_primary_radius, world, world, autocvar_g_balance_hagar_primary_force, self.projectiledeathtype, other);
remove (self);
}
void W_Hagar_Explode2 (void)
{
self.event_damage = SUB_Null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_secondary_damage, autocvar_g_balance_hagar_secondary_edgedamage, autocvar_g_balance_hagar_secondary_radius, world, autocvar_g_balance_hagar_secondary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_secondary_damage, autocvar_g_balance_hagar_secondary_edgedamage, autocvar_g_balance_hagar_secondary_radius, world, world, autocvar_g_balance_hagar_secondary_force, self.projectiledeathtype, other);
remove (self);
}
missile.angles = vectoangles (missile.velocity);
missile.flags = FL_PROJECTILE;
+ missile.missile_flags = MIF_SPLASH;
CSQCProjectile(missile, TRUE, PROJECTILE_HAGAR, TRUE);
missile.angles = vectoangles (missile.velocity);
missile.flags = FL_PROJECTILE;
+ missile.missile_flags = MIF_SPLASH;
CSQCProjectile(missile, TRUE, PROJECTILE_HAGAR_BOUNCING, TRUE);
setorigin (missile, w_shotorg);
setsize(missile, '0 0 0', '0 0 0');
missile.movetype = MOVETYPE_FLY;
+ missile.missile_flags = MIF_SPLASH;
// per-shot spread calculation: the more shots there are, the less spread is applied (based on the bias cvar)
spread_pershot = ((shots - 1) / (autocvar_g_balance_hagar_secondary_load_max - 1));
self.event_damage = SUB_Null;
if(self.projectiledeathtype & HITTYPE_SECONDARY)
- RadiusDamage (self, self.realowner, autocvar_g_balance_hlac_secondary_damage, autocvar_g_balance_hlac_secondary_edgedamage, autocvar_g_balance_hlac_secondary_radius, world, autocvar_g_balance_hlac_secondary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_hlac_secondary_damage, autocvar_g_balance_hlac_secondary_edgedamage, autocvar_g_balance_hlac_secondary_radius, world, world, autocvar_g_balance_hlac_secondary_force, self.projectiledeathtype, other);
else
- RadiusDamage (self, self.realowner, autocvar_g_balance_hlac_primary_damage, autocvar_g_balance_hlac_primary_edgedamage, autocvar_g_balance_hlac_primary_radius, world, autocvar_g_balance_hlac_primary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_hlac_primary_damage, autocvar_g_balance_hlac_primary_edgedamage, autocvar_g_balance_hlac_primary_radius, world, world, autocvar_g_balance_hlac_primary_force, self.projectiledeathtype, other);
remove (self);
}
missile.nextthink = time + autocvar_g_balance_hlac_secondary_lifetime;
missile.flags = FL_PROJECTILE;
+ missile.missile_flags = MIF_SPLASH;
missile.projectiledeathtype = WEP_HLAC | HITTYPE_SECONDARY;
CSQCProjectile(missile, TRUE, PROJECTILE_HLAC, TRUE);
f = self.dmg_last - dmg_remaining_next;
self.dmg_last = dmg_remaining_next;
- RadiusDamage (self, self.realowner, self.dmg * f, self.dmg_edge * f, self.dmg_radius, self.realowner, self.dmg_force * f, self.projectiledeathtype, world);
+ RadiusDamage (self, self.realowner, self.dmg * f, self.dmg_edge * f, self.dmg_radius, self.realowner, world, self.dmg_force * f, self.projectiledeathtype, world);
self.projectiledeathtype |= HITTYPE_BOUNCE;
- //RadiusDamage (self, world, self.dmg * f, self.dmg_edge * f, self.dmg_radius, world, self.dmg_force * f, self.projectiledeathtype, world);
+ //RadiusDamage (self, world, self.dmg * f, self.dmg_edge * f, self.dmg_radius, world, world, self.dmg_force * f, self.projectiledeathtype, world);
if(dt < self.dmg_duration)
self.nextthink = time + 0.05; // soon
gren.damageforcescale = autocvar_g_balance_hook_secondary_damageforcescale;
gren.event_damage = W_Hook_Damage;
gren.damagedbycontents = TRUE;
+ gren.missile_flags = MIF_SPLASH | MIF_ARC;
gren.velocity = '0 0 1' * autocvar_g_balance_hook_secondary_speed;
if(autocvar_g_projectiles_newton_style)
void(float imp) W_SwitchWeapon;
void() W_LastWeapon;
+void SendCSQCShockwaveParticle(float spread, vector endpos)
+{
+ //WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+ WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte(MSG_BROADCAST, TE_CSQC_SHOCKWAVEPARTICLE);
+ WriteCoord(MSG_BROADCAST, w_shotorg_x);
+ WriteCoord(MSG_BROADCAST, w_shotorg_y);
+ WriteCoord(MSG_BROADCAST, w_shotorg_z);
+ WriteCoord(MSG_BROADCAST, endpos_x);
+ WriteCoord(MSG_BROADCAST, endpos_y);
+ WriteCoord(MSG_BROADCAST, endpos_z);
+ WriteByte(MSG_BROADCAST, bound(0, 255 * spread, 255));
+}
+
void W_Laser_Touch (void)
{
PROJECTILE_TOUCH;
self.event_damage = SUB_Null;
if (self.dmg)
- RadiusDamage (self, self.realowner, autocvar_g_balance_laser_secondary_damage, autocvar_g_balance_laser_secondary_edgedamage, autocvar_g_balance_laser_secondary_radius, world, autocvar_g_balance_laser_secondary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_laser_secondary_damage, autocvar_g_balance_laser_secondary_edgedamage, autocvar_g_balance_laser_secondary_radius, world, world, autocvar_g_balance_laser_secondary_force, self.projectiledeathtype, other);
else
- RadiusDamage (self, self.realowner, autocvar_g_balance_laser_primary_damage, autocvar_g_balance_laser_primary_edgedamage, autocvar_g_balance_laser_primary_radius, world, autocvar_g_balance_laser_primary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_laser_primary_damage, autocvar_g_balance_laser_primary_edgedamage, autocvar_g_balance_laser_primary_radius, world, world, autocvar_g_balance_laser_primary_force, self.projectiledeathtype, other);
remove (self);
}
CSQCProjectile(self, TRUE, PROJECTILE_LASER, TRUE);
}
+void W_Laser_Shockwave (void)
+{
+ // declarations
+ float final_damage, final_spread;
+ entity head, next, aim_ent;
+ vector nearest, attack_hitpos, angle_to_head, angle_to_attack, final_force, center;
+
+ // set up the shot direction
+ vector wanted_shot_direction = (v_forward * cos(autocvar_g_balance_laser_primary_shotangle * DEG2RAD) + v_up * sin(autocvar_g_balance_laser_primary_shotangle * DEG2RAD));
+ W_SetupShot_Dir(self, wanted_shot_direction, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_balance_laser_primary_damage);
+ vector attack_endpos = (w_shotorg + (w_shotdir * autocvar_g_balance_laser_primary_radius));
+
+ // find out what we're pointing at
+ WarpZone_TraceLine(w_shotorg, attack_endpos, FALSE, self);
+ aim_ent = trace_ent;
+ attack_hitpos = trace_endpos;
+
+ // do the jump explosion now (also handles the impact effect)
+ RadiusDamageForSource(self, trace_endpos, '0 0 0', self, autocvar_g_balance_laser_primary_damage, autocvar_g_balance_laser_primary_edgedamage, autocvar_g_balance_laser_primary_jumpradius, world, self, TRUE, autocvar_g_balance_laser_primary_force, WEP_LASER, world);
+
+ // also do the firing effect now
+ SendCSQCShockwaveParticle(autocvar_g_balance_laser_primary_spread, attack_hitpos);
+
+ // did we hit a player directly?
+ if(aim_ent.takedamage)
+ {
+ // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
+ if (aim_ent.classname == "player")
+ center = aim_ent.origin + aim_ent.view_ofs;
+ else
+ center = aim_ent.origin + (aim_ent.mins + aim_ent.maxs) * 0.5;
+
+ final_force = (normalize(center - attack_hitpos) * autocvar_g_balance_laser_primary_force);
+ Damage(aim_ent, self, self, autocvar_g_balance_laser_primary_damage, WEP_LASER, aim_ent.origin, final_force);
+ print("Player hit directly via aim!\n");
+ }
+
+ // now figure out if I hit anything else than what my aim directly pointed at...
+ head = WarpZone_FindRadius(w_shotorg, autocvar_g_balance_laser_primary_radius, FALSE);
+ while(head)
+ {
+ next = head.chain;
+
+ if((head != self && head != aim_ent) && (head.takedamage))
+ {
+ // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
+ if (head.classname == "player")
+ center = head.origin + head.view_ofs;
+ else
+ center = head.origin + (head.mins + head.maxs) * 0.5;
+
+ // find the closest point on the enemy to the center of the attack
+ float h = vlen(center - self.origin);
+ float ang = acos(dotproduct(normalize(center - self.origin), w_shotdir));
+ float a = h * cos(ang);
+
+ // ang = angle between shotdir and h
+ // h = hypotenuse, which is the distance between attacker to head
+ // a = adjacent side, which is the distance between attacker and the point on w_shotdir that is closest to head.origin
+
+ nearest = WarpZoneLib_NearestPointOnBox(center + head.mins, center + head.maxs, w_shotorg + a * w_shotdir);
+
+ if(vlen(w_shotorg - nearest) <= autocvar_g_balance_laser_primary_radius)
+ {
+ // is it within the limit of the spread?
+ nearest = head.WarpZone_findradius_nearest;
+ angle_to_head = normalize(nearest - w_shotorg);
+ angle_to_attack = w_shotdir;
+ final_spread = vlen(angle_to_head - angle_to_attack);
+ if(final_spread <= autocvar_g_balance_laser_primary_spread)
+ {
+ // TODO! we MUST check this, otherwise you can shoot through walls!
+ // just how to make sure that if a small part of the player is visible, we'll hit him?
+ // we can just do it the cheap way of tracing from shotorg to nearest, but what if there's an obstruction between those points, but the player still sees the enemy...?
+
+ // is it visible to the weapon?
+ //WarpZone_TraceLine(w_shotorg, nearest, MOVE_WORLDONLY, self);
+ //if(trace_fraction == 1)
+ //{
+ // finally lets do some damage bitches!
+ if(autocvar_g_balance_laser_primary_spread)
+ final_damage = (final_spread / autocvar_g_balance_laser_primary_spread);
+ else
+ final_damage = 1;
+
+ //final_force = (normalize(nearest - w_shotorg) * autocvar_g_balance_laser_primary_force); // we dont want to use nearest here, because that would result in some rather weird force dirs for the attacker...
+ print(strcat("head.origin: ", vtos(head.origin), ", (w_shotorg + a * w_shotdir): ", vtos(w_shotorg + a * w_shotdir), ".\n"));
+ print("a = ", ftos(a), " h = ", ftos(h), " ang = ", ftos(ang), "\n");
+ final_force = (normalize(center - (w_shotorg + a * w_shotdir)) * autocvar_g_balance_laser_primary_force);
+ final_damage = (autocvar_g_balance_laser_primary_damage * final_damage + autocvar_g_balance_laser_primary_edgedamage * (1 - final_damage));
+
+ print(strcat("damage: ", ftos(final_damage), ", force: ", vtos(final_force), ".\n"));
+
+ Damage(head, self, self, final_damage, WEP_LASER, head.origin, final_force);
+
+ print(strcat(vtos(angle_to_head), " - ", vtos(angle_to_attack), ": ", ftos(vlen(angle_to_head - angle_to_attack)), ".\n"));
+ //te_lightning2(world, nearest, w_shotorg);
+
+ //pointparticles(particleeffectnum("rocket_guide"), w_shotorg, w_shotdir * 1000, 1);
+ //SendCSQCShockwaveParticle(autocvar_g_balance_laser_primary_spread, trace_endpos);
+ //}
+ }
+ }
+ }
+ head = next;
+ }
+}
+
void W_Laser_Attack (float issecondary)
{
entity missile;
missile.touch = W_Laser_Touch;
missile.flags = FL_PROJECTILE;
+ missile.missile_flags = MIF_SPLASH;
missile.think = W_Laser_Think;
missile.nextthink = time + autocvar_g_balance_laser_primary_delay;
{
W_DecreaseAmmo(ammo_none, 1, TRUE);
- W_Laser_Attack(0);
+ W_Laser_Shockwave();
weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_laser_primary_animtime, w_ready);
}
}
{
vector org2;
org2 = w_org + w_backoff * 6;
- pointparticles(particleeffectnum("laser_impact"), org2, w_backoff * 1000, 1);
+ pointparticles(particleeffectnum("new_laser_impact"), org2, w_backoff * 1000, 1);
if(!w_issilent)
sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
}
self.event_damage = SUB_Null;
self.takedamage = DAMAGE_NO;
- RadiusDamage (self, self.realowner, autocvar_g_balance_minelayer_damage, autocvar_g_balance_minelayer_edgedamage, autocvar_g_balance_minelayer_radius, world, autocvar_g_balance_minelayer_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_minelayer_damage, autocvar_g_balance_minelayer_edgedamage, autocvar_g_balance_minelayer_radius, world, world, autocvar_g_balance_minelayer_force, self.projectiledeathtype, other);
if (self.realowner.weapon == WEP_MINE_LAYER)
{
if(self.movetype == MOVETYPE_NONE || self.movetype == MOVETYPE_FOLLOW)
self.velocity = self.oldvelocity;
- RadiusDamage (self, self.realowner, autocvar_g_balance_minelayer_remote_damage, autocvar_g_balance_minelayer_remote_edgedamage, autocvar_g_balance_minelayer_remote_radius, world, autocvar_g_balance_minelayer_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_minelayer_remote_damage, autocvar_g_balance_minelayer_remote_edgedamage, autocvar_g_balance_minelayer_remote_radius, world, world, autocvar_g_balance_minelayer_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world);
if (self.realowner.weapon == WEP_MINE_LAYER)
{
mine.nextthink = time;
mine.cnt = time + (autocvar_g_balance_minelayer_lifetime - autocvar_g_balance_minelayer_lifetime_countdown);
mine.flags = FL_PROJECTILE;
+ mine.missile_flags = MIF_SPLASH | MIF_ARC | MIF_PROXY;
CSQCProjectile(mine, TRUE, PROJECTILE_MINE, TRUE);
self.event_damage = SUB_Null;
self.takedamage = DAMAGE_NO;
- RadiusDamage (self, self.realowner, autocvar_g_balance_rocketlauncher_damage, autocvar_g_balance_rocketlauncher_edgedamage, autocvar_g_balance_rocketlauncher_radius, world, autocvar_g_balance_rocketlauncher_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_rocketlauncher_damage, autocvar_g_balance_rocketlauncher_edgedamage, autocvar_g_balance_rocketlauncher_radius, world, world, autocvar_g_balance_rocketlauncher_force, self.projectiledeathtype, other);
if (self.realowner.weapon == WEP_ROCKET_LAUNCHER)
{
self.event_damage = SUB_Null;
self.takedamage = DAMAGE_NO;
- RadiusDamage (self, self.realowner, autocvar_g_balance_rocketlauncher_remote_damage, autocvar_g_balance_rocketlauncher_remote_edgedamage, autocvar_g_balance_rocketlauncher_remote_radius, world, autocvar_g_balance_rocketlauncher_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_rocketlauncher_remote_damage, autocvar_g_balance_rocketlauncher_remote_edgedamage, autocvar_g_balance_rocketlauncher_remote_radius, world, world, autocvar_g_balance_rocketlauncher_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world);
if (self.realowner.weapon == WEP_ROCKET_LAUNCHER)
{
missile.nextthink = time;
missile.cnt = time + autocvar_g_balance_rocketlauncher_lifetime;
missile.flags = FL_PROJECTILE;
+ missile.missile_flags = MIF_SPLASH;
CSQCProjectile(missile, autocvar_g_balance_rocketlauncher_guiderate == 0 && autocvar_g_balance_rocketlauncher_speedaccel == 0, PROJECTILE_ROCKET, FALSE); // because of fly sound
void Seeker_Missile_Explode ()
{
self.event_damage = SUB_Null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_seeker_missile_damage, autocvar_g_balance_seeker_missile_edgedamage, autocvar_g_balance_seeker_missile_radius, world, autocvar_g_balance_seeker_missile_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_seeker_missile_damage, autocvar_g_balance_seeker_missile_edgedamage, autocvar_g_balance_seeker_missile_radius, world, world, autocvar_g_balance_seeker_missile_force, self.projectiledeathtype, other);
remove (self);
}
setsize (missile, '-4 -4 -4', '4 4 4');
missile.movetype = MOVETYPE_FLYMISSILE;
missile.flags = FL_PROJECTILE;
+ missile.missile_flags = MIF_SPLASH | MIF_GUIDED_TAG;
+
W_SETUPPROJECTILEVELOCITY_UP(missile, g_balance_seeker_missile);
missile.angles = vectoangles (missile.velocity);
{
self.event_damage = SUB_Null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_seeker_flac_damage, autocvar_g_balance_seeker_flac_edgedamage, autocvar_g_balance_seeker_flac_radius, world, autocvar_g_balance_seeker_flac_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_seeker_flac_damage, autocvar_g_balance_seeker_flac_edgedamage, autocvar_g_balance_seeker_flac_radius, world, world, autocvar_g_balance_seeker_flac_force, self.projectiledeathtype, other);
remove (self);
}
missile.projectiledeathtype = WEP_SEEKER;
missile.projectiledeathtype = WEP_SEEKER | HITTYPE_SECONDARY;
missile.flags = FL_PROJECTILE;
+ missile.missile_flags = MIF_SPLASH;
// csqc projectiles
//missile.angles = vectoangles (missile.velocity);
setsize (missile, '-2 -2 -2', '2 2 2');
missile.flags = FL_PROJECTILE;
+ //missile.missile_flags = MIF_..?;
missile.movetype = MOVETYPE_FLY;
W_SETUPPROJECTILEVELOCITY(missile, g_balance_seeker_tag);