From: Samual Lenks Date: Sat, 21 Jul 2012 03:13:22 +0000 (-0400) Subject: Merge remote-tracking branch 'origin/master' into samual/spawn_weapons X-Git-Tag: xonotic-v0.8.0~152^2~408^2~77 X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=6018d119b3c9f4e54d6d21f6339948708c83d83f;hp=-c Merge remote-tracking branch 'origin/master' into samual/spawn_weapons Conflicts: effectinfo.txt qcsrc/server/vehicles/raptor.qc qcsrc/server/vehicles/spiderbot.qc --- 6018d119b3c9f4e54d6d21f6339948708c83d83f diff --combined effectinfo.txt index 38a14489d,38413d3c6..e2491883b --- a/effectinfo.txt +++ b/effectinfo.txt @@@ -7411,82 -7411,229 +7411,310 @@@ velocityjitter 64 64 6 //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 diff --combined qcsrc/client/Main.qc index fe9fd6dd3,3ac1e9cf7..6181d789e --- a/qcsrc/client/Main.qc +++ b/qcsrc/client/Main.qc @@@ -87,7 -87,7 +87,7 @@@ void ConsoleCommand_macro_init() 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"); @@@ -766,7 -766,8 +766,8 @@@ void CSQC_Ent_Update(float bIsNewEntity 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)); @@@ -1185,10 -1186,6 +1186,10 @@@ float CSQC_Parse_TempEntity( 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; diff --combined qcsrc/common/constants.qh index c22801c19,076de115e..9799de041 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@@ -36,7 -36,6 +36,7 @@@ const float TE_CSQC_NEXGUNBEAMPARTICLE 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; @@@ -98,6 -97,7 +98,7 @@@ const float ENT_CLIENT_ACCURACY = 30 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; @@@ -349,6 -349,9 +350,9 @@@ float PROJECTILE_SPIDERROCKET = 27 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; @@@ -391,8 -394,12 +395,12 @@@ float DEATH_WAKIBLOWUP = 10036 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; diff --combined qcsrc/server/autocvars.qh index ee01e21d1,c75a43873..f9e1a2f70 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@@ -435,13 -435,11 +435,13 @@@ float autocvar_g_balance_laser_primary_ 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; @@@ -811,7 -809,6 +811,6 @@@ float autocvar_g_freezetag_warmup 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; diff --combined qcsrc/server/cl_client.qc index 15e73aef5,da97ea325..f3feee27a --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@@ -629,7 -629,7 +629,7 @@@ void PlayerTouchExplode(entity p1, enti 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); } @@@ -2171,29 -2171,24 +2171,24 @@@ void SpectateCopy(entity spectatee) 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; @@@ -2201,11 -2196,18 +2196,18 @@@ 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);*/ } } @@@ -2263,17 -2265,19 +2265,19 @@@ float SpectateNext() 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); @@@ -2283,7 -2287,7 +2287,7 @@@ if(!SpectateUpdate()) PutObserverInServer(); - } + //} return 1; } else { return 0; diff --combined qcsrc/server/g_damage.qc index 4174bbc42,ac7c3cd2a..710c7d4e2 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@@ -986,10 -986,11 +986,10 @@@ void Damage (entity targ, entity inflic } 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; @@@ -1009,205 -1010,205 +1009,205 @@@ 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; } @@@ -1219,11 -1220,6 +1219,11 @@@ 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; @@@ -1286,9 -1282,9 +1286,9 @@@ float Fire_AddDamage(entity e, entity o // 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) diff --combined qcsrc/server/tturrets/units/unit_flac.qc index 0f51c10d0,7c21ba7ab..5f83a304f --- a/qcsrc/server/tturrets/units/unit_flac.qc +++ b/qcsrc/server/tturrets/units/unit_flac.qc @@@ -10,11 -10,11 +10,11 @@@ void turret_flac_projectile_think_explo #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); } @@@ -29,7 -29,8 +29,8 @@@ void turret_flac_attack( 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; diff --combined qcsrc/server/tturrets/units/unit_walker.qc index 6714bf611,f47003f4b..482e919c2 --- a/qcsrc/server/tturrets/units/unit_walker.qc +++ b/qcsrc/server/tturrets/units/unit_walker.qc @@@ -51,7 -51,7 +51,7 @@@ void walker_setnoanim( } 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); } @@@ -199,7 -199,7 +199,7 @@@ void walker_fire_rocket(vector org rocket.tur_shotorg = randomvec() * 512; rocket.cnt = time + 1; rocket.enemy = self.enemy; - + if (random() < 0.01) rocket.think = walker_rocket_loop; else @@@ -215,7 -215,8 +215,8 @@@ 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 } diff --combined qcsrc/server/vehicles/racer.qc index 2bde9a533,147c8139c..0600ceb7c --- a/qcsrc/server/vehicles/racer.qc +++ b/qcsrc/server/vehicles/racer.qc @@@ -423,13 -423,13 +423,13 @@@ float racer_frame( 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); @@@ -555,9 -555,9 +555,9 @@@ void racer_blowup( 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); @@@ -625,7 -625,8 +625,8 @@@ void racer_dinit( racer_frame, racer_enter, racer_exit, racer_die, racer_think, - TRUE)) + TRUE, + autocvar_g_vehicle_racer_health)) { remove(self); return; diff --combined qcsrc/server/vehicles/raptor.qc index cccc9b278,c0e0c31a5..c75932d81 --- a/qcsrc/server/vehicles/raptor.qc +++ b/qcsrc/server/vehicles/raptor.qc @@@ -1,8 -1,14 +1,14 @@@ - #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; @@@ -26,6 -32,11 +32,11 @@@ float autocvar_g_vehicle_raptor_bomblet 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; @@@ -79,7 -90,7 +90,7 @@@ void raptor_bomblet_boom( { 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); } @@@ -194,7 -205,8 +205,8 @@@ void raptor_enter( if(self.owner.flagcarried) setorigin(self.owner.flagcarried, '-20 0 96'); - + + CSQCVehicleSetup(self.owner, 0); } void raptor_land() @@@ -274,7 -286,7 +286,7 @@@ float raptor_takeoff( // 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; @@@ -286,13 -298,13 +298,13 @@@ 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); @@@ -308,10 -320,39 +320,39 @@@ 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) @@@ -457,39 -498,14 +498,14 @@@ } } - // 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; @@@ -519,26 -535,81 +535,81 @@@ } 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) @@@ -554,7 -625,7 +625,8 @@@ void raptor_blowup( { 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; @@@ -634,6 -705,38 +706,38 @@@ void raptor_rotor_anglefix( 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() { @@@ -653,7 -756,8 +757,8 @@@ raptor_frame, raptor_enter, raptor_exit, raptor_die, raptor_think, - FALSE)) + FALSE, + autocvar_g_vehicle_raptor_health)) { remove(self); return; @@@ -661,7 -765,9 +766,9 @@@ //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(); @@@ -680,7 -786,7 +787,7 @@@ 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. @@@ -751,6 -857,7 +858,7 @@@ void spawnfunc_vehicle_raptor( precache_sound ("vehicles/raptor_fly.wav"); precache_sound ("vehicles/raptor_speed.wav"); + precache_sound ("vehicles/missile_alarm.wav"); self.think = raptor_dinit; diff --combined qcsrc/server/vehicles/spiderbot.qc index 91136ce56,42bd7902b..4201a5c77 --- a/qcsrc/server/vehicles/spiderbot.qc +++ b/qcsrc/server/vehicles/spiderbot.qc @@@ -8,15 -8,16 +8,16 @@@ float autocvar_g_vehicle_spiderbot_spee 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; @@@ -39,12 -40,17 +40,17 @@@ float autocvar_g_vehicle_spiderbot_mini 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; @@@ -57,6 -63,17 +63,17 @@@ vector autocvar_g_vehicle_spiderbot_bou 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() { @@@ -113,61 -130,179 +130,179 @@@ void spiderbot_guide_release( } } + 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; } @@@ -191,6 -326,12 +326,12 @@@ float spiderbot_frame( 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")); @@@ -219,23 -360,19 +360,19 @@@ //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) { @@@ -272,6 -409,13 +409,13 @@@ } 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; @@@ -323,8 -467,8 +467,8 @@@ } } - 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) { @@@ -342,11 -486,17 +486,17 @@@ 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; @@@ -366,16 -516,16 +516,16 @@@ 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; @@@ -407,7 -557,7 +557,7 @@@ void spiderbot_think( 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; @@@ -566,7 -716,7 +716,7 @@@ void spiderbot_blowup( 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; @@@ -593,6 -743,41 +743,41 @@@ void spiderbot_die( 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( @@@ -608,7 -793,8 +793,8 @@@ spiderbot_frame, spiderbot_enter, spiderbot_exit, spiderbot_die, spiderbot_think, - FALSE)) + FALSE, + autocvar_g_vehicle_spiderbot_health)) { remove(self); return; @@@ -617,7 -803,9 +803,9 @@@ 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"); diff --combined qcsrc/server/vehicles/vehicles.qc index 058ab783f,2f6a191bf..56655aa00 --- a/qcsrc/server/vehicles/vehicles.qc +++ b/qcsrc/server/vehicles/vehicles.qc @@@ -4,6 -4,12 +4,12 @@@ float autocvar_g_vehicles_delayspawn 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(); @@@ -95,7 -101,10 +101,10 @@@ void CSQCVehicleSetup(entity own, floa 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 @@@ -131,6 -140,8 +140,8 @@@ vector targetdrone_getnewspot( } 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() @@@ -190,24 -201,24 +201,24 @@@ void targetdrone_think( { 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; @@@ -226,6 -237,7 +237,7 @@@ void targetdrone_spawn(vector _where, f drone.nextthink = time + 0.1; drone.cnt = _autorenew; } + #endif void vehicles_locktarget(float incr, float decr, float _lock_time) { @@@ -362,7 -374,6 +374,6 @@@ void vehicles_projectile_damage(entity self.think = self.use; self.nextthink = time; } - } void vehicles_projectile_explode() @@@ -379,7 -390,7 +390,7 @@@ 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); } @@@ -778,11 -789,14 +789,14 @@@ void vehicles_exit(float eject } - 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) @@@ -829,7 -843,21 +843,21 @@@ void vehicles_painframe( 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) @@@ -896,7 -924,7 +924,7 @@@ void vehicles_clearrturn( ret = findchain(classname, "vehicle_return"); while(ret) { - if(ret.enemy == self) + if(ret.wp00 == self) { ret.classname = ""; ret.think = SUB_Remove; @@@ -913,10 -941,10 +941,10 @@@ 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); @@@ -951,9 -979,9 +979,9 @@@ void vehicles_showwp( 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; @@@ -966,7 -994,7 +994,7 @@@ 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); @@@ -984,7 -1012,7 +1012,7 @@@ void vehicles_setreturn( ret = spawn(); ret.classname = "vehicle_return"; - ret.enemy = self; + ret.wp00 = self; ret.team = self.team; ret.think = vehicles_showwp; @@@ -1072,7 -1100,8 +1100,8 @@@ float vehicle_initialize(string net_na 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); @@@ -1112,7 -1141,7 +1141,7 @@@ 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; @@@ -1163,6 -1192,25 +1192,25 @@@ 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; diff --combined qcsrc/server/w_common.qc index 9dde1c710,3780fc713..7724d8b23 --- a/qcsrc/server/w_common.qc +++ b/qcsrc/server/w_common.qc @@@ -148,7 -148,7 +148,7 @@@ void FireRailgunBullet (vector start, v // 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; @@@ -339,7 -339,7 +339,7 @@@ float W_BallisticBullet_LeaveSolid(floa void W_BallisticBullet_Touch (void) { - float density; + //float density; if(self.think == W_BallisticBullet_LeaveSolid_think) // skip this! return; @@@ -400,7 -400,7 +400,7 @@@ void fireBallisticBullet_trace_callback 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; diff --combined qcsrc/server/w_crylink.qc index dbc076981,1ce463827..5a19edf36 --- a/qcsrc/server/w_crylink.qc +++ b/qcsrc/server/w_crylink.qc @@@ -69,9 -69,9 +69,9 @@@ void W_Crylink_LinkExplode (entity e, e 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); @@@ -201,7 -201,7 +201,7 @@@ void W_Crylink_LinkJoinEffect_Think( 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); @@@ -214,7 -214,7 +214,7 @@@ 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); @@@ -242,7 -242,7 +242,7 @@@ void W_Crylink_Touch (void 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; @@@ -283,7 -283,7 +283,7 @@@ void W_Crylink_Touch2 (void 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; @@@ -409,7 -409,8 +409,8 @@@ void W_Crylink_Attack (void //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); @@@ -500,7 -501,8 +501,8 @@@ void W_Crylink_Attack2 (void //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); diff --combined qcsrc/server/w_electro.qc index 5ebbce99d,7a91cbd89..19f8b4443 --- a/qcsrc/server/w_electro.qc +++ b/qcsrc/server/w_electro.qc @@@ -39,12 -39,12 +39,12 @@@ void W_Plasma_Explode (void 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); @@@ -55,7 -55,7 +55,7 @@@ void W_Plasma_Explode_Combo (void 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); } @@@ -140,6 -140,7 +140,7 @@@ void W_Electro_Attack( 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); @@@ -185,6 -186,7 +186,7 @@@ void W_Electro_Attack2( 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; diff --combined qcsrc/server/w_fireball.qc index d3e1d66ed,67547e358..2c56756cd --- a/qcsrc/server/w_fireball.qc +++ b/qcsrc/server/w_fireball.qc @@@ -19,7 -19,7 +19,7 @@@ void W_Fireball_Explode (void // 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) { @@@ -159,7 -159,8 +159,8 @@@ void W_Fireball_Attack1( 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); @@@ -289,7 -290,8 +290,8 @@@ void W_Fireball_Attack2( 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); diff --combined qcsrc/server/w_grenadelauncher.qc index 391255d66,5f6c0346f..21bc9afbd --- a/qcsrc/server/w_grenadelauncher.qc +++ b/qcsrc/server/w_grenadelauncher.qc @@@ -20,7 -20,7 +20,7 @@@ void W_Grenade_Explode (void 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); } @@@ -40,7 -40,7 +40,7 @@@ void W_Grenade_Explode2 (void 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); } @@@ -200,6 -200,7 +200,7 @@@ void W_Grenade_Attack (void 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); @@@ -247,6 -248,7 +248,7 @@@ void W_Grenade_Attack2 (void 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); diff --combined qcsrc/server/w_hagar.qc index 931072909,9a4b1ef44..fdf7eaaae --- a/qcsrc/server/w_hagar.qc +++ b/qcsrc/server/w_hagar.qc @@@ -7,7 -7,7 +7,7 @@@ REGISTER_WEAPON(HAGAR, w_hagar, IT_ROCK 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); } @@@ -15,7 -15,7 +15,7 @@@ 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); } @@@ -101,6 -101,7 +101,7 @@@ void W_Hagar_Attack (void missile.angles = vectoangles (missile.velocity); missile.flags = FL_PROJECTILE; + missile.missile_flags = MIF_SPLASH; CSQCProjectile(missile, TRUE, PROJECTILE_HAGAR, TRUE); @@@ -144,6 -145,7 +145,7 @@@ void W_Hagar_Attack2 (void missile.angles = vectoangles (missile.velocity); missile.flags = FL_PROJECTILE; + missile.missile_flags = MIF_SPLASH; CSQCProjectile(missile, TRUE, PROJECTILE_HAGAR_BOUNCING, TRUE); @@@ -197,6 -199,7 +199,7 @@@ void W_Hagar_Attack2_Load_Release (void 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)); diff --combined qcsrc/server/w_hlac.qc index 49d68f2c8,a2697b2f5..231832602 --- a/qcsrc/server/w_hlac.qc +++ b/qcsrc/server/w_hlac.qc @@@ -10,9 -10,9 +10,9 @@@ void W_HLAC_Touch (void 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); } @@@ -102,6 -102,7 +102,7 @@@ void W_HLAC_Attack2f (void 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); diff --combined qcsrc/server/w_hook.qc index c419c7993,63d02604c..ea9514417 --- a/qcsrc/server/w_hook.qc +++ b/qcsrc/server/w_hook.qc @@@ -23,9 -23,9 +23,9 @@@ void W_Hook_ExplodeThink (void 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 @@@ -100,6 -100,7 +100,7 @@@ void W_Hook_Attack2( 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) diff --combined qcsrc/server/w_laser.qc index 89c2840d1,5e2bb075a..cb80b3a8e --- a/qcsrc/server/w_laser.qc +++ b/qcsrc/server/w_laser.qc @@@ -5,29 -5,15 +5,29 @@@ REGISTER_WEAPON(LASER, w_laser, 0, 1, W 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); } @@@ -43,114 -29,6 +43,114 @@@ void W_Laser_Think( 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; @@@ -197,6 -75,7 +197,7 @@@ 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; @@@ -363,7 -242,7 +364,7 @@@ float w_laser(float req { 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); } } @@@ -422,7 -301,7 +423,7 @@@ float w_laser(float req { 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); } diff --combined qcsrc/server/w_minelayer.qc index 58c189f16,4d98f0c91..b83c6f150 --- a/qcsrc/server/w_minelayer.qc +++ b/qcsrc/server/w_minelayer.qc @@@ -70,7 -70,7 +70,7 @@@ void W_Mine_Explode ( 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) { @@@ -97,7 -97,7 +97,7 @@@ void W_Mine_DoRemoteExplode ( 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) { @@@ -308,6 -308,7 +308,7 @@@ void W_Mine_Attack (void 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); diff --combined qcsrc/server/w_rocketlauncher.qc index ae1718aba,643bf4bd5..cf2a75191 --- a/qcsrc/server/w_rocketlauncher.qc +++ b/qcsrc/server/w_rocketlauncher.qc @@@ -28,7 -28,7 +28,7 @@@ void W_Rocket_Explode ( 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) { @@@ -49,7 -49,7 +49,7 @@@ void W_Rocket_DoRemoteExplode ( 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) { @@@ -250,6 -250,7 +250,7 @@@ void W_Rocket_Attack (void 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 diff --combined qcsrc/server/w_seeker.qc index 56efcd913,7cf6cfb73..a6a683389 --- a/qcsrc/server/w_seeker.qc +++ b/qcsrc/server/w_seeker.qc @@@ -13,7 -13,7 +13,7 @@@ REGISTER_WEAPON(SEEKER, w_seeker, IT_RO 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); } @@@ -207,6 -207,8 +207,8 @@@ void Seeker_Fire_Missile(vector f_diff 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); @@@ -223,7 -225,7 +225,7 @@@ void Seeker_Flac_Explode ( { 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); } @@@ -279,6 -281,7 +281,7 @@@ void Seeker_Fire_Flac( 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); @@@ -500,6 -503,7 +503,7 @@@ void Seeker_Fire_Tag( 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);