r6105 - in trunk/data: models/weapons qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Wed Mar 11 17:39:57 EDT 2009
Author: lordhavoc
Date: 2009-03-11 17:39:56 -0400 (Wed, 11 Mar 2009)
New Revision: 6105
Added:
trunk/data/models/weapons/w_uzi.dpm
trunk/data/models/weapons/w_uzi.dpm.animinfo
trunk/data/models/weapons/w_uzi.qh
Modified:
trunk/data/qcsrc/server/cl_client.qc
trunk/data/qcsrc/server/cl_physics.qc
trunk/data/qcsrc/server/cl_player.qc
trunk/data/qcsrc/server/cl_weapons.qc
trunk/data/qcsrc/server/cl_weaponsystem.qc
trunk/data/qcsrc/server/defs.qh
trunk/data/qcsrc/server/g_subs.qc
trunk/data/qcsrc/server/movelib.qc
trunk/data/qcsrc/server/pathlib.qc
trunk/data/qcsrc/server/progs.src
trunk/data/qcsrc/server/steerlib.qc
trunk/data/qcsrc/server/w_hlac.qc
trunk/data/qcsrc/server/w_seeker.qc
trunk/data/qcsrc/server/w_uzi.qc
Log:
added dpm weapon support
added motorsep's fixed up w_uzi model
Added: trunk/data/models/weapons/w_uzi.dpm
===================================================================
(Binary files differ)
Property changes on: trunk/data/models/weapons/w_uzi.dpm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/data/models/weapons/w_uzi.dpm.animinfo
===================================================================
--- trunk/data/models/weapons/w_uzi.dpm.animinfo (rev 0)
+++ trunk/data/models/weapons/w_uzi.dpm.animinfo 2009-03-11 21:39:56 UTC (rev 6105)
@@ -0,0 +1,4 @@
+1 12 40 // fire1
+13 12 40 // fire2
+25 48 10 // idle
+0 1 10 // reload
Added: trunk/data/models/weapons/w_uzi.qh
===================================================================
--- trunk/data/models/weapons/w_uzi.qh (rev 0)
+++ trunk/data/models/weapons/w_uzi.qh 2009-03-11 21:39:56 UTC (rev 6105)
@@ -0,0 +1,12 @@
+
+/*
+Generated header file for w_uzi
+This file contains animation definitions for use in code referencing the model, simply add this file to your progs.src before use.
+*/
+
+vector anim_w_uzi_ref1 = '0 1 20';
+vector anim_w_uzi_fire = '1 12 40';
+vector anim_w_uzi_fire2 = '13 12 40';
+vector anim_w_uzi_idle = '25 48 20';
+
+// end of animation definitions for w_uzi
Modified: trunk/data/qcsrc/server/cl_client.qc
===================================================================
--- trunk/data/qcsrc/server/cl_client.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/cl_client.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -2274,7 +2274,7 @@
self.crouch = TRUE;
self.view_ofs = PL_CROUCH_VIEW_OFS;
setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX);
- player_setanim(self.anim_duck, FALSE, TRUE, TRUE);
+ setanim(self, self.anim_duck, FALSE, TRUE, TRUE);
}
}
else
Modified: trunk/data/qcsrc/server/cl_physics.qc
===================================================================
--- trunk/data/qcsrc/server/cl_physics.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/cl_physics.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -83,9 +83,9 @@
self.flags &~= FL_JUMPRELEASED;
if (self.crouch)
- player_setanim(self.anim_duckjump, FALSE, TRUE, TRUE);
+ setanim(self, self.anim_duckjump, FALSE, TRUE, TRUE);
else
- player_setanim(self.anim_jump, FALSE, TRUE, TRUE);
+ setanim(self, self.anim_jump, FALSE, TRUE, TRUE);
if(g_jump_grunt)
PlayerSound(playersound_jump, CHAN_PLAYER, VOICETYPE_PLAYERSOUND);
Modified: trunk/data/qcsrc/server/cl_player.qc
===================================================================
--- trunk/data/qcsrc/server/cl_player.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/cl_player.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -65,30 +65,6 @@
self = oldself;
}
-float animparseerror;
-vector animparseline(float animfile)
-{
- local string line;
- local float c;
- local vector anim;
- if (animfile < 0)
- return '0 1 2';
- line = fgets(animfile);
- c = tokenize_sane(line);
- if (c != 3)
- {
- animparseerror = TRUE;
- return '0 1 2';
- }
- anim_x = stof(argv(0));
- anim_y = stof(argv(1));
- anim_z = stof(argv(2));
- // don't allow completely bogus values
- if (anim_x < 0 || anim_y < 1 || anim_z < 0.001)
- anim = '0 1 2';
- return anim;
-};
-
void player_setupanimsformodel()
{
local string animfilename;
@@ -155,43 +131,14 @@
else
dprint("File ", animfilename, " not found, assuming legacy .zym model animation timings\n");
// reset animstate now
- player_setanim(self.anim_idle, TRUE, FALSE, TRUE);
+ setanim(self, self.anim_idle, TRUE, FALSE, TRUE);
};
-void player_setanim(vector anim, float looping, float override, float restart)
-{
- if (!restart)
- if (anim_x == self.animstate_startframe)
- if (anim_y == self.animstate_numframes)
- if (anim_z == self.animstate_framerate)
- return;
- self.animstate_startframe = anim_x;
- self.animstate_numframes = anim_y;
- self.animstate_framerate = anim_z;
- self.animstate_starttime = time;
- self.animstate_endtime = time + self.animstate_numframes / self.animstate_framerate;
- self.animstate_looping = looping;
- self.animstate_override = override;
- self.frame = self.animstate_startframe;
-};
-
-void player_updateframe()
-{
- if (time >= self.animstate_endtime)
- {
- if (self.animstate_looping)
- {
- self.animstate_starttime = self.animstate_endtime;
- self.animstate_endtime = self.animstate_endtime + self.animstate_numframes / self.animstate_framerate;
- }
- self.animstate_override = FALSE;
- }
- self.frame = self.animstate_startframe + bound(0, (time - self.animstate_starttime) * self.animstate_framerate, self.animstate_numframes - 1);
-};
-
void player_anim (void)
{
- player_updateframe();
+ updateanim(self);
+ if (self.weaponentity)
+ updateanim(self.weaponentity);
if (self.deadflag != DEAD_NO)
{
@@ -212,43 +159,46 @@
if (!(self.flags & FL_ONGROUND))
{
if (self.crouch)
- player_setanim(self.anim_duckjump, FALSE, TRUE, FALSE);
+ setanim(self, self.anim_duckjump, FALSE, TRUE, FALSE);
else
- player_setanim(self.anim_jump, FALSE, TRUE, FALSE);
+ setanim(self, self.anim_jump, FALSE, TRUE, FALSE);
}
else if (self.crouch)
{
if (self.movement_x * self.movement_x + self.movement_y * self.movement_y > 20)
- player_setanim(self.anim_duckwalk, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_duckwalk, TRUE, FALSE, FALSE);
else
- player_setanim(self.anim_duckidle, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_duckidle, TRUE, FALSE, FALSE);
}
else if ((self.movement_x * self.movement_x + self.movement_y * self.movement_y) > 20)
{
if (self.movement_x > 0 && self.movement_y == 0)
- player_setanim(self.anim_run, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_run, TRUE, FALSE, FALSE);
else if (self.movement_x < 0 && self.movement_y == 0)
- player_setanim(self.anim_runbackwards, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_runbackwards, TRUE, FALSE, FALSE);
else if (self.movement_x == 0 && self.movement_y > 0)
- player_setanim(self.anim_straferight, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_straferight, TRUE, FALSE, FALSE);
else if (self.movement_x == 0 && self.movement_y < 0)
- player_setanim(self.anim_strafeleft, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_strafeleft, TRUE, FALSE, FALSE);
else if (self.movement_x > 0 && self.movement_y > 0)
- player_setanim(self.anim_forwardright, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_forwardright, TRUE, FALSE, FALSE);
else if (self.movement_x > 0 && self.movement_y < 0)
- player_setanim(self.anim_forwardleft, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_forwardleft, TRUE, FALSE, FALSE);
else if (self.movement_x < 0 && self.movement_y > 0)
- player_setanim(self.anim_backright, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_backright, TRUE, FALSE, FALSE);
else if (self.movement_x < 0 && self.movement_y < 0)
- player_setanim(self.anim_backleft, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_backleft, TRUE, FALSE, FALSE);
else
- player_setanim(self.anim_run, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_run, TRUE, FALSE, FALSE);
}
else
- player_setanim(self.anim_idle, TRUE, FALSE, FALSE);
+ setanim(self, self.anim_idle, TRUE, FALSE, FALSE);
}
+
+ if (self.weaponentity)
+ if (!self.weaponentity.animstate_override)
+ setanim(self, self.anim_idle, TRUE, FALSE, FALSE);
}
-//End change by Supajoe on 11:44 PM EST 11/16/03 (Subject: Player animations)
void SpawnThrownWeapon (vector org, float w)
{
@@ -371,9 +321,9 @@
if(sv_gentle < 1) {
if (random() > 0.5)
- player_setanim(self.anim_pain1, FALSE, TRUE, TRUE);
+ setanim(self, self.anim_pain1, FALSE, TRUE, TRUE);
else
- player_setanim(self.anim_pain2, FALSE, TRUE, TRUE);
+ setanim(self, self.anim_pain2, FALSE, TRUE, TRUE);
if(!DEATH_ISWEAPON(deathtype, WEP_LASER) || attacker != self || self.health < 2 * cvar("g_balance_laser_primary_damage") * cvar("g_balance_selfdamagepercent") + 1)
// exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
@@ -520,12 +470,12 @@
self.respawn_countdown = -1; // do not count down
if (random() < 0.5)
{
- player_setanim(self.anim_die1, FALSE, TRUE, TRUE);
+ setanim(self, self.anim_die1, FALSE, TRUE, TRUE);
self.dead_frame = self.anim_dead1_x;
}
else
{
- player_setanim(self.anim_die2, FALSE, TRUE, TRUE);
+ setanim(self, self.anim_die2, FALSE, TRUE, TRUE);
self.dead_frame = self.anim_dead2_x;
}
// set damage function to corpse damage
Modified: trunk/data/qcsrc/server/cl_weapons.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weapons.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/cl_weapons.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -307,7 +307,7 @@
{
if (self.weaponentity.state == WS_CLEAR)
{
- player_setanim(self.anim_draw, FALSE, TRUE, TRUE);
+ setanim(self, self.anim_draw, FALSE, TRUE, TRUE);
self.weaponentity.state = WS_RAISE;
weapon_action(self.switchweapon, WR_SETUP);
// VorteX: add player model weapon select frame here
Modified: trunk/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weaponsystem.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/cl_weaponsystem.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -257,7 +257,7 @@
float tb;
self.nextthink = time;
if (intermission_running)
- self.frame = WFRAME_IDLE;
+ self.frame = self.anim_idle_x;
if (self.owner.weaponentity != self)
{
remove(self);
@@ -273,11 +273,40 @@
self.cnt = self.owner.weapon;
self.dmg = self.owner.modelindex;
self.deadflag = self.owner.deadflag;
+
+ string animfilename;
+ float animfile;
if (self.owner.weaponname != "")
- setmodel(self, strcat("models/weapons/w_", self.owner.weaponname, ".zym")); // precision set below
+ {
+ animfilename = strcat("models/weapons/w_", self.owner.weaponname, ".dpm.animinfo");
+ animfile = fopen(animfilename, FILE_READ);
+ if (animfile >= 0)
+ {
+ animparseerror = FALSE;
+ self.anim_fire1 = animparseline(animfile);
+ self.anim_fire2 = animparseline(animfile);
+ self.anim_idle = animparseline(animfile);
+ self.anim_reload = animparseline(animfile);
+ fclose(animfile);
+ if (animparseerror)
+ print("Parse error in ", animfilename, ", some player animations are broken\n");
+ setmodel(self, strcat("models/weapons/w_", self.owner.weaponname, ".dpm")); // precision set below
+ }
+ else
+ {
+ self.anim_fire1 = '0 1 10';
+ self.anim_fire2 = '1 1 10';
+ self.anim_idle = '2 1 10';
+ self.anim_reload = '3 1 10';
+ setmodel(self, strcat("models/weapons/w_", self.owner.weaponname, ".zym")); // precision set below
+ }
+ }
else
self.model = "";
+ // reset animstate now
+ setanim(self, self.anim_idle, TRUE, FALSE, TRUE);
+
if(cvar("g_shootfromcenter") || cvar("g_shootfromeye"))
{
entity e;
@@ -570,15 +599,29 @@
void weapon_thinkf(float fr, float t, void() func)
{
- if (fr >= 0)
+ vector a;
+ float restartanim;
+
+ if (fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2)
+ restartanim = TRUE;
+ else
+ restartanim = FALSE;
+
+ if (self.weaponentity)
{
- if (self.weaponentity != world)
+ if (fr == WFRAME_IDLE)
+ a = self.weaponentity.anim_idle;
+ else if (fr == WFRAME_FIRE1)
+ a = self.weaponentity.anim_fire1;
+ else if (fr == WFRAME_FIRE2)
+ a = self.weaponentity.anim_fire2;
+ else if (fr == WFRAME_RELOAD)
+ a = self.weaponentity.anim_reload;
+ setanim(self.weaponentity, a, restartanim == FALSE, restartanim, restartanim);
+
+ if(reset)
{
- if(fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2)
- {
- BITXOR_ASSIGN(self.weaponentity.effects, EF_TELEPORT_BIT);
- }
- self.weaponentity.frame = fr;
+ BITXOR_ASSIGN(self.weaponentity.effects, EF_TELEPORT_BIT);
}
}
@@ -617,14 +660,14 @@
self.weapon_think = func;
//dprint("next ", ftos(self.weapon_nextthink), "\n");
- if (fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2)
+ if (reset)
if (t)
if (!self.crouch) // shoot anim stands up, this looks bad
{
local vector anim;
anim = self.anim_shoot;
anim_z = anim_y / t;
- player_setanim(anim, FALSE, TRUE, TRUE);
+ setanim(self, anim, FALSE, TRUE, TRUE);
}
};
Modified: trunk/data/qcsrc/server/defs.qh
===================================================================
--- trunk/data/qcsrc/server/defs.qh 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/defs.qh 2009-03-11 21:39:56 UTC (rev 6105)
@@ -147,8 +147,14 @@
.vector anim_backright; // player running backward and right
.vector anim_backleft; // player running back and left
+// weapon animation vectors:
+.vector anim_fire1;
+.vector anim_fire2;
+.vector anim_idle;
+.vector anim_reload;
+
void() player_setupanimsformodel;
-void player_setanim(vector anim, float looping, float override, float restart);
+void setanim(entity e, vector anim, float looping, float override, float restart);
.string mdl;
Modified: trunk/data/qcsrc/server/g_subs.qc
===================================================================
--- trunk/data/qcsrc/server/g_subs.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/g_subs.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -12,6 +12,61 @@
// if anything breaks, tell the mapper to fix his map! info_null is meant to remove itself immediately.
}
+void setanim(entity e, vector anim, float looping, float override, float restart)
+{
+ if (!restart)
+ if (anim_x == e.animstate_startframe)
+ if (anim_y == e.animstate_numframes)
+ if (anim_z == e.animstate_framerate)
+ return;
+ e.animstate_startframe = anim_x;
+ e.animstate_numframes = anim_y;
+ e.animstate_framerate = anim_z;
+ e.animstate_starttime = time;
+ e.animstate_endtime = time + e.animstate_numframes / e.animstate_framerate;
+ e.animstate_looping = looping;
+ e.animstate_override = override;
+ e.frame = e.animstate_startframe;
+};
+
+void updateanim(entity e)
+{
+ if (time >= e.animstate_endtime)
+ {
+ if (e.animstate_looping)
+ {
+ e.animstate_starttime = e.animstate_endtime;
+ e.animstate_endtime = e.animstate_endtime + e.animstate_numframes / e.animstate_framerate;
+ }
+ e.animstate_override = FALSE;
+ }
+ e.frame = e.animstate_startframe + bound(0, (time - e.animstate_starttime) * e.animstate_framerate, e.animstate_numframes - 1);
+};
+
+float animparseerror;
+vector animparseline(float animfile)
+{
+ local string line;
+ local float c;
+ local vector anim;
+ if (animfile < 0)
+ return '0 1 2';
+ line = fgets(animfile);
+ c = tokenize_sane(line);
+ if (c != 3)
+ {
+ animparseerror = TRUE;
+ return '0 1 2';
+ }
+ anim_x = stof(argv(0));
+ anim_y = stof(argv(1));
+ anim_z = stof(argv(2));
+ // don't allow completely bogus values
+ if (anim_x < 0 || anim_y < 1 || anim_z < 0.001)
+ anim = '0 1 2';
+ return anim;
+};
+
/*
==================
SUB_Remove
Modified: trunk/data/qcsrc/server/movelib.qc
===================================================================
--- trunk/data/qcsrc/server/movelib.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/movelib.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -1,132 +1,132 @@
-/**
- Simulate drag
- self.velocity = movelib_vdrag(self.velocity,0.02,0.5);
-**/
-vector movelib_dragvec(float drag, float exp)
-{
- float lspeed,ldrag;
-
- lspeed = vlen(self.velocity);
- ldrag = lspeed * drag;
- ldrag = ldrag * (drag * exp);
- ldrag = 1 - (ldrag / lspeed);
-
- return self.velocity * ldrag;
-}
-
-/**
- Simulate drag
- self.velocity = movelib_vdrag(somespeed,0.01,0.7);
-**/
-float movelib_dragflt(float fspeed,float drag,float exp)
-{
- float ldrag;
-
- ldrag = fspeed * drag;
- ldrag = ldrag * ldrag * exp;
- ldrag = 1 - (ldrag / fspeed);
-
- return ldrag;
-}
-
-/**
- Do a inertia simulation based on velocity.
- Basicaly, this allows you to simulate objects loss steering with speed.
- self.velocity = movelib_inertia_fromspeed(self.velocity,newvel,1000,0.1,0.9);
-**/
-vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
-{
- float influense;
-
- influense = vlen(self.velocity) * (1 / vel_max);
-
- influense = bound(newmin,influense,oldmax);
-
- return (vel_new * (1 - influense)) + (self.velocity * influense);
-}
-
-vector movelib_inertmove(vector new_vel,float new_bias)
-{
- return new_vel * new_bias + self.velocity * (1-new_bias);
-}
-
-.float movelib_lastupdate;
-void movelib_move(vector force,float max_velocity,float drag,float mass,float breakforce)
-{
- float deltatime;
- float acceleration;
- //float mspeed;
-
- deltatime = time - self.movelib_lastupdate;
- if (deltatime > 0.15) deltatime = 0;
- self.movelib_lastupdate = time;
- if(!deltatime) return;
-
- //mspeed = vlen(self.velocity);
-
- if(mass)
- acceleration = vlen(force) / mass;
- else
- acceleration = vlen(force);
-
- if(self.flags & FL_ONGROUND)
- {
- if(breakforce)
- {
- breakforce = 1 - ((breakforce / mass) * deltatime);
- self.velocity = self.velocity * breakforce;
- }
-
- self.velocity = self.velocity + force * (acceleration * deltatime);
- }
-
- self.velocity = self.velocity + '0 0 -1' * sv_gravity * deltatime;
-
- if(drag)
- self.velocity = movelib_dragvec(drag, 1);
-
- if(max_velocity)
- if(vlen(self.velocity) > max_velocity)
- self.velocity = normalize(self.velocity) * max_velocity;
-}
-
-void movelib_move_simple(vector newdir,float velo,float turnrate)
-{
- vector olddir;
-
- olddir = normalize(self.velocity);
-
- self.velocity = normalize(olddir + newdir * turnrate) * velo;
-}
-
-/*
-vector movelib_accelerate(float force)
-{
- vector vel;
- vel = self.velocity;
- vel = normalize(vel) * (vlen(vel) + force);
- self.velocity = self.velocity + vel;
-}
-
-
-vector movelib_decelerate(float force,float mass)
-{
- vector vel;
- float decel;
-
- if(mass)
- decel = force / mass;
- else
- decel = force;
-
- vel = self.velocity;
- vel = normalize(vel) * max((vlen(vel) - decel),0);
- self.velocity = self.velocity - vel;
-
- if(vlen(self.velocity) < 5) self.velocity = '0 0 0';
-}
-*/
-vector movelib_velocity_transfer(entity source,entity destination)
-{
- return '0 0 0';
-}
+/**
+ Simulate drag
+ self.velocity = movelib_vdrag(self.velocity,0.02,0.5);
+**/
+vector movelib_dragvec(float drag, float exp)
+{
+ float lspeed,ldrag;
+
+ lspeed = vlen(self.velocity);
+ ldrag = lspeed * drag;
+ ldrag = ldrag * (drag * exp);
+ ldrag = 1 - (ldrag / lspeed);
+
+ return self.velocity * ldrag;
+}
+
+/**
+ Simulate drag
+ self.velocity = movelib_vdrag(somespeed,0.01,0.7);
+**/
+float movelib_dragflt(float fspeed,float drag,float exp)
+{
+ float ldrag;
+
+ ldrag = fspeed * drag;
+ ldrag = ldrag * ldrag * exp;
+ ldrag = 1 - (ldrag / fspeed);
+
+ return ldrag;
+}
+
+/**
+ Do a inertia simulation based on velocity.
+ Basicaly, this allows you to simulate objects loss steering with speed.
+ self.velocity = movelib_inertia_fromspeed(self.velocity,newvel,1000,0.1,0.9);
+**/
+vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
+{
+ float influense;
+
+ influense = vlen(self.velocity) * (1 / vel_max);
+
+ influense = bound(newmin,influense,oldmax);
+
+ return (vel_new * (1 - influense)) + (self.velocity * influense);
+}
+
+vector movelib_inertmove(vector new_vel,float new_bias)
+{
+ return new_vel * new_bias + self.velocity * (1-new_bias);
+}
+
+.float movelib_lastupdate;
+void movelib_move(vector force,float max_velocity,float drag,float mass,float breakforce)
+{
+ float deltatime;
+ float acceleration;
+ //float mspeed;
+
+ deltatime = time - self.movelib_lastupdate;
+ if (deltatime > 0.15) deltatime = 0;
+ self.movelib_lastupdate = time;
+ if(!deltatime) return;
+
+ //mspeed = vlen(self.velocity);
+
+ if(mass)
+ acceleration = vlen(force) / mass;
+ else
+ acceleration = vlen(force);
+
+ if(self.flags & FL_ONGROUND)
+ {
+ if(breakforce)
+ {
+ breakforce = 1 - ((breakforce / mass) * deltatime);
+ self.velocity = self.velocity * breakforce;
+ }
+
+ self.velocity = self.velocity + force * (acceleration * deltatime);
+ }
+
+ self.velocity = self.velocity + '0 0 -1' * sv_gravity * deltatime;
+
+ if(drag)
+ self.velocity = movelib_dragvec(drag, 1);
+
+ if(max_velocity)
+ if(vlen(self.velocity) > max_velocity)
+ self.velocity = normalize(self.velocity) * max_velocity;
+}
+
+void movelib_move_simple(vector newdir,float velo,float turnrate)
+{
+ vector olddir;
+
+ olddir = normalize(self.velocity);
+
+ self.velocity = normalize(olddir + newdir * turnrate) * velo;
+}
+
+/*
+vector movelib_accelerate(float force)
+{
+ vector vel;
+ vel = self.velocity;
+ vel = normalize(vel) * (vlen(vel) + force);
+ self.velocity = self.velocity + vel;
+}
+
+
+vector movelib_decelerate(float force,float mass)
+{
+ vector vel;
+ float decel;
+
+ if(mass)
+ decel = force / mass;
+ else
+ decel = force;
+
+ vel = self.velocity;
+ vel = normalize(vel) * max((vlen(vel) - decel),0);
+ self.velocity = self.velocity - vel;
+
+ if(vlen(self.velocity) < 5) self.velocity = '0 0 0';
+}
+*/
+vector movelib_velocity_transfer(entity source,entity destination)
+{
+ return '0 0 0';
+}
Modified: trunk/data/qcsrc/server/pathlib.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/pathlib.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -1,480 +1,480 @@
-#define PFL_GROUNDSNAP 1
-#define PFL_NOOPTIMIZE 2
-#define PFL_SUBPATH3D 4
-
-#define PT_QUICKSTAR 1
-#define PT_QUICKBOX 2
-#define PT_ASTAR 4 // FIXME NOT IMPLEMENTED
-
-//#define PATHLIB_RDFIELDS
-#ifdef PATHLIB_RDFIELDS
- #define path_flags lip
-
- #define path_subpathing_size autoswitch
- #define path_subpathing_bboxexpand welcomemessage_time
-
- #define path_next swampslug
- #define path_prev lasertarget
-#else
- .entity path_next;
- .entity path_prev;
-
- .float path_subpathing_size;
- .float path_subpathing_bboxexpand;
- .float path_flags;
-#endif
-
-#define pathlib_garbagetime 120
-#define pathib_maxdivide 512
-
-.float(vector start,vector end) path_validate;
-
-float pathlib_stdproc_path_validate(vector start,vector end)
-{
- tracebox(start, self.mins, self.maxs, end, MOVE_WORLDONLY, self);
-
- if(vlen(trace_endpos - end) < 32)
- return 1;
-
- return 0;
-}
-
-vector pathlib_groundsnap(vector where)
-{
- float lsize;
-
- lsize = vlen(self.mins - self.maxs) * 0.25;
-
- traceline(where + ('0 0 1' * lsize) ,where - '0 0 10240',MOVE_WORLDONLY,self);
-
- return trace_endpos + ('0 0 1' * lsize);
-
-}
-
-entity pathlib_createpoint(entity parent,entity next,entity first,vector where)
-{
- entity point;
-
- point = spawn();
- point.classname = "path_node";
-
- if(first)
- point.owner = first;
- else
- {
- point.classname = "path_master";
- point.owner = point;
- }
-
- if(parent)
- point.path_prev = parent;
-
- if(next)
- {
- point.path_next = next;
- }
- else
- point.classname = "path_end";
-
- if (point.owner.path_flags & PFL_GROUNDSNAP)
- where = pathlib_groundsnap(where);
-
- setorigin(point,where);
-
-
- return point;
-}
-
-/*
-float pathlib_scoresubpath(vector start,vector point,vector end,float minstep)
-{
- float dist_stp,dist_pte,dist_total;
-
- dist_stp = vlen(start - point);
- if(dist_stp < minstep)
- return 100000000;
-
- dist_pte = vlen(point - end);
- dist_total = dist_stp + dist_pte;
- return -1;
-}
-*/
-
-vector pathlib_subpath_quickbox(entity start,vector vcrash,entity end,float maxsize)
-{
-
- float step;
- float pathscore;
- float pathscore_best;
- float dist;
- vector bestpoint,point;
- float zmin,zmax;
- vector box;
-
- pathscore_best = 0;
-
- step = vlen(self.maxs - self.mins) * start.owner.path_subpathing_bboxexpand;
-
- if(start.owner.path_flags & PFL_SUBPATH3D)
- {
- zmin = maxsize * -1;
- zmax = maxsize;
- }
- else
- {
- zmin = 0;
- zmax = 1;
- }
-
- for(box_z = zmin; box_z < zmax; box_z += step)
- for(box_y = -maxsize; box_y < maxsize; box_y += step)
- for(box_x = -maxsize; box_x < maxsize; box_x += step)
- {
-
- point = vcrash + box;
-
- if(start.owner.path_flags & PFL_GROUNDSNAP)
- point = pathlib_groundsnap(point);
-
- if(self.path_validate(start.origin,point))
- {
- dist = vlen(start.origin - point);
- if(dist > step)
- {
- pathscore = 1 / (dist + vlen(point - end.origin));
- if(pathscore > pathscore_best)
- {
- bestpoint = point;
- pathscore_best = pathscore;
- }
- }
- }
-
- }
-
- if(pathscore_best != 0)
- return bestpoint;
-
- return start.origin;
-}
-
-vector pathlib_subpath_quickstar(entity start,entity end,float gridsize)
-{
- vector point, best_point;
- float score, best_score;
- vector dir_end;
-
- dir_end = normalize(end.origin - start.origin);
- dir_end_x = dir_end_x * -1;
-
- makevectors(dir_end);
-
- best_score = 0;
- score = 0;
-
- best_point = start.origin;
-
- // Forward
- point = start.origin + v_forward * gridsize;
- point = pathlib_groundsnap(point);
- if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
- if(score < best_score) { best_point = point; best_score = score; }
- //te_lightning1(world,start.origin,point);
-
- // Forward-right
- point = start.origin + (v_forward + v_right * 0.5) * gridsize;
- point = pathlib_groundsnap(point);
- if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
- if(score < best_score) { best_point = point; best_score = score; }
- //te_lightning1(world,start.origin,point);
-
-
- // Forward-left
- point = start.origin + (v_forward - v_right * 0.5) * gridsize;
- point = pathlib_groundsnap(point);
- if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
- if(score < best_score) { best_point = point; best_score = score; }
- //te_lightning1(world,start.origin,point);
-
-
- // Right
- point = start.origin + v_right * gridsize;
- point = pathlib_groundsnap(point);
- if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
- if(score < best_score) { best_point = point; best_score = score; }
- //te_lightning1(world,start.origin,point);
-
- // Left
- point = start.origin - v_right * gridsize;
- point = pathlib_groundsnap(point);
- if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
- if(score < best_score) { best_point = point; best_score = score; }
- //te_lightning1(world,start.origin,point);
-
- // Back
- point = start.origin - v_forward * gridsize;
- point = pathlib_groundsnap(point);
- if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
- if(score < best_score) { best_point = point; best_score = score; }
- //te_lightning1(world,start.origin,point);
-
- // Back-right
-
- point = start.origin - (v_forward + v_right * 0.5) * gridsize;
- point = pathlib_groundsnap(point);
- if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
- if(score < best_score) { best_point = point; best_score = score; }
- //te_lightning1(world,start.origin,point);
-
- // Back-left
- point = start.origin - (v_forward - v_right * 0.5) * gridsize;
- point = pathlib_groundsnap(point);
- if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
- if(score < best_score) { best_point = point; best_score = score; }
- //te_lightning1(world,start.origin,point);
-
- return(best_point);
-}
-
-float pathlib_path(entity start,entity end,float pathing_method)
-{
- vector vcrash;
- vector subpath_point;
- entity subpoint;
-
- // Fail.
- if(start.cnt > pathib_maxdivide)
- {
- bprint("To many segments!\n");
- return 0;
- }
-
- if(self.path_validate(start.origin,end.origin))
- return 1;
-
- vcrash = trace_endpos;
-
- switch(pathing_method)
- {
- case PT_QUICKSTAR:
- subpath_point = pathlib_subpath_quickstar(start,end,start.owner.path_subpathing_size);
- break;
- case PT_QUICKBOX:
- subpath_point = pathlib_subpath_quickbox(start,vcrash,end,start.owner.path_subpathing_size);
- break;
- case PT_ASTAR:
- dprint("Pathlib error: A* pathing not implemented!\n");
- return 0;
- default:
- subpath_point = pathlib_subpath_quickstar(start,end,start.owner.path_subpathing_size);
- dprint("Pathlib warning: unknown pathing method, using quickstar!\n");
- break;
- }
-
- if(subpath_point == start.origin)
- return 0; // Fail.
-
- subpoint = pathlib_createpoint(start,end,start.owner,subpath_point);
-
- subpoint.cnt = start.cnt +1;
- start.path_next = subpoint;
- end.path_prev = subpoint;
-
- if(self.path_validate(start.origin,end.origin))
- return 1;
-
- return pathlib_path(subpoint,end,pathing_method);
-}
-
-void pathlib_path_optimize(entity start,entity end)
-{
- entity point,point_tmp;
- float c;
-
- point = start.path_next;
-
- while(point != end)
- {
- ++c;
- if(c > 5000)
- {
- dprint("pathlib_path_optimize runaway!\n");
- return;
- }
-
- point_tmp = point;
- point = point.path_next;
- if(self.path_validate(point_tmp.path_prev.origin,point_tmp.path_next.origin))
- {
-
- point_tmp.path_next.path_prev = point_tmp.path_prev;
- point_tmp.path_prev.path_next = point_tmp.path_next;
- remove(point_tmp);
- }
- }
-}
-
-void pathlib_deletepath(entity start)
-{
- entity e;
-
- e = findchainentity(owner, start);
- while(e)
- {
- e.think = SUB_Remove;
- e.nextthink = time;
- e = e.chain;
- }
-}
-
-//#define DEBUGPATHING
-#ifdef DEBUGPATHING
-void pathlib_showpath(entity start)
-{
- entity e;
- e = start;
- while(e.path_next)
- {
- te_lightning1(e,e.origin,e.path_next.origin);
- e = e.path_next;
- }
-}
-
-void path_dbg_think()
-{
- pathlib_showpath(self);
- self.nextthink = time + 1;
-}
-#endif
-/**
- Pathing from 'from' to 'to'
-**/
-entity pathlib_makepath(vector from, vector to,float pathflags,float subpathing_size, float subpathing_bboxexpand,float pathing_method)
-{
- entity e_start,e_end;
-
- if(!self.path_validate)
- self.path_validate = pathlib_stdproc_path_validate;
-
-
- if(subpathing_size < 10)
- subpathing_size = 500;
-
- if(subpathing_bboxexpand < 1)
- subpathing_bboxexpand = 1;
-
- if(pathflags & PFL_GROUNDSNAP)
- {
- from = pathlib_groundsnap(from);
- to = pathlib_groundsnap(to);
- }
-
- e_start = pathlib_createpoint(world,world,world,from);
- e_start.path_flags = pathflags;
-
- e_start.path_subpathing_size = subpathing_size;
- e_start.path_subpathing_bboxexpand = subpathing_bboxexpand;
-
- e_start.owner = e_start;
-
- e_end = pathlib_createpoint(e_start,world,e_start,to);
- e_start.path_next = e_end;
- e_start.cnt = 0;
-
- if(!pathlib_path(e_start,e_end,pathing_method))
- {
- bprint("Fail, Fail, Fail!\n");
- pathlib_deletepath(e_start);
- remove(e_start);
-
- return world;
- }
-
- pathlib_path_optimize(e_start,e_end);
-
-#ifdef DEBUGPATHING
- e_start.think = path_dbg_think;
- e_start.nextthink = time + 1;
-#endif
-
- return e_start;
-
-}
-
-/*
-.entity goalcurrent, goalstack01, goalstack02, goalstack03;
-.entity goalstack04, goalstack05, goalstack06, goalstack07;
-.entity goalstack08, goalstack09, goalstack10, goalstack11;
-.entity goalstack12, goalstack13, goalstack14, goalstack15;
-.entity goalstack16, goalstack17, goalstack18, goalstack19;
-.entity goalstack20, goalstack21, goalstack22, goalstack23;
-.entity goalstack24, goalstack25, goalstack26, goalstack27;
-.entity goalstack28, goalstack29, goalstack30, goalstack31;
-*/
-
-#define node_left goalstack01
-#define node_right goalstack02
-#define node_front goalstack03
-#define node_back goalstack04
-
-#define node_open goalstack05
-#define node_closed goalstack06
-#define node_blocked goalstack07
-
-
-
-float pointinbox(vector point,vector box,float ssize)
-{
- return 0;
-}
-#ifdef DEBUGPATHING
-
-/* TESTING */
-void pathlib_test_think()
-{
- pathlib_showpath(self.enemy);
-
- self.nextthink = time + 0.5;
-}
-void pathlib_test_dinit()
-{
- entity path;
- entity end;
-
- if(self.target == "")
- {
- bprint("^1 ==== ERROR: pathlib_test with no target. ====\n");
- remove(self);
- return;
- }
-
- end = find(world,targetname,self.target);
- if(!end)
- {
- bprint("^1 ==== ERROR: pathlib_test with no valid target. ====\n");
- remove(self);
- return;
- }
-
- setsize(self,'-50 -50 0','50 50 50');
- path = pathlib_makepath(self.origin,end.origin, PFL_GROUNDSNAP,500,1.25,PT_QUICKSTAR);
-
- if(!path)
- {
- bprint("^1 ==== ERROR: pathlib_test pathing fail ====\n");
- remove(self);
- return;
- }
-
- self.enemy = path;
- self.think = pathlib_test_think;
- self.nextthink = time + 0.5;
-
-}
-void spawnfunc_pathlib_test()
-{
- self.think = pathlib_test_dinit;
- self.nextthink = time + 2;
-}
-
-#endif
+#define PFL_GROUNDSNAP 1
+#define PFL_NOOPTIMIZE 2
+#define PFL_SUBPATH3D 4
+
+#define PT_QUICKSTAR 1
+#define PT_QUICKBOX 2
+#define PT_ASTAR 4 // FIXME NOT IMPLEMENTED
+
+//#define PATHLIB_RDFIELDS
+#ifdef PATHLIB_RDFIELDS
+ #define path_flags lip
+
+ #define path_subpathing_size autoswitch
+ #define path_subpathing_bboxexpand welcomemessage_time
+
+ #define path_next swampslug
+ #define path_prev lasertarget
+#else
+ .entity path_next;
+ .entity path_prev;
+
+ .float path_subpathing_size;
+ .float path_subpathing_bboxexpand;
+ .float path_flags;
+#endif
+
+#define pathlib_garbagetime 120
+#define pathib_maxdivide 512
+
+.float(vector start,vector end) path_validate;
+
+float pathlib_stdproc_path_validate(vector start,vector end)
+{
+ tracebox(start, self.mins, self.maxs, end, MOVE_WORLDONLY, self);
+
+ if(vlen(trace_endpos - end) < 32)
+ return 1;
+
+ return 0;
+}
+
+vector pathlib_groundsnap(vector where)
+{
+ float lsize;
+
+ lsize = vlen(self.mins - self.maxs) * 0.25;
+
+ traceline(where + ('0 0 1' * lsize) ,where - '0 0 10240',MOVE_WORLDONLY,self);
+
+ return trace_endpos + ('0 0 1' * lsize);
+
+}
+
+entity pathlib_createpoint(entity parent,entity next,entity first,vector where)
+{
+ entity point;
+
+ point = spawn();
+ point.classname = "path_node";
+
+ if(first)
+ point.owner = first;
+ else
+ {
+ point.classname = "path_master";
+ point.owner = point;
+ }
+
+ if(parent)
+ point.path_prev = parent;
+
+ if(next)
+ {
+ point.path_next = next;
+ }
+ else
+ point.classname = "path_end";
+
+ if (point.owner.path_flags & PFL_GROUNDSNAP)
+ where = pathlib_groundsnap(where);
+
+ setorigin(point,where);
+
+
+ return point;
+}
+
+/*
+float pathlib_scoresubpath(vector start,vector point,vector end,float minstep)
+{
+ float dist_stp,dist_pte,dist_total;
+
+ dist_stp = vlen(start - point);
+ if(dist_stp < minstep)
+ return 100000000;
+
+ dist_pte = vlen(point - end);
+ dist_total = dist_stp + dist_pte;
+ return -1;
+}
+*/
+
+vector pathlib_subpath_quickbox(entity start,vector vcrash,entity end,float maxsize)
+{
+
+ float step;
+ float pathscore;
+ float pathscore_best;
+ float dist;
+ vector bestpoint,point;
+ float zmin,zmax;
+ vector box;
+
+ pathscore_best = 0;
+
+ step = vlen(self.maxs - self.mins) * start.owner.path_subpathing_bboxexpand;
+
+ if(start.owner.path_flags & PFL_SUBPATH3D)
+ {
+ zmin = maxsize * -1;
+ zmax = maxsize;
+ }
+ else
+ {
+ zmin = 0;
+ zmax = 1;
+ }
+
+ for(box_z = zmin; box_z < zmax; box_z += step)
+ for(box_y = -maxsize; box_y < maxsize; box_y += step)
+ for(box_x = -maxsize; box_x < maxsize; box_x += step)
+ {
+
+ point = vcrash + box;
+
+ if(start.owner.path_flags & PFL_GROUNDSNAP)
+ point = pathlib_groundsnap(point);
+
+ if(self.path_validate(start.origin,point))
+ {
+ dist = vlen(start.origin - point);
+ if(dist > step)
+ {
+ pathscore = 1 / (dist + vlen(point - end.origin));
+ if(pathscore > pathscore_best)
+ {
+ bestpoint = point;
+ pathscore_best = pathscore;
+ }
+ }
+ }
+
+ }
+
+ if(pathscore_best != 0)
+ return bestpoint;
+
+ return start.origin;
+}
+
+vector pathlib_subpath_quickstar(entity start,entity end,float gridsize)
+{
+ vector point, best_point;
+ float score, best_score;
+ vector dir_end;
+
+ dir_end = normalize(end.origin - start.origin);
+ dir_end_x = dir_end_x * -1;
+
+ makevectors(dir_end);
+
+ best_score = 0;
+ score = 0;
+
+ best_point = start.origin;
+
+ // Forward
+ point = start.origin + v_forward * gridsize;
+ point = pathlib_groundsnap(point);
+ if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+ if(score < best_score) { best_point = point; best_score = score; }
+ //te_lightning1(world,start.origin,point);
+
+ // Forward-right
+ point = start.origin + (v_forward + v_right * 0.5) * gridsize;
+ point = pathlib_groundsnap(point);
+ if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+ if(score < best_score) { best_point = point; best_score = score; }
+ //te_lightning1(world,start.origin,point);
+
+
+ // Forward-left
+ point = start.origin + (v_forward - v_right * 0.5) * gridsize;
+ point = pathlib_groundsnap(point);
+ if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+ if(score < best_score) { best_point = point; best_score = score; }
+ //te_lightning1(world,start.origin,point);
+
+
+ // Right
+ point = start.origin + v_right * gridsize;
+ point = pathlib_groundsnap(point);
+ if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+ if(score < best_score) { best_point = point; best_score = score; }
+ //te_lightning1(world,start.origin,point);
+
+ // Left
+ point = start.origin - v_right * gridsize;
+ point = pathlib_groundsnap(point);
+ if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+ if(score < best_score) { best_point = point; best_score = score; }
+ //te_lightning1(world,start.origin,point);
+
+ // Back
+ point = start.origin - v_forward * gridsize;
+ point = pathlib_groundsnap(point);
+ if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+ if(score < best_score) { best_point = point; best_score = score; }
+ //te_lightning1(world,start.origin,point);
+
+ // Back-right
+
+ point = start.origin - (v_forward + v_right * 0.5) * gridsize;
+ point = pathlib_groundsnap(point);
+ if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+ if(score < best_score) { best_point = point; best_score = score; }
+ //te_lightning1(world,start.origin,point);
+
+ // Back-left
+ point = start.origin - (v_forward - v_right * 0.5) * gridsize;
+ point = pathlib_groundsnap(point);
+ if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+ if(score < best_score) { best_point = point; best_score = score; }
+ //te_lightning1(world,start.origin,point);
+
+ return(best_point);
+}
+
+float pathlib_path(entity start,entity end,float pathing_method)
+{
+ vector vcrash;
+ vector subpath_point;
+ entity subpoint;
+
+ // Fail.
+ if(start.cnt > pathib_maxdivide)
+ {
+ bprint("To many segments!\n");
+ return 0;
+ }
+
+ if(self.path_validate(start.origin,end.origin))
+ return 1;
+
+ vcrash = trace_endpos;
+
+ switch(pathing_method)
+ {
+ case PT_QUICKSTAR:
+ subpath_point = pathlib_subpath_quickstar(start,end,start.owner.path_subpathing_size);
+ break;
+ case PT_QUICKBOX:
+ subpath_point = pathlib_subpath_quickbox(start,vcrash,end,start.owner.path_subpathing_size);
+ break;
+ case PT_ASTAR:
+ dprint("Pathlib error: A* pathing not implemented!\n");
+ return 0;
+ default:
+ subpath_point = pathlib_subpath_quickstar(start,end,start.owner.path_subpathing_size);
+ dprint("Pathlib warning: unknown pathing method, using quickstar!\n");
+ break;
+ }
+
+ if(subpath_point == start.origin)
+ return 0; // Fail.
+
+ subpoint = pathlib_createpoint(start,end,start.owner,subpath_point);
+
+ subpoint.cnt = start.cnt +1;
+ start.path_next = subpoint;
+ end.path_prev = subpoint;
+
+ if(self.path_validate(start.origin,end.origin))
+ return 1;
+
+ return pathlib_path(subpoint,end,pathing_method);
+}
+
+void pathlib_path_optimize(entity start,entity end)
+{
+ entity point,point_tmp;
+ float c;
+
+ point = start.path_next;
+
+ while(point != end)
+ {
+ ++c;
+ if(c > 5000)
+ {
+ dprint("pathlib_path_optimize runaway!\n");
+ return;
+ }
+
+ point_tmp = point;
+ point = point.path_next;
+ if(self.path_validate(point_tmp.path_prev.origin,point_tmp.path_next.origin))
+ {
+
+ point_tmp.path_next.path_prev = point_tmp.path_prev;
+ point_tmp.path_prev.path_next = point_tmp.path_next;
+ remove(point_tmp);
+ }
+ }
+}
+
+void pathlib_deletepath(entity start)
+{
+ entity e;
+
+ e = findchainentity(owner, start);
+ while(e)
+ {
+ e.think = SUB_Remove;
+ e.nextthink = time;
+ e = e.chain;
+ }
+}
+
+//#define DEBUGPATHING
+#ifdef DEBUGPATHING
+void pathlib_showpath(entity start)
+{
+ entity e;
+ e = start;
+ while(e.path_next)
+ {
+ te_lightning1(e,e.origin,e.path_next.origin);
+ e = e.path_next;
+ }
+}
+
+void path_dbg_think()
+{
+ pathlib_showpath(self);
+ self.nextthink = time + 1;
+}
+#endif
+/**
+ Pathing from 'from' to 'to'
+**/
+entity pathlib_makepath(vector from, vector to,float pathflags,float subpathing_size, float subpathing_bboxexpand,float pathing_method)
+{
+ entity e_start,e_end;
+
+ if(!self.path_validate)
+ self.path_validate = pathlib_stdproc_path_validate;
+
+
+ if(subpathing_size < 10)
+ subpathing_size = 500;
+
+ if(subpathing_bboxexpand < 1)
+ subpathing_bboxexpand = 1;
+
+ if(pathflags & PFL_GROUNDSNAP)
+ {
+ from = pathlib_groundsnap(from);
+ to = pathlib_groundsnap(to);
+ }
+
+ e_start = pathlib_createpoint(world,world,world,from);
+ e_start.path_flags = pathflags;
+
+ e_start.path_subpathing_size = subpathing_size;
+ e_start.path_subpathing_bboxexpand = subpathing_bboxexpand;
+
+ e_start.owner = e_start;
+
+ e_end = pathlib_createpoint(e_start,world,e_start,to);
+ e_start.path_next = e_end;
+ e_start.cnt = 0;
+
+ if(!pathlib_path(e_start,e_end,pathing_method))
+ {
+ bprint("Fail, Fail, Fail!\n");
+ pathlib_deletepath(e_start);
+ remove(e_start);
+
+ return world;
+ }
+
+ pathlib_path_optimize(e_start,e_end);
+
+#ifdef DEBUGPATHING
+ e_start.think = path_dbg_think;
+ e_start.nextthink = time + 1;
+#endif
+
+ return e_start;
+
+}
+
+/*
+.entity goalcurrent, goalstack01, goalstack02, goalstack03;
+.entity goalstack04, goalstack05, goalstack06, goalstack07;
+.entity goalstack08, goalstack09, goalstack10, goalstack11;
+.entity goalstack12, goalstack13, goalstack14, goalstack15;
+.entity goalstack16, goalstack17, goalstack18, goalstack19;
+.entity goalstack20, goalstack21, goalstack22, goalstack23;
+.entity goalstack24, goalstack25, goalstack26, goalstack27;
+.entity goalstack28, goalstack29, goalstack30, goalstack31;
+*/
+
+#define node_left goalstack01
+#define node_right goalstack02
+#define node_front goalstack03
+#define node_back goalstack04
+
+#define node_open goalstack05
+#define node_closed goalstack06
+#define node_blocked goalstack07
+
+
+
+float pointinbox(vector point,vector box,float ssize)
+{
+ return 0;
+}
+#ifdef DEBUGPATHING
+
+/* TESTING */
+void pathlib_test_think()
+{
+ pathlib_showpath(self.enemy);
+
+ self.nextthink = time + 0.5;
+}
+void pathlib_test_dinit()
+{
+ entity path;
+ entity end;
+
+ if(self.target == "")
+ {
+ bprint("^1 ==== ERROR: pathlib_test with no target. ====\n");
+ remove(self);
+ return;
+ }
+
+ end = find(world,targetname,self.target);
+ if(!end)
+ {
+ bprint("^1 ==== ERROR: pathlib_test with no valid target. ====\n");
+ remove(self);
+ return;
+ }
+
+ setsize(self,'-50 -50 0','50 50 50');
+ path = pathlib_makepath(self.origin,end.origin, PFL_GROUNDSNAP,500,1.25,PT_QUICKSTAR);
+
+ if(!path)
+ {
+ bprint("^1 ==== ERROR: pathlib_test pathing fail ====\n");
+ remove(self);
+ return;
+ }
+
+ self.enemy = path;
+ self.think = pathlib_test_think;
+ self.nextthink = time + 0.5;
+
+}
+void spawnfunc_pathlib_test()
+{
+ self.think = pathlib_test_dinit;
+ self.nextthink = time + 2;
+}
+
+#endif
Modified: trunk/data/qcsrc/server/progs.src
===================================================================
--- trunk/data/qcsrc/server/progs.src 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/progs.src 2009-03-11 21:39:56 UTC (rev 6105)
@@ -81,8 +81,28 @@
g_triggers.qc
+// model animation files
+../../models/weapons/w_campingrifle.qh
+../../models/weapons/w_crylink.qh
+../../models/weapons/w_electro.qh
+../../models/weapons/w_flamethrower.qh
+../../models/weapons/w_gl.qh
+../../models/weapons/w_hagar.qh
+../../models/weapons/w_hlac.qh
+../../models/weapons/w_hlacmod.qh
+../../models/weapons/w_hookgun.qh
+../../models/weapons/w_laser.qh
+../../models/weapons/w_minstanex.qh
+../../models/weapons/w_nex.qh
+../../models/weapons/w_porto.qh
+../../models/weapons/w_rl.qh
+../../models/weapons/w_seeker.qh
+../../models/weapons/w_shotgun.qh
+../../models/weapons/w_uzi.qh
+
cl_weaponsystem.qc
w_common.qc
+
w_laser.qc
w_shotgun.qc
w_uzi.qc
Modified: trunk/data/qcsrc/server/steerlib.qc
===================================================================
--- trunk/data/qcsrc/server/steerlib.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/steerlib.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -1,448 +1,448 @@
-/**
- Uniform pull towards a point
-**/
-vector steerlib_pull(vector point)
-{
- return normalize(point - self.origin);
-}
-
-/**
- Uniform push from a point
-**/
-vector steerlib_push(vector point)
-{
- return normalize(self.origin - point);
-}
-
-/**
- Pull toward a point, The further away, the stronger the pull.
-**/
-vector steerlib_arrive(vector point,float maximal_distance)
-{
- float distance;
- vector direction;
-
- distance = bound(0.001,vlen(self.origin - point),maximal_distance);
- direction = normalize(point - self.origin);
- return direction * (distance / maximal_distance);
-}
-
-/**
- Pull toward a point increasing the pull the closer we get
-**/
-vector steerlib_attract(vector point, float maximal_distance)
-{
- float distance;
- vector direction;
-
- distance = bound(0.001,vlen(self.origin - point),maximal_distance);
- direction = normalize(point - self.origin);
-
- return direction * (1-(distance / maximal_distance));
-}
-
-vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense)
-{
- float distance;
- vector direction;
- float influense;
-
- distance = bound(0.00001,vlen(self.origin - point),max_distance);
- direction = normalize(point - self.origin);
-
- influense = 1 - (distance / max_distance);
- influense = min_influense + (influense * (max_influense - min_influense));
-
- return direction * influense;
-}
-
-/*
-vector steerlib_attract2(vector point, float maximal_distance,float min_influense,float max_influense,float distance)
-{
- //float distance;
- vector current_direction;
- vector target_direction;
- float i_target,i_current;
-
- if(!distance)
- distance = vlen(self.origin - point);
-
- distance = bound(0.001,distance,maximal_distance);
-
- target_direction = normalize(point - self.origin);
- current_direction = normalize(self.velocity);
-
- i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
- i_current = 1 - i_target;
-
- // i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
-
- string s;
- s = ftos(i_target);
- bprint("IT: ",s,"\n");
- s = ftos(i_current);
- bprint("IC : ",s,"\n");
-
- return normalize((target_direction * i_target) + (current_direction * i_current));
-}
-*/
-/**
- Move away from a point.
-**/
-vector steerlib_repell(vector point,float maximal_distance)
-{
- float distance;
- vector direction;
-
- distance = bound(0.001,vlen(self.origin - point),maximal_distance);
- direction = normalize(self.origin - point);
-
- return direction * (1-(distance / maximal_distance));
-}
-
-/**
- Try to keep at ideal_distance away from point
-**/
-vector steerlib_standoff(vector point,float ideal_distance)
-{
- float distance;
- vector direction;
-
- distance = vlen(self.origin - point);
-
-
- if(distance < ideal_distance)
- {
- direction = normalize(self.origin - point);
- return direction * (distance / ideal_distance);
- }
-
- direction = normalize(point - self.origin);
- return direction * (ideal_distance / distance);
-
-}
-
-/**
- A random heading in a forward halfcicrle
-
- use like:
- self.target = steerlib_waner(256,32,self.target)
-
- where range is the cicrle radius and tresh is how close we need to be to pick a new heading.
-**/
-vector steerlib_waner(float range,float tresh,vector oldpoint)
-{
- vector wander_point;
- wander_point = v_forward - oldpoint;
-
- if (vlen(wander_point) > tresh)
- return oldpoint;
-
- range = bound(0,range,1);
-
- wander_point = self.origin + v_forward * 128;
- wander_point = wander_point + randomvec() * (range * 128) - randomvec() * (range * 128);
-
- return normalize(wander_point - self.origin);
-}
-
-/**
- Dodge a point. dont work to well.
-**/
-vector steerlib_dodge(vector point,vector dodge_dir,float min_distance)
-{
- float distance;
-
- distance = max(vlen(self.origin - point),min_distance);
-
- return dodge_dir * (min_distance/distance);
-}
-
-/**
- flocking by .flock_id
- Group will move towards the unified direction while keeping close to eachother.
-**/
-.float flock_id;
-vector steerlib_flock(float radius, float standoff,float separation_force,float flock_force)
-{
- entity flock_member;
- vector push,pull;
- float ccount;
-
- flock_member = findradius(self.origin,radius);
- while(flock_member)
- {
- if(flock_member != self)
- if(flock_member.flock_id == self.flock_id)
- {
- ++ccount;
- push = push + (steerlib_repell(flock_member.origin,standoff) * separation_force);
- pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity,radius) * flock_force);
- }
- flock_member = flock_member.chain;
- }
- return push + (pull* (1 / ccount));
-}
-
-/**
- All members want to be in the center, and keep away from eachother.
- The furtehr form the center the more they want to be there.
-
- This results in a aligned movement (?!) much like flocking.
-**/
-vector steerlib_swarm(float radius, float standoff,float separation_force,float swarm_force)
-{
- entity swarm_member;
- vector force,center;
- float ccount;
-
- swarm_member = findradius(self.origin,radius);
-
- while(swarm_member)
- {
- if(swarm_member.flock_id == self.flock_id)
- {
- ++ccount;
- center = center + swarm_member.origin;
- force = force + (steerlib_repell(swarm_member.origin,standoff) * separation_force);
- }
- swarm_member = swarm_member.chain;
- }
-
- center = center * (1 / ccount);
- force = force + (steerlib_arrive(center,radius) * swarm_force);
-
- return force;
-}
-
-/**
- Steer towards the direction least obstructed.
- Run four tracelines in a forward funnel, bias each diretion negative if something is found there.
-**/
-vector steerlib_traceavoid(float pitch,float length)
-{
- vector vup_left,vup_right,vdown_left,vdown_right;
- float fup_left,fup_right,fdown_left,fdown_right;
- vector upwish,downwish,leftwish,rightwish;
- vector v_left,v_down;
-
- v_left = v_right * -1;
- v_down = v_up * -1;
-
- vup_left = (v_forward + (v_left * pitch + v_up * pitch)) * length;
- traceline(self.origin, self.origin + vup_left,MOVE_NOMONSTERS,self);
- fup_left = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
-
- vup_right = (v_forward + (v_right * pitch + v_up * pitch)) * length;
- traceline(self.origin,self.origin + vup_right ,MOVE_NOMONSTERS,self);
- fup_right = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
-
- vdown_left = (v_forward + (v_left * pitch + v_down * pitch)) * length;
- traceline(self.origin,self.origin + vdown_left,MOVE_NOMONSTERS,self);
- fdown_left = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
-
- vdown_right = (v_forward + (v_right * pitch + v_down * pitch)) * length;
- traceline(self.origin,self.origin + vdown_right,MOVE_NOMONSTERS,self);
- fdown_right = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
-
- upwish = v_up * (fup_left + fup_right);
- downwish = v_down * (fdown_left + fdown_right);
- leftwish = v_left * (fup_left + fdown_left);
- rightwish = v_right * (fup_right + fdown_right);
-
- return (upwish+leftwish+downwish+rightwish) * 0.25;
-
-}
-
-
-
-//////////////////////////////////////////////
-// Testting //
-// Everything below this point is a mess :D //
-//////////////////////////////////////////////
-//#define TLIBS_TETSLIBS
-#ifdef TLIBS_TETSLIBS
-void flocker_die()
-{
- sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-
- pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
-
- self.owner.cnt += 1;
- self.owner = world;
-
- self.nextthink = time;
- self.think = SUB_Remove;
-}
-
-
-void flocker_think()
-{
- vector dodgemove,swarmmove;
- vector reprellmove,wandermove,newmove;
-
- self.angles_x = self.angles_x * -1;
- makevectors(self.angles);
- self.angles_x = self.angles_x * -1;
-
- dodgemove = steerlib_traceavoid(0.35,1000);
- swarmmove = steerlib_flock(500,75,700,500);
- reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,2000) * 700;
-
- if(vlen(dodgemove) == 0)
- {
- self.pos1 = steerlib_waner(0.5,0.1,self.pos1);
- wandermove = self.pos1 * 50;
- }
- else
- self.pos1 = normalize(self.velocity);
-
- dodgemove = dodgemove * vlen(self.velocity) * 5;
-
- newmove = swarmmove + reprellmove + wandermove + dodgemove;
- self.velocity = movelib_inertmove_byspeed(newmove,300,0.2,0.9);
- //self.velocity = movelib_inertmove(dodgemove,0.65);
-
- self.velocity = movelib_dragvec(0.01,0.6);
-
- self.angles = vectoangles(self.velocity);
-
- if(self.health <= 0)
- flocker_die();
- else
- self.nextthink = time + 0.1;
-}
-
-
-void spawn_flocker()
-{
- entity flocker;
-
- flocker = spawn ();
-
- setorigin(flocker, self.origin + '0 0 32');
- setmodel (flocker, "models/turrets/rocket.md3");
- setsize (flocker, '-3 -3 -3', '3 3 3');
-
- flocker.flock_id = self.flock_id;
- flocker.classname = "flocker";
- flocker.owner = self;
- flocker.think = flocker_think;
- flocker.nextthink = time + random() * 5;
- flocker.solid = SOLID_BBOX;
- flocker.movetype = MOVETYPE_BOUNCEMISSILE;
- flocker.effects = EF_LOWPRECISION;
- flocker.velocity = randomvec() * 300;
- flocker.angles = vectoangles(flocker.velocity);
- flocker.health = 10;
- flocker.pos1 = normalize(flocker.velocity + randomvec() * 0.1);
-
- self.cnt = self.cnt -1;
-
-}
-
-void flockerspawn_think()
-{
-
-
- if(self.cnt > 0)
- spawn_flocker();
-
- self.nextthink = time + self.delay;
-
-}
-
-void flocker_hunter_think()
-{
- vector dodgemove,attractmove,newmove;
- entity e,ee;
- float d,bd;
-
- self.angles_x = self.angles_x * -1;
- makevectors(self.angles);
- self.angles_x = self.angles_x * -1;
-
- if(self.enemy)
- if(vlen(self.enemy.origin - self.origin) < 64)
- {
- ee = self.enemy;
- ee.health = -1;
- self.enemy = world;
-
- }
-
- if(!self.enemy)
- {
- e = findchainfloat(flock_id,self.flock_id);
- while(e)
- {
- d = vlen(self.origin - e.origin);
-
- if(e != self.owner)
- if(e != ee)
- if(d > bd)
- {
- self.enemy = e;
- bd = d;
- }
- e = e.chain;
- }
- }
-
- if(self.enemy)
- attractmove = steerlib_attract(self.enemy.origin+self.enemy.velocity * 0.1,5000) * 1250;
- else
- attractmove = normalize(self.velocity) * 200;
-
- dodgemove = steerlib_traceavoid(0.35,1500) * vlen(self.velocity);
-
- newmove = dodgemove + attractmove;
- self.velocity = movelib_inertmove_byspeed(newmove,1250,0.3,0.7);
- self.velocity = movelib_dragvec(0.01,0.5);
-
-
- self.angles = vectoangles(self.velocity);
- self.nextthink = time + 0.1;
-}
-
-
-float globflockcnt;
-void spawnfunc_flockerspawn()
-{
- precache_model ( "models/turrets/rocket.md3");
- precache_model("models/turrets/c512.md3");
- ++globflockcnt;
-
- if(!self.cnt) self.cnt = 20;
- if(!self.delay) self.delay = 0.25;
- if(!self.flock_id) self.flock_id = globflockcnt;
-
- self.think = flockerspawn_think;
- self.nextthink = time + 0.25;
-
- self.enemy = spawn();
-
- setmodel(self.enemy, "models/turrets/rocket.md3");
- setorigin(self.enemy,self.origin + '0 0 768' + (randomvec() * 128));
-
- self.enemy.classname = "FLock Hunter";
- self.enemy.scale = 3;
- self.enemy.effects = EF_LOWPRECISION;
- self.enemy.movetype = MOVETYPE_BOUNCEMISSILE;
- self.enemy.solid = SOLID_BBOX;
- self.enemy.think = flocker_hunter_think;
- self.enemy.nextthink = time + 10;
- self.enemy.flock_id = self.flock_id;
- self.enemy.owner = self;
-}
-#endif
-
-
+/**
+ Uniform pull towards a point
+**/
+vector steerlib_pull(vector point)
+{
+ return normalize(point - self.origin);
+}
+
+/**
+ Uniform push from a point
+**/
+vector steerlib_push(vector point)
+{
+ return normalize(self.origin - point);
+}
+
+/**
+ Pull toward a point, The further away, the stronger the pull.
+**/
+vector steerlib_arrive(vector point,float maximal_distance)
+{
+ float distance;
+ vector direction;
+
+ distance = bound(0.001,vlen(self.origin - point),maximal_distance);
+ direction = normalize(point - self.origin);
+ return direction * (distance / maximal_distance);
+}
+
+/**
+ Pull toward a point increasing the pull the closer we get
+**/
+vector steerlib_attract(vector point, float maximal_distance)
+{
+ float distance;
+ vector direction;
+
+ distance = bound(0.001,vlen(self.origin - point),maximal_distance);
+ direction = normalize(point - self.origin);
+
+ return direction * (1-(distance / maximal_distance));
+}
+
+vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense)
+{
+ float distance;
+ vector direction;
+ float influense;
+
+ distance = bound(0.00001,vlen(self.origin - point),max_distance);
+ direction = normalize(point - self.origin);
+
+ influense = 1 - (distance / max_distance);
+ influense = min_influense + (influense * (max_influense - min_influense));
+
+ return direction * influense;
+}
+
+/*
+vector steerlib_attract2(vector point, float maximal_distance,float min_influense,float max_influense,float distance)
+{
+ //float distance;
+ vector current_direction;
+ vector target_direction;
+ float i_target,i_current;
+
+ if(!distance)
+ distance = vlen(self.origin - point);
+
+ distance = bound(0.001,distance,maximal_distance);
+
+ target_direction = normalize(point - self.origin);
+ current_direction = normalize(self.velocity);
+
+ i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
+ i_current = 1 - i_target;
+
+ // i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
+
+ string s;
+ s = ftos(i_target);
+ bprint("IT: ",s,"\n");
+ s = ftos(i_current);
+ bprint("IC : ",s,"\n");
+
+ return normalize((target_direction * i_target) + (current_direction * i_current));
+}
+*/
+/**
+ Move away from a point.
+**/
+vector steerlib_repell(vector point,float maximal_distance)
+{
+ float distance;
+ vector direction;
+
+ distance = bound(0.001,vlen(self.origin - point),maximal_distance);
+ direction = normalize(self.origin - point);
+
+ return direction * (1-(distance / maximal_distance));
+}
+
+/**
+ Try to keep at ideal_distance away from point
+**/
+vector steerlib_standoff(vector point,float ideal_distance)
+{
+ float distance;
+ vector direction;
+
+ distance = vlen(self.origin - point);
+
+
+ if(distance < ideal_distance)
+ {
+ direction = normalize(self.origin - point);
+ return direction * (distance / ideal_distance);
+ }
+
+ direction = normalize(point - self.origin);
+ return direction * (ideal_distance / distance);
+
+}
+
+/**
+ A random heading in a forward halfcicrle
+
+ use like:
+ self.target = steerlib_waner(256,32,self.target)
+
+ where range is the cicrle radius and tresh is how close we need to be to pick a new heading.
+**/
+vector steerlib_waner(float range,float tresh,vector oldpoint)
+{
+ vector wander_point;
+ wander_point = v_forward - oldpoint;
+
+ if (vlen(wander_point) > tresh)
+ return oldpoint;
+
+ range = bound(0,range,1);
+
+ wander_point = self.origin + v_forward * 128;
+ wander_point = wander_point + randomvec() * (range * 128) - randomvec() * (range * 128);
+
+ return normalize(wander_point - self.origin);
+}
+
+/**
+ Dodge a point. dont work to well.
+**/
+vector steerlib_dodge(vector point,vector dodge_dir,float min_distance)
+{
+ float distance;
+
+ distance = max(vlen(self.origin - point),min_distance);
+
+ return dodge_dir * (min_distance/distance);
+}
+
+/**
+ flocking by .flock_id
+ Group will move towards the unified direction while keeping close to eachother.
+**/
+.float flock_id;
+vector steerlib_flock(float radius, float standoff,float separation_force,float flock_force)
+{
+ entity flock_member;
+ vector push,pull;
+ float ccount;
+
+ flock_member = findradius(self.origin,radius);
+ while(flock_member)
+ {
+ if(flock_member != self)
+ if(flock_member.flock_id == self.flock_id)
+ {
+ ++ccount;
+ push = push + (steerlib_repell(flock_member.origin,standoff) * separation_force);
+ pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity,radius) * flock_force);
+ }
+ flock_member = flock_member.chain;
+ }
+ return push + (pull* (1 / ccount));
+}
+
+/**
+ All members want to be in the center, and keep away from eachother.
+ The furtehr form the center the more they want to be there.
+
+ This results in a aligned movement (?!) much like flocking.
+**/
+vector steerlib_swarm(float radius, float standoff,float separation_force,float swarm_force)
+{
+ entity swarm_member;
+ vector force,center;
+ float ccount;
+
+ swarm_member = findradius(self.origin,radius);
+
+ while(swarm_member)
+ {
+ if(swarm_member.flock_id == self.flock_id)
+ {
+ ++ccount;
+ center = center + swarm_member.origin;
+ force = force + (steerlib_repell(swarm_member.origin,standoff) * separation_force);
+ }
+ swarm_member = swarm_member.chain;
+ }
+
+ center = center * (1 / ccount);
+ force = force + (steerlib_arrive(center,radius) * swarm_force);
+
+ return force;
+}
+
+/**
+ Steer towards the direction least obstructed.
+ Run four tracelines in a forward funnel, bias each diretion negative if something is found there.
+**/
+vector steerlib_traceavoid(float pitch,float length)
+{
+ vector vup_left,vup_right,vdown_left,vdown_right;
+ float fup_left,fup_right,fdown_left,fdown_right;
+ vector upwish,downwish,leftwish,rightwish;
+ vector v_left,v_down;
+
+ v_left = v_right * -1;
+ v_down = v_up * -1;
+
+ vup_left = (v_forward + (v_left * pitch + v_up * pitch)) * length;
+ traceline(self.origin, self.origin + vup_left,MOVE_NOMONSTERS,self);
+ fup_left = trace_fraction;
+
+ //te_lightning1(world,self.origin, trace_endpos);
+
+ vup_right = (v_forward + (v_right * pitch + v_up * pitch)) * length;
+ traceline(self.origin,self.origin + vup_right ,MOVE_NOMONSTERS,self);
+ fup_right = trace_fraction;
+
+ //te_lightning1(world,self.origin, trace_endpos);
+
+ vdown_left = (v_forward + (v_left * pitch + v_down * pitch)) * length;
+ traceline(self.origin,self.origin + vdown_left,MOVE_NOMONSTERS,self);
+ fdown_left = trace_fraction;
+
+ //te_lightning1(world,self.origin, trace_endpos);
+
+ vdown_right = (v_forward + (v_right * pitch + v_down * pitch)) * length;
+ traceline(self.origin,self.origin + vdown_right,MOVE_NOMONSTERS,self);
+ fdown_right = trace_fraction;
+
+ //te_lightning1(world,self.origin, trace_endpos);
+
+ upwish = v_up * (fup_left + fup_right);
+ downwish = v_down * (fdown_left + fdown_right);
+ leftwish = v_left * (fup_left + fdown_left);
+ rightwish = v_right * (fup_right + fdown_right);
+
+ return (upwish+leftwish+downwish+rightwish) * 0.25;
+
+}
+
+
+
+//////////////////////////////////////////////
+// Testting //
+// Everything below this point is a mess :D //
+//////////////////////////////////////////////
+//#define TLIBS_TETSLIBS
+#ifdef TLIBS_TETSLIBS
+void flocker_die()
+{
+ sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+
+ pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
+
+ self.owner.cnt += 1;
+ self.owner = world;
+
+ self.nextthink = time;
+ self.think = SUB_Remove;
+}
+
+
+void flocker_think()
+{
+ vector dodgemove,swarmmove;
+ vector reprellmove,wandermove,newmove;
+
+ self.angles_x = self.angles_x * -1;
+ makevectors(self.angles);
+ self.angles_x = self.angles_x * -1;
+
+ dodgemove = steerlib_traceavoid(0.35,1000);
+ swarmmove = steerlib_flock(500,75,700,500);
+ reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,2000) * 700;
+
+ if(vlen(dodgemove) == 0)
+ {
+ self.pos1 = steerlib_waner(0.5,0.1,self.pos1);
+ wandermove = self.pos1 * 50;
+ }
+ else
+ self.pos1 = normalize(self.velocity);
+
+ dodgemove = dodgemove * vlen(self.velocity) * 5;
+
+ newmove = swarmmove + reprellmove + wandermove + dodgemove;
+ self.velocity = movelib_inertmove_byspeed(newmove,300,0.2,0.9);
+ //self.velocity = movelib_inertmove(dodgemove,0.65);
+
+ self.velocity = movelib_dragvec(0.01,0.6);
+
+ self.angles = vectoangles(self.velocity);
+
+ if(self.health <= 0)
+ flocker_die();
+ else
+ self.nextthink = time + 0.1;
+}
+
+
+void spawn_flocker()
+{
+ entity flocker;
+
+ flocker = spawn ();
+
+ setorigin(flocker, self.origin + '0 0 32');
+ setmodel (flocker, "models/turrets/rocket.md3");
+ setsize (flocker, '-3 -3 -3', '3 3 3');
+
+ flocker.flock_id = self.flock_id;
+ flocker.classname = "flocker";
+ flocker.owner = self;
+ flocker.think = flocker_think;
+ flocker.nextthink = time + random() * 5;
+ flocker.solid = SOLID_BBOX;
+ flocker.movetype = MOVETYPE_BOUNCEMISSILE;
+ flocker.effects = EF_LOWPRECISION;
+ flocker.velocity = randomvec() * 300;
+ flocker.angles = vectoangles(flocker.velocity);
+ flocker.health = 10;
+ flocker.pos1 = normalize(flocker.velocity + randomvec() * 0.1);
+
+ self.cnt = self.cnt -1;
+
+}
+
+void flockerspawn_think()
+{
+
+
+ if(self.cnt > 0)
+ spawn_flocker();
+
+ self.nextthink = time + self.delay;
+
+}
+
+void flocker_hunter_think()
+{
+ vector dodgemove,attractmove,newmove;
+ entity e,ee;
+ float d,bd;
+
+ self.angles_x = self.angles_x * -1;
+ makevectors(self.angles);
+ self.angles_x = self.angles_x * -1;
+
+ if(self.enemy)
+ if(vlen(self.enemy.origin - self.origin) < 64)
+ {
+ ee = self.enemy;
+ ee.health = -1;
+ self.enemy = world;
+
+ }
+
+ if(!self.enemy)
+ {
+ e = findchainfloat(flock_id,self.flock_id);
+ while(e)
+ {
+ d = vlen(self.origin - e.origin);
+
+ if(e != self.owner)
+ if(e != ee)
+ if(d > bd)
+ {
+ self.enemy = e;
+ bd = d;
+ }
+ e = e.chain;
+ }
+ }
+
+ if(self.enemy)
+ attractmove = steerlib_attract(self.enemy.origin+self.enemy.velocity * 0.1,5000) * 1250;
+ else
+ attractmove = normalize(self.velocity) * 200;
+
+ dodgemove = steerlib_traceavoid(0.35,1500) * vlen(self.velocity);
+
+ newmove = dodgemove + attractmove;
+ self.velocity = movelib_inertmove_byspeed(newmove,1250,0.3,0.7);
+ self.velocity = movelib_dragvec(0.01,0.5);
+
+
+ self.angles = vectoangles(self.velocity);
+ self.nextthink = time + 0.1;
+}
+
+
+float globflockcnt;
+void spawnfunc_flockerspawn()
+{
+ precache_model ( "models/turrets/rocket.md3");
+ precache_model("models/turrets/c512.md3");
+ ++globflockcnt;
+
+ if(!self.cnt) self.cnt = 20;
+ if(!self.delay) self.delay = 0.25;
+ if(!self.flock_id) self.flock_id = globflockcnt;
+
+ self.think = flockerspawn_think;
+ self.nextthink = time + 0.25;
+
+ self.enemy = spawn();
+
+ setmodel(self.enemy, "models/turrets/rocket.md3");
+ setorigin(self.enemy,self.origin + '0 0 768' + (randomvec() * 128));
+
+ self.enemy.classname = "FLock Hunter";
+ self.enemy.scale = 3;
+ self.enemy.effects = EF_LOWPRECISION;
+ self.enemy.movetype = MOVETYPE_BOUNCEMISSILE;
+ self.enemy.solid = SOLID_BBOX;
+ self.enemy.think = flocker_hunter_think;
+ self.enemy.nextthink = time + 10;
+ self.enemy.flock_id = self.flock_id;
+ self.enemy.owner = self;
+}
+#endif
+
+
Modified: trunk/data/qcsrc/server/w_hlac.qc
===================================================================
--- trunk/data/qcsrc/server/w_hlac.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/w_hlac.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -1,216 +1,216 @@
-.float HLAC_bulletcounter;
-void W_HLAC_Touch (void)
-{
- PROJECTILE_TOUCH;
-
- self.event_damage = SUB_Null;
-
- RadiusDamage (self, self.owner, cvar("g_balance_hlac_primary_damage"), cvar("g_balance_hlac_primary_edgedamage"), cvar("g_balance_hlac_primary_radius"), world, cvar("g_balance_hlac_primary_force"), self.projectiledeathtype, other);
-
- remove (self);
-}
-
-void W_HLAC_Touch2 (void)
-{
- PROJECTILE_TOUCH;
-
- self.event_damage = SUB_Null;
-
- RadiusDamage (self, self.owner, cvar("g_balance_hlac_secondary_damage"), cvar("g_balance_hlac_secondary_edgedamage"), cvar("g_balance_hlac_secondary_radius"), world, cvar("g_balance_hlac_secondary_force"), self.projectiledeathtype, other);
-
- remove (self);
-}
-
-void W_HLAC_Attack (void)
-{
- local entity missile;
- float spread;
-
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- {
- self.ammo_cells = self.ammo_cells - cvar("g_balance_hlac_primary_ammo");
- }
-
- spread = cvar("g_balance_hlac_primary_spread_min") + (cvar("g_balance_hlac_primary_spread_add") * self.HLAC_bulletcounter);
- spread = min(spread,cvar("g_balance_hlac_primary_spread_max"));
- if(self.crouch)
- spread = spread * cvar("g_balance_hlac_primary_spread_crouchmod");
-
- W_SetupShot (self, '24 8 -11', FALSE, 3, "weapons/lasergun_fire.wav");
- pointparticles(particleeffectnum("laser_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
- if (!g_norecoil)
- {
- self.punchangle_x = random () - 0.5;
- self.punchangle_y = random () - 0.5;
- }
-
- missile = spawn ();
- missile.owner = self;
- missile.classname = "hlacbolt";
- // missile.dmg = issecondary;
- missile.bot_dodge = TRUE;
-
- missile.bot_dodgerating = cvar("g_balance_hlac_primary_damage");
-
- missile.movetype = MOVETYPE_FLY;
- missile.solid = SOLID_BBOX;
-
- setorigin (missile, w_shotorg);
-
- missile.velocity = (w_shotdir + randomvec() * spread) * cvar("g_balance_hlac_primary_speed");
-
- W_SetupProjectileVelocity(missile);
- missile.angles = vectoangles (missile.velocity);
-
- missile.touch = W_HLAC_Touch;
- missile.think = SUB_Remove;
-
- missile.nextthink = time + cvar("g_balance_hlac_primary_lifetime");
-
- missile.flags = FL_PROJECTILE;
- missile.projectiledeathtype = WEP_HLAC;
-
- CSQCProjectile(missile, TRUE, PROJECTILE_HLAC, TRUE);
-}
-
-void W_HLAC_Attack2f (void)
-{
- local entity missile;
- float spread;
-
- spread = cvar("g_balance_hlac_secondary_spread");
-
-
- if(self.crouch)
- spread = spread * cvar("g_balance_hlac_secondary_spread_crouchmod");
-
- W_SetupShot (self, '25 8 -8', FALSE, 3, "weapons/lasergun_fire.wav");
- pointparticles(particleeffectnum("laser_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
-
- missile = spawn ();
- missile.owner = self;
- missile.classname = "hlacbolt";
- // missile.dmg = issecondary;
- missile.bot_dodge = TRUE;
-
- missile.bot_dodgerating = cvar("g_balance_hlac_secondary_damage");
-
- missile.movetype = MOVETYPE_FLY;
- missile.solid = SOLID_BBOX;
-
- setorigin (missile, w_shotorg);
-
- missile.velocity = (w_shotdir + randomvec() * spread) * cvar("g_balance_hlac_secondary_speed");
-
- W_SetupProjectileVelocity(missile);
- missile.angles = vectoangles (missile.velocity);
-
- missile.touch = W_HLAC_Touch2;
- missile.think = SUB_Remove;
-
- missile.nextthink = time + cvar("g_balance_hlac_secondary_lifetime");
-
- missile.flags = FL_PROJECTILE;
- missile.projectiledeathtype = WEP_HLAC | HITTYPE_SECONDARY;
-
- CSQCProjectile(missile, TRUE, PROJECTILE_HLAC, TRUE);
-}
-
-void W_HLAC_Attack2 (void)
-{
- float i;
-
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- {
- self.ammo_cells = self.ammo_cells - cvar("g_balance_hlac_secondary_ammo");
- }
-
- for(i=cvar("g_balance_hlac_secondary_shots");i>0;--i)
- W_HLAC_Attack2f();
-
- if (!g_norecoil)
- {
- self.punchangle_x = random () - 0.5;
- self.punchangle_y = random () - 0.5;
- }
-
- // ATTACK_FINISHED(self) = time + cvar("g_balance_hlac_secondary_refire");
-}
-
-
-// weapon frames
-void HLAC_fire1_02()
-{
- if(self.weapon != self.switchweapon) // abort immediately if switching
- {
- w_ready();
- return;
- }
-
- if (self.BUTTON_ATCK)
- {
- if (!weapon_action(self.weapon, WR_CHECKAMMO1))
- {
- W_SwitchWeapon_Force(self, w_getbestweapon(self));
- w_ready();
- return;
- }
-
- ATTACK_FINISHED(self) = time + cvar("g_balance_hlac_primary_refire");
- W_HLAC_Attack();
- self.HLAC_bulletcounter = self.HLAC_bulletcounter + 1;
- weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_hlac_primary_refire"), HLAC_fire1_02);
- }
- else
- {
- weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_hlac_primary_animtime"), w_ready);
- }
-};
-
-void spawnfunc_weapon_hlac (void)
-{
- weapon_defaultspawnfunc(WEP_HLAC);
-}
-
-float w_hlac(float req)
-{
- if (req == WR_AIM)
- self.BUTTON_ATCK = bot_aim(cvar("g_balance_hlac_primary_speed"), 0, cvar("g_balance_hlac_primary_lifetime"), FALSE);
- else if (req == WR_THINK)
- {
- if (self.BUTTON_ATCK)
- if (weapon_prepareattack(0, cvar("g_balance_hlac_primary_refire")))
- {
- self.HLAC_bulletcounter = 0;
- W_HLAC_Attack();
- weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_hlac_primary_refire"), HLAC_fire1_02);
- }
-
- if (self.BUTTON_ATCK2)
- if (weapon_prepareattack(1, cvar("g_balance_hlac_secondary_refire")))
- {
- W_HLAC_Attack2();
- weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_hlac_secondary_animtime"), w_ready);
- }
-
- }
- else if (req == WR_PRECACHE)
- {
- precache_model ("models/weapons/g_hlac.md3");
- precache_model ("models/weapons/v_hlac.md3");
- precache_model ("models/weapons/w_hlac.zym");
- precache_sound ("weapons/lasergun_fire.wav");
-
- }
- else if (req == WR_SETUP)
- weapon_setup(WEP_HLAC);
- else if (req == WR_CHECKAMMO1)
- return self.ammo_cells >= cvar("g_balance_hlac_primary_ammo");
- else if (req == WR_CHECKAMMO2)
- return self.ammo_cells >= cvar("g_balance_hlac_secondary_ammo");
- else if (req == WR_SUICIDEMESSAGE)
- w_deathtypestring = "should have used a smaller gun";
- else if (req == WR_KILLMESSAGE)
- w_deathtypestring = "was cut down by";
- return TRUE;
-};
+.float HLAC_bulletcounter;
+void W_HLAC_Touch (void)
+{
+ PROJECTILE_TOUCH;
+
+ self.event_damage = SUB_Null;
+
+ RadiusDamage (self, self.owner, cvar("g_balance_hlac_primary_damage"), cvar("g_balance_hlac_primary_edgedamage"), cvar("g_balance_hlac_primary_radius"), world, cvar("g_balance_hlac_primary_force"), self.projectiledeathtype, other);
+
+ remove (self);
+}
+
+void W_HLAC_Touch2 (void)
+{
+ PROJECTILE_TOUCH;
+
+ self.event_damage = SUB_Null;
+
+ RadiusDamage (self, self.owner, cvar("g_balance_hlac_secondary_damage"), cvar("g_balance_hlac_secondary_edgedamage"), cvar("g_balance_hlac_secondary_radius"), world, cvar("g_balance_hlac_secondary_force"), self.projectiledeathtype, other);
+
+ remove (self);
+}
+
+void W_HLAC_Attack (void)
+{
+ local entity missile;
+ float spread;
+
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ self.ammo_cells = self.ammo_cells - cvar("g_balance_hlac_primary_ammo");
+ }
+
+ spread = cvar("g_balance_hlac_primary_spread_min") + (cvar("g_balance_hlac_primary_spread_add") * self.HLAC_bulletcounter);
+ spread = min(spread,cvar("g_balance_hlac_primary_spread_max"));
+ if(self.crouch)
+ spread = spread * cvar("g_balance_hlac_primary_spread_crouchmod");
+
+ W_SetupShot (self, '24 8 -11', FALSE, 3, "weapons/lasergun_fire.wav");
+ pointparticles(particleeffectnum("laser_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
+ if (!g_norecoil)
+ {
+ self.punchangle_x = random () - 0.5;
+ self.punchangle_y = random () - 0.5;
+ }
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.classname = "hlacbolt";
+ // missile.dmg = issecondary;
+ missile.bot_dodge = TRUE;
+
+ missile.bot_dodgerating = cvar("g_balance_hlac_primary_damage");
+
+ missile.movetype = MOVETYPE_FLY;
+ missile.solid = SOLID_BBOX;
+
+ setorigin (missile, w_shotorg);
+
+ missile.velocity = (w_shotdir + randomvec() * spread) * cvar("g_balance_hlac_primary_speed");
+
+ W_SetupProjectileVelocity(missile);
+ missile.angles = vectoangles (missile.velocity);
+
+ missile.touch = W_HLAC_Touch;
+ missile.think = SUB_Remove;
+
+ missile.nextthink = time + cvar("g_balance_hlac_primary_lifetime");
+
+ missile.flags = FL_PROJECTILE;
+ missile.projectiledeathtype = WEP_HLAC;
+
+ CSQCProjectile(missile, TRUE, PROJECTILE_HLAC, TRUE);
+}
+
+void W_HLAC_Attack2f (void)
+{
+ local entity missile;
+ float spread;
+
+ spread = cvar("g_balance_hlac_secondary_spread");
+
+
+ if(self.crouch)
+ spread = spread * cvar("g_balance_hlac_secondary_spread_crouchmod");
+
+ W_SetupShot (self, '25 8 -8', FALSE, 3, "weapons/lasergun_fire.wav");
+ pointparticles(particleeffectnum("laser_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.classname = "hlacbolt";
+ // missile.dmg = issecondary;
+ missile.bot_dodge = TRUE;
+
+ missile.bot_dodgerating = cvar("g_balance_hlac_secondary_damage");
+
+ missile.movetype = MOVETYPE_FLY;
+ missile.solid = SOLID_BBOX;
+
+ setorigin (missile, w_shotorg);
+
+ missile.velocity = (w_shotdir + randomvec() * spread) * cvar("g_balance_hlac_secondary_speed");
+
+ W_SetupProjectileVelocity(missile);
+ missile.angles = vectoangles (missile.velocity);
+
+ missile.touch = W_HLAC_Touch2;
+ missile.think = SUB_Remove;
+
+ missile.nextthink = time + cvar("g_balance_hlac_secondary_lifetime");
+
+ missile.flags = FL_PROJECTILE;
+ missile.projectiledeathtype = WEP_HLAC | HITTYPE_SECONDARY;
+
+ CSQCProjectile(missile, TRUE, PROJECTILE_HLAC, TRUE);
+}
+
+void W_HLAC_Attack2 (void)
+{
+ float i;
+
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ self.ammo_cells = self.ammo_cells - cvar("g_balance_hlac_secondary_ammo");
+ }
+
+ for(i=cvar("g_balance_hlac_secondary_shots");i>0;--i)
+ W_HLAC_Attack2f();
+
+ if (!g_norecoil)
+ {
+ self.punchangle_x = random () - 0.5;
+ self.punchangle_y = random () - 0.5;
+ }
+
+ // ATTACK_FINISHED(self) = time + cvar("g_balance_hlac_secondary_refire");
+}
+
+
+// weapon frames
+void HLAC_fire1_02()
+{
+ if(self.weapon != self.switchweapon) // abort immediately if switching
+ {
+ w_ready();
+ return;
+ }
+
+ if (self.BUTTON_ATCK)
+ {
+ if (!weapon_action(self.weapon, WR_CHECKAMMO1))
+ {
+ W_SwitchWeapon_Force(self, w_getbestweapon(self));
+ w_ready();
+ return;
+ }
+
+ ATTACK_FINISHED(self) = time + cvar("g_balance_hlac_primary_refire");
+ W_HLAC_Attack();
+ self.HLAC_bulletcounter = self.HLAC_bulletcounter + 1;
+ weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_hlac_primary_refire"), HLAC_fire1_02);
+ }
+ else
+ {
+ weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_hlac_primary_animtime"), w_ready);
+ }
+};
+
+void spawnfunc_weapon_hlac (void)
+{
+ weapon_defaultspawnfunc(WEP_HLAC);
+}
+
+float w_hlac(float req)
+{
+ if (req == WR_AIM)
+ self.BUTTON_ATCK = bot_aim(cvar("g_balance_hlac_primary_speed"), 0, cvar("g_balance_hlac_primary_lifetime"), FALSE);
+ else if (req == WR_THINK)
+ {
+ if (self.BUTTON_ATCK)
+ if (weapon_prepareattack(0, cvar("g_balance_hlac_primary_refire")))
+ {
+ self.HLAC_bulletcounter = 0;
+ W_HLAC_Attack();
+ weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_hlac_primary_refire"), HLAC_fire1_02);
+ }
+
+ if (self.BUTTON_ATCK2)
+ if (weapon_prepareattack(1, cvar("g_balance_hlac_secondary_refire")))
+ {
+ W_HLAC_Attack2();
+ weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_hlac_secondary_animtime"), w_ready);
+ }
+
+ }
+ else if (req == WR_PRECACHE)
+ {
+ precache_model ("models/weapons/g_hlac.md3");
+ precache_model ("models/weapons/v_hlac.md3");
+ precache_model ("models/weapons/w_hlac.zym");
+ precache_sound ("weapons/lasergun_fire.wav");
+
+ }
+ else if (req == WR_SETUP)
+ weapon_setup(WEP_HLAC);
+ else if (req == WR_CHECKAMMO1)
+ return self.ammo_cells >= cvar("g_balance_hlac_primary_ammo");
+ else if (req == WR_CHECKAMMO2)
+ return self.ammo_cells >= cvar("g_balance_hlac_secondary_ammo");
+ else if (req == WR_SUICIDEMESSAGE)
+ w_deathtypestring = "should have used a smaller gun";
+ else if (req == WR_KILLMESSAGE)
+ w_deathtypestring = "was cut down by";
+ return TRUE;
+};
Modified: trunk/data/qcsrc/server/w_seeker.qc
===================================================================
--- trunk/data/qcsrc/server/w_seeker.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/w_seeker.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -1,471 +1,471 @@
-//.float speed; = switchweapon
-//.float proxytime; = autoswitch
-//.float tl; = wait
-
-void Seeker_Missile_Explode ()
-{
- self.event_damage = SUB_Null;
- RadiusDamage (self, self.owner, cvar("g_balance_seeker_missile_damage"), cvar("g_balance_seeker_missile_edgedamage"), cvar("g_balance_seeker_missile_radius"), world, cvar("g_balance_seeker_missile_force"), self.projectiledeathtype, other);
-
- remove (self);
-}
-
-void Seeker_Missile_Touch()
-{
- PROJECTILE_TOUCH;
-
- Seeker_Missile_Explode();
-}
-
-void Seeker_Missile_Think()
-{
- entity e;
- vector desireddir, olddir, newdir, eorg;
- float turnrate;
- float dist;
-
- if (time > self.cnt)
- Seeker_Missile_Explode();
-
- if (!self.switchweapon)
- self.switchweapon = cvar("g_balance_seeker_missile_speed");
-
- if ((self.switchweapon < cvar("g_balance_seeker_missile_speed_max")) && cvar("g_balance_seeker_missile_speed_accel"))
- self.switchweapon = self.switchweapon * cvar("g_balance_seeker_missile_accel");
-
- if (self.switchweapon > cvar("g_balance_seeker_missile_speed_max"))
- self.switchweapon = self.switchweapon * cvar("g_balance_seeker_missile_decel");
-
- if (self.enemy != world)
- if (self.enemy.takedamage != DAMAGE_AIM || self.enemy.deadflag != DEAD_NO)
- self.enemy = world;
-
- if (self.enemy != world)
- {
- e = self.enemy;
- eorg = 0.5 * (e.absmin + e.absmax);
- turnrate = cvar("g_balance_seeker_missile_turnrate"); // how fast to turn
- desireddir = normalize(eorg - self.origin);
- olddir = normalize(self.velocity); // get my current direction
- dist = vlen(eorg - self.origin);
-
- // Do evasive maneuvers for world objects? ( this should be a cpu hog. :P )
- if (cvar("g_balance_seeker_missile_smart") && (dist > cvar("g_balance_seeker_missile_smart_mindist")))
- {
- // Is it a better idea (shorter distance) to trace to the target itself?
- if ( vlen(self.origin + olddir * self.wait) < dist)
- traceline(self.origin, self.origin + olddir * self.wait, FALSE, self);
- else
- traceline(self.origin, eorg, FALSE, self);
-
- // Setup adaptive tracelength
- self.wait = vlen(self.origin - trace_endpos);
- if (self.wait < cvar("g_balance_seeker_missile_smart_trace_min")) self.wait = cvar("g_balance_seeker_missile_smart_trace_min");
- if (self.wait > cvar("g_balance_seeker_missile_smart_trace_max")) self.wait = cvar("g_balance_seeker_missile_smart_trace_max");
-
- // Calc how important it is that we turn and add this to the desierd (enemy) dir.
- desireddir = normalize(((trace_plane_normal * (1 - trace_fraction)) + (desireddir * trace_fraction)) * 0.5);
- }
-
- //newdir = normalize((olddir + desireddir * turnrate) * 0.5);// take the average of the 2 directions; not the best method but simple & easy
- newdir = normalize(olddir + desireddir * turnrate);// take the average of the 2 directions; not the best method but simple & easy
-
- self.velocity = newdir * self.switchweapon; // make me fly in the new direction at my flight speed
- }
-
- // Proxy
- if (cvar("g_balance_seeker_missile_proxy"))
- {
- if ( dist <= cvar("g_balance_seeker_missile_proxy_maxrange"))
- {
- if (self.autoswitch == 0)
- {
- self.autoswitch = time + cvar("g_balance_seeker_missile_proxy_delay");
- }
- else
- {
- if (self.autoswitch <= time)
- {
- Seeker_Missile_Explode();
- self.autoswitch = 0;
- }
- }
- }
- else
- {
- if (self.autoswitch != 0)
- self.autoswitch = 0;
- }
- }
- ///////////////
-
- if (self.enemy.deadflag != DEAD_NO)
- {
- self.enemy = world;
- self.cnt = time + 1 + (random() * 4);
- self.nextthink = self.cnt;
- return;
- }
-
- self.angles = vectoangles(self.velocity); // turn model in the new flight direction
- self.nextthink = time + 0.05;
-
- UpdateCSQCProjectile(self);
-}
-
-
-
-void Seeker_Missile_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
-{
- float d;
- d = damage;
-
- if (self.owner == attacker)
- d = d * 0.25;
-
- self.health = self.health - d;
-
- if (self.health <= 0)
- W_PrepareExplosionByDamage(attacker, Seeker_Missile_Explode);
-}
-
-void Seeker_Missile_Animate()
-{
- self.frame = self.frame +1;
- self.nextthink = time + 0.05;
-
- if (self.enemy != world)
- if (self.enemy.takedamage != DAMAGE_AIM || self.enemy.deadflag != DEAD_NO)
- self.enemy = world;
-
- if(self.frame == 5)
- {
- self.think = Seeker_Missile_Think;
- self.nextthink = time;// + cvar("g_balance_seeker_missile_activate_delay"); // cant dealy with csqc projectiles
-
- if (cvar("g_balance_seeker_guided_proxy"))
- self.movetype = MOVETYPE_BOUNCEMISSILE;
- else
- self.movetype = MOVETYPE_FLYMISSILE;
- }
-
- UpdateCSQCProjectile(self);
-}
-
-void Seeker_Fire_Missile(vector f_org)
-{
- local entity missile;
-
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - cvar("g_balance_seeker_missile_ammo");
-
- makevectors(self.v_angle);
- W_SetupShot (self, f_org, FALSE, 2, "weapons/seeker_fire.wav");
- pointparticles(particleeffectnum("seeker_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
-
- //self.detornator = FALSE;
-
- missile = spawn();
- missile.owner = self;
- missile.classname = "seeker_missile";
- missile.bot_dodge = TRUE;
- missile.bot_dodgerating = cvar("g_balance_seeker_missile_damage");
-
- missile.think = Seeker_Missile_Animate;
-
- //if (!cvar("g_balance_seeker_missile_proxy"))
- missile.touch = Seeker_Missile_Touch;
-
- missile.event_damage = Seeker_Missile_Damage;
- missile.nextthink = time;// + 0.2;// + cvar("g_balance_seeker_missile_activate_delay");
- missile.cnt = time + cvar("g_balance_seeker_missile_lifetime");
- missile.enemy = self.enemy;
- missile.switchweapon = cvar("g_balance_seeker_missile_speed");
- missile.solid = SOLID_BBOX;
- missile.scale = 2;
- missile.takedamage = DAMAGE_YES;
- missile.damageforcescale = 4;
- missile.health = 5;
- missile.projectiledeathtype = WEP_SEEKER;
-
- setorigin (missile, w_shotorg);
- setsize (missile, '-2 -2 -2', '2 2 2');
-
-
- missile.movetype = MOVETYPE_FLYMISSILE;// MOVETYPE_TOSS;
-
- missile.flags = FL_PROJECTILE;
-
- missile.velocity = (w_shotdir + '0 0 0.45') * missile.switchweapon;
- W_SetupProjectileVelocity(missile);
-
- missile.switchweapon = vlen(missile.velocity);
- missile.angles = vectoangles (missile.velocity);
-
- CSQCProjectile(missile, FALSE, PROJECTILE_SEEKER, TRUE);
-}
-
-void Seeker_Vollycontroler_Think()
-{
- float c;
- entity oldself,oldenemy;
- self.cnt = self.cnt - 1;
-
- if ((self.owner.ammo_rockets < cvar("g_balance_seeker_missile_ammo")) || (self.cnt <= -1) || (self.owner.deadflag != DEAD_NO))
- {
- remove(self);
- return;
- }
-
- self.nextthink = time + cvar("g_balance_seeker_missile_delay");
-
- oldself = self;
- self = self.owner;
-
- oldenemy = self.enemy;
- self.enemy = oldself.enemy;
-
- c = mod(oldself.cnt, 4);
- switch(c)
- {
- case 0:
- Seeker_Fire_Missile('37.5 17 -22');
- break;
- case 1:
- Seeker_Fire_Missile('37.5 9.5 -22');
- break;
- case 2:
- Seeker_Fire_Missile('40 17 -29');
- break;
- case 3:
- default:
- Seeker_Fire_Missile('40 9.5 -29');
- break;
- }
-
- self.enemy = oldenemy;
- self = oldself;
-}
-
-void Seeker_Tag_Explode ()
-{
- //if(other==self.owner)
- // return;
- Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_BOUNCE);
-
- remove (self);
-}
-
-void Seeker_Tag_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
-{
- self.health = self.health - damage;
- if (self.health <= 0)
- Seeker_Tag_Explode();
-}
-
-void Seeker_Tag_Think()
-{
- remove(self);
- return;
-}
-
-void Seeker_Tag_Touch()
-{
- vector dir;
- vector org2;
-
- dir = normalize (self.owner.origin - self.origin);
- org2 = findbetterlocation (self.origin, 8);
-
- te_knightspike(org2);
-
- self.event_damage = SUB_Null;
- Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_HEADSHOT);
-
- if (other.takedamage == DAMAGE_AIM && other.deadflag == DEAD_NO)
- {
- entity e;
- e = spawn();
- e.cnt = cvar("g_balance_seeker_missile_count");
- e.owner = self.owner;
- e.enemy = other;
- e.think = Seeker_Vollycontroler_Think;
- e.nextthink = time;
-
- //sprint(self.owner, "^1Target lock ^3[^7 ",other.netname, " ^3]^1 acquired - autofire activated.\n");
- //sprint(other,"^1You are targeted!\n");
-
- // stuffcmd(other,"play2 weapons/zany-alarm4.ogg\n");
- // stuffcmd(self.owner, "play2 weapons/zany-lock4.ogg\n");
- }
-
- remove(self);
- return;
-}
-
-
-
-void Seeker_Fire_Tag()
-{
- local entity missile;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - cvar("g_balance_seeker_tag_ammo");
-
- W_SetupShot (self, '56 13 -15', FALSE, 2, "weapons/tag_fire.wav");
-
- missile = spawn();
- missile.owner = self;
- missile.classname = "seeker_tag";
- missile.bot_dodge = TRUE;
- missile.bot_dodgerating = 50;
- missile.touch = Seeker_Tag_Touch;
- missile.think = Seeker_Tag_Think;
- missile.nextthink = time + 15;
- missile.movetype = MOVETYPE_FLY;
- missile.solid = SOLID_BBOX;
- missile.owner = self;
-
- missile.takedamage = DAMAGE_YES;
- missile.event_damage = Seeker_Tag_Explode;
- missile.health = 5;
-
- setorigin (missile, w_shotorg);
-
- missile.flags = FL_PROJECTILE;
-
- missile.velocity = w_shotdir * cvar("g_balance_seeker_tag_speed");
- missile.movetype = MOVETYPE_BOUNCEMISSILE;
- W_SetupProjectileVelocity(missile);
- missile.angles = vectoangles (missile.velocity);
-
- CSQCProjectile(missile, TRUE, PROJECTILE_TAG, FALSE); // has sound
-}
-
-
-void Seeker_Flac_Explode ()
-{
- self.event_damage = SUB_Null;
-
- RadiusDamage (self, self.owner, cvar("g_balance_seeker_flac_damage"), cvar("g_balance_seeker_flac_edgedamage"), cvar("g_balance_seeker_flac_radius"), world, cvar("g_balance_seeker_flac_force"), self.projectiledeathtype, other);
-
- remove (self);
-}
-
-void Seeker_Flac_Touch()
-{
- PROJECTILE_TOUCH;
-
- Seeker_Flac_Explode();
-}
-
-void Seeker_Fire_Flac()
-{
- local entity missile;
- vector f_org;
- float c;
-
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - cvar("g_balance_seeker_flac_ammo");
-
- c = mod(self.bulletcounter, 4);
- switch(c)
- {
- case 1:
- f_org = '37.5 17 -22';
- break;
- case 2:
- f_org = '37.5 9.5 -22';
- break;
- case 3:
- f_org = '40 17 -29';
- break;
- case 0:
- default:
- f_org = '40 9.5 -29';
- break;
- }
- W_SetupShot (self, f_org, FALSE, 2, "weapons/flac_fire.wav");
-
- pointparticles(particleeffectnum("hagar_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
-
- missile = spawn ();
- missile.owner = missile.realowner = self;
- missile.classname = "missile";
- missile.bot_dodge = TRUE;
- missile.bot_dodgerating = cvar("g_balance_seeker_flac_damage");
- missile.touch = Seeker_Flac_Explode;
- missile.use = Seeker_Flac_Explode;
- missile.think = Seeker_Flac_Explode;
- missile.nextthink = time + cvar("g_balance_seeker_flac_lifetime") + cvar("g_balance_seeker_flac_lifetime_rand");
- missile.solid = SOLID_BBOX;
- missile.scale = 0.4; // BUG: the model is too big
- missile.projectiledeathtype = WEP_SEEKER;
- setorigin (missile, w_shotorg);
- missile.projectiledeathtype = WEP_SEEKER | HITTYPE_SECONDARY;
-
- missile.movetype = MOVETYPE_FLY;
- w_shotdir = w_shotdir + '0 0 0.3';
- missile.velocity = (w_shotdir + randomvec() * cvar("g_balance_seeker_flac_spread")) * cvar("g_balance_seeker_flac_speed");
-
- W_SetupProjectileVelocity(missile);
-
- missile.angles = vectoangles (missile.velocity);
- missile.flags = FL_PROJECTILE;
-
- CSQCProjectile(missile, TRUE, PROJECTILE_FLAC, TRUE);
-}
-
-void spawnfunc_weapon_seeker (void)
-{
- weapon_defaultspawnfunc(WEP_SEEKER);
-}
-
-float w_seeker(float req)
-{
- if (req == WR_AIM)
- self.BUTTON_ATCK = bot_aim(cvar("g_balance_seeker_tag_speed"), 0, 20, FALSE);
-
- else if (req == WR_THINK)
- {
- if (self.BUTTON_ATCK)
- if (weapon_prepareattack(0, cvar("g_balance_seeker_tag_refire")))
- {
- Seeker_Fire_Tag();
- weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_seeker_tag_animtime"), w_ready);
- }
-
- if (self.BUTTON_ATCK2)
- if (weapon_prepareattack(1, cvar("g_balance_seeker_flac_refire")))
- {
- Seeker_Fire_Flac();
- weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_seeker_flac_animtime"), w_ready);
- }
-
- }
- else if (req == WR_PRECACHE)
- {
- precache_model ("models/weapons/g_seeker.md3");
- precache_model ("models/weapons/v_seeker.md3");
- precache_model ("models/weapons/w_seeker.zym");
- precache_sound ("weapons/tag_fire.wav");
- precache_sound ("weapons/flac_fire.wav");
- precache_sound ("weapons/seeker_fire.wav");
- }
- else if (req == WR_SETUP)
- weapon_setup(WEP_SEEKER);
- else if (req == WR_CHECKAMMO1)
- return self.ammo_rockets >= cvar("g_balance_seeker_tag_ammo") + cvar("g_balance_seeker_missile_ammo");
- else if (req == WR_CHECKAMMO2)
- return self.ammo_rockets >= cvar("g_balance_seeker_flac_ammo");
- else if (req == WR_SUICIDEMESSAGE)
- w_deathtypestring = "played with tiny rockets";
- else if (req == WR_KILLMESSAGE)
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- w_deathtypestring = "ran into #'s flac";
- else
- w_deathtypestring = "was tagged by";
- }
- return TRUE;
-};
-
+//.float speed; = switchweapon
+//.float proxytime; = autoswitch
+//.float tl; = wait
+
+void Seeker_Missile_Explode ()
+{
+ self.event_damage = SUB_Null;
+ RadiusDamage (self, self.owner, cvar("g_balance_seeker_missile_damage"), cvar("g_balance_seeker_missile_edgedamage"), cvar("g_balance_seeker_missile_radius"), world, cvar("g_balance_seeker_missile_force"), self.projectiledeathtype, other);
+
+ remove (self);
+}
+
+void Seeker_Missile_Touch()
+{
+ PROJECTILE_TOUCH;
+
+ Seeker_Missile_Explode();
+}
+
+void Seeker_Missile_Think()
+{
+ entity e;
+ vector desireddir, olddir, newdir, eorg;
+ float turnrate;
+ float dist;
+
+ if (time > self.cnt)
+ Seeker_Missile_Explode();
+
+ if (!self.switchweapon)
+ self.switchweapon = cvar("g_balance_seeker_missile_speed");
+
+ if ((self.switchweapon < cvar("g_balance_seeker_missile_speed_max")) && cvar("g_balance_seeker_missile_speed_accel"))
+ self.switchweapon = self.switchweapon * cvar("g_balance_seeker_missile_accel");
+
+ if (self.switchweapon > cvar("g_balance_seeker_missile_speed_max"))
+ self.switchweapon = self.switchweapon * cvar("g_balance_seeker_missile_decel");
+
+ if (self.enemy != world)
+ if (self.enemy.takedamage != DAMAGE_AIM || self.enemy.deadflag != DEAD_NO)
+ self.enemy = world;
+
+ if (self.enemy != world)
+ {
+ e = self.enemy;
+ eorg = 0.5 * (e.absmin + e.absmax);
+ turnrate = cvar("g_balance_seeker_missile_turnrate"); // how fast to turn
+ desireddir = normalize(eorg - self.origin);
+ olddir = normalize(self.velocity); // get my current direction
+ dist = vlen(eorg - self.origin);
+
+ // Do evasive maneuvers for world objects? ( this should be a cpu hog. :P )
+ if (cvar("g_balance_seeker_missile_smart") && (dist > cvar("g_balance_seeker_missile_smart_mindist")))
+ {
+ // Is it a better idea (shorter distance) to trace to the target itself?
+ if ( vlen(self.origin + olddir * self.wait) < dist)
+ traceline(self.origin, self.origin + olddir * self.wait, FALSE, self);
+ else
+ traceline(self.origin, eorg, FALSE, self);
+
+ // Setup adaptive tracelength
+ self.wait = vlen(self.origin - trace_endpos);
+ if (self.wait < cvar("g_balance_seeker_missile_smart_trace_min")) self.wait = cvar("g_balance_seeker_missile_smart_trace_min");
+ if (self.wait > cvar("g_balance_seeker_missile_smart_trace_max")) self.wait = cvar("g_balance_seeker_missile_smart_trace_max");
+
+ // Calc how important it is that we turn and add this to the desierd (enemy) dir.
+ desireddir = normalize(((trace_plane_normal * (1 - trace_fraction)) + (desireddir * trace_fraction)) * 0.5);
+ }
+
+ //newdir = normalize((olddir + desireddir * turnrate) * 0.5);// take the average of the 2 directions; not the best method but simple & easy
+ newdir = normalize(olddir + desireddir * turnrate);// take the average of the 2 directions; not the best method but simple & easy
+
+ self.velocity = newdir * self.switchweapon; // make me fly in the new direction at my flight speed
+ }
+
+ // Proxy
+ if (cvar("g_balance_seeker_missile_proxy"))
+ {
+ if ( dist <= cvar("g_balance_seeker_missile_proxy_maxrange"))
+ {
+ if (self.autoswitch == 0)
+ {
+ self.autoswitch = time + cvar("g_balance_seeker_missile_proxy_delay");
+ }
+ else
+ {
+ if (self.autoswitch <= time)
+ {
+ Seeker_Missile_Explode();
+ self.autoswitch = 0;
+ }
+ }
+ }
+ else
+ {
+ if (self.autoswitch != 0)
+ self.autoswitch = 0;
+ }
+ }
+ ///////////////
+
+ if (self.enemy.deadflag != DEAD_NO)
+ {
+ self.enemy = world;
+ self.cnt = time + 1 + (random() * 4);
+ self.nextthink = self.cnt;
+ return;
+ }
+
+ self.angles = vectoangles(self.velocity); // turn model in the new flight direction
+ self.nextthink = time + 0.05;
+
+ UpdateCSQCProjectile(self);
+}
+
+
+
+void Seeker_Missile_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+ float d;
+ d = damage;
+
+ if (self.owner == attacker)
+ d = d * 0.25;
+
+ self.health = self.health - d;
+
+ if (self.health <= 0)
+ W_PrepareExplosionByDamage(attacker, Seeker_Missile_Explode);
+}
+
+void Seeker_Missile_Animate()
+{
+ self.frame = self.frame +1;
+ self.nextthink = time + 0.05;
+
+ if (self.enemy != world)
+ if (self.enemy.takedamage != DAMAGE_AIM || self.enemy.deadflag != DEAD_NO)
+ self.enemy = world;
+
+ if(self.frame == 5)
+ {
+ self.think = Seeker_Missile_Think;
+ self.nextthink = time;// + cvar("g_balance_seeker_missile_activate_delay"); // cant dealy with csqc projectiles
+
+ if (cvar("g_balance_seeker_guided_proxy"))
+ self.movetype = MOVETYPE_BOUNCEMISSILE;
+ else
+ self.movetype = MOVETYPE_FLYMISSILE;
+ }
+
+ UpdateCSQCProjectile(self);
+}
+
+void Seeker_Fire_Missile(vector f_org)
+{
+ local entity missile;
+
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ self.ammo_rockets = self.ammo_rockets - cvar("g_balance_seeker_missile_ammo");
+
+ makevectors(self.v_angle);
+ W_SetupShot (self, f_org, FALSE, 2, "weapons/seeker_fire.wav");
+ pointparticles(particleeffectnum("seeker_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
+
+ //self.detornator = FALSE;
+
+ missile = spawn();
+ missile.owner = self;
+ missile.classname = "seeker_missile";
+ missile.bot_dodge = TRUE;
+ missile.bot_dodgerating = cvar("g_balance_seeker_missile_damage");
+
+ missile.think = Seeker_Missile_Animate;
+
+ //if (!cvar("g_balance_seeker_missile_proxy"))
+ missile.touch = Seeker_Missile_Touch;
+
+ missile.event_damage = Seeker_Missile_Damage;
+ missile.nextthink = time;// + 0.2;// + cvar("g_balance_seeker_missile_activate_delay");
+ missile.cnt = time + cvar("g_balance_seeker_missile_lifetime");
+ missile.enemy = self.enemy;
+ missile.switchweapon = cvar("g_balance_seeker_missile_speed");
+ missile.solid = SOLID_BBOX;
+ missile.scale = 2;
+ missile.takedamage = DAMAGE_YES;
+ missile.damageforcescale = 4;
+ missile.health = 5;
+ missile.projectiledeathtype = WEP_SEEKER;
+
+ setorigin (missile, w_shotorg);
+ setsize (missile, '-2 -2 -2', '2 2 2');
+
+
+ missile.movetype = MOVETYPE_FLYMISSILE;// MOVETYPE_TOSS;
+
+ missile.flags = FL_PROJECTILE;
+
+ missile.velocity = (w_shotdir + '0 0 0.45') * missile.switchweapon;
+ W_SetupProjectileVelocity(missile);
+
+ missile.switchweapon = vlen(missile.velocity);
+ missile.angles = vectoangles (missile.velocity);
+
+ CSQCProjectile(missile, FALSE, PROJECTILE_SEEKER, TRUE);
+}
+
+void Seeker_Vollycontroler_Think()
+{
+ float c;
+ entity oldself,oldenemy;
+ self.cnt = self.cnt - 1;
+
+ if ((self.owner.ammo_rockets < cvar("g_balance_seeker_missile_ammo")) || (self.cnt <= -1) || (self.owner.deadflag != DEAD_NO))
+ {
+ remove(self);
+ return;
+ }
+
+ self.nextthink = time + cvar("g_balance_seeker_missile_delay");
+
+ oldself = self;
+ self = self.owner;
+
+ oldenemy = self.enemy;
+ self.enemy = oldself.enemy;
+
+ c = mod(oldself.cnt, 4);
+ switch(c)
+ {
+ case 0:
+ Seeker_Fire_Missile('37.5 17 -22');
+ break;
+ case 1:
+ Seeker_Fire_Missile('37.5 9.5 -22');
+ break;
+ case 2:
+ Seeker_Fire_Missile('40 17 -29');
+ break;
+ case 3:
+ default:
+ Seeker_Fire_Missile('40 9.5 -29');
+ break;
+ }
+
+ self.enemy = oldenemy;
+ self = oldself;
+}
+
+void Seeker_Tag_Explode ()
+{
+ //if(other==self.owner)
+ // return;
+ Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_BOUNCE);
+
+ remove (self);
+}
+
+void Seeker_Tag_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+ self.health = self.health - damage;
+ if (self.health <= 0)
+ Seeker_Tag_Explode();
+}
+
+void Seeker_Tag_Think()
+{
+ remove(self);
+ return;
+}
+
+void Seeker_Tag_Touch()
+{
+ vector dir;
+ vector org2;
+
+ dir = normalize (self.owner.origin - self.origin);
+ org2 = findbetterlocation (self.origin, 8);
+
+ te_knightspike(org2);
+
+ self.event_damage = SUB_Null;
+ Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_HEADSHOT);
+
+ if (other.takedamage == DAMAGE_AIM && other.deadflag == DEAD_NO)
+ {
+ entity e;
+ e = spawn();
+ e.cnt = cvar("g_balance_seeker_missile_count");
+ e.owner = self.owner;
+ e.enemy = other;
+ e.think = Seeker_Vollycontroler_Think;
+ e.nextthink = time;
+
+ //sprint(self.owner, "^1Target lock ^3[^7 ",other.netname, " ^3]^1 acquired - autofire activated.\n");
+ //sprint(other,"^1You are targeted!\n");
+
+ // stuffcmd(other,"play2 weapons/zany-alarm4.ogg\n");
+ // stuffcmd(self.owner, "play2 weapons/zany-lock4.ogg\n");
+ }
+
+ remove(self);
+ return;
+}
+
+
+
+void Seeker_Fire_Tag()
+{
+ local entity missile;
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ self.ammo_rockets = self.ammo_rockets - cvar("g_balance_seeker_tag_ammo");
+
+ W_SetupShot (self, '56 13 -15', FALSE, 2, "weapons/tag_fire.wav");
+
+ missile = spawn();
+ missile.owner = self;
+ missile.classname = "seeker_tag";
+ missile.bot_dodge = TRUE;
+ missile.bot_dodgerating = 50;
+ missile.touch = Seeker_Tag_Touch;
+ missile.think = Seeker_Tag_Think;
+ missile.nextthink = time + 15;
+ missile.movetype = MOVETYPE_FLY;
+ missile.solid = SOLID_BBOX;
+ missile.owner = self;
+
+ missile.takedamage = DAMAGE_YES;
+ missile.event_damage = Seeker_Tag_Explode;
+ missile.health = 5;
+
+ setorigin (missile, w_shotorg);
+
+ missile.flags = FL_PROJECTILE;
+
+ missile.velocity = w_shotdir * cvar("g_balance_seeker_tag_speed");
+ missile.movetype = MOVETYPE_BOUNCEMISSILE;
+ W_SetupProjectileVelocity(missile);
+ missile.angles = vectoangles (missile.velocity);
+
+ CSQCProjectile(missile, TRUE, PROJECTILE_TAG, FALSE); // has sound
+}
+
+
+void Seeker_Flac_Explode ()
+{
+ self.event_damage = SUB_Null;
+
+ RadiusDamage (self, self.owner, cvar("g_balance_seeker_flac_damage"), cvar("g_balance_seeker_flac_edgedamage"), cvar("g_balance_seeker_flac_radius"), world, cvar("g_balance_seeker_flac_force"), self.projectiledeathtype, other);
+
+ remove (self);
+}
+
+void Seeker_Flac_Touch()
+{
+ PROJECTILE_TOUCH;
+
+ Seeker_Flac_Explode();
+}
+
+void Seeker_Fire_Flac()
+{
+ local entity missile;
+ vector f_org;
+ float c;
+
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ self.ammo_rockets = self.ammo_rockets - cvar("g_balance_seeker_flac_ammo");
+
+ c = mod(self.bulletcounter, 4);
+ switch(c)
+ {
+ case 1:
+ f_org = '37.5 17 -22';
+ break;
+ case 2:
+ f_org = '37.5 9.5 -22';
+ break;
+ case 3:
+ f_org = '40 17 -29';
+ break;
+ case 0:
+ default:
+ f_org = '40 9.5 -29';
+ break;
+ }
+ W_SetupShot (self, f_org, FALSE, 2, "weapons/flac_fire.wav");
+
+ pointparticles(particleeffectnum("hagar_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
+
+ missile = spawn ();
+ missile.owner = missile.realowner = self;
+ missile.classname = "missile";
+ missile.bot_dodge = TRUE;
+ missile.bot_dodgerating = cvar("g_balance_seeker_flac_damage");
+ missile.touch = Seeker_Flac_Explode;
+ missile.use = Seeker_Flac_Explode;
+ missile.think = Seeker_Flac_Explode;
+ missile.nextthink = time + cvar("g_balance_seeker_flac_lifetime") + cvar("g_balance_seeker_flac_lifetime_rand");
+ missile.solid = SOLID_BBOX;
+ missile.scale = 0.4; // BUG: the model is too big
+ missile.projectiledeathtype = WEP_SEEKER;
+ setorigin (missile, w_shotorg);
+ missile.projectiledeathtype = WEP_SEEKER | HITTYPE_SECONDARY;
+
+ missile.movetype = MOVETYPE_FLY;
+ w_shotdir = w_shotdir + '0 0 0.3';
+ missile.velocity = (w_shotdir + randomvec() * cvar("g_balance_seeker_flac_spread")) * cvar("g_balance_seeker_flac_speed");
+
+ W_SetupProjectileVelocity(missile);
+
+ missile.angles = vectoangles (missile.velocity);
+ missile.flags = FL_PROJECTILE;
+
+ CSQCProjectile(missile, TRUE, PROJECTILE_FLAC, TRUE);
+}
+
+void spawnfunc_weapon_seeker (void)
+{
+ weapon_defaultspawnfunc(WEP_SEEKER);
+}
+
+float w_seeker(float req)
+{
+ if (req == WR_AIM)
+ self.BUTTON_ATCK = bot_aim(cvar("g_balance_seeker_tag_speed"), 0, 20, FALSE);
+
+ else if (req == WR_THINK)
+ {
+ if (self.BUTTON_ATCK)
+ if (weapon_prepareattack(0, cvar("g_balance_seeker_tag_refire")))
+ {
+ Seeker_Fire_Tag();
+ weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_seeker_tag_animtime"), w_ready);
+ }
+
+ if (self.BUTTON_ATCK2)
+ if (weapon_prepareattack(1, cvar("g_balance_seeker_flac_refire")))
+ {
+ Seeker_Fire_Flac();
+ weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_seeker_flac_animtime"), w_ready);
+ }
+
+ }
+ else if (req == WR_PRECACHE)
+ {
+ precache_model ("models/weapons/g_seeker.md3");
+ precache_model ("models/weapons/v_seeker.md3");
+ precache_model ("models/weapons/w_seeker.zym");
+ precache_sound ("weapons/tag_fire.wav");
+ precache_sound ("weapons/flac_fire.wav");
+ precache_sound ("weapons/seeker_fire.wav");
+ }
+ else if (req == WR_SETUP)
+ weapon_setup(WEP_SEEKER);
+ else if (req == WR_CHECKAMMO1)
+ return self.ammo_rockets >= cvar("g_balance_seeker_tag_ammo") + cvar("g_balance_seeker_missile_ammo");
+ else if (req == WR_CHECKAMMO2)
+ return self.ammo_rockets >= cvar("g_balance_seeker_flac_ammo");
+ else if (req == WR_SUICIDEMESSAGE)
+ w_deathtypestring = "played with tiny rockets";
+ else if (req == WR_KILLMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ w_deathtypestring = "ran into #'s flac";
+ else
+ w_deathtypestring = "was tagged by";
+ }
+ return TRUE;
+};
+
Modified: trunk/data/qcsrc/server/w_uzi.qc
===================================================================
--- trunk/data/qcsrc/server/w_uzi.qc 2009-03-11 20:45:17 UTC (rev 6104)
+++ trunk/data/qcsrc/server/w_uzi.qc 2009-03-11 21:39:56 UTC (rev 6105)
@@ -1,3 +1,4 @@
+
// leilei's fancy muzzleflash stuff
void W_Uzi_Flash_Go() {
if (self.frame > 10){
@@ -128,11 +129,13 @@
precache_model ("models/uziflash.md3");
precache_model ("models/weapons/g_uzi.md3");
precache_model ("models/weapons/v_uzi.md3");
- precache_model ("models/weapons/w_uzi.zym");
+ precache_model ("models/weapons/w_uzi.dpm");
precache_sound ("weapons/uzi_fire.wav");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_UZI);
+ }
else if (req == WR_CHECKAMMO1)
return self.ammo_nails >= cvar("g_balance_uzi_first_ammo");
else if (req == WR_CHECKAMMO2)
More information about the nexuiz-commits
mailing list