From d33abfb65b625b182ce3dc4ffc14809262df644b Mon Sep 17 00:00:00 2001 From: esteel Date: Thu, 10 Nov 2005 20:26:17 +0000 Subject: [PATCH] homing missles from Wazat, minor menu corrections git-svn-id: svn://svn.icculus.org/nexuiz/trunk@571 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/default.cfg | 10 +- data/menu/creategame/gamemodes/gamemisc.menu | 7 +- data/menu/creategame/gamemodes/runematch.menu | 2 +- data/menu/creategame/weapon.menu | 15 ++ data/menu/data/gamemodes/gamemisc.menu | 7 + data/menu/data/weapon.menu | 21 +++ data/models/laser_dot.mdl | Bin 0 -> 26836 bytes data/qcsrc/gamec/GameC.dsp | 4 + data/qcsrc/gamec/cl_weaponsystem.c | 64 ++++++++ data/qcsrc/gamec/defs.h | 3 + data/qcsrc/gamec/g_world.c | 4 + data/qcsrc/gamec/w_rocketlauncher.c | 153 +++++++++++++++++- 12 files changed, 275 insertions(+), 15 deletions(-) create mode 100644 data/models/laser_dot.mdl diff --git a/data/default.cfg b/data/default.cfg index 696da8e94..1621d73f3 100755 --- a/data/default.cfg +++ b/data/default.cfg @@ -1,5 +1,4 @@ // Nexuiz version - set g_nexuizversion 1.3 // team aliases @@ -9,7 +8,6 @@ alias team_green "color 3" alias team_yellow "color 12" // other aliases - alias "+scores" "+showscores; ping" alias "-scores" "-showscores" @@ -99,6 +97,7 @@ set g_pickup_items 1 set g_instagib 0 set g_rocketarena 0 set g_vampire 0 +set g_homing_missile 0 set g_midair 0 set g_fullbrightplayers 0 set g_fullbrightitems 0 @@ -285,10 +284,9 @@ set g_balance_rocketlauncher_force 600 set g_balance_rocketlauncher_radius 170 set g_balance_rocketlauncher_speed 850 set g_balance_rocketlauncher_refire 1 -//set g_balance_falldamage_deadminspeed 100 -//set g_balance_falldamage_minspeed 600 -//set g_balance_falldamage_factor 0.05 -//set g_balance_falldamage_maxdamage 50 +set g_balance_rocketlauncher_homing_speed 1000 //650 +set g_balance_rocketlauncher_homing_turnrate 0.75 //0.5 +set g_balance_rocketlauncher_homing_allow_steal 1 set g_balance_falldamage_deadminspeed 150 set g_balance_falldamage_minspeed 1400 set g_balance_falldamage_factor 0.15 diff --git a/data/menu/creategame/gamemodes/gamemisc.menu b/data/menu/creategame/gamemodes/gamemisc.menu index 4cea87f43..f32733f6f 100644 --- a/data/menu/creategame/gamemodes/gamemisc.menu +++ b/data/menu/creategame/gamemodes/gamemisc.menu @@ -9,7 +9,7 @@ Item Layout Misc Item ScrollWindow ScrollWindow { - size '780 585' + size '780 535' flag [FlagEmbedded] Item Arrangement Arrangement @@ -153,6 +153,11 @@ Item Layout Misc text "Vampire Mode" target "::Data::Game::Misc::Vampire::Switch" } + Derive Nex_Option_Switch HomingRocket + { + text "Laser-Guide Rockets" + target "::Data::Game::Misc::HomingRocket::Switch" + } Derive Nex_Option_Switch MidAir { text "MidAir" diff --git a/data/menu/creategame/gamemodes/runematch.menu b/data/menu/creategame/gamemodes/runematch.menu index c1a0ef8fd..4f2ce4b9c 100644 --- a/data/menu/creategame/gamemodes/runematch.menu +++ b/data/menu/creategame/gamemodes/runematch.menu @@ -6,7 +6,7 @@ Item Layout Runematch Item ScrollWindow ScrollWindow { - size '780 585' + size '780 535' flag [FlagEmbedded] Item Arrangement Arrangement diff --git a/data/menu/creategame/weapon.menu b/data/menu/creategame/weapon.menu index 931c3f4a7..2ba3c62c2 100644 --- a/data/menu/creategame/weapon.menu +++ b/data/menu/creategame/weapon.menu @@ -364,6 +364,21 @@ Item Window Weapon text "Rocket Launcher Refire" target "Data::Weapon::RocketLauncherrefire::Text" } + Derive Nex_Option_EditBox RocketLauncherGuidedSpeed + { + text "Guided Rocket Launcher Speed" + target "Data::Weapon::RocketLauncherGuidedSpeed::Text" + } + Derive Nex_Option_EditBox RocketLauncherGuidedTurnRate + { + text "Guided Rocket Launcher Turn Rate" + target "Data::Weapon::RocketLauncherGuidedTurnRate::Text" + } + Derive Nex_Option_Switch RocketLauncherGuidedAllowSteal + { + text "Guided Rocket Launcher Allow Confusion" + target "Data::Weapon::RocketLauncherGuidedAllowSteal::Switch" + } Derive Nex_Line Seperator {} Derive TextButton Reset diff --git a/data/menu/data/gamemodes/gamemisc.menu b/data/menu/data/gamemodes/gamemisc.menu index 57fb598a1..5fc6af235 100644 --- a/data/menu/data/gamemodes/gamemisc.menu +++ b/data/menu/data/gamemodes/gamemisc.menu @@ -158,6 +158,13 @@ Item DataContainer Misc [DataLink_OnOffSwitch] } + Item Data_Cvar HomingRocket + { + cvarName "g_homing_missile" + defValue 0 + + [DataLink_OnOffSwitch] + } Item Data_Cvar MidAir { cvarName "g_midair" diff --git a/data/menu/data/weapon.menu b/data/menu/data/weapon.menu index 3c94e5aa2..6e8de5979 100644 --- a/data/menu/data/weapon.menu +++ b/data/menu/data/weapon.menu @@ -466,4 +466,25 @@ Item DataContainer Weapon [DataLink_Setting] } + Item Data_Cvar RocketLauncherGuidedSpeed + { + cvarName "g_balance_rocketlauncher_homing_speed" + defValue 650 + + [DataLink_Setting] + } + Item Data_Cvar RocketLauncherGuidedTurnRate + { + cvarName "g_balance_rocketlauncher_homing_turnrate" + defValue 0.5 + + [DataLink_Setting] + } + Item Data_Cvar RocketLauncherGuidedAllowSteal + { + cvarName "g_balance_rocketlauncher_homing_allow_steal" + defValue 1 + + [DataLink_OnOffSwitch] + } } diff --git a/data/models/laser_dot.mdl b/data/models/laser_dot.mdl new file mode 100644 index 0000000000000000000000000000000000000000..ef12c6416532a74ce1727085403f31cd1418983c GIT binary patch literal 26836 zcmeI4J&#pY6oxMZ=QemI(v52 z`n>g$^~cs^H1%`d713L_?3YReL_h>YKmYKmYKmYKmYKmYKmYKmYKmYKmYKmYKmTfnep%Roh9`7E}O}G=DSJe^Ne{ipYJwL#?0s5V@>AsY{`7S*Jd)G?=w&4^Zn+@ zeC9LBn5hS>`A(8kuH@81*6wcy_8ad*PHnKp`+K9jA2}7Q@njUr`;t=|t?~Xdi}L>D z)Fx{@8HK`woVz|;JQ*_zGjirfiYH@6;YH58xp*>W6n^B)j}}kHjKY(g`LW{3m{ItW zGs6~7#_a0<4m@rdKX*Q(@Fu68w8r}mP=X_i7z7G`k=lpQ-z7G`klQPXZnxt&dEy1pK_7h`HK)}!|PsBS+^vHg5p zw~NiF9puywnsGZAH|=~q$(vG}XZlV4GNgQ=U+1ste*Pqd{6W*t2Pbtt)TX>JY4W~i zlILQZHl}H+LQY@wQo0agx)ekDDD~3W9Mb+arUTQI7TTQl<~HrDC-Ljl#x4COUJfbR z=g05re*89t_;%BeuTJW?+@@%sA7e9#M@CKfDdljy9*1vY3RmklE literal 0 HcmV?d00001 diff --git a/data/qcsrc/gamec/GameC.dsp b/data/qcsrc/gamec/GameC.dsp index 2f498cfb5..4e42131af 100644 --- a/data/qcsrc/gamec/GameC.dsp +++ b/data/qcsrc/gamec/GameC.dsp @@ -243,6 +243,10 @@ SOURCE=.\g_violence.c SOURCE=.\g_world.c # End Source File +# Begin Source File + +SOURCE=.\teamplay.c +# End Source File # End Group # Begin Group "map" diff --git a/data/qcsrc/gamec/cl_weaponsystem.c b/data/qcsrc/gamec/cl_weaponsystem.c index ade939f41..8e246391b 100644 --- a/data/qcsrc/gamec/cl_weaponsystem.c +++ b/data/qcsrc/gamec/cl_weaponsystem.c @@ -7,6 +7,67 @@ =========================================================================== */ +void LaserTarget_Think() +{ + entity e; + vector offset; + float uselaser; + uselaser = 0; + + // list of weapons that will use the laser, and the options that enable it + if(self.owner.laser_on && self.owner.weapon == WEP_ROCKET_LAUNCHER && cvar("g_homing_missile")) + uselaser = 1; + // example + //if(self.owner.weapon == WEP_ELECTRO && cvar("g_homing_electro")) + // uselaser = 1; + + + + // if a laser-enabled weapon isn't selected, delete any existing laser and quit + if(!uselaser) + { + // rocket launcher isn't selected, so no laser target. + if(self.lasertarget != world) + { + remove(self.lasertarget); + self.lasertarget = world; + } + return; + } + + if(!self.lasertarget) + { + // we don't have a lasertarget entity, so spawn one + //bprint("create laser target\n"); + e = self.lasertarget = spawn(); + e.owner = self.owner; // Its owner is my owner + e.classname = "laser_target"; + e.movetype = MOVETYPE_NOCLIP; // don't touch things + setmodel(e, "models/laser_dot.mdl"); // what it looks like + e.scale = 1.25; // make it larger + e.alpha = 0.25; // transparency + e.colormod = '255 0 0' * (1/255) * 8; // change colors + e.effects = EF_FULLBRIGHT; + // make it dynamically glow + // you should avoid over-using this, as it can slow down the player's computer. + e.glow_color = 251; // red color + e.glow_size = 12; + } + else + e = self.lasertarget; + + // move the laser dot to where the player is looking + + makevectors(self.owner.v_angle); // set v_forward etc to the direction the player is looking + offset = '0 0 26' + v_right*3; + traceline(self.owner.origin + offset, self.owner.origin + offset + v_forward * 2048, FALSE, self); // trace forward until you hit something, like a player or wall + setorigin(e, trace_endpos + v_forward*8); // move me to where the traceline ended + if(trace_plane_normal != '0 0 0') + e.angles = vectoangles(trace_plane_normal); + else + e.angles = vectoangles(v_forward); +} + void() CL_Weaponentity_Think = { self.nextthink = time; @@ -17,6 +78,9 @@ void() CL_Weaponentity_Think = } self.effects = self.owner.effects; self.alpha = self.owner.alpha; + + // create or update the lasertarget entity + LaserTarget_Think(); }; void() CL_ExteriorWeaponentity_Think = diff --git a/data/qcsrc/gamec/defs.h b/data/qcsrc/gamec/defs.h index f91b9a42b..fddac4871 100644 --- a/data/qcsrc/gamec/defs.h +++ b/data/qcsrc/gamec/defs.h @@ -203,3 +203,6 @@ float GRAPHOOK_RELEASE = 21; // (note: you can change the hook impulse #'s to whatever you please) .float hook_time; +// Laser target for laser-guided weapons +.entity lasertarget; +.float laser_on; diff --git a/data/qcsrc/gamec/g_world.c b/data/qcsrc/gamec/g_world.c index f5915b97c..66e074895 100644 --- a/data/qcsrc/gamec/g_world.c +++ b/data/qcsrc/gamec/g_world.c @@ -90,6 +90,10 @@ void worldspawn (void) precache_model ("models/weapons/w_rl.zym"); precache_model ("models/weapons/w_shotgun.zym"); precache_model ("models/weapons/w_uzi.zym"); + + // laser for laser-guided weapons + precache_model ("models/laser_dot.mdl"); + precache_sound ("announcer/1fragleft.wav"); precache_sound ("announcer/1minuteremains.wav"); precache_sound ("announcer/2fragsleft.wav"); diff --git a/data/qcsrc/gamec/w_rocketlauncher.c b/data/qcsrc/gamec/w_rocketlauncher.c index 6bdb10d07..2a6323140 100644 --- a/data/qcsrc/gamec/w_rocketlauncher.c +++ b/data/qcsrc/gamec/w_rocketlauncher.c @@ -5,7 +5,8 @@ void() rlauncher_select_01; float() rlauncher_check = { - if (self.ammo_rockets >= 3) + if (self.attack_finished > time // don't switch while guiding a missile + || self.ammo_rockets >= 3) return TRUE; return FALSE; }; @@ -16,6 +17,15 @@ void(float req) w_rlauncher = rlauncher_ready_01(); else if (req == WR_FIRE1) weapon_prepareattack(rlauncher_check, rlauncher_check, rlauncher_fire1_01, cvar("g_balance_rocketlauncher_refire")); + else if (req == WR_FIRE2 && cvar("g_homing_missile")) + { + if(self.exteriorweaponentity.attack_finished < time) + { + self.exteriorweaponentity.attack_finished = time + 0.4; + self.laser_on = !self.laser_on; + sound (self, CHAN_AUTO, "weapons/tink1.wav", 1, ATTN_NORM); + } + } else if (req == WR_RAISE) rlauncher_select_01(); else if (req == WR_UPDATECOUNTS) @@ -40,11 +50,87 @@ void W_Rocket_Explode (void) self.event_damage = SUB_Null; RadiusDamage (self, self.owner, cvar("g_balance_rocketlauncher_damage"), cvar("g_balance_rocketlauncher_edgedamage"), cvar("g_balance_rocketlauncher_radius"), world, cvar("g_balance_rocketlauncher_force"), IT_ROCKET_LAUNCHER); + if (self.owner.weapon == WEP_ROCKET_LAUNCHER) + { + if(cvar("g_homing_missile")) + self.owner.attack_finished = time + cvar("g_balance_rocketlauncher_refire"); + } + remove (self); } +entity FindLaserTarget(entity e, float dist_variance, float dot_variance) +{ + entity head, selected; + vector dir; + float dist, maxdist,// bestdist, + dot,// bestdot, + points, bestpoints; + //bestdist = 9999; + //bestdot = -2; + bestpoints = 0; + maxdist = 800; + selected = world; + + makevectors(e.angles); + + head = find(world, classname, "laser_target"); + while(head) + { + points = 0; + dir = normalize(head.origin - self.origin); + dot = dir * v_forward; + dist = vlen(head.origin - self.origin); + if(dist > maxdist) + dist = maxdist; + + // gain points for being in front + points = points + ((dot+1)*0.5) * 500 + * (1 + crandom()*dot_variance); + // gain points for being close away + points = points + (1 - dist/maxdist) * 1000 + * (1 + crandom()*dot_variance); + + traceline(e.origin, head.origin, TRUE, self); + if(trace_fraction < 1) + { + points = 0; + } + + if(points > bestpoints)//random() > 0.5)// + { + bestpoints = points; + selected = head; + } + + + /* + dot = dir * v_forward; + if(dot > bestdot * (1 + crandom()*dot_variance)) + { + dist = vlen(head.origin - self.origin); + if(dist < bestdist * (1 + crandom()*dist_variance)) + { + traceline(e.origin, head.origin, TRUE, self); + if(trace_fraction >= 1) + { + } + } + } + */ + head = find(head, classname, "laser_target"); + } + + //bprint(selected.owner.netname); + //bprint("\n"); + return selected; +} + void W_Rocket_Think (void) { + entity e; + vector desireddir, olddir, newdir; + float turnrate; self.nextthink = time; if (time > self.cnt) { @@ -52,8 +138,59 @@ void W_Rocket_Think (void) return; } if (self.owner.weapon == WEP_ROCKET_LAUNCHER) - if (self.owner.button3) - W_Rocket_Explode (); + { + if(cvar("g_homing_missile")) + { + if(!self.owner.button0) + self.ltime = -1; // indicate that the player has let go of the button + + + if (self.owner.button0 && self.ltime < 0) // if the player let go of the button and then pushed it again + { + W_Rocket_Explode (); + return; + } + + if(cvar("g_balance_rocketlauncher_homing_allow_steal")) + { + if(self.owner.laser_on) + { + if(self.attack_finished < time) + { + self.attack_finished = time + 0.2 + random()*0.3; + self.enemy = FindLaserTarget(self, 0.7, 0.7); + } + + if(!self.enemy) + self.enemy = self.owner.weaponentity.lasertarget; + } + else self.enemy = world; + } + else // don't allow stealing: always target my owner's laser (if it exists) + self.enemy = self.owner.weaponentity.lasertarget; + + if(self.enemy != world) + { + //bprint(strcat("Targeting ", self.enemy.owner.netname, "'s laser\n")); + if(!self.speed) + self.speed = vlen(self.velocity); + e = self.enemy;//self.owner.weaponentity.lasertarget; + turnrate = cvar("g_balance_rocketlauncher_homing_turnrate");//0.65; // how fast to turn + desireddir = normalize(e.origin - self.origin); // get direction from my position to the laser target + olddir = normalize(self.velocity); // get my current direction + newdir = normalize((olddir + desireddir * turnrate) * 0.5); // take the average of the 2 directions; not the best method but simple & easy + self.velocity = newdir * self.speed; // make me fly in the new direction at my flight speed + self.angles = vectoangles(self.velocity); // turn model in the new flight direction + + self.owner.attack_finished = time + 0.2; + } + } + else + { + if (self.owner.button3) + W_Rocket_Explode (); + } + } } void W_Rocket_Touch (void) @@ -101,7 +238,10 @@ void W_Rocket_Attack (void) setsize (missile, '0 0 0', '0 0 0'); setorigin (missile, org); - missile.velocity = v_forward * cvar("g_balance_rocketlauncher_speed"); + if(cvar("g_homing_missile") && self.laser_on) + missile.velocity = v_forward * cvar("g_balance_rocketlauncher_homing_speed"); + else + missile.velocity = v_forward * cvar("g_balance_rocketlauncher_speed"); missile.angles = vectoangles (missile.velocity); missile.touch = W_Rocket_Touch; @@ -122,11 +262,10 @@ void W_Rocket_Attack (void) // weapon frames void() rlauncher_ready_01 = {weapon_thinkf(WFRAME_IDLE, 0.1, rlauncher_ready_01); self.weaponentity.state = WS_READY;}; -void() rlauncher_select_01 = {weapon_thinkf(-1, cvar("g_balance_weaponswitchdelay"), w_ready); weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, '0 0 0');}; -void() rlauncher_deselect_01 = {weapon_thinkf(-1, cvar("g_balance_weaponswitchdelay"), w_clear); weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, PLAYER_WEAPONSELECTION_RANGE);}; +void() rlauncher_select_01 = {weapon_thinkf(-1, cvar("g_balance_weaponswitchdelay"), w_ready); weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, '0 0 0'); self.laser_on = 1;}; +void() rlauncher_deselect_01 = {weapon_thinkf(-1, cvar("g_balance_weaponswitchdelay"), w_clear); weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, PLAYER_WEAPONSELECTION_RANGE); self.laser_on = 0;}; void() rlauncher_fire1_01 = { weapon_doattack(rlauncher_check, rlauncher_check, W_Rocket_Attack); weapon_thinkf(WFRAME_FIRE1, 0.3, rlauncher_ready_01); }; - -- 2.39.2