[nexuiz-commits] r6251 - in branches/nexuiz-2.0: . Docs/htmlfiles/img data data/gfx data/maps data/models/turrets data/qcsrc/common data/qcsrc/server data/qcsrc/server/tturrets/include data/qcsrc/server/tturrets/system data/qcsrc/server/tturrets/units data/scripts
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sun Mar 22 17:23:05 EDT 2009
Author: div0
Date: 2009-03-22 17:23:04 -0400 (Sun, 22 Mar 2009)
New Revision: 6251
Added:
branches/nexuiz-2.0/data/gfx/colors/
branches/nexuiz-2.0/data/maps/walker_pathtest2.bsp
branches/nexuiz-2.0/data/qcsrc/server/verbstack.qc
branches/nexuiz-2.0/data/scripts/cel.shader
Modified:
branches/nexuiz-2.0/.patchsets
branches/nexuiz-2.0/Docs/htmlfiles/img/nexuiz_logo.jpg
branches/nexuiz-2.0/data/models/turrets/walker_body.md3
branches/nexuiz-2.0/data/qcsrc/common/constants.qh
branches/nexuiz-2.0/data/qcsrc/server/bots.qc
branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc
branches/nexuiz-2.0/data/qcsrc/server/extensions.qh
branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc
branches/nexuiz-2.0/data/qcsrc/server/havocbot.qc
branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
branches/nexuiz-2.0/data/qcsrc/server/movelib.qc
branches/nexuiz-2.0/data/qcsrc/server/pathlib.qc
branches/nexuiz-2.0/data/qcsrc/server/progs.src
branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/include/turrets.qh
branches/nexuiz-2.0/data/qcsrc/server/tturrets/include/turrets_early.qh
branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_aimprocs.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_damage.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_main.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_misc.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_scoreprocs.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_checkpoint.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_common.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_ewheel.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_flac.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_hellion.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_hk.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_machinegun.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_mlrs.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_phaser.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_plasma.qc
branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_walker.qc
branches/nexuiz-2.0/data/scripts/shaderlist.txt
branches/nexuiz-2.0/data/turrets.cfg
branches/nexuiz-2.0/data/unit_flac.cfg
branches/nexuiz-2.0/data/unit_fusreac.cfg
branches/nexuiz-2.0/data/unit_machinegun.cfg
branches/nexuiz-2.0/data/unit_mlrs.cfg
branches/nexuiz-2.0/data/unit_plasma.cfg
branches/nexuiz-2.0/data/unit_walker.cfg
Log:
r6237 | div0 | 2009-03-20 17:49:18 +0100 (Fri, 20 Mar 2009) | 2 lines
make version image versionless for the time being (removes a 2.4.2)
r6239 | div0 | 2009-03-20 18:10:17 +0100 (Fri, 20 Mar 2009) | 2 lines
add lots of useful color tga files
r6240 | div0 | 2009-03-20 18:23:05 +0100 (Fri, 20 Mar 2009) | 2 lines
easy cel shading: q3map2 ... -bsp -celshader cel/black_ink -flat ...
r6241 | mand1nga | 2009-03-21 04:33:41 +0100 (Sat, 21 Mar 2009) | 1 line
Replaced water levels with meaningful constants
r6242 | div0 | 2009-03-21 15:08:50 +0100 (Sat, 21 Mar 2009) | 2 lines
minstagib: play hit sound for shidl hits again
r6243 | div0 | 2009-03-21 21:47:35 +0100 (Sat, 21 Mar 2009) | 2 lines
make gettaginfo_relative_ent invisible :(
r6244 | div0 | 2009-03-21 23:12:11 +0100 (Sat, 21 Mar 2009) | 2 lines
DP_QC_GETTIME, sv_cmd time
r6245 | tzork | 2009-03-22 15:09:56 +0100 (Sun, 22 Mar 2009) | 3 lines
pathlib changed to use with AStar.
add verbstack for stack based ai.
r6246 | tzork | 2009-03-22 15:10:40 +0100 (Sun, 22 Mar 2009) | 1 line
Massive turrets updates.
r6247 | tzork | 2009-03-22 15:12:11 +0100 (Sun, 22 Mar 2009) | 1 line
updated turrets cfg.
r6248 | tzork | 2009-03-22 15:14:29 +0100 (Sun, 22 Mar 2009) | 3 lines
Testmap for a* + walkers.
forgot one cfg
new walker body (swim animation)
r6249 | tzork | 2009-03-22 15:37:23 +0100 (Sun, 22 Mar 2009) | 3 lines
fixed a ent leak.
pathlib bugs without DEBUGPATHING on (?) have it on for now.
r6250 | mand1nga | 2009-03-22 19:39:18 +0100 (Sun, 22 Mar 2009) | 3 lines
Fix for bot_aim() suggested by Qantourisc, makes this code dependent of "time" instead of "frametime". **Please test**
Removed old commented code
Modified: branches/nexuiz-2.0/.patchsets
===================================================================
--- branches/nexuiz-2.0/.patchsets 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/.patchsets 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,2 +1,2 @@
master = svn://svn.icculus.org/nexuiz/trunk
-revisions_applied = 1-6039,6044-6220,6223-6236
+revisions_applied = 1-6039,6044-6250
Modified: branches/nexuiz-2.0/Docs/htmlfiles/img/nexuiz_logo.jpg
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/gfx/colors (from rev 6250, trunk/data/gfx/colors)
Copied: branches/nexuiz-2.0/data/maps/walker_pathtest2.bsp (from rev 6250, trunk/data/maps/walker_pathtest2.bsp)
===================================================================
(Binary files differ)
Modified: branches/nexuiz-2.0/data/models/turrets/walker_body.md3
===================================================================
(Binary files differ)
Modified: branches/nexuiz-2.0/data/qcsrc/common/constants.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/constants.qh 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/common/constants.qh 2009-03-22 21:23:04 UTC (rev 6251)
@@ -417,3 +417,9 @@
//misc. stuff
#define NEWLINES "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+
+// water levels
+float WATERLEVEL_NONE = 0;
+float WATERLEVEL_WETFEET = 1;
+float WATERLEVEL_SWIMMING = 2;
+float WATERLEVEL_SUBMERGED = 3;
Modified: branches/nexuiz-2.0/data/qcsrc/server/bots.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/bots.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/bots.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -2,7 +2,7 @@
float AI_STATUS_ROAMING = 1; // Bot is just crawling the map. No enemies at sight
float AI_STATUS_ATTACKING = 2; // There are enemies at sight
float AI_STATUS_RUNNING = 4; // Bot is bunny hopping
-float AI_STATUS_DANGER_AHEAD = 8; // There is lava/slime/abism ahead
+float AI_STATUS_DANGER_AHEAD = 8; // There is lava/slime/trigger_hurt ahead
float AI_STATUS_OUT_JUMPPAD = 16; // Trying to get out of a "vertical" jump pad
float AI_STATUS_OUT_WATER = 32; // Trying to get out of water
@@ -1213,7 +1213,7 @@
maxdistance = 50000;
else
maxdistance = 1500;
-
+
for(i=increment;!navigation_markroutes_nearestwaypoints(waylist, i)&&i<maxdistance;i+=increment);
searching = TRUE;
@@ -1714,6 +1714,7 @@
.float bot_nextthink;
.float bot_badaimtime;
.float bot_aimthinktime;
+.float bot_prevaimtime;
.vector bot_mouseaim;
.vector bot_badaimoffset;
.vector bot_1st_order_aimfilter;
@@ -1724,39 +1725,9 @@
.vector bot_olddesiredang;
float bot_aimdir(vector v, float maxfiredeviation)
{
-/*
- local float snapcos;
- local vector olddir, newdir, desireddir;
-
- makevectors(self.v_angle);
- olddir = newdir = v_forward;
- desireddir = normalize(v);
- snapcos = cos(cvar("bot_ai_aimskill_snapangle") * frametime * (skill + 1) * 0.5);
- if (desireddir * olddir < v_forward_x)
- newdir = desireddir;
- else
- {
- local float blendrate;
- blendrate = cvar("bot_ai_aimskill_blendrate") * frametime * (skill + 1) * 0.5;
- newdir = olddir + (desireddir - olddir) * bound(0, blendrate, 1);
- }
-
- // decide whether to fire this time
- if ((desireddir * newdir) >= cos(maxfiredeviation))
- self.bot_firetimer = time + 0.3;
-
- self.v_angle = vectoangles(newdir);
- self.v_angle_x = self.v_angle_x * -1;
-
- makevectors(self.v_angle);
- shotorg = self.origin + self.view_ofs;
- shotdir = newdir;
-
- return time < self.bot_firetimer;
-*/
-
- local float dist;
+ local float dist, delta_t, blend;
local vector desiredang, diffang;
+ local float delta_t;
//dprint("aim ", self.netname, ": old:", vtos(self.v_angle));
// make sure v_angle is sane first
@@ -1796,9 +1767,11 @@
self.bot_olddesiredang = desiredang;
//dprint(" diff:", vtos(diffang));
+ delta_t = time-self.bot_prevaimtime;
+ self.bot_prevaimtime = time;
// Here we will try to anticipate the comming aiming direction
self.bot_1st_order_aimfilter= self.bot_1st_order_aimfilter
- + (diffang * (1 / frametime) - self.bot_1st_order_aimfilter) * bound(0, cvar("bot_ai_aimskill_order_filter_1st"),1);
+ + (diffang * (1 / delta_t) - self.bot_1st_order_aimfilter) * bound(0, cvar("bot_ai_aimskill_order_filter_1st"),1);
self.bot_2nd_order_aimfilter= self.bot_2nd_order_aimfilter
+ (self.bot_1st_order_aimfilter - self.bot_2nd_order_aimfilter) * bound(0, cvar("bot_ai_aimskill_order_filter_2nd"),1);
self.bot_3th_order_aimfilter= self.bot_3th_order_aimfilter
@@ -1808,7 +1781,6 @@
self.bot_5th_order_aimfilter= self.bot_5th_order_aimfilter
+ (self.bot_4th_order_aimfilter - self.bot_5th_order_aimfilter) * bound(0, cvar("bot_ai_aimskill_order_filter_5th"),1);
- local float blend;
//blend = (bound(0,skill,10)*0.1)*pow(1-bound(0,skill,10)*0.05,2.5)*5.656854249; //Plot formule before changing !
blend = bound(0,skill,10)*0.1;
desiredang = desiredang + blend *
@@ -1861,7 +1833,7 @@
blendrate = cvar("bot_ai_aimskill_blendrate");
r = max(fixedrate, blendrate);
//self.v_angle = self.v_angle + diffang * bound(frametime, r * frametime * (2+skill*skill*0.05-random()*0.05*(10-skill)), 1);
- self.v_angle = self.v_angle + diffang * bound(frametime, r * frametime * (2+pow(skill+self.bot_mouseskill,3)*0.005-random()), 1);
+ self.v_angle = self.v_angle + diffang * bound(delta_t, r * delta_t * (2+pow(skill+self.bot_mouseskill,3)*0.005-random()), 1);
self.v_angle = self.v_angle * bound(0,cvar("bot_ai_aimskill_mouse"),1) + desiredang * bound(0,(1-cvar("bot_ai_aimskill_mouse")),1);
//self.v_angle = self.v_angle + diffang * bound(0, r * frametime * (skill * 0.5 + 2), 1);
//self.v_angle = self.v_angle + diffang * (1/ blendrate);
Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -33,7 +33,7 @@
float mjumpheight;
mjumpheight = cvar("sv_jumpvelocity");
- if (self.waterlevel >= 2)
+ if (self.waterlevel >= WATERLEVEL_SWIMMING)
{
if (self.watertype == CONTENT_WATER)
self.velocity_z = 200;
@@ -490,7 +490,7 @@
{
self.wasFlying = 0;
- if(self.waterlevel < 2)
+ if(self.waterlevel < WATERLEVEL_SWIMMING)
if(time >= self.ladder_time)
if not(self.hook)
{
@@ -525,7 +525,7 @@
else
self.flags |= FL_JUMPRELEASED;
- if (self.waterlevel == 2)
+ if (self.waterlevel == WATERLEVEL_SWIMMING)
CheckWaterJump ();
}
@@ -533,7 +533,7 @@
{
self.velocity_x = self.movedir_x;
self.velocity_y = self.movedir_y;
- if (time > self.teleport_time || self.waterlevel == 0)
+ if (time > self.teleport_time || self.waterlevel == WATERLEVEL_NONE)
{
self.flags &~= FL_WATERJUMP;
self.teleport_time = 0;
@@ -564,7 +564,7 @@
self.velocity = self.velocity + wishdir * min(f, sv_accelerate*maxspd_mod * frametime * wishspeed);
}
}
- else if (self.waterlevel >= 2)
+ else if (self.waterlevel >= WATERLEVEL_SWIMMING)
{
// swimming
self.flags &~= FL_ONGROUND;
@@ -611,14 +611,14 @@
self.watertype = self.ladder_entity.skin;
f = self.ladder_entity.origin_z + self.ladder_entity.maxs_z;
if ((self.origin_z + self.view_ofs_z) < f)
- self.waterlevel = 3;
+ self.waterlevel = WATERLEVEL_SUBMERGED;
else if ((self.origin_z + (self.mins_z + self.maxs_z) * 0.5) < f)
- self.waterlevel = 2;
+ self.waterlevel = WATERLEVEL_SWIMMING;
else if ((self.origin_z + self.mins_z + 1) < f)
- self.waterlevel = 1;
+ self.waterlevel = WATERLEVEL_WETFEET;
else
{
- self.waterlevel = 0;
+ self.waterlevel = WATERLEVEL_NONE;
self.watertype = CONTENT_EMPTY;
}
}
Modified: branches/nexuiz-2.0/data/qcsrc/server/extensions.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/extensions.qh 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/extensions.qh 2009-03-22 21:23:04 UTC (rev 6251)
@@ -763,6 +763,19 @@
//gettaginfo_name is set to the name of the bone whose index had been specified in gettaginfo
//gettaginfo_offset, gettaginfo_forward, gettaginfo_right, gettaginfo_up contain the transformation matrix of the bone relative to its parent. Note that the matrix may contain a scaling component.
+//DP_QC_GETTIME
+//idea: tZork
+//darkplaces implementation: tZork, div0
+//constant definitions:
+float GETTIME_FRAMESTART = 0; // time of start of frame
+float GETTIME_REALTIME = 1; // current time (may be OS specific)
+float GETTIME_HIRES = 2; // like REALTIME, but may reset between QC invocations and thus can be higher precision
+float GETTIME_UPTIME = 3; // time since start of the engine
+//builtin definitions:
+float(float tmr) gettime = #519;
+//description:
+//some timers to query...
+
//DP_QC_MINMAXBOUND
//idea: LordHavoc
//darkplaces implementation: LordHavoc
Modified: branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -75,7 +75,7 @@
{
if(a.flags & FL_ONGROUND)
return 0;
- if(a.waterlevel >= 2)
+ if(a.waterlevel >= WATERLEVEL_SWIMMING)
return 0;
traceline(a.origin, a.origin - '0 0 48', MOVE_NORMAL, a);
if(trace_fraction < 1)
@@ -684,6 +684,7 @@
centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, "^3Remaining extra lives: ",ftos(targ.armorvalue)));
damage = 0;
targ.hitsound += 1;
+ attacker.hitsound += 1; // TODO change this to a future specific hitsound for armor hit
}
if (DEATH_ISWEAPON(deathtype, WEP_LASER))
{
Modified: branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -859,6 +859,18 @@
return;
}
+ if(argv(0) == "time")
+ {
+ print("time = ", ftos(time), "\n");
+ print("frame start = ", ftos(gettime(GETTIME_FRAMESTART)), "\n");
+ print("realtime = ", ftos(gettime(GETTIME_REALTIME)), "\n");
+ print("hires = ", ftos(gettime(GETTIME_HIRES)), "\n");
+ print("uptime = ", ftos(gettime(GETTIME_UPTIME)), "\n");
+ print("localtime = ", strftime(TRUE, "%a %b %e %H:%M:%S %Z %Y"), "\n");
+ print("gmtime = ", strftime(FALSE, "%a %b %e %H:%M:%S %Z %Y"), "\n");
+ return;
+ }
+
print("Invalid command. For a list of supported commands, try sv_cmd help.\n");
}
Modified: branches/nexuiz-2.0/data/qcsrc/server/havocbot.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/havocbot.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/havocbot.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -153,7 +153,7 @@
return;
}
- if(self.waterlevel > 1)
+ if(self.waterlevel > WATERLEVEL_WETFEET)
{
self.aistatus &~= AI_STATUS_RUNNING;
return;
@@ -357,9 +357,9 @@
if(self.goalcurrent==world)
{
dir = '0 0 0';
- if(self.waterlevel>2)
+ if(self.waterlevel>WATERLEVEL_SWIMMING)
dir_z = 1;
- else if(self.velocity_z >= 0 && !(self.waterlevel == 1 && self.watertype == CONTENT_WATER))
+ else if(self.velocity_z >= 0 && !(self.waterlevel == WATERLEVEL_WETFEET && self.watertype == CONTENT_WATER))
self.BUTTON_JUMP = TRUE;
else
self.BUTTON_JUMP = FALSE;
@@ -421,7 +421,7 @@
if (self.waterlevel)
{
- if(self.waterlevel>2)
+ if(self.waterlevel>WATERLEVEL_SWIMMING)
{
// flatdir_z = 1;
self.aistatus |= AI_STATUS_OUT_WATER;
@@ -429,7 +429,7 @@
else
{
if(self.velocity_z >= 0 && !(self.watertype == CONTENT_WATER && self.goalcurrent.origin_z < self.origin_z) &&
- ( !(self.waterlevel == 1 && self.watertype == CONTENT_WATER) || self.aistatus & AI_STATUS_OUT_WATER))
+ ( !(self.waterlevel == WATERLEVEL_WETFEET && self.watertype == CONTENT_WATER) || self.aistatus & AI_STATUS_OUT_WATER))
self.BUTTON_JUMP = TRUE;
else
self.BUTTON_JUMP = FALSE;
@@ -899,7 +899,7 @@
// TODO: tracewalk() should take care of this job (better path finding under water)
// if we don't have a goal and we're under water look for a waypoint near the "shore" and push it
if(self.goalcurrent==world)
- if(self.waterlevel==2 || self.aistatus & AI_STATUS_OUT_WATER)
+ if(self.waterlevel==WATERLEVEL_SWIMMING || self.aistatus & AI_STATUS_OUT_WATER)
{
// Look for the closest waypoint out of water
local entity newgoal, head;
@@ -987,7 +987,7 @@
//dprint(etos(self), " ");
//dprint(vtos(now), ":", vtos(next), "=", vtos(v), " (blend ", ftos(blend), ")\n");
//v = now * (distanceblend) + next * (1-distanceblend);
- if (self.waterlevel < 2)
+ if (self.waterlevel < WATERLEVEL_SWIMMING)
v_z = 0;
//dprint("walk at:", vtos(v), "\n");
//te_lightning2(world, self.origin, self.goalcurrent.origin);
Modified: branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -2120,7 +2120,10 @@
vector gettaginfo_relative(entity e, float tag)
{
if(!gettaginfo_relative_ent)
+ {
gettaginfo_relative_ent = spawn();
+ gettaginfo_relative_ent.effects = EF_NODRAW;
+ }
gettaginfo_relative_ent.model = e.model;
gettaginfo_relative_ent.modelindex = e.modelindex;
gettaginfo_relative_ent.frame = e.frame;
Modified: branches/nexuiz-2.0/data/qcsrc/server/movelib.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/movelib.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/movelib.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -31,7 +31,7 @@
/**
Do a inertia simulation based on velocity.
- Basicaly, this allows you to simulate objects loss steering with speed.
+ Basicaly, this allows you to simulate loss of steering with higher 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)
@@ -55,14 +55,15 @@
{
float deltatime;
float acceleration;
- //float mspeed;
+ float mspeed;
+ vector breakvec;
deltatime = time - self.movelib_lastupdate;
if (deltatime > 0.15) deltatime = 0;
self.movelib_lastupdate = time;
if(!deltatime) return;
- //mspeed = vlen(self.velocity);
+ mspeed = vlen(self.velocity);
if(mass)
acceleration = vlen(force) / mass;
@@ -72,61 +73,144 @@
if(self.flags & FL_ONGROUND)
{
if(breakforce)
- {
- breakforce = 1 - ((breakforce / mass) * deltatime);
- self.velocity = self.velocity * breakforce;
- }
+ {
+ breakvec = (normalize(self.velocity) * (breakforce / mass) * deltatime);
+ self.velocity = self.velocity - breakvec;
+ }
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(self.waterlevel > 1)
+ {
+ self.velocity = self.velocity + force * (acceleration * deltatime);
+ self.velocity = self.velocity + '0 0 0.05' * sv_gravity * deltatime;
+ }
+ else
+ self.velocity = self.velocity + '0 0 -1' * sv_gravity * deltatime;
+
+ mspeed = vlen(self.velocity);
- if(drag)
- self.velocity = movelib_dragvec(drag, 1);
-
if(max_velocity)
- if(vlen(self.velocity) > max_velocity)
- self.velocity = normalize(self.velocity) * max_velocity;
-}
+ if(mspeed > max_velocity)
+ self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
+}
+
+/*
+.float mass;
+.float side_friction;
+.float ground_friction;
+.float air_friction;
+.float water_friction;
+.float buoyancy;
+float movelib_deltatime;
+
+void movelib_startupdate()
+{
+ movelib_deltatime = time - self.movelib_lastupdate;
+
+ if (movelib_deltatime > 0.5)
+ movelib_deltatime = 0;
+
+ self.movelib_lastupdate = time;
+}
-void movelib_move_simple(vector newdir,float velo,float turnrate)
-{
- vector olddir;
+void movelib_update(vector dir,float force)
+{
+ vector acceleration;
+ float old_speed;
+ float ffriction,v_z;
+
+ vector breakvec;
+ vector old_dir;
+ vector ggravity;
+ vector old;
+
+ if(!movelib_deltatime)
+ return;
+ v_z = self.velocity_z;
+ old_speed = vlen(self.velocity);
+ old_dir = normalize(self.velocity);
+
+ //ggravity = (sv_gravity / self.mass) * '0 0 100';
+ acceleration = (force / self.mass) * dir;
+ //acceleration -= old_dir * (old_speed / self.mass);
+ acceleration -= ggravity;
+
+ if(self.waterlevel > 1)
+ {
+ ffriction = self.water_friction;
+ acceleration += self.buoyancy * '0 0 1';
+ }
+ else
+ if(self.flags & FL_ONGROUND)
+ ffriction = self.ground_friction;
+ else
+ ffriction = self.air_friction;
+
+ acceleration *= ffriction;
+ //self.velocity = self.velocity * (ffriction * movelib_deltatime);
+ self.velocity += acceleration * movelib_deltatime;
+ self.velocity_z = v_z;
+
+}
+*/
- olddir = normalize(self.velocity);
-
- self.velocity = normalize(olddir + newdir * turnrate) * velo;
-}
-
-/*
-vector movelib_accelerate(float force)
+void movelib_move_simple(vector newdir,float velo,float blendrate)
{
- vector vel;
- vel = self.velocity;
- vel = normalize(vel) * (vlen(vel) + force);
- self.velocity = self.velocity + vel;
+ self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
}
-
-
-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';
-}
+void movelib_beak_simple(float force)
+{
+ float mspeed;
+ vector mdir;
+
+ mspeed = max(0,vlen(self.velocity) - force);
+ mdir = normalize(self.velocity);
+ self.velocity = mdir * mspeed;
+}
+
+
+void movelib_groundalign4point(float spring_length,float spring_up)
+{
+ vector a,b,c,d,e,r,push_angle;
+ push_angle_y = 0;
+ r = (self.absmax + self.absmin) * 0.5 + (v_up * spring_up);
+ e = v_up * spring_length;
+
+ a = r + (v_forward * self.maxs_x) + (v_right * self.maxs_y);
+ b = r + (v_forward * self.maxs_x) - (v_right * self.maxs_y);
+ c = r - (v_forward * self.maxs_x) + (v_right * self.maxs_y);
+ d = r - (v_forward * self.maxs_x) - (v_right * self.maxs_y);
+
+ traceline(a, a - e,MOVE_NORMAL,self);
+ a_z = (1 - trace_fraction);
+ r = trace_endpos;
+ traceline(b, b - e,MOVE_NORMAL,self);
+ b_z = (1 - trace_fraction);
+ r += trace_endpos;
+ traceline(c, c - e,MOVE_NORMAL,self);
+ c_z = (1 - trace_fraction);
+ r += trace_endpos;
+ traceline(d, d - e,MOVE_NORMAL,self);
+ d_z = (1 - trace_fraction);
+ r += trace_endpos;
+ a_x = r_z;
+ r = self.origin;
+ r_z = r_z;
+
+ push_angle_x = (a_z - c_z) * 45;
+ push_angle_x += (b_z - d_z) * 45;
+
+ push_angle_z = (b_z - a_z) * 45;
+ push_angle_z += (d_z - c_z) * 45;
+
+ self.angles_x += push_angle_x * 0.95;
+ self.angles_z += push_angle_z * 0.95;
+
+ setorigin(self,r);
+}
+
Modified: branches/nexuiz-2.0/data/qcsrc/server/pathlib.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/pathlib.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/pathlib.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,480 +1,998 @@
-#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 PATHLIB_RDFIELDS
+#ifdef PATHLIB_RDFIELDS
+ #define path_next swampslug
+ #define path_prev lasertarget
+#else
+ .entity path_next;
+ .entity path_prev;
+#endif
+
+entity openlist;
+entity closedlist;
+entity scraplist;
+
+.float pathlib_node_g;
+.float pathlib_node_h;
+.float pathlib_node_f;
+
+float pathlib_open_cnt;
+float pathlib_closed_cnt;
+float pathlib_made_cnt;
+float pathlib_merge_cnt;
+float pathlib_recycle_cnt;
+float pathlib_searched_cnt;
+
+float pathlib_bestopen_seached;
+float pathlib_bestcash_hits;
+float pathlib_bestcash_saved;
+
+float pathlib_gridsize;
+
+float pathlib_movecost;
+float pathlib_movecost_diag;
+float pathlib_movecost_waterfactor;
+
+float pathlib_edge_check_size;
+
+float pathlib_foundgoal;
+entity goal_node;
+
+entity best_open_node;
+.float is_path_node;
+
+
+
+#define DEBUGPATHING
+#ifdef DEBUGPATHING
+float edge_show(vector point,float fsize);
+void mark_error(vector where,float lifetime);
+void mark_info(vector where,float lifetime);
+entity mark_misc(vector where,float lifetime);
+
+
+
+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;
+}
+
+void __showpath2_think()
+{
+ mark_info(self.origin,1);
+ if(self.path_next)
+ {
+ self.path_next.think = __showpath2_think;
+ self.path_next.nextthink = time + 0.15;
+ }
+ else
+ {
+ self.owner.think = __showpath2_think;
+ self.owner.nextthink = time + 0.15;
+ }
+}
+
+void pathlib_showpath2(entity path)
+{
+ path.think = __showpath2_think;
+ path.nextthink = time;
+}
+
+#endif
+
+/*
+float pathlib_stdproc_path_validate(vector start,vector end)
+{
+ tracebox(start, self.mins * 2, self.maxs * 2, end, MOVE_WORLDONLY, self);
+
+ if(vlen(trace_endpos - end) < 5)
+ return 1;
+
+ return 0;
+}
+*/
+
+
+void pathlib_deletepath(entity start)
+{
+ entity e;
+
+ e = findchainentity(owner, start);
+ while(e)
+ {
+ e.think = SUB_Remove;
+ e.nextthink = time;
+ e = e.chain;
+ }
+}
+
+float fsnap(float val,float fsize)
+{
+ return rint(val / fsize) * fsize;
+}
+
+vector vsnap(vector point,float fsize)
+{
+ vector vret;
+
+ vret_x = rint(point_x / fsize) * fsize;
+ vret_y = rint(point_y / fsize) * fsize;
+ vret_z = ceil(point_z / fsize) * fsize;
+
+ return vret;
+}
+
+
+#define floor_failmask (DPCONTENTS_SLIME | DPCONTENTS_LAVA)
+// | DPCONTENTS_MONSTERCLIP | DPCONTENTS_DONOTENTER
+float walknode_stepsize;
+vector walknode_stepup;
+vector walknode_maxdrop;
+vector walknode_boxup;
+vector walknode_boxmax;
+vector walknode_boxmin;
+float pathlib_movenode_goodnode;
+
+float floor_ok(vector point)
+{
+ float pc;
+
+ if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+ return 0;
+
+ pc = pointcontents(point);
+
+ switch(pc)
+ {
+ case CONTENT_SOLID:
+ case CONTENT_SLIME:
+ case CONTENT_LAVA:
+ case CONTENT_SKY:
+ return 0;
+ case CONTENT_EMPTY:
+ if not (pointcontents(point - '0 0 1') == CONTENT_SOLID)
+ return 0;
+ break;
+ case CONTENT_WATER:
+ return 1;
+ }
+ if(pointcontents(point - '0 0 1') == CONTENT_SOLID)
+ return 1;
+
+ return 0;
+}
+
+float inwater(vector point)
+{
+ if(pointcontents(point) == CONTENT_WATER)
+ return 1;
+
+ return 0;
+}
+
+//#define _pcheck(p) traceline(p+z_up,p-z_down,MOVE_WORLDONLY,self); if(trace_fraction == 1.0) return 1
+#define _pcheck(p) traceline(p+z_up,p-z_down,MOVE_WORLDONLY,self); if not(floor_ok(trace_endpos)) return 1
+float edge_check(vector point,float fsize)
+{
+ vector z_up,z_down;
+
+ z_up = '0 0 1' * fsize;
+ z_down = '0 0 1' * fsize;
+
+ _pcheck(point + ('1 1 0' * fsize));
+ _pcheck(point + ('1 -1 0' * fsize));
+ _pcheck(point + ('1 0 0' * fsize));
+
+ _pcheck(point + ('0 1 0' * fsize));
+ _pcheck(point + ('0 -1 0' * fsize));
+
+ _pcheck(point + ('-1 0 0' * fsize));
+ _pcheck(point + ('-1 1 0' * fsize));
+ _pcheck(point + ('-1 -1 0' * fsize));
+
+ return 0;
+}
+
+#ifdef DEBUGPATHING
+#define _pshow(p) mark_error(p,10)
+float edge_show(vector point,float fsize)
+{
+
+ _pshow(point + ('1 1 0' * fsize));
+ _pshow(point + ('1 -1 0' * fsize));
+ _pshow(point + ('1 0 0' * fsize));
+
+ _pshow(point + ('0 1 0' * fsize));
+ _pshow(point + ('0 -1 0' * fsize));
+
+ _pshow(point + ('-1 0 0' * fsize));
+ _pshow(point + ('-1 1 0' * fsize));
+ _pshow(point + ('-1 -1 0' * fsize));
+
+ return 0;
+}
+#endif
+
+var vector pathlib_movenode(vector start,vector end,float doedge);
+vector pathlib_wateroutnode(vector start,vector end)
+{
+ vector surface;
+
+ pathlib_movenode_goodnode = 0;
+
+ end_x = fsnap(end_x, pathlib_gridsize);
+ end_y = fsnap(end_y, pathlib_gridsize);
+
+ traceline(end + ('0 0 0.25' * pathlib_gridsize),end - ('0 0 1' * pathlib_gridsize),MOVE_WORLDONLY,self);
+ end = trace_endpos;
+
+ if not(pointcontents(end - '0 0 1') == CONTENT_SOLID)
+ return end;
+
+ for(surface = start ; surface_z < (end_z + 32); ++surface_z)
+ {
+ if(pointcontents(surface) == CONTENT_EMPTY)
+ break;
+ }
+ //mark_error(surface,10);
+
+ if(pointcontents(surface + '0 0 1') != CONTENT_EMPTY)
+ return end;
+
+ tracebox(start + '0 0 64', walknode_boxmin,walknode_boxmax, end + '0 0 64', MOVE_WORLDONLY, self);
+ if(trace_fraction == 1)
+ {
+ pathlib_movenode_goodnode = 1;
+ //mark_error(end + '0 0 64',30);
+ }
+
+ if(fabs(surface_z - end_z) > 32)
+ pathlib_movenode_goodnode = 0;
+
+ return end;
+}
+
+vector pathlib_swimnode(vector start,vector end)
+{
+ pathlib_movenode_goodnode = 0;
+
+ if(pointcontents(start) != CONTENT_WATER)
+ return end;
+
+ end_x = fsnap(end_x, pathlib_gridsize);
+ end_y = fsnap(end_y, pathlib_gridsize);
+
+ if(pointcontents(end) == CONTENT_EMPTY)
+ return pathlib_wateroutnode( start, end);
+
+ tracebox(start, walknode_boxmin,walknode_boxmax, end, MOVE_WORLDONLY, self);
+ if(trace_fraction == 1)
+ pathlib_movenode_goodnode = 1;
+
+ return end;
+}
+
+vector pathlib_flynode(vector start,vector end)
+{
+ pathlib_movenode_goodnode = 0;
+
+ /*
+ if(pointcontents(start) == CONTENT_EMPTY)
+ return end;
+
+ if(pointcontents(end) == CONTENT_EMPTY)
+ return end;
+ */
+ end_x = fsnap(end_x, pathlib_gridsize);
+ end_y = fsnap(end_y, pathlib_gridsize);
+
+ tracebox(start, walknode_boxmin,walknode_boxmax, end, MOVE_WORLDONLY, self);
+ if(trace_fraction == 1)
+ pathlib_movenode_goodnode = 1;
+
+ return end;
+}
+
+vector pathlib_walknode(vector start,vector end,float doedge)
+{
+ vector direction,point,last_point,s,e;
+ float steps, distance, i,laststep;
+
+ pathlib_movenode_goodnode = 0;
+
+ s = start;
+ e = end;
+ e_z = 0;
+ s_z = 0;
+ direction = normalize(s - e);
+
+ distance = vlen(start - end);
+ laststep = distance / walknode_stepsize;
+ steps = floor(laststep);
+ laststep = laststep - steps;
+
+ point = start;
+ s = point + walknode_stepup;
+ e = point - walknode_maxdrop;
+
+ traceline(s, e,MOVE_WORLDONLY,self);
+ if(trace_fraction == 1.0)
+ return trace_endpos;
+
+ if (floor_ok(trace_endpos) == 0)
+ return trace_endpos;
+
+ last_point = trace_endpos;
+
+ for(i = 0; i < steps; ++i)
+ {
+ point = last_point + direction * walknode_stepsize;
+
+ s = point + walknode_stepup;
+ e = point - walknode_maxdrop;
+ traceline(s, e,MOVE_WORLDONLY,self);
+ if(trace_fraction == 1.0)
+ return trace_endpos;
+
+ point = trace_endpos;
+ if not(floor_ok(trace_endpos))
+ return trace_endpos;
+
+ tracebox(last_point + walknode_boxup, walknode_boxmin,walknode_boxmax, point + walknode_boxup, MOVE_WORLDONLY, self);
+ if(trace_fraction != 1.0)
+ return trace_endpos;
+
+ if(doedge)
+ if(edge_check(point,pathlib_edge_check_size))
+ return trace_endpos;
+
+ last_point = point;
+ }
+
+ point = last_point + direction * walknode_stepsize * laststep;
+
+ point_x = fsnap(point_x, pathlib_gridsize);
+ point_y = fsnap(point_y, pathlib_gridsize);
+
+ s = point + walknode_stepup;
+ e = point - walknode_maxdrop;
+ traceline(s, e,MOVE_WORLDONLY,self);
+
+ if(trace_fraction == 1.0)
+ return trace_endpos;
+
+ point = trace_endpos;
+
+ if not(floor_ok(trace_endpos))
+ return trace_endpos;
+
+ tracebox(last_point + walknode_boxup, walknode_boxmin,walknode_boxmax, point + walknode_boxup, MOVE_WORLDONLY, self);
+ if(trace_fraction != 1.0)
+ return trace_endpos;
+
+ pathlib_movenode_goodnode = 1;
+ return point;
+}
+
+var float pathlib_cost(entity parent,vector to, float static_cost);
+float pathlib_g_static(entity parent,vector to, float static_cost)
+{
+ if(inwater(to))
+ return parent.pathlib_node_g + static_cost * pathlib_movecost_waterfactor;
+ else
+ return parent.pathlib_node_g + static_cost;
+}
+
+float pathlib_g_euclidean(entity parent,vector to, float static_cost)
+{
+ return vlen(parent.origin - to);
+}
+
+var float(vector from,vector to) pathlib_heuristic;
+float pathlib_h_manhattan(vector a,vector b)
+{
+ //h(n) = D * (abs(n.x-goal.x) + abs(n.y-goal.y))
+
+ float h;
+ h = fabs(a_x - b_x);
+ h = h + fabs(a_y - b_y);
+ h = pathlib_gridsize * h;
+
+ return h;
+}
+
+float pathlib_h_diagonal(vector a,vector b)
+{
+ //h(n) = D * max(abs(n.x-goal.x), abs(n.y-goal.y))
+ float h,x,y;
+
+ x = fabs(a_x - b_x);
+ y = fabs(a_y - b_y);
+ h = pathlib_movecost * max(x,y);
+
+ return h;
+}
+
+float pathlib_h_euclidean(vector a,vector b)
+{
+ return vlen(a - b);
+}
+
+float pathlib_h_diagonal2(vector a,vector b)
+{
+ float h_diag,h_str,h,x,y;
+
+ /*
+ h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
+ h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
+ h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
+ */
+
+ x = fabs(a_x - b_x);
+ y = fabs(a_y - b_y);
+
+ h_diag = min(x,y);
+ h_str = x + y;
+
+ h = pathlib_movecost_diag * h_diag;
+ h += pathlib_movecost * (h_str - 2 * h_diag);
+
+ return h;
+}
+
+float pathlib_h_diagonal2tbs(vector start,vector point,vector end)
+{
+ float h_diag,h_str,h,x,y;
+
+ /*
+ h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
+ h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
+ h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
+ */
+
+ float dx1,dx2,dy1,dy2,fcross;
+ dx1 = point_x - end_x;
+ dy1 = point_y - end_y;
+ dx2 = start_x - end_x;
+ dy2 = start_y - end_y;
+ fcross = fabs(dx1*dy2 - dx2*dy1);
+
+ x = fabs(point_x - end_x);
+ y = fabs(point_y - end_y);
+
+ h_diag = min(x,y);
+ h_str = x + y;
+
+ h = pathlib_movecost_diag * h_diag;
+ h += pathlib_movecost * (h_str - 2 * h_diag);
+
+ return h + (fcross * 0.001);
+}
+
+float pathlib_h_diagonal2sdp(vector preprev,vector prev,vector point,vector end)
+{
+ float h_diag,h_str,h,x,y,z;
+
+ //h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
+ //h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
+ //h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
+
+ x = fabs(point_x - end_x);
+ y = fabs(point_y - end_y);
+ z = fabs(point_z - end_z);
+
+ h_diag = min3(x,y,z);
+ h_str = x + y + z;
+
+ h = pathlib_movecost_diag * h_diag;
+ h += pathlib_movecost * (h_str - 2 * h_diag);
+
+ float m;
+ vector d1,d2;
+
+ m = 0.999;
+ d1 = normalize(preprev - prev);
+ d2 = normalize(prev - point);
+ if(vlen(d1-d2) > 0.6)
+ m = 1;
+
+
+ return h * m;
+}
+
+
+float pathlib_h_diagonal3(vector a,vector b)
+{
+ float h_diag,h_str,h,x,y,z;
+
+ //h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
+ //h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
+ //h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
+
+ x = fabs(a_x - b_x);
+ y = fabs(a_y - b_y);
+ z = fabs(a_z - b_z);
+
+ h_diag = min3(x,y,z);
+ h_str = x + y + z;
+
+ h = pathlib_movecost_diag * h_diag;
+ h += pathlib_movecost * (h_str - 2 * h_diag);
+
+ //if(inwater(a))
+ //h =
+
+ return h;
+}
+
+//#define PATHLIB_USE_NODESCRAP
+float pathlib_scraplist_cnt;
+entity newnode()
+{
+ entity n;
+#ifdef PATHLIB_USE_NODESCRAP
+ if(pathlib_scraplist_cnt)
+ {
+ n = findentity(world,owner,scraplist);
+ if(n)
+ {
+ --pathlib_scraplist_cnt;
+ ++pathlib_recycle_cnt;
+ return n;
+ }
+ else
+ pathlib_scraplist_cnt = 0;
+ }
+#endif
+ ++pathlib_made_cnt;
+ n = spawn();
+ return n;
+}
+
+void dumpnode(entity n)
+{
+#ifdef PATHLIB_USE_NODESCRAP
+ ++pathlib_scraplist_cnt;
+ n.owner = scraplist;
+#else
+ n.is_path_node = FALSE;
+ n.think = SUB_Remove;
+ n.nextthink= time;
+#endif
+}
+
+entity pathlib_mknode(vector where,entity parent)
+{
+ entity node;
+
+ node = newnode();
+ node.is_path_node = TRUE;
+ node.owner = openlist;
+ node.path_prev = parent;
+
+ setorigin(node, where);
+
+ ++pathlib_open_cnt;
+
+ //if(inwater(where))
+ //{
+ //node.waterlevel = 1;
+ //mark_info(where,5);
+ //}
+ //mark_info(where,30);
+ return node;
+}
+var float pathlib_expandnode(entity node, vector start, vector goal);
+float pathlib_expandnode_star(entity node, vector start, vector goal);
+float pathlib_expandnode_box(entity node, vector start, vector goal);
+
+float pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost)
+{
+ entity node;
+ float h,g,f,doedge;
+ vector where;
+
+ ++pathlib_searched_cnt;
+
+ if(inwater(parent.origin))
+ {
+ if(inwater(to))
+ {
+ //bprint("Switch to water tracing\n");
+ pathlib_expandnode = pathlib_expandnode_box;
+ pathlib_movenode = pathlib_swimnode;
+ }
+ else
+ {
+
+ //bprint("Switch to get out of water tracing\n");
+ pathlib_expandnode = pathlib_expandnode_box;
+ pathlib_movenode = pathlib_swimnode;
+ }
+ }
+ else
+ {
+ if(inwater(to))
+ {
+ //bprint("Switch to get into water tracing\n");
+ pathlib_expandnode = pathlib_expandnode_box;
+ pathlib_movenode = pathlib_swimnode;
+ }
+ else
+ {
+
+ //bprint("Switch to land tracing\n");
+ pathlib_expandnode = pathlib_expandnode_star;
+ pathlib_movenode = pathlib_walknode;
+ doedge = 1;
+ }
+ }
+
+ where = pathlib_movenode(parent.origin,to,0);
+ if not(pathlib_movenode_goodnode)
+ {
+ //mark_error(where,15);
+ return 0;
+ }
+
+ if(doedge)
+ if(edge_check(where,pathlib_edge_check_size))
+ return 0;
+
+ h = pathlib_heuristic(where,goal);
+
+ /*
+ if(parent.path_prev)
+ h = pathlib_h_diagonal2sdp(parent.path_prev.origin,parent.origin,where,goal);
+ else
+ h = pathlib_heuristic(where,goal);
+ */
+
+
+ //h = 0;
+ g = pathlib_cost(parent,where,cost);
+ f = g + h;
+
+ node = findradius(where,pathlib_gridsize * 0.75);
+ while(node)
+ {
+ if(node.is_path_node == TRUE)
+ {
+ ++pathlib_merge_cnt;
+ if(node.owner == openlist)
+ {
+ if(node.pathlib_node_g > g)
+ {
+ node.pathlib_node_h = h;
+ node.pathlib_node_g = g;
+ node.pathlib_node_f = f;
+ node.path_prev = parent;
+ }
+
+ if not (best_open_node)
+ best_open_node = node;
+ else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
+ best_open_node = node;
+ }
+
+ return 1;
+ }
+ node = node.chain;
+ }
+
+ node = pathlib_mknode(where,parent);
+
+ node.pathlib_node_h = h;
+ node.pathlib_node_g = g;
+ node.pathlib_node_f = f;
+
+ if not (best_open_node)
+ best_open_node = node;
+ else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
+ best_open_node = node;
+
+ return 1;
+}
+
+entity pathlib_getbestopen()
+{
+ entity node;
+ entity bestnode;
+
+ if(best_open_node)
+ {
+ ++pathlib_bestcash_hits;
+ pathlib_bestcash_saved += pathlib_open_cnt;
+
+ return best_open_node;
+ }
+
+ node = findchainentity(owner,openlist);
+ if(!node)
+ return world;
+
+ bestnode = node;
+ while(node)
+ {
+ ++pathlib_bestopen_seached;
+ if(node.pathlib_node_f < bestnode.pathlib_node_f)
+ bestnode = node;
+
+ node = node.chain;
+ }
+
+ return bestnode;
+}
+
+void pathlib_close_node(entity node,vector goal)
+{
+
+ if(node.owner == closedlist)
+ {
+ dprint("Pathlib: Tried to close a closed node!\n");
+ return;
+ }
+
+ if(node == best_open_node)
+ best_open_node = world;
+
+ ++pathlib_closed_cnt;
+ --pathlib_open_cnt;
+
+ node.owner = closedlist;
+
+ if(vlen(node.origin - goal) <= pathlib_gridsize)
+ {
+ //if(vlen(node.origin - goal) < 128)
+ vector goalmove;
+ goalmove = pathlib_walknode(node.origin,goal,1);
+ if(pathlib_movenode_goodnode)
+ {
+ goal_node = node;
+ pathlib_foundgoal = TRUE;
+ }
+ }
+}
+
+float pathlib_expandnode_star(entity node, vector start, vector goal)
+{
+ vector point;
+ vector where;
+ float nodecnt;
+
+ where = node.origin;
+
+ v_forward = '1 0 0';
+ v_right = '0 1 0';
+
+ // Forward
+ point = where + v_forward * pathlib_gridsize;
+ nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+ // Back
+ point = where - v_forward * pathlib_gridsize;
+ nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+ // Right
+ point = where + v_right * pathlib_gridsize;
+ nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+ // Left
+ point = where - v_right * pathlib_gridsize;
+ nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+ // Forward-right
+ point = where + v_forward * pathlib_gridsize + v_right * pathlib_gridsize;
+ nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+ // Forward-left
+ point = where + v_forward * pathlib_gridsize - v_right * pathlib_gridsize;
+ nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+ // Back-right
+ point = where - v_forward * pathlib_gridsize + v_right * pathlib_gridsize;
+ nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+ // Back-left
+ point = where - v_forward * pathlib_gridsize - v_right * pathlib_gridsize;
+ nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+ return pathlib_open_cnt;
+}
+
+float pathlib_expandnode_box(entity node, vector start, vector goal)
+{
+ vector v;
+
+ for(v_z = node.origin_z - pathlib_gridsize; v_z <= node.origin_z + pathlib_gridsize; v_z += pathlib_gridsize)
+ for(v_y = node.origin_y - pathlib_gridsize; v_y <= node.origin_y + pathlib_gridsize; v_y += pathlib_gridsize)
+ for(v_x = node.origin_x - pathlib_gridsize; v_x <= node.origin_x + pathlib_gridsize; v_x += pathlib_gridsize)
+ {
+ if(vlen(v - node.origin))
+ pathlib_makenode(node,start,v,goal,pathlib_movecost);
+ }
+
+ return pathlib_open_cnt;
+}
+
+void pathlib_cleanup()
+{
+ entity node;
+
+ best_open_node = world;
+
+ node = findfloat(world,is_path_node, TRUE);
+ while(node)
+ {
+ node.path_next = world;
+ node.path_prev = world;
+ node.is_path_node = FALSE;
+ dumpnode(node);
+ node = findfloat(node,is_path_node, TRUE);
+ }
+
+ if(openlist)
+ remove(openlist);
+
+ if(closedlist)
+ remove(closedlist);
+}
+
+entity pathlib_astar(vector from,vector to)
+{
+ entity path;
+ entity open,n;
+
+ pathlib_cleanup();
+
+ pathlib_heuristic = pathlib_h_diagonal3;
+ pathlib_cost = pathlib_g_static;
+ pathlib_expandnode = pathlib_expandnode_star;
+ pathlib_movenode = pathlib_walknode;
+
+ if not(openlist)
+ openlist = spawn();
+
+ if not(closedlist)
+ closedlist = spawn();
+
+ if not(scraplist)
+ scraplist = spawn();
+
+ pathlib_closed_cnt = 0;
+ pathlib_open_cnt = 0;
+ pathlib_made_cnt = 0;
+ pathlib_merge_cnt = 0;
+ pathlib_searched_cnt = 0;
+ pathlib_bestcash_hits = 0;
+ pathlib_bestcash_saved = 0;
+ pathlib_recycle_cnt = 0;
+
+ pathlib_gridsize = 192;
+ pathlib_movecost = pathlib_gridsize;
+ pathlib_movecost_diag = vlen(('1 1 0' * pathlib_gridsize));
+ pathlib_movecost_waterfactor = 1.1;
+ pathlib_foundgoal = 0;
+
+ walknode_boxmax = self.maxs * 1.5;
+ walknode_boxmin = self.mins * 1.5;
+
+ pathlib_edge_check_size = (vlen(walknode_boxmin - walknode_boxmax) * 0.25);
+
+ walknode_boxup = '0 0 2' * self.maxs_z;
+ walknode_stepsize = 32;
+ walknode_stepup = '0 0 1' * walknode_stepsize;
+ walknode_maxdrop = '0 0 3' * walknode_stepsize;
+
+ dprint("AStar init. ", ftos(pathlib_scraplist_cnt), " nodes on scrap\n");
+ path = pathlib_mknode(from,world);
+ pathlib_close_node(path,to);
+ if(pathlib_foundgoal)
+ {
+ dprint("A* Goal fond in first square!\n");
+
+ open = spawn();
+ open.owner = open;
+ open.classname = "path_end";
+ setorigin(open,path.origin);
+ pathlib_cleanup();
+
+ return open;
+ }
+
+ if(pathlib_expandnode(path,from,to) <= 0)
+ {
+ dprint("A* pathing fail\n");
+ pathlib_cleanup();
+ return world;
+ }
+
+ best_open_node = pathlib_getbestopen();
+ n = best_open_node;
+ pathlib_close_node(best_open_node,to);
+ if(inwater(n.origin))
+ pathlib_expandnode_box(n,from,to);
+ else
+ pathlib_expandnode_star(n,from,to);
+
+ while(pathlib_open_cnt)
+ {
+ best_open_node = pathlib_getbestopen();
+ n = best_open_node;
+ pathlib_close_node(best_open_node,to);
+
+ if(inwater(n.origin))
+ pathlib_expandnode_box(n,from,to);
+ else
+ pathlib_expandnode(n,from,to);
+
+ if(pathlib_foundgoal)
+ {
+ dprint("Path found, re-tracing...\n");
+
+ open = goal_node;
+ open.is_path_node = FALSE;
+ open.classname = "path_end";
+ open.owner = path;
+ open.path_next = world;
+
+
+ while(open.path_prev != path)
+ {
+ n = open;
+ open = open.path_prev;
+ open.owner = path;
+ open.path_next = n;
+
+ open.is_path_node = FALSE;
+ open.classname = "path_node";
+ }
+
+ open.path_prev = path;
+ path.path_next = open;
+ path.classname = "path_master";
+ path.is_path_node = FALSE;
+ path.owner = path;
+
+ pathlib_cleanup();
+
+#ifdef DEBUGPATHING
+ dprint("Chain done..\n");
+ pathlib_showpath2(path);
+
+
+ dprint(" Nodes reused: ", ftos(pathlib_recycle_cnt),"\n");
+ dprint(" Nodes created: ", ftos(pathlib_made_cnt),"\n");
+ dprint(" Nodes make/reuse: ", ftos(pathlib_made_cnt / pathlib_recycle_cnt),"\n");
+ dprint(" Nodes open: ", ftos(pathlib_open_cnt),"\n");
+ dprint(" Nodes merged: ", ftos(pathlib_merge_cnt),"\n");
+ dprint(" Nodes closed: ", ftos(pathlib_closed_cnt),"\n");
+ dprint(" Nodes searched: ", ftos(pathlib_searched_cnt),"\n");
+ dprint("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
+ dprint(" Nodes bestcash hits: ", ftos(pathlib_bestcash_hits),"\n");
+ dprint(" Nodes bestcash save: ", ftos(pathlib_bestcash_saved),"\n");
+ dprint("AStar done. ", ftos(pathlib_scraplist_cnt), " nodes on scrap\n\n");
+
+#endif
+ return path;
+ }
+ }
+
+ dprint("A* Faild to find a path! Try a smaller gridsize.\n");
+
+ pathlib_cleanup();
+
+ return world;
+}
+
Modified: branches/nexuiz-2.0/data/qcsrc/server/progs.src
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/progs.src 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/progs.src 2009-03-22 21:23:04 UTC (rev 6251)
@@ -65,10 +65,10 @@
cl_physics.qc
// tZork's libs
+verbstack.qc
movelib.qc
steerlib.qc
pathlib.qc
-//animation.qc
g_world.qc
g_casings.qc
Modified: branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -16,7 +16,7 @@
self.flags |= FL_INWATER;
self.dmgtime = 0;
}
- if (self.waterlevel != 3)
+ if (self.waterlevel != WATERLEVEL_SUBMERGED)
{
if(self.air_finished < time + 9)
PlayerSound(playersound_gasp, CHAN_PLAYER, VOICETYPE_PLAYERSOUND);
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/include/turrets.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/include/turrets.qh 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/include/turrets.qh 2009-03-22 21:23:04 UTC (rev 6251)
@@ -7,8 +7,6 @@
#include "../system/system_scoreprocs.qc" /// Target calssification
#include "../system/system_damage.qc" /// Outch, they are hurting me! what should i do?
-#include "../units/unit_common.qc" /// Some "make life easyer" funcs.
-
// Non combat units
#include "../units/unit_fusionreactor.qc" /// Supply unites that need it with power
#include "../units/unit_targettrigger.qc" /// Hit me!
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/include/turrets_early.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/include/turrets_early.qh 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/include/turrets_early.qh 2009-03-22 21:23:04 UTC (rev 6251)
@@ -7,31 +7,51 @@
vector real_origin(entity ent);
+/// Map time control over pain inflicted
+.float turret_scale_damage;
+/// Map time control targetting range
+.float turret_scale_range;
+/// Map time control refire
+.float turret_scale_refire;
+/// Map time control ammo held and recharged
+.float turret_scale_ammo;
+/// Map time control aim speed
+.float turret_scale_aim;
+/// Map time control health
+.float turret_scale_health;
+/// Map time control respawn time
+.float turret_scale_respawn;
+
+/// Used for cvar reloading
+.string cvar_basename;
+
/// target selection flags
.float target_select_flags;
.float target_validate_flags;
/// Dont select a target on its own.
-#define TFL_TARGETSELECT_NO 1024
+#define TFL_TARGETSELECT_NO 2
/// Need line of sight
-#define TFL_TARGETSELECT_LOS 2
+#define TFL_TARGETSELECT_LOS 4
/// Players are valid targets
-#define TFL_TARGETSELECT_PLAYERS 4
+#define TFL_TARGETSELECT_PLAYERS 8
/// Missiles are valid targets
-#define TFL_TARGETSELECT_MISSILES 8
+#define TFL_TARGETSELECT_MISSILES 16
/// Responds to turret_trigger_target events
-#define TFL_TARGETSELECT_TRIGGERTARGET 16
+#define TFL_TARGETSELECT_TRIGGERTARGET 32
/// Angular limitations of turret head limits target selection
-#define TFL_TARGETSELECT_ANGLELIMITS 32
+#define TFL_TARGETSELECT_ANGLELIMITS 64
/// Range limits apply in targetselection
-#define TFL_TARGETSELECT_RANGELIMTS 64
+#define TFL_TARGETSELECT_RANGELIMTS 128
/// DOnt select targets with a .team matching its own
-#define TFL_TARGETSELECT_TEAMCHECK 4096
+#define TFL_TARGETSELECT_TEAMCHECK 256
/// Cant select targets on its own. needs to be triggerd or slaved.
-#define TFL_TARGETSELECT_NOBUILTIN 256
+#define TFL_TARGETSELECT_NOBUILTIN 512
/// TFL_TARGETSELECT_TEAMCHECK is inverted (selects only mebers of own .team)
-#define TFL_TARGETSELECT_OWNTEAM 2048
+#define TFL_TARGETSELECT_OWNTEAM 1024
/// Turrets aren't valid targets
-#define TFL_TARGETSELECT_NOTURRETS 128
+#define TFL_TARGETSELECT_NOTURRETS 2048
+/// Use feild of view
+#define TFL_TARGETSELECT_FOV 4096
/// aim flags
.float aim_flags;
@@ -40,7 +60,7 @@
/// Go for ground, not direct hit
#define TFL_AIM_GROUND 2
/// Go for ground, not direct hit, but only if target is on ground.
-#define TFL_AIM_GROUND2 4
+#define TFL_AIM_GROUND2 4
/// Use balistic aim. FIXME: not implemented
#define TFL_AIM_BALISTIC 8
/// Try to predict target movement (does not account for gravity)
@@ -53,10 +73,10 @@
#define TFL_AIM_BEHIND 128
/// blend real and predicted z positions. (fake bounce prediction)
#define TFL_AIM_ZEASE 256
-// Try to do real prediction of targets z pos at impact.
-//#define TFL_AIM_ZPREDICT 256
+/// Try to do real prediction of targets z pos at impact.
+#define TFL_AIM_ZPREDICT 512
/// Simply aim at target's current location
-#define TFL_AIM_SIMPLE 512
+#define TFL_AIM_SIMPLE 1024
/// track (turn and pitch head) flags
.float track_flags;
@@ -84,8 +104,6 @@
/// How prefire check is preformed
.float firecheck_flags;
-/// Dont do any chekcs
-#define TFL_FIRECHECK_NO 8192
/// Dont kill the world
#define TFL_FIRECHECK_WORLD 2
/// Dont kill the dead
@@ -110,6 +128,10 @@
#define TFL_FIRECHECK_OTHER_AMMO 2048
/// Check own .attack_finished_single vs time
#define TFL_FIRECHECK_REFIRE 4096
+/// Move the acctual target to aimspot before tracing impact (and back after)
+#define TFL_FIRECHECK_VERIFIED 8192
+/// Dont do any chekcs
+#define TFL_FIRECHECK_NO 16384
/// How shooting is done
.float shoot_flags;
@@ -160,7 +182,7 @@
#define TFL_TURRCAPS_MOVE 16384
/// Will roam arround even if not chasing anyting
#define TFL_TURRCAPS_ROAM 32768
-#define TFL_TURRCAPS_LINKED 65536
+#define TFL_TURRCAPS_HEADATTACHED 65536
/// Ammo types needed and/or provided
.float ammo_flags;
@@ -198,7 +220,7 @@
/// Die and stay dead.
#define TFL_DMG_DEATH_NORESPAWN 256
/// Supress std turret gibs on death
-#define RFL_DMG_DEATH_NOGIBS 512
+#define TFL_DMG_DEATH_NOGIBS 512
// Spawnflags
/// Spawn in teambased modes
@@ -208,7 +230,7 @@
/*
-* Fields commnly used by turrets
+* Fields used by turrets
*/
/// Turrets internal ai speed
.float ticrate;
@@ -228,8 +250,8 @@
/// on/off toggle.
.float tur_active;
-/// Aim from this point,
-.vector tur_aimorg;
+// Aim from this point,
+//.vector tur_aimorg;
/// and shoot from here. (could be non constant, think MLRS)
.vector tur_shotorg;
@@ -305,6 +327,8 @@
.float target_select_missilebias;
/// (dis)Favot living players (-1 to diable targeting compleatly)
.float target_select_playerbias;
+/// Field of view
+//.float target_select_fov;
/*
* Aim refers to real aiming, not gun pos (thats done by track)
@@ -433,14 +457,15 @@
/*
* Target selection
*/
-/// "closeer is beter" selection
-float turret_stdproc_targetscore_close(entity e_turret, entity e_target);
-/// "further is beter" selection
-float turret_stdproc_targetscore_far(entity e_turret, entity e_target);
-/// only target_range_optimal
-float turret_stdproc_targetscore_optimal(entity e_turret, entity e_target);
-/// defendpos
-float turret_stdproc_targetscore_defend(entity e_turret, entity e_target);
+// noting uses the following atm.
+// "closeer is beter" selection
+//float turret_stdproc_targetscore_close(entity e_turret, entity e_target);
+// "further is beter" selection
+//float turret_stdproc_targetscore_far(entity e_turret, entity e_target);
+// only target_range_optimal
+//float turret_stdproc_targetscore_optimal(entity e_turret, entity e_target);
+// defendpos
+//float turret_stdproc_targetscore_defend(entity e_turret, entity e_target);
/// Generic fairly smart bias-aware target selection.
float turret_stdproc_targetscore_generic(entity e_turret, entity e_target);
/// Experimental supportunits targetselector
@@ -482,9 +507,14 @@
/// updates aim org, shot org, shot dir and enemy org for selected turret
void turret_do_updates(entity e_turret);
-.vector tur_aimorg_updated;
-.vector tur_shotorg_updated;
+//.vector tur_aimorg_updated; // creates to much aim issues. using tur_shotorg_updated insted.
+//.vector tur_shotorg_updated; // DP8815 fixes gettaginfo, no longer needed.
.vector tur_shotdir_updated;
void turrets_precash();
+
+
+
#endif // TTURRETS_ENABLED
+
+
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_aimprocs.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_aimprocs.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_aimprocs.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,38 +1,4 @@
/*
-* Straight line, Dead-on (no prediction)
-* Usefull for "stupid turrets" or ones
-* that launch guided weapons and just need to apeer to
-* somewhat face (and/or track) the target.
-
-supports:
-TFL_AIM_NO
-*/
-/*
-vector turret_stdproc_aim_simple()
-{
- float s_bu; // Solidity backup (for ground shooters)
- vector aim_pos;
-
- if (self.aim_flags & TFL_AIM_NO) return self.idle_aim;
-
- aim_pos = self.enemy.origin;
-
- // Target ground?
- if (self.aim_flags & TFL_AIM_GROUND)
- {
- s_bu = self.enemy.solid;
- self.enemy.solid = SOLID_NOT;
- traceline(self.enemy.origin + '0 0 128',self.enemy.origin + '0 0 -99999',1,self.enemy);
- self.enemy.solid = s_bu;
- aim_pos = trace_endpos;
- }
-
- // This is where its at.
- return aim_pos;
-}
-*/
-
-/*
* Generic aim
supports:
@@ -47,36 +13,35 @@
not supported:
TFL_AIM_BALISTIC
*/
-
-
vector turret_stdproc_aim_generic()
{
- vector pre_pos;
+
+ vector pre_pos,prep;
float distance,impact_time,i,mintime;
- vector prep;
- //if (self.aim_flags == TFL_AIM_NO)
- // return self.idle_aim;
+ turret_tag_fire_update();
- // Baseline
- pre_pos = real_origin(self.enemy);
-
if(self.aim_flags & TFL_AIM_SIMPLE)
- return pre_pos;
+ return real_origin(self.enemy);
- // This is not accurate enougth
- //pre_pos = bot_shotlead(pre_pos, self.enemy.velocity, self.shot_speed, 0.01); //self.enemy.velocity; * (self.tur_dist_aimpos / self.shot_speed);
-
- // Keep track of when we can shoot the next tim and
+ // Keep track of when we can shoot the next time and
// try to predict where the target will be then, so we can put our aimpoint there.
- // + sys_ticrate becouse projectiles dont move during the first tic of their life.
- mintime = max(self.attack_finished_single - time,0) + (sys_ticrate * 2);
+ // + sys_ticrate for non hitscan, becouse spawned
+ // projectiles dont move during the first tic of their life.
+ if (self.turrcaps_flags & TFL_TURRCAPS_HITSCAN)
+ mintime = max(self.attack_finished_single - time,0);
+ else
+ mintime = max(self.attack_finished_single - time,0) + sys_ticrate;
+ // Baseline
+ pre_pos = real_origin(self.enemy) + (self.enemy.velocity * mintime);
+
if (self.aim_flags & TFL_AIM_INFRONT) // Aim a bit in front of the target
- pre_pos += normalize(normalize(self.enemy.velocity) * 16);
+ pre_pos = pre_pos + (normalize(self.enemy.velocity) * 64);
+
if (self.aim_flags & TFL_AIM_BEHIND) // Aim a bit behind the target
- pre_pos -= normalize(normalize(self.enemy.velocity) * 16);
+ pre_pos = pre_pos - (normalize(self.enemy.velocity) * 32);
// Lead?
if (self.aim_flags & TFL_AIM_LEAD)
@@ -84,74 +49,71 @@
{
// FIXME: this cant be the best way to do this..
prep = pre_pos;
- for(i = 0; i < 3; ++i)
+ for(i = 0; i < 4; ++i)
{
- distance = vlen(prep - self.tur_shotorg_updated);
+ distance = vlen(prep - self.tur_shotorg);
impact_time = distance / self.shot_speed;
- prep = pre_pos + self.enemy.velocity * (impact_time + mintime);
+ prep = pre_pos + self.enemy.velocity * impact_time;
+ }
+ /*
+ // tnx and all credit to Rudolf "div0" Polzer for this solution.
+ // hmm tobad it dont work.
+ q = solve_quadratic(self.enemy.velocity*self.enemy.velocity - self.shot_speed*self.shot_speed, 2*(pre_pos*self.enemy.velocity), pre_pos * pre_pos);
+ if(q_x > 0)
+ impact_time = q_x;
+ else
+ impact_time = q_y;
- }
+ prep = self.enemy.origin + (self.enemy.velocity * impact_time);
+ */
- /* no worky well :/
+ if(self.aim_flags & TFL_AIM_ZPREDICT)
if not(self.enemy.flags & FL_ONGROUND)
+ if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
{
- float z;
- z = self.enemy.velocity_z;
- z = z - (sv_gravity * impact_time);
- prep_z += z;
+ float vz;
+ prep_z = pre_pos_z;
+ vz = self.enemy.velocity_z;
+ for(i = 0; i < impact_time; i += sys_ticrate)
+ {
+ vz = vz - (sv_gravity * sys_ticrate);
+ prep_z = prep_z + vz * sys_ticrate;
+ }
}
- */
pre_pos = prep;
}
else
- {
pre_pos = pre_pos + self.enemy.velocity * mintime;
- }
-
// Smooth out predict-Z?
+ /*
if (self.aim_flags & TFL_AIM_ZEASE)
+ if (self.enemy.flags & FL_CLIENT)
{
vector v;
v = real_origin(self.enemy);
pre_pos_z = (pre_pos_z + v_z) * 0.5;
}
+ */
+ if(self.aim_flags & TFL_AIM_GROUND2)
+ {
+ tracebox(pre_pos + '0 0 32',self.enemy.mins,self.enemy.maxs,pre_pos -'0 0 48',MOVE_WORLDONLY,self.enemy);
+ if(trace_fraction != 1.0)
+ pre_pos = trace_endpos;
+ }
+
+ /*
// This turret should hit the ground neer a target rather the do a direct hit
- if ( (self.aim_flags & TFL_AIM_GROUND) ||
- ((self.aim_flags & TFL_AIM_GROUND2) && (self.enemy.flags & FL_ONGROUND)) )
+ if (self.aim_flags & TFL_AIM_GROUND)
{
- traceline(pre_pos + '0 0 8',pre_pos - '0 0 10000',1,self.enemy);
+ traceline(pre_pos + '0 0 8',pre_pos - '0 0 10000',MOVE_WORLDONLY,self.enemy);
pre_pos = trace_endpos;
}
+ */
return pre_pos;
}
-
-
-/*
-* Aim where it is
-supports:
-TFL_AIM_NO
-*/
-/*
-vector turret_stdproc_aim_rail()
-{
- vector pre_pos;
-
- if (self.aim_flags & TFL_AIM_NO)
- return self.idle_aim;
-
- pre_pos = real_origin(self.enemy);
-
- self.tur_dist_impact_to_aimpos = vlen(self.enemy.origin - self.tur_aimorg_updated);
-
- self.tur_impacttime = time;
-
- return pre_pos;
-
-}
-*/
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_damage.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_damage.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -156,7 +156,7 @@
// Trow fake parts arround
// base
- if not(self.damage_flags & RFL_DMG_DEATH_NOGIBS)
+ if not(self.damage_flags & TFL_DMG_DEATH_NOGIBS)
{
makevectors(self.angles);
if (random() > 0.5)
@@ -284,8 +284,13 @@
else
baseent = self;
+ // Enougth allready!
+ if (self.health <= 0)
+ return;
- if (self.health <= 0) return;
+ // Inactive turrets take no damage. (hm..)
+ if not (baseent.tur_active)
+ return;
if (teamplay != 0)
if (self.team == attacker.team)
@@ -307,8 +312,10 @@
if (self.classname == "turret_head")
if (baseent.damage_flags & TFL_DMG_HEADSHAKE)
{
- self.angles_x = self.angles_x + random() * damage;
- self.angles_y = self.angles_y + random() * damage;
+ //baseent.tur_aimoff_x += (random() * damage);
+ //baseent.tur_aimoff_y += ((random()*0.75) * damage);
+ self.angles_x = self.angles_x + (-0.5 + random()) * damage;
+ self.angles_y = self.angles_y + (-0.5 + random()) * damage;
}
if (baseent.turrcaps_flags & TFL_TURRCAPS_MOVE)
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_main.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_main.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_main.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,26 +1,20 @@
#define cvar_base "g_turrets_unit_"
-//.float tur_lastscore;
-.string cvar_basename;
-
+#define cvar_gets(s_base,s_add) strcat(s_base,s_add)
+/*
string cvar_gets(string s_base,string s_add)
{
return strcat(s_base,s_add);
}
+*/
-.float turret_scale_damage;
-.float turret_scale_range;
-.float turret_scale_refire;
-.float turret_scale_ammo;
-.float turret_scale_aim;
-.float turret_scale_health;
-.float turret_scale_respawn;
-
void load_unit_settings(entity ent,string unitname,float is_reload)
{
string sbase;
+ // dprint("Reloading turret ",e_turret.netname,"\n");
+
if (ent == world)
return;
@@ -39,42 +33,46 @@
ent.tur_head.avelocity = '0 0 0';
ent.tur_head.angles = ent.angles;
}
- ent.health = cvar(cvar_gets(sbase,"_health")) * ent.turret_scale_health;
+ ent.health = cvar(cvar_gets(sbase,"_health")) * ent.turret_scale_health;
ent.respawntime = cvar(cvar_gets(sbase,"_respawntime")) * ent.turret_scale_respawn;
- ent.shot_dmg = cvar(cvar_gets(sbase,"_shot_dmg")) * ent.turret_scale_damage;
- ent.shot_refire = cvar(cvar_gets(sbase,"_shot_refire")) * ent.turret_scale_refire;
- ent.shot_radius = cvar(cvar_gets(sbase,"_shot_radius")) * ent.turret_scale_damage;
- ent.shot_speed = cvar(cvar_gets(sbase,"_shot_speed"));
- ent.shot_spread = cvar(cvar_gets(sbase,"_shot_spread"));
- ent.shot_force = cvar(cvar_gets(sbase,"_shot_force")) * ent.turret_scale_damage;
- ent.shot_volly = cvar(cvar_gets(sbase,"_shot_volly"));
+ ent.shot_dmg = cvar(cvar_gets(sbase,"_shot_dmg")) * ent.turret_scale_damage;
+ ent.shot_refire = cvar(cvar_gets(sbase,"_shot_refire")) * ent.turret_scale_refire;
+ ent.shot_radius = cvar(cvar_gets(sbase,"_shot_radius")) * ent.turret_scale_damage;
+ ent.shot_speed = cvar(cvar_gets(sbase,"_shot_speed"));
+ ent.shot_spread = cvar(cvar_gets(sbase,"_shot_spread"));
+ ent.shot_force = cvar(cvar_gets(sbase,"_shot_force")) * ent.turret_scale_damage;
+ ent.shot_volly = cvar(cvar_gets(sbase,"_shot_volly"));
ent.shot_volly_refire = cvar(cvar_gets(sbase,"_shot_volly_refire")) * ent.turret_scale_refire;
- ent.target_range = cvar(cvar_gets(sbase,"_target_range")) * ent.turret_scale_range;
- ent.target_range_min = cvar(cvar_gets(sbase,"_target_range_min")) * ent.turret_scale_range;
- ent.target_range_fire = cvar(cvar_gets(sbase,"_target_range_fire")) * ent.turret_scale_range;
+ ent.target_range = cvar(cvar_gets(sbase,"_target_range")) * ent.turret_scale_range;
+ ent.target_range_min = cvar(cvar_gets(sbase,"_target_range_min")) * ent.turret_scale_range;
+ ent.target_range_fire = cvar(cvar_gets(sbase,"_target_range_fire")) * ent.turret_scale_range;
ent.target_range_optimal = cvar(cvar_gets(sbase,"_target_range_optimal")) * ent.turret_scale_range;
- ent.target_select_rangebias = cvar(cvar_gets(sbase,"_target_select_rangebias"));
- ent.target_select_samebias = cvar(cvar_gets(sbase,"_target_select_samebias"));
- ent.target_select_anglebias = cvar(cvar_gets(sbase,"_target_select_anglebias"));
+ ent.target_select_rangebias = cvar(cvar_gets(sbase,"_target_select_rangebias"));
+ ent.target_select_samebias = cvar(cvar_gets(sbase,"_target_select_samebias"));
+ ent.target_select_anglebias = cvar(cvar_gets(sbase,"_target_select_anglebias"));
ent.target_select_playerbias = cvar(cvar_gets(sbase,"_target_select_playerbias"));
+ //ent.target_select_fov = cvar(cvar_gets(sbase,"_target_select_fov"));
- ent.ammo_max = cvar(cvar_gets(sbase,"_ammo_max")) * ent.turret_scale_ammo;
- //ent.ammo = cvar(cvar_gets(sbase,"_ammo"));
+ ent.ammo_max = cvar(cvar_gets(sbase,"_ammo_max")) * ent.turret_scale_ammo;
ent.ammo_recharge = cvar(cvar_gets(sbase,"_ammo_recharge")) * ent.turret_scale_ammo;
ent.aim_firetolerance_dist = cvar(cvar_gets(sbase,"_aim_firetolerance_dist"));
-// ent.aim_firetolerance_angle = cvar(cvar_gets(sbase,"_aim_firetolerance_angle"));
- ent.aim_speed = cvar(cvar_gets(sbase,"_aim_speed")) * ent.turret_scale_aim;
- ent.aim_maxrot = cvar(cvar_gets(sbase,"_aim_maxrot"));
+ ent.aim_speed = cvar(cvar_gets(sbase,"_aim_speed")) * ent.turret_scale_aim;
+ ent.aim_maxrot = cvar(cvar_gets(sbase,"_aim_maxrot"));
ent.aim_maxpitch = cvar(cvar_gets(sbase,"_aim_maxpitch"));
- ent.track_type = cvar(cvar_gets(sbase,"_track_type"));
+ ent.track_type = cvar(cvar_gets(sbase,"_track_type"));
ent.track_accel_pitch = cvar(cvar_gets(sbase,"_track_accel_pitch"));
- ent.track_accel_rot = cvar(cvar_gets(sbase,"_track_accel_rot"));
- ent.track_blendrate = cvar(cvar_gets(sbase,"_track_blendrate"));
+ ent.track_accel_rot = cvar(cvar_gets(sbase,"_track_accel_rot"));
+ ent.track_blendrate = cvar(cvar_gets(sbase,"_track_blendrate"));
+
+ if(is_reload)
+ if(ent.turret_respawnhook)
+ ent.turret_respawnhook();
+
}
float turret_stdproc_true()
@@ -93,15 +91,13 @@
}
/**
-** updates enemy distances, preicted impact point/time
-** & aim<->predict impact distance.
-** Also translates shoot & aimorgs by current rotation.
+** updates enemy distances, predicted impact point/time
+** and updated aim<->predict impact distance.
**/
void turret_do_updates(entity e_turret)
{
vector enemy_pos;
-
- if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
+ if (e_turret.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
{
e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;
e_turret.angles_x = e_turret.angles_x * -1;
@@ -117,36 +113,103 @@
}
enemy_pos = real_origin(e_turret.enemy);
- e_turret.tur_shotorg_updated = e_turret.origin + v_forward * e_turret.tur_shotorg_x + v_right * e_turret.tur_shotorg_y + v_up * e_turret.tur_shotorg_z;
- e_turret.tur_aimorg_updated = e_turret.origin + v_forward * e_turret.tur_aimorg_x + v_right * e_turret.tur_aimorg_y + v_up * e_turret.tur_aimorg_z;
- e_turret.tur_shotdir_updated = v_forward; // normalize((e_turret.tur_shotorg_updated + v_forward) - e_turret.tur_shotorg_updated);
+ turret_tag_fire_update();
+ e_turret.tur_shotdir_updated = normalize(v_forward);
- e_turret.tur_dist_enemy = vlen(e_turret.tur_aimorg_updated - enemy_pos);
- e_turret.tur_dist_aimpos = vlen(e_turret.tur_aimorg_updated - e_turret.tur_aimpos);
+ e_turret.tur_dist_enemy = vlen(e_turret.tur_shotorg - enemy_pos);
+ e_turret.tur_dist_aimpos = vlen(e_turret.tur_shotorg - e_turret.tur_aimpos);
- //traceline(e_turret.tur_aimorg_updated,e_turret.tur_aimorg_updated + (e_turret.tur_shotdir_updated * e_turret.tur_dist_aimpos),MOVE_NORMAL,e_turret);
- tracebox(e_turret.tur_aimorg_updated, '-1 -1 -1','1 1 1',e_turret.tur_aimorg_updated + (e_turret.tur_shotdir_updated * e_turret.tur_dist_aimpos),MOVE_NORMAL,e_turret);
+ if(e_turret.firecheck_flags & TFL_FIRECHECK_VERIFIED)
+ if(e_turret.enemy)
+ {
+ enemy_pos = e_turret.enemy.origin;
+ setorigin(e_turret.enemy,e_turret.tur_aimpos);
+ }
- //traceline(e_turret.tur_aimorg_updated,e_turret.tur_aimpos,MOVE_NORMAL,e_turret);
+ tracebox(e_turret.tur_shotorg, '-1 -1 -1','1 1 1',e_turret.tur_shotorg + (e_turret.tur_shotdir_updated * e_turret.tur_dist_aimpos),MOVE_NORMAL,e_turret);
- e_turret.tur_impactpoint = trace_endpos;
- e_turret.tur_impactent = trace_ent;
+ if(e_turret.firecheck_flags & TFL_FIRECHECK_VERIFIED)
+ if(e_turret.enemy)
+ setorigin(e_turret.enemy,enemy_pos);
+
+ e_turret.tur_impactpoint = trace_endpos;
+ e_turret.tur_impactent = trace_ent;
e_turret.tur_dist_impact_to_aimpos = vlen(trace_endpos - e_turret.tur_aimpos);
- e_turret.tur_impacttime = vlen(e_turret.tur_aimorg_updated - trace_endpos) / e_turret.shot_speed;
+ e_turret.tur_impacttime = vlen(e_turret.tur_shotorg - trace_endpos) / e_turret.shot_speed;
+}
/*
-.float tur_dist_enemy;
-.float tur_dist_aimpos;
-.float tur_dist_impact_to_aimpos;
-*/
+vector turret_fovsearch_pingpong()
+{
+ vector wish_angle;
+ if(self.phase < time)
+ {
+ if( self.tur_head.phase )
+ self.tur_head.phase = 0;
+ else
+ self.tur_head.phase = 1;
+ self.phase = time + 5;
+ }
+ if( self.tur_head.phase)
+ wish_angle = self.idle_aim + '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
+ else
+ wish_angle = self.idle_aim - '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
+
+ return wish_angle;
}
+vector turret_fovsearch_steprot()
+{
+ vector wish_angle;
+ //float rot_add;
+
+ wish_angle = self.tur_head.angles;
+ wish_angle_x = self.idle_aim_x;
+
+ if (self.phase < time)
+ {
+ //rot_add = self.aim_maxrot / self.target_select_fov;
+ wish_angle_y += (self.target_select_fov * 2);
+
+ if(wish_angle_y > 360)
+ wish_angle_y = wish_angle_y - 360;
+
+ self.phase = time + 1.5;
+ }
+
+ return wish_angle;
+}
+
+vector turret_fovsearch_random()
+{
+ vector wish_angle;
+
+ if (self.phase < time)
+ {
+ wish_angle_y = random() * self.aim_maxrot;
+ if(random() < 0.5)
+ wish_angle_y *= -1;
+
+ wish_angle_x = random() * self.aim_maxpitch;
+ if(random() < 0.5)
+ wish_angle_x *= -1;
+
+ self.phase = time + 5;
+
+ self.tur_aimpos = wish_angle;
+ }
+
+ return self.idle_aim + self.tur_aimpos;
+}
+*/
+
/**
** Handles head rotation according to
** the units .track_type and .track_flags
**/
+//.entity aim_mark;
void turret_stdproc_track()
{
vector wish_angle; // This is where we want to aim
@@ -154,68 +217,83 @@
vector real_angle; // This is where we can aim
float f_tmp;
+ /*
+ if(!self.aim_mark)
+ {
+ self.aim_mark = mark_misc(self.tur_aimpos,0);
+ self.aim_mark.colormod = '1 1 0';
+ }
+ */
+
if (self.track_flags == TFL_TRACK_NO)
return;
- if(!self.tur_active)
+ /*
+ if not(self.tur_active)
{
wish_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);
}
else if (self.enemy == world)
{
- if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
+ if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
wish_angle = self.idle_aim + self.angles;
else
if(time > self.lip)
+ {
+ if(self.target_select_flags & TFL_TARGETSELECT_FOV)
+ wish_angle = self.idle_aim; //turret_fovsearch_steprot();
+ }
+ else
+ {
+ //wish_angle = self.tur_head.angles;
wish_angle = self.idle_aim;
- else
- wish_angle = self.tur_head.angles;
+ //wish_angle = normalize(self.tur_aimpos - self.tur_head.origin);
+ //wish_angle = vectoangles(wish_angle); // And make a angle
+ }
+ }
+ else
+ */
+ if(!self.tur_active)
+ {
+ wish_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);
}
+ else if (self.enemy == world)
+ {
+ if(time > self.lip)
+ if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+ wish_angle = self.idle_aim + self.angles;
+ else
+ wish_angle = self.idle_aim;
+ else
+ wish_angle = vectoangles(self.tur_aimpos - self.tur_head.origin);
+ }
else
{
// Find the direction
- if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
- wish_angle = normalize(self.tur_aimpos - self.origin);
+ /*
+ if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+ wish_angle = normalize(self.tur_aimpos - self.tur_shotorg);
else
- wish_angle = normalize(self.tur_aimpos - self.tur_head.origin);
-
+ */
+ wish_angle = normalize(self.tur_aimpos - self.tur_shotorg);
wish_angle = vectoangles(wish_angle); // And make a angle
}
// Find the diffrence between where we currently aim and where we want to aim
- if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
- real_angle = wish_angle - (self.angles + self.tur_head.angles);
- else
+ if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
{
- real_angle = wish_angle - self.tur_head.angles;
-
+ real_angle = wish_angle - (self.angles + self.tur_head.angles);
+ real_angle = shortangle_v(real_angle,(self.angles + self.tur_head.angles));
}
-
- if(real_angle_x > self.tur_head.angles_x)
- {
- if(real_angle_x >= 180)
- real_angle_x -= 360;
- }
else
{
- if(real_angle_x <= -180)
- real_angle_x += 360;
+ real_angle = wish_angle - self.tur_head.angles;
+ real_angle = shortangle_v(real_angle,self.tur_head.angles);
}
- if(real_angle_y > self.tur_head.angles_y)
- {
- if(real_angle_y >= 180)
- real_angle_y -= 360;
- }
- else
- {
- if(real_angle_y <= -180)
- real_angle_y += 360;
- }
// Limit pitch
-
if (self.track_flags & TFL_TRACK_PITCH)
real_angle_x = bound(self.aim_maxpitch * -1,real_angle_x,self.aim_maxpitch);
@@ -223,80 +301,89 @@
if (self.track_flags & TFL_TRACK_ROT)
real_angle_y = bound(self.aim_maxrot * -1,real_angle_y,self.aim_maxrot);
-
- if (self.track_type == TFL_TRACKTYPE_STEPMOTOR)
+ switch(self.track_type)
{
- f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
+ case TFL_TRACKTYPE_STEPMOTOR:
- // Limit turning speed
- real_angle_x = bound((-1 * f_tmp),real_angle_x, f_tmp);
- real_angle_y = bound((-1 * f_tmp),real_angle_y, f_tmp);
+ /*
+ setorigin(self.aim_mark,self.tur_aimpos);
+ wish_angle = normalize(self.tur_aimpos - self.tur_shotorg_updated);
+ real_angle = vectoangles(wish_angle);
+ self.tur_head.angles = real_angle;
+ return;
+ */
+ f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
- // Limit pich and rot.
- if (self.track_flags & TFL_TRACK_PITCH)
- self.tur_head.angles_x = bound((-1 * self.aim_maxpitch),self.tur_head.angles_x + real_angle_x,self.aim_maxpitch);
+ // Limit turning speed
+ real_angle_x = bound((-1 * f_tmp),real_angle_x, f_tmp);
+ real_angle_y = bound((-1 * f_tmp),real_angle_y, f_tmp);
- if (self.track_flags & TFL_TRACK_ROT)
- self.tur_head.angles_y = bound((-1 * self.aim_maxrot),self.tur_head.angles_y + real_angle_y,self.aim_maxrot);
+ // Limit pich and rot.
+ if (self.track_flags & TFL_TRACK_PITCH)
+ self.tur_head.angles_x = bound((-1 * self.aim_maxpitch),self.tur_head.angles_x + real_angle_x,self.aim_maxpitch);
- return;
- }
+ if (self.track_flags & TFL_TRACK_ROT)
+ self.tur_head.angles_y = bound((-1 * self.aim_maxrot),self.tur_head.angles_y + real_angle_y,self.aim_maxrot);
- if (self.track_type == TFL_TRACKTYPE_FLUIDPRECISE)
- {
- if (self.track_flags & TFL_TRACK_PITCH)
- self.tur_head.avelocity_x = real_angle_x;
+ return;
- if (self.track_flags & TFL_TRACK_ROT)
- self.tur_head.avelocity_y = real_angle_y;
- }
- else if (self.track_type == TFL_TRACKTYPE_FLUIDINERTIA)
- {
- f_tmp = self.aim_speed * self.ticrate;
+ break;
- real_angle_y = bound(self.aim_speed * -1,real_angle_y * self.track_accel_rot * f_tmp,self.aim_speed);
- real_angle_x = bound(self.aim_speed * -1,real_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed);
- real_angle = (self.tur_head.avelocity * self.track_blendrate) + (real_angle * (1 - self.track_blendrate));
+ case TFL_TRACKTYPE_FLUIDPRECISE:
- if (self.track_flags & TFL_TRACK_PITCH) self.tur_head.avelocity_x = real_angle_x;
- if (self.track_flags & TFL_TRACK_ROT) self.tur_head.avelocity_y = real_angle_y;
- self.tur_head.avelocity_z = real_angle_z;
- setsize(self,self.mins,self.maxs);
+ real_angle_y = bound(self.aim_speed * -1,real_angle_y ,self.aim_speed);
+ real_angle_x = bound(self.aim_speed * -1,real_angle_x ,self.aim_speed);
+
+ break;
+
+ case TFL_TRACKTYPE_FLUIDINERTIA:
+
+ f_tmp = self.aim_speed * self.ticrate;
+
+ real_angle_y = bound(self.aim_speed * -1,real_angle_y * self.track_accel_rot * f_tmp,self.aim_speed);
+ real_angle_x = bound(self.aim_speed * -1,real_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed);
+ real_angle = (self.tur_head.avelocity * self.track_blendrate) + (real_angle * (1 - self.track_blendrate));
+
+ self.tur_head.avelocity_z = real_angle_z;
+
+ break;
}
// Limit pitch
- /*
if (self.track_flags & TFL_TRACK_PITCH)
{
- if (self.tur_head.angles_x > self.aim_maxpitch)
+ self.tur_head.avelocity_x = real_angle_x;
+ if (self.tur_head.angles_x > 360)
{
- self.tur_head.angles_x = self.aim_maxpitch;
- self.tur_head.avelocity_x = 0;
+ self.tur_head.angles_x -= floor(self.tur_head.angles_x / 360) * 360;
+ //self.tur_head.angles_x = self.aim_maxpitch;
+ //self.tur_head.avelocity_x = 0;
}
- else if (self.tur_head.angles_x < (self.aim_maxpitch * -1))
+ else if (self.tur_head.angles_x < -360)
{
- self.tur_head.angles_x = (self.aim_maxpitch * -1);
- self.tur_head.avelocity_x = 0;
+ self.tur_head.angles_x += floor(self.tur_head.angles_x / 360) * 360;
+ //self.tur_head.angles_x = (self.aim_maxpitch * -1);
+ //self.tur_head.avelocity_x = 0;
}
}
// Limit rot
if (self.track_flags & TFL_TRACK_ROT)
{
- if (self.tur_head.angles_y > self.aim_maxrot)
+ self.tur_head.avelocity_y = real_angle_y;
+ if (self.tur_head.angles_y > 360)
{
- self.tur_head.angles_y = self.aim_maxrot;
- self.tur_head.avelocity_y = 0;
+ self.tur_head.angles_y -= floor(self.tur_head.angles_y / 360) * 360;
+ //self.tur_head.angles_y = self.aim_maxrot;
+ //self.tur_head.avelocity_y = 0;
}
- else if (self.tur_head.angles_y < (self.aim_maxrot * -1))
+ else if (self.tur_head.angles_y < -360)
{
- self.tur_head.angles_y = (self.aim_maxrot * -1);
- self.tur_head.avelocity_y = 0;
+ self.tur_head.angles_y += floor(self.tur_head.angles_y / 360) * 360;
+ //self.tur_head.angles_y = (self.aim_maxrot * -1);
+ //self.tur_head.avelocity_y = 0;
}
}
- */
-
-
}
/*
@@ -330,13 +417,10 @@
if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)
if (self.attack_finished_single >= time) return 0;
- // Special case..
+ // Special case: volly fire turret that has to fire a full volly if a shot was fired.
if((self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) && (self.volly_counter != self.shot_volly))
- {
return 1;
- }
-
//
if (self.firecheck_flags & TFL_FIRECHECK_DEAD)
if (self.enemy.deadflag != DEAD_NO) return 0;
@@ -372,15 +456,14 @@
// Volly status
if (self.shot_volly > 1)
- {
if (self.volly_counter == self.shot_volly)
if (self.ammo < (self.shot_dmg * self.shot_volly))
return 0;
- }
- //if(self.tur_enemy_adist >= self.aim_firetolerance) return 0;
+ if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED)
+ if(self.tur_impactent != self.enemy)
+ return 0;
-
return 1;
}
@@ -407,51 +490,49 @@
//if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)
// return -0.5;
- if (!e_target)// == world)
+ if(e_target.owner == e_turret)
+ return -0.5;
+
+ if not(checkpvs(e_target.origin, e_turret))
return -1;
- if (e_target.classname == "grapplinghook")
- return - 1.5;
+ if (!e_target)// == world)
+ return -2;
if(g_onslaught)
if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!
- return - 1.75;
+ return - 3;
if (validate_flags & TFL_TARGETSELECT_NO)
- return -2;
+ return -4;
// If only this was used more..
if (e_target.flags & FL_NOTARGET)
- return -3;
+ return -5;
// Cant touch this
if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
- return -4;
+ return -6;
// player
if (e_target.flags & FL_CLIENT)
{
- if (!(validate_flags & TFL_TARGETSELECT_PLAYERS))
- return -5;
+ if not (validate_flags & TFL_TARGETSELECT_PLAYERS)
+ return -7;
if (e_target.deadflag != DEAD_NO)
- return -6;
+ return -8;
}
// enemy turrets
- if (e_target.turret_firefunc || e_target.owner.tur_head == e_target)
- {
- if (validate_flags & TFL_TARGETSELECT_NOTURRETS)
- return -5.5;
- }
+ if (validate_flags & TFL_TARGETSELECT_NOTURRETS)
+ if (e_target.turret_firefunc || e_target.owner.tur_head == e_target)
+ return -9;
-
// Missile
if (e_target.flags & FL_PROJECTILE)
- {
- if (!(validate_flags & TFL_TARGETSELECT_MISSILES))
- return -7;
- }
+ if not (validate_flags & TFL_TARGETSELECT_MISSILES)
+ return -10;
// Team check
if (validate_flags & TFL_TARGETSELECT_TEAMCHECK)
@@ -459,18 +540,18 @@
if (validate_flags & TFL_TARGETSELECT_OWNTEAM)
{
if (e_target.team != e_turret.team)
- return -8;
+ return -11;
if (e_turret.team != e_target.owner.team)
- return -8.5;
+ return -12;
}
else
{
if (e_target.team == e_turret.team)
- return -9;
+ return -13;
if (e_turret.team == e_target.owner.team)
- return -9.5;
+ return -14;
}
}
@@ -479,38 +560,56 @@
if (validate_flags & TFL_TARGETSELECT_RANGELIMTS)
{
if (tvt_dist < e_turret.target_range_min)
- return -13;
+ return -15;
if (tvt_dist > e_turret.target_range)
- return -14;
+ return -16;
}
// Can we even aim this thing?
- tvt_thadv = angleofs(e_turret.tur_head,e_target);
+ if(e_turret.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+ {
+ tvt_thadv = angleofs3(e_turret.tur_head.origin,e_turret.angles + e_turret.tur_head.angles ,e_target);
+ }
+ else
+ {
+ tvt_thadv = angleofs(e_turret.tur_head,e_target);
+ }
+
tvt_tadv = angleofs(e_turret,e_target);
tvt_thadf = vlen(tvt_thadv);
tvt_tadf = vlen(tvt_tadv);
+ /*
+ if(validate_flags & TFL_TARGETSELECT_FOV)
+ {
+ if(e_turret.target_select_fov < tvt_thadf)
+ return -21;
+ }
+ */
+
if (validate_flags & TFL_TARGETSELECT_ANGLELIMITS)
{
if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch)
- return -11;
+ return -17;
if (fabs(tvt_tadv_y) > e_turret.aim_maxrot)
- return -12;
+ return -18;
}
// Line of sight?
if (validate_flags & TFL_TARGETSELECT_LOS)
{
v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5);
- //v_tmp = e_target.origin;
- traceline(e_turret.origin + e_turret.tur_aimorg,v_tmp,0,e_turret);
+ traceline(e_turret.tur_shotorg,v_tmp,0,e_turret);
if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos))
- return -10;
+ return -19;
}
+ if (e_target.classname == "grapplinghook")
+ return -20;
+
#ifdef TURRET_DEBUG_TARGETSELECT
bprint("Target:",e_target.netname," is a valid target for ",e_turret.netname,"\n");
#endif
@@ -528,7 +627,7 @@
m_score = 0;
if(self.enemy)
- if(turret_validate_target(self,self.enemy,self.target_select_flags) > 0)
+ if(turret_validate_target(self,self.enemy,self.target_validate_flags) > 0)
{
e_enemy = self.enemy;
m_score = self.turret_score_target(self,e_enemy) * self.target_select_samebias;
@@ -544,6 +643,7 @@
f = turret_validate_target(self,e,self.target_select_flags);
if (f > 0)
{
+ bprint(e.netname," = ",ftos(f),"\n");
score = self.turret_score_target(self,e);
if ((score > m_score) && (score > 0))
{
@@ -561,24 +661,18 @@
{
entity e;
- self.nextthink = (time + self.ticrate);
+ self.nextthink = time + self.ticrate;
// ONS uses somewhat backwards linking.
if (teamplay)
{
- if (g_onslaught)
- {
-
- }
- else
- {
+ if not (g_onslaught)
if (self.target)
{
e = find(world,targetname,self.target);
if (e != world)
self.team = e.team;
}
- }
if (self.team != self.tur_head.team)
turret_stdproc_respawn();
@@ -612,15 +706,12 @@
}
#endif
- //Do custom prethink, and bail if it fails.
- //if (!self.turret_prethink()) return;
-
// Handle ammo
if (self.ammo < self.ammo_max)
self.ammo = min(self.ammo + self.ammo_recharge,self.ammo_max);
- // Inactive turrets needs to run the think loop too
+ // Inactive turrets needs to run the think loop,
// So they can handle animation and wake up if need be.
if(!self.tur_active)
{
@@ -632,8 +723,6 @@
if(self.deadflag != DEAD_NO)
{
dprint("Warning:dead turret running the think function!\n");
- //self.enemy = world;
- //turret_stdproc_track();
return;
}
@@ -644,7 +733,6 @@
// Do a self.turret_fire for every valid target.
e = findradius(self.origin,self.target_range);
-
while (e)
{
if (turret_validate_target(self,e,self.target_validate_flags))
@@ -653,38 +741,39 @@
turret_do_updates(self);
- if ( self.turret_firecheckfunc() ) turret_fire();
+ if (self.turret_firecheckfunc())
+ turret_fire();
}
e = e.chain;
}
self.enemy = world;
-
}
else
{
// Special case for volly always. if it fired once it must compleate the volly.
- if((self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) && (self.volly_counter != self.shot_volly))
- {
- // Predict or whatnot
- if not((self.aim_flags & TFL_AIM_NO))
- self.tur_aimpos = turret_stdproc_aim_generic();
+ if(self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
+ if(self.volly_counter != self.shot_volly)
+ {
+ // Predict or whatnot
+ if not((self.aim_flags & TFL_AIM_NO))
+ self.tur_aimpos = turret_stdproc_aim_generic();
- // Turn & pitch
- if (!self.track_flags & TFL_TRACK_NO)
- turret_stdproc_track();
+ // Turn & pitch
+ if (!self.track_flags & TFL_TRACK_NO)
+ turret_stdproc_track();
- turret_do_updates(self);
+ turret_do_updates(self);
- // Fire!
- if (self.turret_firecheckfunc() != 0)
- turret_fire();
+ // Fire!
+ if (self.turret_firecheckfunc() != 0)
+ turret_fire();
- self.turret_postthink();
+ self.turret_postthink();
- return;
- }
+ return;
+ }
// Check if we have a vailid enemy, and try to find one if we dont.
if ((turret_validate_target(self,self.enemy,self.target_validate_flags) <= 0) && (self.cnt < time))
@@ -710,27 +799,30 @@
else
self.lip = time + cvar("g_turrets_aimidle_delay"); // Keep track of the last time we had a target.
+
+ /*
+ turret_do_updates(self);
+ if (self.turret_firecheckfunc() > 0)
+ turret_fire();
+ */
+
//turret_do_updates(self);
-
// Predict or whatnot
if not((self.aim_flags & TFL_AIM_NO))
self.tur_aimpos = turret_stdproc_aim_generic();
- // Fire?
- //if (self.turret_firecheckfunc() != 0)
- // turret_fire();
-
//turret_do_updates(self);
-
// Turn & pitch
if (!self.track_flags & TFL_TRACK_NO)
turret_stdproc_track();
turret_do_updates(self);
-
// Fire?
- if (self.turret_firecheckfunc() != 0)
+ if (self.turret_firecheckfunc())
turret_fire();
+
+
+
}
// do any per-turret stuff
@@ -778,7 +870,7 @@
*/
void turret_stdproc_use()
{
- //bprint("Used:",self.netname, " By ",other.classname,"\n");
+ dprint("Turret ",self.netname, " used by ",activator.classname,"\n");
self.team = activator.team;
@@ -791,21 +883,24 @@
/*
* Standard turret initialization. use this!
-* (unless you have a very good reason not to.)
+* (unless you have a very good reason not to)
* Any special stuff like multiple cannon models should be done
* after this is proc called.
-* if the return value is 0, the turret should be removed.
+* if the return value is 0, the turret _must_ be removed.
*/
float turret_stdproc_init (string cvar_base_name)
{
- entity e;
+ entity e,ee;
// Are turrets allowed atm?
- if (cvar("g_turrets") == 0) return 0;
+ if (cvar("g_turrets") == 0)
+ return 0;
// Better more then once then never.
// turret_gibs_precash();
+ // Terrainbase spawnflag. This puts a enlongated model
+ // under the turret, so it looks ok on uneaven surfaces.
if (self.spawnflags & 2)
{
entity tb;
@@ -820,24 +915,28 @@
self.cvar_basename = cvar_base_name;
load_unit_settings(self,self.cvar_basename,0);
- // Group all turrets into the same team if in non teamplaymode, so they dont try to kill eachother.
+ // Handle turret teams.
if (cvar("g_assult") != 0)
{
if (!self.team)
self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize
}
else if (!teamplay)
- self.team = MAX_SHOT_DISTANCE;
+ self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
else if(g_onslaught && self.targetname)
{
e = find(world,target,self.targetname);
if(e != world)
+ {
self.team = e.team;
+ ee = e;
+ }
}
else if(!self.team)
- self.team = MAX_SHOT_DISTANCE;
+ self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
+
/*
* Try to guess some reasonaly defaults
* for missing params and do sanety checks
@@ -846,53 +945,61 @@
* as possible beforehand.
*/
if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
- {
- // Support units generaly dont need to have a high speed ai-loop
- if (!self.ticrate) self.ticrate = 0.25; // Speed of this turrets AI loop
- }
+ if (!self.ticrate) self.ticrate = 0.2; // Support units generaly dont need to have a high speed ai-loop
else
- {
- if (!self.ticrate) self.ticrate = 0.1; // Speed of this turrets AI loop
- }
+ if (!self.ticrate) self.ticrate = 0.1; // 10 fps for normal turrets
- self.ticrate = bound(0.01,self.ticrate,60); // keep it sane plz
+ self.ticrate = bound(sys_ticrate,self.ticrate,60); // keep it sane
// General stuff
- if (self.netname == "") self.netname = "turret";
+ if (self.netname == "")
+ self.netname = self.classname;
- if (!self.respawntime) self.respawntime = 60;
+ if (!self.respawntime)
+ self.respawntime = 60;
self.respawntime = max(-1,self.respawntime);
- if (!self.health) self.health = 1000;
+ if (!self.health)
+ self.health = 1000;
self.tur_health = max(1,self.health);
- if (!self.turrcaps_flags) self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
+ if (!self.turrcaps_flags)
+ self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
- if (!self.damage_flags) self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
+ if (!self.damage_flags)
+ self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
// Shot stuff.
- if (!self.shot_refire) self.shot_refire = 1;
+ if (!self.shot_refire)
+ self.shot_refire = 1;
self.shot_refire = bound(0.01,self.shot_refire,9999);
- if (!self.shot_dmg) self.shot_dmg = self.shot_refire * 50;
+ if (!self.shot_dmg)
+ self.shot_dmg = self.shot_refire * 50;
self.shot_dmg = max(1,self.shot_dmg);
- if (!self.shot_radius) self.shot_radius = self.shot_dmg * 0.5;
+ if (!self.shot_radius)
+ self.shot_radius = self.shot_dmg * 0.5;
self.shot_radius = max(1,self.shot_radius);
- if (!self.shot_speed) self.shot_speed = 2500;
+ if (!self.shot_speed)
+ self.shot_speed = 2500;
self.shot_speed = max(1,self.shot_speed);
- if (!self.shot_spread) self.shot_spread = 0.0125;
+ if (!self.shot_spread)
+ self.shot_spread = 0.0125;
self.shot_spread = bound(0.0001,self.shot_spread,500);
- if (!self.shot_force) self.shot_force = self.shot_dmg * 0.5 + self.shot_radius * 0.5;
+ if (!self.shot_force)
+ self.shot_force = self.shot_dmg * 0.5 + self.shot_radius * 0.5;
self.shot_force = bound(0.001,self.shot_force,MAX_SHOT_DISTANCE * 0.5);
- if (!self.shot_volly) self.shot_volly = 1;
+ if (!self.shot_volly)
+ self.shot_volly = 1;
self.shot_volly = bound(1,self.shot_volly,floor(self.ammo_max / self.shot_dmg));
- if (!self.shot_volly_refire) self.shot_volly_refire = self.shot_refire * self.shot_volly;
+ if (!self.shot_volly_refire)
+ self.shot_volly_refire = self.shot_refire * self.shot_volly;
self.shot_volly_refire = bound(self.shot_refire,self.shot_volly_refire,60);
if (!self.firecheck_flags)
@@ -901,37 +1008,47 @@
TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_WORLD;
// Range stuff.
- if (!self.target_range) self.target_range = self.shot_speed * 0.5;
+ if (!self.target_range)
+ self.target_range = self.shot_speed * 0.5;
self.target_range = bound(0,self.target_range,MAX_SHOT_DISTANCE);
- if (!self.target_range_min) self.target_range_min = self.shot_radius * 2;
+ if (!self.target_range_min)
+ self.target_range_min = self.shot_radius * 2;
self.target_range_min = bound(0,self.target_range_min,MAX_SHOT_DISTANCE);
- if (!self.target_range_fire) self.target_range_fire = self.target_range * 0.8;
+ if (!self.target_range_fire)
+ self.target_range_fire = self.target_range * 0.8;
self.target_range_fire = bound(0,self.target_range_fire,MAX_SHOT_DISTANCE);
- if (!self.target_range_optimal) self.target_range_optimal = self.target_range_fire * 0.5;
+ if (!self.target_range_optimal)
+ self.target_range_optimal = self.target_range_fire * 0.5;
self.target_range_optimal = bound(0,self.target_range_optimal,MAX_SHOT_DISTANCE);
// Aim stuff.
- if (!self.aim_maxrot) self.aim_maxrot = 45;
- self.aim_maxrot = bound(0,self.aim_maxrot,361);
+ if (!self.aim_maxrot)
+ self.aim_maxrot = 90;
+ self.aim_maxrot = bound(0,self.aim_maxrot,360);
- if (!self.aim_maxpitch) self.aim_maxpitch = 20;
+ if (!self.aim_maxpitch)
+ self.aim_maxpitch = 20;
self.aim_maxpitch = bound(0,self.aim_maxpitch,90);
- if (!self.aim_speed) self.aim_speed = 36;
+ if (!self.aim_speed)
+ self.aim_speed = 36;
self.aim_speed = bound(0.1,self.aim_speed, 1000);
- if (!self.aim_firetolerance_dist) self.aim_firetolerance_dist = 5 + (self.shot_radius * 2);
+ if (!self.aim_firetolerance_dist)
+ self.aim_firetolerance_dist = 5 + (self.shot_radius * 2);
self.aim_firetolerance_dist = bound(0.1,self.aim_firetolerance_dist,MAX_SHOT_DISTANCE);
-// if (!self.aim_firetolerance_angle) self.aim_firetolerance_angle = 10;
-// self.aim_firetolerance_angle = bound(0.1,self.aim_firetolerance_angle,360);
+ if (!self.aim_flags)
+ {
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+ if(self.turrcaps_flags & TFL_TURRCAPS_RADIUSDMG)
+ self.aim_flags |= TFL_AIM_GROUND2;
+ }
- if (!self.aim_flags) self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE;
-
// Sill the most tested (and aim-effective)
if (!self.track_type) self.track_type = TFL_TRACKTYPE_STEPMOTOR;
@@ -940,71 +1057,93 @@
// Fluid / Ineria mode. Looks mutch nicer, bit experimental &
// Can inmapt aim preformance alot.
// needs a bit diffrent aimspeed
- if (!self.aim_speed) self.aim_speed = 180;
- self.aim_speed = bound(0.1,self.aim_speed, 1000);
- if (!self.track_accel_pitch) self.track_accel_pitch = 0.75;
- if (!self.track_accel_rot) self.track_accel_rot = 0.75;
- if (!self.track_blendrate) self.track_blendrate = 0.35;
+ if (!self.aim_speed)
+ self.aim_speed = 180;
+ self.aim_speed = bound(0.1,self.aim_speed, 1000);
+
+ if (!self.track_accel_pitch)
+ self.track_accel_pitch = 0.5;
+
+ if (!self.track_accel_rot)
+ self.track_accel_rot = 0.5;
+
+ if (!self.track_blendrate)
+ self.track_blendrate = 0.35;
}
- if (!self.track_flags) self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROT;
+ if (!self.track_flags)
+ self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROT;
// Target selection stuff.
- if (!self.target_select_rangebias) self.target_select_rangebias = 1;
+ if (!self.target_select_rangebias)
+ self.target_select_rangebias = 1;
self.target_select_rangebias = bound(-10,self.target_select_rangebias,10);
- if (!self.target_select_samebias) self.target_select_samebias = 1;
+ if (!self.target_select_samebias)
+ self.target_select_samebias = 1;
self.target_select_samebias = bound(-10,self.target_select_samebias,10);
- if (!self.target_select_anglebias) self.target_select_anglebias = 1;
+ if (!self.target_select_anglebias)
+ self.target_select_anglebias = 1;
self.target_select_anglebias = bound(-10,self.target_select_anglebias,10);
- if (!self.target_select_missilebias) self.target_select_missilebias = -10;
+ if (!self.target_select_missilebias)
+ self.target_select_missilebias = -10;
+
self.target_select_missilebias = bound(-10,self.target_select_missilebias,10);
self.target_select_playerbias = bound(-10,self.target_select_playerbias,10);
if (!self.target_select_flags)
+ {
+ self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_TEAMCHECK
+ | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
+
if (self.turrcaps_flags & TFL_TURRCAPS_MISSILEKILL)
- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_MISSILES |
- TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
- else
- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS |
- TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
+ self.target_select_flags |= TFL_TARGETSELECT_MISSILES;
- //if(!self.target_validate_flags)
+ if (self.turrcaps_flags & TFL_TURRCAPS_PLAYERKILL)
+ self.target_select_flags |= TFL_TARGETSELECT_PLAYERS;
+ //else
+ // self.target_select_flags = TFL_TARGETSELECT_NO;
+ }
+
self.target_validate_flags = self.target_select_flags;
// Ammo stuff
- if (!self.ammo_max) self.ammo_max = self.shot_dmg * 10;
+ if (!self.ammo_max)
+ self.ammo_max = self.shot_dmg * 10;
self.ammo_max = max(self.shot_dmg,self.ammo_max);
- if (!self.ammo) self.ammo = self.shot_dmg * 5;
+ if (!self.ammo)
+ self.ammo = self.shot_dmg * 5;
self.ammo = bound(0,self.ammo,self.ammo_max);
- if (!self.ammo_recharge) self.ammo_recharge = self.shot_dmg / 2;
+ if (!self.ammo_recharge)
+ self.ammo_recharge = self.shot_dmg * 0.5;
self.ammo_recharge = max(0,self.ammo_recharge);
// Convert the recharge from X per sec to X per ticrate
self.ammo_recharge = self.ammo_recharge * self.ticrate;
- if (!self.ammo_flags) self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
+ if (!self.ammo_flags)
+ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
// Offsets & origins
- if (!self.tur_aimorg) self.tur_aimorg = '0 0 50';
if (!self.tur_shotorg) self.tur_shotorg = '50 0 50';
// End of default & sanety checks, start building the turret.
// Spawn extra bits
- self.tur_head = spawn();
-
+ self.tur_head = spawn();
self.tur_head.netname = self.tur_head.classname = "turret_head";
- self.tur_head.team = self.team;
+ self.tur_head.team = self.team;
+ self.tur_head.owner = self;
// Defend mode?
+ if(!self.tur_defend)
if (self.target != "")
{
self.tur_defend = find(world, targetname, self.target);
@@ -1015,12 +1154,9 @@
}
}
-// Claim ownership
- self.tur_head.owner = self;
// Put pices in place
-
- if (!(self.turrcaps_flags & TFL_TURRCAPS_LINKED))
+ if (!(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED))
setorigin(self.tur_head,self.origin);
// In target defense mode, aim on the spot to defens when idle.
@@ -1029,70 +1165,46 @@
else
self.idle_aim = self.angles;
- if (!(self.turrcaps_flags & TFL_TURRCAPS_LINKED))
+ if (!(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED))
self.tur_head.angles = self.idle_aim;
- if (!self.health) self.health = 150;
- self.tur_health = self.health;
+ if (!self.health)
+ self.health = 150;
+ self.tur_health = self.health;
self.tur_head.health = self.health;
- //Solid bbox for preformance reasons
- self.solid = SOLID_BBOX;
- self.tur_head.solid = SOLID_BBOX;
+ self.solid = SOLID_BBOX;
+ self.tur_head.solid = SOLID_BBOX;
- self.takedamage = DAMAGE_AIM;
- self.tur_head.takedamage = DAMAGE_AIM;
+ self.takedamage = DAMAGE_AIM;
+ self.tur_head.takedamage = DAMAGE_AIM;
self.movetype = MOVETYPE_NOCLIP;
self.tur_head.movetype = MOVETYPE_NOCLIP;
- // Team colouring?track
+ // Team color
if (self.team == COLOR_TEAM1) self.colormod = '1.4 0.8 0.8';
if (self.team == COLOR_TEAM2) self.colormod = '0.8 0.8 1.4';
// Attach stdprocs. override when and what needed
if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
{
- //self.turret_prethink = turret_stdproc_true;
self.turret_score_target = turret_stdproc_targetscore_support;
- //self.turret_aim = turret_stdproc_aim_generic;
- //self.turret_track = turret_stdproc_track;
self.turret_firecheckfunc = turret_stdproc_firecheck;
self.turret_firefunc = turret_stdproc_fire;
self.turret_postthink = turret_stdproc_nothing;
-
- //self.turret_damagefunc = turret_stdproc_damage;
- //self.event_damage = turret_stdproc_damage;
- self.tur_head.event_damage = turret_stdproc_damage;
-
- //self.turret_diefunc = turret_stdproc_die;
- //self.turret_spawnfunc = turret_stdproc_respawn;
-
+ self.tur_head.event_damage = turret_stdproc_damage;
}
else
{
-
- //self.turret_prethink = turret_stdproc_true;
self.turret_score_target = turret_stdproc_targetscore_generic;
-
- //if (self.aim_flags & TFL_AIM_SIMPLE)
- // self.turret_aim = turret_stdproc_aim_simple;
- //else
- // self.turret_aim = turret_stdproc_aim_generic;
-
- //self.turret_track = turret_stdproc_track;
self.turret_firecheckfunc = turret_stdproc_firecheck;
self.turret_firefunc = turret_stdproc_fire;
self.turret_postthink = turret_stdproc_nothing;
-
- //self.turret_damagefunc = turret_stdproc_damage;
- self.event_damage = turret_stdproc_damage;
- self.tur_head.event_damage = turret_stdproc_damage;
-
- //self.turret_diefunc = turret_stdproc_die;
- //self.turret_spawnfunc = turret_stdproc_respawn;
- self.turret_addtarget = turret_stdproc_false;
+ self.event_damage = turret_stdproc_damage;
+ self.tur_head.event_damage = turret_stdproc_damage;
+ self.turret_addtarget = turret_stdproc_false;
}
self.use = turret_stdproc_use;
@@ -1120,11 +1232,13 @@
self.tur_active = 1;
- //if (g_onslaught)
- // self.use();
+ // In ONS mode, and linked to a ONS ent. need to call the use to set team.
+ if (g_onslaught && ee)
+ {
+ activator = ee;
+ self.use();
+ }
- //turret_stdproc_use();
-
return 1;
}
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_misc.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_misc.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_misc.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,20 +1,21 @@
//--// Some support routines //--//
-
float shortangle_f(float ang1,float ang2)
{
+
if(ang1 > ang2)
{
- if(ang1 >= 180)
+ if(ang1 > 180)
return ang1 - 360;
}
else
{
- if(ang1 <= -180)
+ if(ang1 < -180)
return ang1 + 360;
}
return ang1;
}
+
vector shortangle_v(vector ang1,vector ang2)
{
vector vtmp;
@@ -25,7 +26,6 @@
return vtmp;
}
-
// Get real origin
vector real_origin(entity ent)
{
@@ -42,15 +42,82 @@
//v = v + ent.origin;
v = v + ((ent.absmin + ent.absmax) * 0.5);
return v;
-
}
-// Plug this into wherever precashing is done.
+// Plug this into wherever precache is done.
void g_turrets_common_precash()
{
precache_model ("models/turrets/c512.md3");
+ precache_model ("models/marker.md3");
}
+void SUB_Remove();
+void marker_think()
+{
+ if(self.cnt)
+ if(self.cnt < time)
+ {
+ self.think = SUB_Remove;
+ self.nextthink = time;
+ return;
+ }
+
+ self.frame += 1;
+ if(self.frame > 29)
+ self.frame = 0;
+
+ self.nextthink = time;
+}
+
+void mark_error(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "error_marker";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 0;
+ if(lifetime)
+ err.cnt = lifetime + time;
+}
+
+void mark_info(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "info_marker";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 1;
+ if(lifetime)
+ err.cnt = lifetime + time;
+}
+
+entity mark_misc(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "mark_misc";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 3;
+ if(lifetime)
+ err.cnt = lifetime + time;
+ return err;
+}
+
/*
* Paint a v_color colord circle on target onwho
* that fades away over f_time
@@ -147,3 +214,160 @@
return v_res;
}
+vector angleofs3(vector from,vector from_a, entity to)
+{
+ vector v_res;
+
+ // makevectors(from.angles);
+ v_res = normalize(to.origin - from);
+ v_res = vectoangles(v_res);
+ v_res = v_res - from_a;
+
+ if (v_res_x < 0) v_res_x += 360;
+ if (v_res_x > 180) v_res_x -= 360;
+
+ if (v_res_y < 0) v_res_y += 360;
+ if (v_res_y > 180) v_res_y -= 360;
+
+ return v_res;
+}
+
+float turret_tag_setup(float linked)
+{
+ vector v;
+ float f;
+
+ // Laters dooz
+ if (linked)
+ return 0;
+
+ f = gettagindex(self,"tag_head");
+ v = gettaginfo(self,f);
+ setorigin(self.tur_head,v);
+
+ f = gettagindex(self.tur_head,"tag_fire");
+ v = gettaginfo(self.tur_head,f);
+ self.tur_shotorg = v;
+
+ return 1;
+}
+
+float turret_tag_fire_update()
+{
+ vector v;
+ float f;
+
+ f = gettagindex(self.tur_head,"tag_fire");
+ v = gettaginfo(self.tur_head,f);
+
+ self.tur_shotorg = v;
+
+ return 1;
+}
+
+void FireImoBeam (vector start,vector end,vector smin,vector smax,
+ float bforce,float f_dmg,float f_velfactor, float deathtype)
+
+{
+ local vector hitloc, force, endpoint, dir;
+ local entity ent;
+
+ dir = normalize(end - start);
+ force = dir * bforce;
+
+ // go a little bit into the wall because we need to hit this wall later
+ end = end + dir;
+
+ // trace multiple times until we hit a wall, each obstacle will be made unsolid.
+ // note down which entities were hit so we can damage them later
+ while (1)
+ {
+ tracebox(start, smin, smax, end, FALSE, self);
+
+ // if it is world we can't hurt it so stop now
+ if (trace_ent == world || trace_fraction == 1)
+ break;
+
+ if (trace_ent.solid == SOLID_BSP)
+ break;
+
+ // make the entity non-solid so we can hit the next one
+ trace_ent.railgunhit = TRUE;
+ trace_ent.railgunhitloc = end;
+ trace_ent.railgunhitsolidbackup = trace_ent.solid;
+
+ // stop if this is a wall
+
+ // make the entity non-solid
+ trace_ent.solid = SOLID_NOT;
+ }
+
+ endpoint = trace_endpos;
+
+ // find all the entities the railgun hit and restore their solid state
+ ent = findfloat(world, railgunhit, TRUE);
+ while (ent)
+ {
+ // restore their solid type
+ ent.solid = ent.railgunhitsolidbackup;
+ ent = findfloat(ent, railgunhit, TRUE);
+ }
+
+ // find all the entities the railgun hit and hurt them
+ ent = findfloat(world, railgunhit, TRUE);
+ while (ent)
+ {
+ // get the details we need to call the damage function
+ hitloc = ent.railgunhitloc;
+ ent.railgunhitloc = '0 0 0';
+ ent.railgunhitsolidbackup = SOLID_NOT;
+ ent.railgunhit = FALSE;
+
+ // apply the damage
+ if (ent.takedamage)
+ {
+ Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
+ ent.velocity = ent.velocity * f_velfactor;
+ //ent.alpha = 0.25 + random() * 0.75;
+ }
+
+ // advance to the next entity
+ ent = findfloat(ent, railgunhit, TRUE);
+ }
+ trace_endpos = endpoint;
+}
+
+void turrets_precash()
+{
+ precache_model ("models/turrets/c512.md3");
+
+ precache_sound ("turrets/phaser.ogg");
+
+ precache_model ("models/turrets/base-gib1.md3");
+ precache_model ("models/turrets/base-gib2.md3");
+ precache_model ("models/turrets/base-gib3.md3");
+ precache_model ("models/turrets/base-gib4.md3");
+
+ precache_model ("models/turrets/head-gib1.md3");
+ precache_model ("models/turrets/head-gib2.md3");
+ precache_model ("models/turrets/head-gib3.md3");
+ precache_model ("models/turrets/head-gib4.md3");
+
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/flac.md3");
+ precache_model ("models/turrets/pd_proj.md3");
+ precache_model ("models/turrets/reactor.md3");
+ precache_model ("models/turrets/mlrs_rocket.md3");
+ precache_model ("models/turrets/hellion.md3");
+ precache_model ("models/turrets/hunter2.md3");
+ precache_model ("models/turrets/hk.md3");
+ precache_model ("models/turrets/machinegun.md3");
+ precache_model ("models/turrets/rocket.md3");
+ precache_model ("models/turrets/mlrs.md3");
+ precache_model ("models/turrets/phaser.md3");
+ precache_model ("models/turrets/phaser_beam.md3");
+ precache_model ("models/turrets/plasmad.md3");
+ precache_model ("models/turrets/plasma.md3");
+ precache_model ("models/turrets/tesla_head.md3");
+ precache_model ("models/turrets/tesla_base.md3");
+}
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_scoreprocs.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_scoreprocs.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/system_scoreprocs.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -37,9 +37,8 @@
float score; // Total score
float d_score; // Distance score
- //float da_score; // Distance from aimpoint score
+ //float da_score; // Distance from aimpoint score
float a_score; // Angular score
- //float s_score; // samescore (same target as last time)
float m_score; // missile score
float p_score; // player score
@@ -84,18 +83,16 @@
p_score = 1;
d_score = max(d_score,0);
- //s_score = max(s_score,0);
a_score = max(a_score,0);
m_score = max(m_score,0);
p_score = max(p_score,0);
- // (s_score * e_turret.target_select_samebias) +
score = (d_score * e_turret.target_select_rangebias) +
(a_score * e_turret.target_select_anglebias) +
(m_score * e_turret.target_select_missilebias) +
(p_score * e_turret.target_select_playerbias);
- if(e_turret.target_range_fire < vlen(e_turret.tur_shotorg_updated - real_origin(e_target)))
+ if(e_turret.target_range_fire < vlen(e_turret.tur_shotorg - real_origin(e_target)))
score *= 0.1;
#ifdef TURRET_DEBUG
@@ -137,6 +134,7 @@
return score;
}
+/*
float turret_stdproc_targetscore_close(entity e_turret,entity e_target)
{
return 1 - (tvt_dist / e_turret.target_range);
@@ -162,3 +160,4 @@
return 0;
//min(e_target.origin,e_turret.tur_defend.origin) / max(e_target.origin,e_turret.tur_defend.origin);
}
+*/
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_checkpoint.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_checkpoint.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_checkpoint.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -14,6 +14,7 @@
#define pathgoal goalstack01
#define pathcurrent goalstack02
+/*
entity path_makeorcache(entity forwho,entity start, entity end)
{
entity oldself;
@@ -21,11 +22,12 @@
oldself = self;
self = forwho;
- pth = pathlib_makepath(start.origin,end.origin,PFL_GROUNDSNAP,500,1.5,PT_QUICKSTAR);
+ //pth = pathlib_makepath(start.origin,end.origin,PFL_GROUNDSNAP,500,1.5,PT_QUICKSTAR);
self = oldself;
return pth;
}
+*/
void turret_checkpoint_use()
{
@@ -42,6 +44,9 @@
*/
void turret_checkpoint_init()
{
+ traceline(self.origin, self.origin - '0 0 1024', MOVE_WORLDONLY, self);
+ setorigin(self,trace_endpos + '0 0 8');
+
if(self.target != "")
{
self.enemy = find(world,targetname,self.target);
@@ -54,7 +59,7 @@
{
setorigin(self,self.origin);
self.think = turret_checkpoint_init;
- self.nextthink = time + 0.25;
+ self.nextthink = time + 0.1;
}
// Compat.
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_common.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_common.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_common.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,150 +1 @@
-float turret_tag_setup(float linked)
-{
- vector v;
- float f;
- // Laters dooz
- if (linked)
- return 0;
-
- f = gettagindex(self,"tag_head");
- v = gettaginfo_relative(self,f);
- v = v + self.origin;
- setorigin(self.tur_head,v);
-
- f = gettagindex(self.tur_head,"tag_fire");
- v = gettaginfo_relative(self.tur_head,f) + (self.tur_head.origin - self.origin);
- v_y *= -1;
- self.tur_shotorg = v;
-
- f = gettagindex(self.tur_head,"tag_aim");
- v = gettaginfo_relative(self.tur_head,f) + (self.tur_head.origin - self.origin);
- self.tur_aimorg = v;
-
- return 1;
-}
-
-float turret_tag_fire_update()
-{
- vector v;
- float f;
-
- f = gettagindex(self.tur_head,"tag_fire");
- v = gettaginfo_relative(self.tur_head,f) + (self.tur_head.origin - self.origin);
- v_y *= -1;
- self.tur_shotorg = v;
-
- f = gettagindex(self.tur_head,"tag_aim");
- v = gettaginfo_relative(self.tur_head,f) + (self.tur_head.origin - self.origin);
- self.tur_aimorg = v;
-
- return 1;
-}
-
-void FireImoBeam (vector start,vector end,vector smin,vector smax,
- float bforce,float f_dmg,float f_velfactor, float deathtype)
-
-{
- local vector hitloc, force, endpoint, dir;
- local entity ent;
-
- dir = normalize(end - start);
- force = dir * bforce;
-
- // go a little bit into the wall because we need to hit this wall later
- end = end + dir;
-
- // trace multiple times until we hit a wall, each obstacle will be made unsolid.
- // note down which entities were hit so we can damage them later
- while (1)
- {
- tracebox(start, smin, smax, end, FALSE, self);
-
- // if it is world we can't hurt it so stop now
- if (trace_ent == world || trace_fraction == 1)
- break;
-
- if (trace_ent.solid == SOLID_BSP)
- break;
-
- // make the entity non-solid so we can hit the next one
- trace_ent.railgunhit = TRUE;
- trace_ent.railgunhitloc = end;
- trace_ent.railgunhitsolidbackup = trace_ent.solid;
-
- // stop if this is a wall
-
-
- // make the entity non-solid
- trace_ent.solid = SOLID_NOT;
- }
-
- endpoint = trace_endpos;
-
- // find all the entities the railgun hit and restore their solid state
- ent = findfloat(world, railgunhit, TRUE);
- while (ent)
- {
- // restore their solid type
- ent.solid = ent.railgunhitsolidbackup;
- ent = findfloat(ent, railgunhit, TRUE);
- }
-
- // find all the entities the railgun hit and hurt them
- ent = findfloat(world, railgunhit, TRUE);
- while (ent)
- {
- // get the details we need to call the damage function
- hitloc = ent.railgunhitloc;
- ent.railgunhitloc = '0 0 0';
- ent.railgunhitsolidbackup = SOLID_NOT;
- ent.railgunhit = FALSE;
-
- // apply the damage
- if (ent.takedamage)
- {
- Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
- ent.velocity = ent.velocity * f_velfactor;
- //ent.alpha = 0.25 + random() * 0.75;
- }
-
- // advance to the next entity
- ent = findfloat(ent, railgunhit, TRUE);
- }
- trace_endpos = endpoint;
-}
-
-void turrets_precash()
-{
- precache_model ("models/turrets/c512.md3");
-
- precache_sound ("turrets/phaser.ogg");
-
- precache_model ("models/turrets/base-gib1.md3");
- precache_model ("models/turrets/base-gib2.md3");
- precache_model ("models/turrets/base-gib3.md3");
- precache_model ("models/turrets/base-gib4.md3");
-
- precache_model ("models/turrets/head-gib1.md3");
- precache_model ("models/turrets/head-gib2.md3");
- precache_model ("models/turrets/head-gib3.md3");
- precache_model ("models/turrets/head-gib4.md3");
-
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/flac.md3");
- precache_model ("models/turrets/pd_proj.md3");
- precache_model ("models/turrets/reactor.md3");
- precache_model ("models/turrets/mlrs_rocket.md3");
- precache_model ("models/turrets/hellion.md3");
- precache_model ("models/turrets/hunter2.md3");
- precache_model ("models/turrets/hk.md3");
- precache_model ("models/turrets/machinegun.md3");
- precache_model ("models/turrets/rocket.md3");
- precache_model ("models/turrets/mlrs.md3");
- precache_model ("models/turrets/phaser.md3");
- precache_model ("models/turrets/phaser_beam.md3");
- precache_model ("models/turrets/plasmad.md3");
- precache_model ("models/turrets/plasma.md3");
- precache_model ("models/turrets/tesla_head.md3");
- precache_model ("models/turrets/tesla_base.md3");
-}
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_ewheel.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_ewheel.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_ewheel.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -23,22 +23,17 @@
void ewheel_attack()
{
entity proj;
- vector v;
- float f,i;
+ float i;
for (i=0;i<1;++i)
{
- f = gettagindex(self.tur_head,"tag_fire");
- v = gettaginfo_relative(self.tur_head,f);
- v_y = v_y * -1;
- self.tur_shotorg = v;
turret_do_updates(self);
sound (self, CHAN_WEAPON, "weapons/lasergun_fire.wav", VOL_BASE, ATTN_NORM);
- pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg_updated, self.tur_shotdir_updated * 1000, 1);
+ pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
proj = spawn ();
- setorigin(proj, self.tur_shotorg_updated);
+ setorigin(proj, self.tur_shotorg);
//setsize(proj, '-0.5 -0.5 -0.5', '0.5 0.5 0.5');
//setmodel(proj, "models/laser.mdl"); // precision set above
proj.classname = "ewheel bolt";
@@ -66,12 +61,13 @@
}
-#define EWHEEL_MASS 50
+#define EWHEEL_MASS 25
#define EWHEEL_MAXSPEED 800
-#define EWHEEL_ACCEL_SLOW 25
-#define EWHEEL_ACCEL_FAST 100
-#define EWHEEL_BREAK_SLOW 100
+#define EWHEEL_ACCEL_SLOW 100
+#define EWHEEL_ACCEL_FAST 350
+#define EWHEEL_BREAK_SLOW 150
#define EWHEEL_BREAK_FAST 250
+#define EWHEEL_DRAG 0.25
void ewheel_enemymove()
{
@@ -116,33 +112,31 @@
self.angles_y = (self.angles_y + real_angle_y);
// Simulate banking
- self.angles_z = bound(-45,real_angle_y * -1,45);
+ self.angles_z = bound(-45,real_angle_y * -2,45);
-
if (self.frame > 40)
self.frame = 1;
makevectors(self.angles);
-
if (self.tur_dist_aimpos > self.target_range_optimal)
{
- if ( angle_ofs < 10 )
+ if ( angle_ofs < 1 )
{
self.frame += 2;
- movelib_move(v_forward * EWHEEL_ACCEL_FAST,EWHEEL_MAXSPEED,0,EWHEEL_MASS,0);
+ movelib_move(v_forward * EWHEEL_ACCEL_FAST,EWHEEL_MAXSPEED,EWHEEL_DRAG,EWHEEL_MASS,0);
}
- else if (angle_ofs < 16)
+ else if (angle_ofs < 2)
{
- self.frame += 0.5;
- movelib_move(v_forward,EWHEEL_MAXSPEED,0,EWHEEL_MASS,EWHEEL_BREAK_SLOW);
+ self.frame += 1;
+ movelib_move(v_forward * EWHEEL_ACCEL_SLOW,EWHEEL_MAXSPEED,EWHEEL_DRAG,EWHEEL_MASS,EWHEEL_BREAK_SLOW);
}
else
{
- movelib_move('0 0 0',EWHEEL_MAXSPEED,0,EWHEEL_MASS,EWHEEL_BREAK_FAST);
+ movelib_move('0 0 0',EWHEEL_MAXSPEED,EWHEEL_DRAG,EWHEEL_MASS,EWHEEL_BREAK_FAST);
}
}
else
- movelib_move('0 0 0',EWHEEL_MAXSPEED,0,EWHEEL_MASS,EWHEEL_BREAK_FAST);
+ movelib_move('0 0 0',EWHEEL_MAXSPEED,EWHEEL_DRAG,EWHEEL_MASS,EWHEEL_BREAK_FAST);
}
void ewheel_roammove()
@@ -225,15 +219,18 @@
void ewheel_respawnhook()
{
setorigin(self,self.pos1);
-
- //self.angles = self.wkr_spawn.angles;
-
}
void ewheel_diehook()
{
}
+float ewheel_firecheck()
+{
+ bprint("Firecheck\n");
+ return 1;
+}
+
void turret_ewheel_dinit()
{
entity e;
@@ -258,8 +255,8 @@
}
self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
- self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM | TFL_TURRCAPS_LINKED;
- self.aim_flags = TFL_AIM_SIMPLE;// TFL_AIM_LEAD | TFL_AIM_ZEASE;
+ self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM | TFL_TURRCAPS_HEADATTACHED;
+ //self.aim_flags = TFL_AIM_SIMPLE;// TFL_AIM_LEAD | TFL_AIM_ZEASE;
self.turret_respawnhook = ewheel_respawnhook;
self.turret_diehook = ewheel_diehook;
@@ -270,10 +267,11 @@
remove(self);
return;
}
+ //self.turret_firecheckfunc = ewheel_firecheck;
self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
- self.damage_flags |= RFL_DMG_DEATH_NOGIBS;
+ self.damage_flags |= TFL_DMG_DEATH_NOGIBS;
//self.flags = FL_CLIENT;
self.iscreature = TRUE;
@@ -289,22 +287,6 @@
self.pos1 = self.origin;
- vector v;
- float f;
- f = gettagindex(self.tur_head,"tag_fire");
- v = gettaginfo_relative(self.tur_head,f);
- v_y = v_y * -1;
-
- //setsize(self,WALKER_MIN,WALKER_MAX);
- //setsize(self,'-70 -70 0','70 70 55');
-
- self.tur_shotorg = v;
- self.tur_aimorg = v;
-
- self.tur_aimorg_x = 0;
- self.tur_aimorg_y = 0;
- self.tur_aimorg_z = 25;
-
self.idle_aim = '0 0 0';
// Our fire routine
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_flac.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_flac.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_flac.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -11,14 +11,14 @@
sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
proj = spawn ();
- setorigin(proj, self.tur_shotorg_updated);
+ setorigin(proj, self.tur_shotorg);
// setmodel(proj, "models/turrets/pd_proj.md3");
setsize(proj, '0 0 0', '0 0 0');
- proj.classname = "turret_fire";
+ proj.classname = "flac_projectile";
proj.owner = self;
proj.bot_dodge = TRUE;
proj.bot_dodgerating = self.shot_dmg;
- proj.solid = SOLID_NOT;
+ proj.solid = SOLID_BBOX;
proj.movetype = MOVETYPE_FLYMISSILE;
proj.flags = FL_PROJECTILE;
// proj.effects = EF_LOWPRECISION;
@@ -44,14 +44,16 @@
float ftmp;
// FIXME: tur_impacttime is not accurate enougth, this is a dirty hakk to make flac work.
+
if(self.enemy != world)
if(self.cnt < time)
- if(vlen(self.origin - self.enemy.origin) > self.owner.shot_radius * 0.5)
+ if(vlen(self.origin - self.enemy.origin) > self.owner.shot_radius * 0.25)
{
self.nextthink = time; //vlen(self.origin - self.enemy.origin) / self.owner.shot_speed;
return;
}
+
te_explosion (self.origin);
ftmp = crandom();
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -28,12 +28,16 @@
{
}
+void turret_fusionreactor_respawnhook()
+{
+ self.tur_head.avelocity = '0 50 0';
+}
void turret_fusionreactor_dinit()
{
if (self.netname == "") self.netname = "Fusionreactor";
- self.turrcaps_flags =TFL_TURRCAPS_SUPPORT | TFL_TURRCAPS_AMMOSOURCE;
+ self.turrcaps_flags = TFL_TURRCAPS_SUPPORT | TFL_TURRCAPS_AMMOSOURCE;
self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
@@ -42,11 +46,9 @@
self.firecheck_flags = TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_OTHER_AMMO | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_WORLD;
self.shoot_flags = TFL_SHOOT_HITALLVALID;
-
self.aim_flags = TFL_AIM_NO;
-
self.track_flags = TFL_TRACK_NO;
-
+ self.turret_respawnhook = turret_fusionreactor_respawnhook;
if (turret_stdproc_init("fusreac_std") == 0)
{
remove(self);
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_hellion.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_hellion.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_hellion.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -30,7 +30,7 @@
sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
missile = spawn ();
- setorigin(missile, self.tur_shotorg_updated);
+ setorigin(missile, self.tur_shotorg);
setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
missile.classname = "hellion_missile";
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_hk.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_hk.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_hk.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -90,7 +90,7 @@
missile = spawn ();
missile.solid = SOLID_BBOX;
setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
- setorigin(missile, self.tur_shotorg_updated);
+ setorigin(missile, self.tur_shotorg);
missile.scale = 1;
missile.classname = "hk_missile";
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_machinegun.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_machinegun.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_machinegun.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -9,9 +9,9 @@
entity flash;
sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
- fireBallisticBullet (self.tur_shotorg_updated, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant"));
+ fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant"));
- te_smallflash(self.tur_shotorg_updated);
+ te_smallflash(self.tur_shotorg);
// trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);
// muzzle flash for 3rd person view
@@ -33,9 +33,14 @@
if (self.netname == "") self.netname = "Machinegun Turret";
self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
- self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL;// | TFL_TURRCAPS_MISSILEKILL;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE | TFL_AIM_SHOTTIMECOMPENSATE;
+ self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL;// | TFL_TURRCAPS_MISSILEKILL;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE;
+ if(cvar("g_antilag_bullets"))
+ self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
+ else
+ self.aim_flags |= TFL_AIM_SHOTTIMECOMPENSATE;
+
if (turret_stdproc_init("machinegun_std") == 0)
{
remove(self);
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_mlrs.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_mlrs.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_mlrs.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -2,6 +2,7 @@
void turret_mlrs_dinit();
void turret_mlrs_attack();
void turret_mlrs_rocket_explode();
+void turret_mlrs_rocket_touch();
void turret_mlrs_postthink()
{
@@ -19,8 +20,9 @@
sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", VOL_BASE, ATTN_NORM);
missile = spawn ();
+ //setsize (missile, '0 0 0', '0 0 0'); // give it some size so it can be shot
setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
- setorigin(missile, self.tur_shotorg_updated);
+ setorigin(missile, self.tur_shotorg);
missile.classname = "mlrs_missile";
missile.owner = self;
missile.bot_dodge = TRUE;
@@ -37,7 +39,7 @@
missile.movetype = MOVETYPE_FLYMISSILE;
missile.velocity = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
missile.angles = vectoangles(missile.velocity);
- missile.touch = turret_mlrs_rocket_explode;
+ missile.touch = turret_mlrs_rocket_touch;
missile.flags = FL_PROJECTILE;
missile.solid = SOLID_BBOX;
missile.enemy = self.enemy;
@@ -49,6 +51,16 @@
//self.tur_head.frame = 7 - self.volly_counter;
}
+void turret_mlrs_rocket_touch()
+{
+ if( (other == self.owner) || (other == self.owner.tur_head) )
+ return;
+
+ PROJECTILE_TOUCH;
+
+ turret_mlrs_rocket_explode();
+}
+
void turret_mlrs_rocket_explode()
{
vector org2;
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_phaser.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_phaser.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_phaser.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -60,8 +60,8 @@
entity oldself;
oldself = self;
self = self.owner;
- FireImoBeam ( self.tur_shotorg_updated,
- self.tur_shotorg_updated + self.tur_shotdir_updated * self.target_range_fire,
+ FireImoBeam ( self.tur_shotorg,
+ self.tur_shotorg + self.tur_shotdir_updated * self.target_range_fire,
'-1 -1 -1' * self.shot_radius,
'1 1 1' * self.shot_radius,
self.shot_force,
@@ -69,7 +69,7 @@
0.75,
DEATH_TURRET);
self = oldself;
- self.scale = vlen(self.owner.tur_shotorg_updated - trace_endpos) / 256;
+ self.scale = vlen(self.owner.tur_shotorg - trace_endpos) / 256;
}
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_plasma.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_plasma.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_plasma.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -17,6 +17,9 @@
if (self.tur_head.frame > 5)
self.tur_head.frame = 0;
+ setsize(self,self.mins,self.maxs);
+ setsize(self.tur_head,self.tur_head.mins,self.tur_head.maxs);
+
/*
float h;
h = self.health / self.tur_health;
@@ -48,11 +51,11 @@
turret_tag_fire_update();
sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
- pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg_updated, self.tur_shotdir_updated * 1000, 1);
+ pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
proj = spawn ();
- setorigin(proj, self.tur_shotorg_updated);
- setsize(proj, '-0.5 -0.5 -0.5', '0.5 0.5 0.5');
+ setorigin(proj, self.tur_shotorg);
+ setsize(proj, '-1 -1 -1', '1 1 1');
//setmodel(proj, "models/elaser.mdl"); // precision set above
proj.classname = "plasmabomb";
proj.owner = self;
@@ -89,7 +92,7 @@
sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
proj = spawn ();
- setorigin(proj, self.tur_shotorg_updated);
+ setorigin(proj, self.tur_shotorg);
setsize(proj, '0 0 0', '0 0 0');
//setmodel(proj, "models/elaser.mdl"); // precision set above
proj.classname = "plasmabomb";
@@ -100,7 +103,8 @@
proj.nextthink = time + 9;
proj.solid = SOLID_BBOX;
proj.movetype = MOVETYPE_FLYMISSILE;
- proj.velocity = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+ //proj.velocity = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+ proj.velocity = self.tur_shotdir_updated * self.shot_speed;
proj.angles = vectoangles(proj.velocity);
proj.touch = turret_plasma_projectile_explode;
proj.flags = FL_PROJECTILE;
@@ -150,17 +154,23 @@
self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
// How to aim
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE | TFL_AIM_GROUND2;
+ //self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;// | TFL_AIM_ZPREDICT | TFL_AIM_GROUND2;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_GROUND2;
+ self.turrcaps_flags = TFL_TURRCAPS_MISSILEKILL | TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
- self.damage_flags |= TFL_DMG_HEADSHAKE;
-
if (turret_stdproc_init("plasma_std") == 0)
{
remove(self);
return;
}
+
+ self.damage_flags |= TFL_DMG_HEADSHAKE;
+ //self.firecheck_flags |= (TFL_FIRECHECK_AFF | TFL_FIRECHECK_VERIFIED);
self.firecheck_flags |= TFL_FIRECHECK_AFF;
+ //self.target_select_flags |= TFL_TARGETSELECT_FOV;
+ //self.target_select_fov = 45;
+
setmodel(self,"models/turrets/base.md3");
setmodel(self.tur_head,"models/turrets/plasma.md3");
@@ -172,6 +182,7 @@
// Custom per turret frame stuff. usualy animation.
self.turret_postthink = turret_plasma_postthink;
+ turret_do_updates(self);
}
@@ -183,16 +194,19 @@
self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
// How to aim at targets
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE | TFL_AIM_GROUND2;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZPREDICT | TFL_AIM_GROUND2 | TFL_AIM_INFRONT;
+ self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
- self.damage_flags |= TFL_DMG_HEADSHAKE;
-
if (turret_stdproc_init("plasma_dual") == 0)
{
remove(self);
return;
}
+ self.damage_flags |= TFL_DMG_HEADSHAKE;
+ self.firecheck_flags |= (TFL_FIRECHECK_AFF | TFL_FIRECHECK_VERIFIED);
+ //self.firecheck_flags |= TFL_FIRECHECK_AFF;
+
setmodel(self,"models/turrets/base.md3");
setmodel(self.tur_head,"models/turrets/plasmad.md3");
@@ -218,6 +232,7 @@
*/
void spawnfunc_turret_plasma()
{
+ g_turrets_common_precash();
//precache_model ("models/turrets/plasma.md3");
//precache_model ("models/turrets/base.md3");
@@ -229,6 +244,7 @@
*/
void spawnfunc_turret_plasma_dual()
{
+
//precache_model ("models/turrets/plasmad.md3");
//precache_model ("models/turrets/base.md3");
Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_walker.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_walker.qc 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/unit_walker.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,36 +1,44 @@
-//#define rocket_rack tur_head.enemy
-
#define ANIM_NO 0
-#define ANIM_WALK 1
-#define ANIM_RUN 1.1
-#define ANIM_STRAFE_L 2
-#define ANIM_STRAFE_R 3
-#define ANIM_TURN 2
-#define ANIM_JUMP 4
-#define ANIM_LAND 5
-#define ANIM_PAIN 6
-#define ANIM_MEELE 7
+#define ANIM_REVERSE 1
+#define ANIM_WALK 2
+#define ANIM_RUN 3
+#define ANIM_STRAFE_L 4
+#define ANIM_STRAFE_R 5
+#define ANIM_TURN 6
+#define ANIM_JUMP 7
+#define ANIM_LAND 8
+#define ANIM_PAIN 9
+#define ANIM_MEELE 10
+#define ANIM_SWIM 11
+#define ANIM_ROAM 12
+#define WVM_IDLE_UP 25
+#define WVM_IDLE 50
+
+#define WVM_PATH 1000
+#define WVM_ENEMY 2000
+#define WVM_STOP 3000
+#define WVM_DODGE 4000
+#define walker_verbs_move verbs_move
+
+#define WVA_MINIGUN 1
+#define WVA_ROCKET 10
+#define WVA_MEELE 20
+#define walker_verbs_attack verbs_attack
+
+#define WVI_IDLE 1
+#define WVI_ROAM 10
+#define walker_verbs_idle verbs_idle
+
.float animflag;
-
.entity wkr_props;
.entity wkr_spawn;
#define WALKER_MIN '-70 -70 5'
#define WALKER_MAX '70 70 70'
-/*
-.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 WALKER_PATH(s,e) pathlib_astar(s,e)
-
float walker_firecheck()
{
return turret_stdproc_firecheck();
@@ -43,84 +51,202 @@
makevectors(self.angles);
where = self.origin + v_forward * 128;
- e = findradius(where,128);
+ e = findradius(where,64);
while (e)
{
if (turret_validate_target(self,e,self.target_validate_flags))
- if (e != self)
+ if (e != self && e.owner != self)
Damage(e,self,self,cvar("g_turrets_unit_walker_std_meele_dmg"),DEATH_TURRET,'0 0 0', v_forward * cvar("g_turrets_unit_walker_std_meele_force") );
e = e.chain;
}
}
+.vector moveto;
+.vector steerto;
void walker_animate()
{
+ vector wish_angle,real_angle;
+ float vz;
+ wish_angle = self.steerto;
+ real_angle = wish_angle - self.angles;
+ vz = self.velocity_z;
+
+ if (self.tur_head.frame != 0)
+ self.tur_head.frame = self.tur_head.frame +1;
+
+ if (self.tur_head.frame > 12)
+ self.tur_head.frame = 0;
+
switch (self.animflag)
{
case ANIM_NO:
if(self.frame != 0)
self.frame = 0;
+
+ movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));
break;
+ case ANIM_REVERSE:
+ if ((self.frame < 5) || (self.frame > 25))
+ self.frame = 5;
+
+ self.frame = self.frame +1;
+ movelib_move_simple(v_forward * -1 ,cvar("g_turrets_unit_walker_speed_walk"),0.6);
+
+ if (self.frame > 25)
+ self.frame = 5;
+ break;
+
+ case ANIM_TURN:
+
+ if (self.frame < 30)
+ self.frame = 30;
+
+ self.frame = self.frame + 1;
+
+ self.angles_y += bound(-15,shortangle_f(real_angle_y,self.angles_y),15);
+
+ movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));
+
+ if (self.frame > 55)
+ self.frame = 35;
+
+ break;
+
case ANIM_WALK:
- self.frame = self.frame + 1;
+ if ((self.frame < 5) || (self.frame > 25))
+ self.frame = 5;
+
+ self.frame = self.frame +1;
+ self.angles_y += bound(-10,shortangle_f(real_angle_y,self.angles_y),10);
+ movelib_move_simple(v_forward ,cvar("g_turrets_unit_walker_speed_walk"),0.6);
+
if (self.frame > 25)
self.frame = 5;
break;
+ case ANIM_ROAM:
+ if ((self.frame < 5) || (self.frame > 25))
+ self.frame = 5;
+
+ self.frame = self.frame +1;
+
+ self.angles_y += bound(-15,shortangle_f(real_angle_y,self.angles_y),15);
+
+ movelib_move_simple(v_forward ,cvar("g_turrets_unit_walker_speed_roam"),0.5);
+
+ if (self.frame > 25)
+ self.frame = 5;
+ break;
+
+ case ANIM_SWIM:
+ if (self.frame < 142)
+ self.frame = 142;
+
+ self.frame = self.frame +1;
+ self.angles_y += bound(-10,shortangle_f(real_angle_y,self.angles_y),10);
+ self.angles_x += bound(-10,shortangle_f(real_angle_x,self.angles_x),10);
+ movelib_move_simple(v_forward, cvar("g_turrets_unit_walker_speed_swim"),0.3);
+ vz = self.velocity_z + sin(time * 4) * 8;
+
+ if (self.frame > 151)
+ self.frame = 146;
+ break;
+
case ANIM_RUN:
- self.frame = self.frame + 2;
+ if ((self.frame < 5) || (self.frame > 25))
+ self.frame = 5;
+
+ self.angles_y += bound(-5,shortangle_f(real_angle_y,self.angles_y),5);
+ movelib_move_simple(v_forward, cvar("g_turrets_unit_walker_speed_run"),0.6);
+
if (self.frame > 25)
self.frame = 5;
break;
case ANIM_STRAFE_L:
- if (self.frame < 35) self.frame = 35;
+ if (self.frame < 30)
+ self.frame = 30;
+
self.frame = self.frame + 1;
- if (self.frame > 55) self.frame = 35;
+ self.angles_y += bound(-2.5,shortangle_f(real_angle_y,self.angles_y),2.5);
+ movelib_move_simple(v_right * -1, cvar("g_turrets_unit_walker_speed_walk"),0.8);
+
+ if (self.frame > 55)
+ self.frame = 35;
break;
case ANIM_STRAFE_R:
- if (self.frame < 65) self.frame = 65;
+ if (self.frame < 60)
+ self.frame = 60;
+
self.frame = self.frame + 1;
- if (self.frame > 85) self.frame = 65;
+ self.angles_y += bound(-2.5,shortangle_f(real_angle_y,self.angles_y),2.5);
+ movelib_move_simple(v_right, cvar("g_turrets_unit_walker_speed_walk"),0.8);
+
+ if (self.frame > 85)
+ self.frame = 65;
+
break;
case ANIM_JUMP:
- if (self.frame < 95) self.frame = 95;
+ if (self.frame < 95)
+ self.frame = 95;
+
+ self.velocity += '0 0 1' * cvar("g_turrets_unit_walker_speed_jump");
+
if (self.frame > 100)
self.frame = self.frame + 1;
break;
case ANIM_LAND:
- if (self.frame < 100) self.frame = 100;
+ if (self.frame < 100)
+ self.frame = 100;
+
self.frame = self.frame + 1;
+
if (self.frame > 107)
self.animflag = ANIM_NO;
+
break;
case ANIM_PAIN:
- if (self.frame < 60) self.frame = 90;
+ if (self.frame < 60)
+ self.frame = 90;
+
self.frame = self.frame + 1;
+
if (self.frame > 95)
self.animflag = ANIM_NO;
+
break;
case ANIM_MEELE:
- if (self.frame < 123) self.frame = 123;
- self.frame = self.frame + 1;
+ movelib_beak_simple(250);
+ if (self.frame < 123)
+ self.frame = 123;
+
+ self.frame = self.frame + 2;
+
if (self.frame == 133)
walker_meele_do_dmg();
if (self.frame > 140)
+ {
self.animflag = ANIM_NO;
+ self.frame = 0;
+ }
+ }
+ self.velocity_z = vz;
- }
+ if(self.flags & FL_ONGROUND)
+ movelib_groundalign4point(300,100);
+
}
@@ -154,7 +280,6 @@
walker_rocket_explode();
}
-//#define WALKER_ROCKET_MOVE movelib_move(newdir * 275,900,0.1,10)
#define WALKER_ROCKET_MOVE movelib_move_simple(newdir,1000,cvar("g_turrets_unit_walker_std_rocket_tunrate")); UpdateCSQCProjectile(self)
void walker_rocket_loop();
void walker_rocket_think()
@@ -202,12 +327,8 @@
// Enemy dead? just keep on the current heading then.
if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
{
-
// Make sure we dont return to tracking a respawned player
self.enemy = world;
-
- // Turn model
- self.angles = vectoangles(self.velocity);
}
if (self.enemy)
@@ -220,12 +341,7 @@
newdir = normalize(self.velocity);
}
- // Turn model
- self.angles = vectoangles(self.velocity);
-
-
WALKER_ROCKET_MOVE;
- //UpdateCSQCProjectile(self);
}
void walker_rocket_loop3()
@@ -270,8 +386,6 @@
self.think = walker_rocket_loop3;
return;
}
-
- self.angles = vectoangles(self.velocity);
newdir = steerlib_pull(self.tur_shotorg);
WALKER_ROCKET_MOVE;
}
@@ -290,9 +404,9 @@
entity rocket;
- //self.angles_x *= -1;
+ self.angles_x *= -1;
makevectors(self.angles);
- //self.angles_x *= -1;
+ self.angles_x *= -1;
te_explosion (org);
@@ -325,7 +439,7 @@
rocket.nextthink = time;// + 0.25;
rocket.movetype = MOVETYPE_FLY;
- rocket.velocity = normalize((v_forward + v_up * 0.25) + (randomvec() * 0.1)) * cvar("g_turrets_unit_walker_std_rocket_speed");
+ rocket.velocity = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * cvar("g_turrets_unit_walker_std_rocket_speed");
rocket.angles = vectoangles(rocket.velocity);
rocket.touch = walker_rocket_explode;
rocket.flags = FL_PROJECTILE;
@@ -335,15 +449,6 @@
CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
}
-/*
-#define s_turn 10
-#define s_walk 100
-#define s_run 300
-#define s_accel1 8
-#define s_accel2 16
-#define s_decel 8
-*/
-
void rv_think()
{
float f;
@@ -369,7 +474,7 @@
else
f = gettagindex(self.owner,"tag_rocket02");
- org = self.owner.origin + gettaginfo_relative(self.owner,f);
+ org = gettaginfo(self.owner,f);
self.nextthink = time + 0.2;
oldself = self;
@@ -379,68 +484,110 @@
}
/*
-void acb_run()
+void walker_move()
{
- //bprint("run\n");
- animation_set(self,5,25,40,AF_ENDCALLBACK,5);
-}
-void acb_walk()
-{
- bprint("walk\n");
- animation_set(self,5,25,20,AF_ENDCALLBACK,5);
-}
-void acb_meele()
-{
- walker_do_meele();
-}
+ vector major,minor,f,b,l,r;
+ float lf,lb,lr,ll,bl,tl;
-void set_acb(void() acb_func)
-{
- self.animator_callback = acb_func;
- if(animation_query(self) != AS_RUNNING)
+ if(self.animflag == ANIM_MEELE)
+ return;
+
+ tl = vlen(self.origin - self.moveto);
+ switch(self.waterlevel)
{
- bprint("Not running\n");
- acb_func();
+ case 0:
+ self.animflag = ANIM_WALK;
+ case 1:
+ case 2:
+ if(self.animflag == ANIM_WALK)
+ self.animflag = ANIM_WALK;
+ else
+ self.animflag = ANIM_SWIM;
+ break;
+ case 3:
+ self.animflag = ANIM_SWIM;
}
+
+ if(self.animflag == ANIM_SWIM)
+ {
+ self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95));
+ return;
+ }
+
+ if(tl < 250)
+ {
+ self.animflag = ANIM_WALK;
+ }
else
{
- if not(self.animator.anim_flags & AF_ENDCALLBACK)
- self.animator.anim_flags = self.animator.anim_flags | AF_ENDCALLBACK;
+ self.animflag = ANIM_RUN;
}
+
+ self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95));
+ f = self.origin + v_forward;
+ lf = vlen(self.moveto - f);
+ bl = lf;
+ major = v_forward;
+ minor = major;
+
+ b = self.origin - v_forward;
+ lb = vlen(self.moveto - b);
+ if(bl > lb)
+ {
+ minor = major;
+ major = v_forward * -1;
+ bl = lb;
+ }
+
+ r = self.origin + v_right;
+ lr = vlen(self.moveto - r);
+ if(bl > lr)
+ {
+
+ minor = major;
+ major = v_right;
+ bl = lr;
+ self.steerto = vectoangles(v_right);
+ self.animflag = ANIM_STRAFE_R;
+
+ }
+
+ l = self.origin - v_right;
+ ll = vlen(self.moveto - l);
+ if(bl > ll)
+ {
+
+ minor = major;
+ major = v_right * -1;
+ bl = ll;
+ self.steerto = vectoangles(v_right*-1);
+ self.animflag = ANIM_STRAFE_L;
+
+ }
+
}
*/
-void walker_postthink()
+float walker_moveverb_path(float eval)
{
- vector wish_angle;
- vector real_angle;
- vector steer;
- float vel;
-
- //if (self.flags & FL_ONGROUND)
- //if (self.animflag != ANIM_MEELE)
- // self.animflag = ANIM_NO;
-
- if (self.tur_head.attack_finished_single < time)
- if (self.enemy)
+ if(eval)
{
- entity rv;
+ if(self.animflag == ANIM_MEELE)
+ return VS_CALL_NO;
- rv = spawn();
- rv.think = rv_think;
- rv.nextthink = time;
- rv.cnt = 4;
- rv.owner = self;
+ if(self.pathcurrent)
+ return verb.verb_static_value;
- self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");
+ return VS_CALL_NO;
}
// Do we have a path?
- if (self.pathcurrent)
+ if not(self.pathcurrent)
{
- //set_acb(acb_walk);
- self.animflag = ANIM_WALK;
-
+ return VS_CALL_NO;
+ }
+ else
+ {
// Are we close enougth to a path node to switch to the next?
if (vlen(self.origin - self.pathcurrent.origin) < 64)
if (self.pathcurrent.path_next == world)
@@ -456,7 +603,7 @@
if(self.pathgoal.enemy)
{
- self.pathcurrent = pathlib_makepath(self.pathgoal.origin,self.pathgoal.enemy.origin,PFL_GROUNDSNAP,1500,2,PT_QUICKBOX);
+ self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
self.pathgoal = self.pathgoal.enemy;
}
}
@@ -465,105 +612,236 @@
}
else
self.pathcurrent = self.pathcurrent.path_next;
+ }
- steer = steerlib_attract2(self.pathcurrent.origin,0.5,2000,0.95);
- vel = 150;
- }
- else // Roaming mode
+
+ if (self.pathcurrent)
{
- if (self.enemy)
+ switch(self.waterlevel)
{
- wish_angle = angleofs(self,self.enemy);
- steer = steerlib_pull(self.enemy.origin);
-
- if (self.tur_dist_aimpos < cvar("g_turrets_unit_walker_std_meele_range"))
- {
- if (fabs(wish_angle_y) < 15)
- {
- vel = 0;
- //set_acb(acb_meele);
- //walker_do_meele();
- self.animflag = ANIM_MEELE;
- return;
- }
- }
- else
- {
- if (fabs(wish_angle_y) < 15)
- {
- //set_acb(acb_run);
- self.animflag = ANIM_RUN;
- vel = 300;
- }
- else if (fabs(wish_angle_y) < 30)
- {
- //set_acb(acb_walk);
+ case 0:
+ self.animflag = ANIM_WALK;
+ case 1:
+ case 2:
+ if(self.animflag == ANIM_WALK)
self.animflag = ANIM_WALK;
- vel = 150;
- }
else
- {
- //set_acb(acb_walk);
- self.animflag = ANIM_WALK;
- vel = 50;
- }
- }
+ self.animflag = ANIM_SWIM;
+ break;
+ case 3:
+ self.animflag = ANIM_SWIM;
}
- else
- {
- vel = 0;
- if(self.animflag != ANIM_MEELE)
- self.animflag = ANIM_NO;
- }
+ self.moveto = self.pathcurrent.origin;
+ self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95));
+
+ return VS_CALL_YES_DOING;
}
+ else
+ return VS_CALL_YES_DONE;
+}
- // Align the walker to the ground
+float walker_moveverb_enemy(float eval)
+{
+ if(eval)
+ {
+ if(self.animflag == ANIM_MEELE)
+ return VS_CALL_NO;
- self.angles_x = self.angles_x * -1;
- makevectors(self.angles);
- self.angles_x = self.angles_x * -1;
+ if(self.enemy == world)
+ return VS_CALL_NO;
- traceline(self.origin + '0 0 15', self.origin - '0 0 150' ,MOVE_WORLDONLY,self);
- wish_angle = (trace_endpos);
- traceline(self.origin + v_forward * 10 + '0 0 15', self.origin + v_forward * 10 - '0 0 150' ,MOVE_WORLDONLY,self);
- real_angle = vectoangles(normalize( trace_endpos - wish_angle));
+ if(tracewalk(self.enemy, self.origin, self.mins, self.maxs, self.enemy.origin, MOVE_NORMAL))
+ return verb.verb_static_value;
- self.angles_x = real_angle_x;
- self.angles_z = real_angle_z;
+ return VS_CALL_NO;
+ }
- if(vel == 0)
+ switch(self.waterlevel)
{
- self.velocity = '0 0 0';
- //animator_remove(self);
+ case 0:
+ if(self.tur_dist_enemy > 500)
+ self.animflag = ANIM_RUN;
+ else
+ self.animflag = ANIM_WALK;
+ case 1:
+ case 2:
+ if(self.animflag == ANIM_WALK)
+ self.animflag = ANIM_WALK;
+ else
+ self.animflag = ANIM_SWIM;
+ break;
+ case 3:
+ self.animflag = ANIM_SWIM;
}
- else
+
+ self.moveto = self.enemy.origin;
+ self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95));
+
+ return VS_CALL_YES_DOING;
+}
+
+float walker_moveverb_idle_pause(float eval)
+{
+ if(eval)
{
- steer = steer * 0.5 + steerlib_traceavoid(0.3,256);
- float vz;
- vz = self.velocity_z;
- movelib_move_simple(steer * 200,vel,0.5);
- self.velocity_z = vz;
+ if(self.animflag == ANIM_MEELE)
+ return VS_CALL_NO;
- wish_angle = vectoangles(self.velocity);
+ return verb.verb_static_value;
- real_angle = wish_angle - self.angles;
+ }
- real_angle_y = shortangle_f(real_angle_y,self.angles_y);
+ self.moveto = self.origin;
+ self.steerto = v_forward;
+ self.animflag = ANIM_NO;
- self.angles_y = self.angles_y + bound(-5,real_angle_y,5);
+ return VS_CALL_YES_DOING;
+}
+
+float walker_moveverb_idle_roam(float eval)
+{
+ if(eval)
+ {
+ if(self.animflag == ANIM_MEELE)
+ return VS_CALL_NO;
+
+ return verb.verb_static_value;
}
- walker_animate();
- if (self.tur_head.frame != 0)
- self.tur_head.frame = self.tur_head.frame +1;
+ vector v;
+ v_x = (random() * 32) - (random() * 32);
+ v_y = (random() * 32) - (random() * 32);
+ v = self.origin + v_forward * 64 + v;
+ self.pos1 = self.pos1 * 0.9 + v * 0.1;
- if (self.tur_head.frame > 12)
- self.tur_head.frame = 0;
+ self.moveto = self.origin + v_forward * 10;
+ v = self.angles;
+ v_y += random() * 15;
+ v_y -= random() * 15;
+ self.steerto = v;
+ switch(self.waterlevel)
+ {
+ case 0:
+ self.animflag = ANIM_ROAM;
+ case 1:
+ case 2:
+ if(self.animflag != ANIM_SWIM)
+ self.animflag = ANIM_ROAM;
+
+ break;
+ case 3:
+ self.animflag = ANIM_SWIM;
+ }
+
+ return VS_CALL_YES_DOING;
}
+float walker_moveverb_idle(float eval)
+{
+ if(eval)
+ {
+ if(self.animflag == ANIM_MEELE)
+ return VS_CALL_NO;
+
+ return verb.verb_static_value;
+ }
+
+ if(verb.wait < time)
+ {
+ verb.wait = random() * 10;
+
+ if(random() < 0.5)
+ verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause, WVM_IDLE + WVM_IDLE_UP, verb.wait);
+ else
+ verbstack_push(self.walker_verbs_move, walker_moveverb_idle_roam, WVM_IDLE + WVM_IDLE_UP, verb.wait);
+
+ verb.wait += time;
+ }
+
+ return VS_CALL_YES_DOING;
+}
+float walker_attackverb_meele(float eval)
+{
+ if(eval)
+ {
+ if(cvar("g_turrets_nofire"))
+ return VS_CALL_NO;
+
+ if(self.animflag == ANIM_SWIM || self.animflag == ANIM_MEELE)
+ return VS_CALL_NO;
+
+ if(!self.enemy)
+ return VS_CALL_NO;
+
+ vector wish_angle;
+ wish_angle = angleofs(self,self.enemy);
+
+ if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_meele_range"))
+ if (fabs(wish_angle_y) < 15)
+ return verb.verb_static_value;
+
+ return VS_CALL_NO;
+ }
+
+ self.moveto = self.enemy.origin;
+ self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95));
+
+ self.animflag = ANIM_MEELE;
+
+ return VS_CALL_YES_DOING;
+}
+
+float walker_attackverb_rockets(float eval)
+{
+ if(eval)
+ {
+ if (self.tur_head.attack_finished_single > time)
+ return VS_CALL_NO;
+
+ if not(self.enemy)
+ return VS_CALL_NO;
+
+ if (cvar("g_turrets_nofire"))
+ return VS_CALL_NO;
+
+ if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_rockets_range_min"))
+ return VS_CALL_NO;
+
+ if (self.tur_dist_enemy > cvar("g_turrets_unit_walker_std_rockets_range"))
+ return VS_CALL_NO;
+
+ return verb.verb_static_value;
+ }
+
+ entity rv;
+ rv = spawn();
+ rv.think = rv_think;
+ rv.nextthink = time;
+ rv.cnt = 4;
+ rv.owner = self;
+
+ self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");
+
+ return VS_CALL_YES_DONE;
+
+}
+
+void walker_postthink()
+{
+
+ self.angles_x *= -1;
+ makevectors(self.angles);
+ self.angles_x *= -1;
+
+ verbstack_pop(self.walker_verbs_attack);
+ verbstack_pop(self.walker_verbs_move);
+
+ walker_animate();
+}
+
void walker_attack()
{
entity flash;
@@ -574,13 +852,13 @@
sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
- fireBallisticBullet (self.tur_shotorg_updated, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant"));
- te_smallflash(self.tur_shotorg_updated);
+ fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant"));
+ //te_smallflash(self.tur_shotorg_updated);
if (!(self.uzi_bulletcounter & 3))
{
- trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);
+ //trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);
// te_lightning1(self,self.tur_shotorg_updated,trace_endpos);
flash = spawn();
setmodel(flash, "models/uziflash.md3"); // precision set below
@@ -603,15 +881,13 @@
vector vtmp;
entity e;
- //load_unit_settings(self.rocket_rack,"walker_std_rocket",1);
-
self.origin = self.wkr_spawn.origin;
self.wkr_props.solid = SOLID_BBOX;
self.wkr_props.alpha = 1;
self.angles = self.wkr_spawn.angles;
- vtmp = self.origin;
- vtmp_z +=self.wkr_spawn.origin_z + self.wkr_spawn.maxs_z;
+ vtmp = self.wkr_spawn.origin;
+ vtmp_z += self.wkr_spawn.maxs_z;
setorigin(self,vtmp);
if (self.target != "")
@@ -619,7 +895,7 @@
e = find(world,targetname,self.target);
if (!e)
{
- bprint("Warning! initital waypoint for Walker does NOT exsist!\n");
+ dprint("Warning! initital waypoint for Walker does NOT exsist!\n");
self.target = "";
}
@@ -627,15 +903,13 @@
dprint("Warning: not a turrret path\n");
else
{
- self.pathcurrent = pathlib_makepath(self.origin,e.origin,PFL_GROUNDSNAP,500,2,PT_QUICKBOX);
+ self.pathcurrent = WALKER_PATH(self.origin,e.origin);
self.pathgoal = e;
}
}
}
void walker_diehook()
{
- //animator_remove(self);
-
if(self.pathcurrent)
pathlib_deletepath(self.pathcurrent.owner);
@@ -646,15 +920,15 @@
if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
{
-
remove(self.wkr_props);
- //remove(self.rocket_rack);
remove(self.wkr_spawn);
+ remove(self.walker_verbs_move);
+ remove(self.walker_verbs_attack);
+ remove(self.walker_verbs_idle);
}
}
-//.string target_start;
void turret_walker_dinit()
{
@@ -662,14 +936,19 @@
if (self.netname == "") self.netname = "Walker Turret";
-
self.wkr_props = spawn();
self.wkr_spawn = spawn();
self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
- self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM | TFL_TURRCAPS_LINKED;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE | TFL_AIM_SHOTTIMECOMPENSATE;
+ self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_HEADATTACHED;
+ self.aim_flags = TFL_AIM_LEAD;
+ if(cvar("g_antilag_bullets"))
+ self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
+ else
+ self.aim_flags |= TFL_AIM_SHOTTIMECOMPENSATE;
+
+
self.turret_respawnhook = walker_respawnhook;
self.turret_diehook = walker_diehook;
@@ -679,10 +958,22 @@
remove(self);
return;
}
- self.damage_flags |= RFL_DMG_DEATH_NOGIBS;
+ self.walker_verbs_move = spawn();
+ self.walker_verbs_attack = spawn();
+ self.walker_verbs_idle = spawn();
+
+ verbstack_push(self.walker_verbs_move, walker_moveverb_idle, WVM_IDLE, 0);
+ verbstack_push(self.walker_verbs_move, walker_moveverb_enemy, WVM_ENEMY, 0);
+ verbstack_push(self.walker_verbs_move, walker_moveverb_path, WVM_PATH, 0);
+
+ verbstack_push(self.walker_verbs_attack, walker_attackverb_meele, WVA_MEELE, 0);
+ verbstack_push(self.walker_verbs_attack, walker_attackverb_rockets, WVA_ROCKET, 0);
+
+ self.damage_flags |= TFL_DMG_DEATH_NOGIBS;
+
self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;// | TFL_TARGETSELECT_LOS;
+ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
//self.flags = FL_CLIENT;
self.iscreature = TRUE;
@@ -690,47 +981,28 @@
self.solid = SOLID_SLIDEBOX;
self.takedamage = DAMAGE_AIM;
+ setmodel(self,"models/turrets/walker_body.md3");
+ setmodel(self.tur_head,"models/turrets/walker_head_minigun.md3");
setmodel(self.wkr_props,"models/turrets/walker_props.md3");
setmodel(self.wkr_spawn,"models/turrets/walker_spawn.md3");
setorigin(self.wkr_spawn,self.origin);
+ setattachment(self.tur_head,self,"tag_head");
+ setattachment(self.wkr_props,self,"tag_head");
self.wkr_spawn.angles = self.angles;
self.wkr_spawn.solid = SOLID_NOT;
-
- traceline(self.wkr_spawn.origin + '0 0 16', self.wkr_spawn.origin - '0 0 10000', MOVE_NOMONSTERS, self);
+ traceline(self.wkr_spawn.origin + '0 0 16', self.wkr_spawn.origin - '0 0 10000', MOVE_WORLDONLY, self);
setorigin(self.wkr_spawn,trace_endpos + '0 0 4');
setorigin(self,self.wkr_spawn.origin);
- setmodel(self,"models/turrets/walker_body.md3");
- setmodel(self.tur_head,"models/turrets/walker_head_minigun.md3");
-
- setattachment(self.tur_head,self,"tag_head");
- setattachment(self.wkr_props,self,"tag_head");
-
- vector v;
- float f;
- f = gettagindex(self.tur_head,"tag_fire");
- v = gettaginfo_relative(self.tur_head,f);
- v_y = v_y * -1;
-
setsize(self,WALKER_MIN,WALKER_MAX);
- //setsize(self,'-70 -70 0','70 70 55');
- self.tur_shotorg = v;
- self.tur_aimorg = v;// + '0 0 10';
-
self.idle_aim = '0 0 0';
+ self.turret_firecheckfunc = walker_firecheck;
+ self.turret_firefunc = walker_attack;
+ self.turret_postthink = walker_postthink;
-// self.v_home = self.origin;
-
- self.turret_firecheckfunc = walker_firecheck;
-
- // Our fire routine
- self.turret_firefunc = walker_attack;
-
- self.turret_postthink = walker_postthink;
-
if (self.target != "")
{
e = find(world,targetname,self.target);
@@ -744,7 +1016,7 @@
dprint("Warning: not a turrret path\n");
else
{
- self.pathcurrent = pathlib_makepath(self.origin,e.origin,PFL_GROUNDSNAP,500,2,PT_QUICKBOX);
+ self.pathcurrent = WALKER_PATH(self.origin,e.origin);
self.pathgoal = e;
}
}
@@ -756,12 +1028,13 @@
void spawnfunc_turret_walker()
{
+ g_turrets_common_precash();
precache_model ("models/turrets/walker_head_minigun.md3");
precache_model ("models/turrets/walker_body.md3");
precache_model ("models/turrets/walker_props.md3");
precache_model ("models/turrets/walker_spawn.md3");
precache_model ( "models/turrets/rocket.md3");
-
+ precache_sound ( "weapons/rocket_impact.wav" );
self.think = turret_walker_dinit;
self.nextthink = time + 0.5;
}
Copied: branches/nexuiz-2.0/data/qcsrc/server/verbstack.qc (from rev 6250, trunk/data/qcsrc/server/verbstack.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/verbstack.qc (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/server/verbstack.qc 2009-03-22 21:23:04 UTC (rev 6251)
@@ -0,0 +1,111 @@
+entity verb;
+.entity verbs_idle;
+.entity verbs_attack;
+.entity verbs_move;
+
+.float(float eval) verb_call;
+.entity verbstack;
+.float verb_static_value;
+
+#define VS_CALL_NO 0
+#define VS_CALL_YES_DOING -1
+#define VS_CALL_YES_DONE -2
+#define VS_CALL_REMOVE -3
+
+entity verbstack_push(entity stack, float(float eval) vrb_call, float val_static, float vrb_life)
+{
+ entity vrb;
+
+ vrb = spawn();
+ vrb.owner = self;
+ vrb.verbstack = stack;
+ vrb.verb_call = vrb_call;
+ vrb.verb_static_value = val_static;
+
+ if(vrb_life)
+ {
+ vrb.think = SUB_Remove;
+ vrb.nextthink = time + vrb_life;
+ }
+
+ return vrb;
+}
+
+float verbstack_pop(entity stack)
+{
+ entity vrb;
+ entity bestverb,oldself;
+ float value,bestvalue;
+
+ oldself = self;
+
+ vrb = findchainentity(verbstack,stack);
+ while(vrb)
+ {
+ verb = vrb;
+ self = vrb.owner;
+ value = vrb.verb_call(TRUE);
+ if(value < 0)
+ {
+ if(value == VS_CALL_REMOVE)
+ remove(vrb);
+ }
+ else
+ {
+ if(value > bestvalue)
+ {
+ bestverb = vrb;
+ bestvalue = value;
+ }
+ }
+ vrb = vrb.chain;
+ }
+
+ if(bestverb)
+ {
+ verb = bestverb;
+ self = verb.owner;
+ value = bestverb.verb_call(FALSE);
+ if(value == VS_CALL_REMOVE)
+ remove(bestverb);
+ }
+
+ self = oldself;
+
+ return value;
+}
+
+entity verbstack_pull(entity stack)
+{
+ entity vrb;
+ entity bestverb,oldself;
+ float value,bestvalue;
+
+ oldself = self;
+
+ vrb = findchainentity(verbstack,stack);
+ while(vrb)
+ {
+ self = vrb.owner;
+ verb = vrb;
+ value = vrb.verb_call(TRUE);
+ if(value > 0)
+ {
+ if(value == VS_CALL_REMOVE)
+ remove(vrb);
+ }
+ else
+ {
+ if(value > bestvalue)
+ {
+ bestverb = vrb;
+ bestvalue = value;
+ }
+ }
+ vrb =vrb.chain;
+ }
+
+ self = oldself;
+
+ return bestverb;
+}
Copied: branches/nexuiz-2.0/data/scripts/cel.shader (from rev 6250, trunk/data/scripts/cel.shader)
===================================================================
--- branches/nexuiz-2.0/data/scripts/cel.shader (rev 0)
+++ branches/nexuiz-2.0/data/scripts/cel.shader 2009-03-22 21:23:04 UTC (rev 6251)
@@ -0,0 +1,480 @@
+textures/cel/black_ink
+{
+ qer_editorimage gfx/colors/black.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/black.tga
+ rgbGen identity
+ }
+}
+textures/cel/blue_ink
+{
+ qer_editorimage gfx/colors/blue.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/blue.tga
+ rgbGen identity
+ }
+}
+textures/cel/cyan_ink
+{
+ qer_editorimage gfx/colors/cyan.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/cyan.tga
+ rgbGen identity
+ }
+}
+textures/cel/green_ink
+{
+ qer_editorimage gfx/colors/green.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/green.tga
+ rgbGen identity
+ }
+}
+textures/cel/pink_ink
+{
+ qer_editorimage gfx/colors/pink.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/pink.tga
+ rgbGen identity
+ }
+}
+textures/cel/red_ink
+{
+ qer_editorimage gfx/colors/red.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/red.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-0_ink
+{
+ qer_editorimage gfx/colors/vga-0.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-0.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-1_ink
+{
+ qer_editorimage gfx/colors/vga-1.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-1.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-2_ink
+{
+ qer_editorimage gfx/colors/vga-2.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-2.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-3_ink
+{
+ qer_editorimage gfx/colors/vga-3.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-3.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-4_ink
+{
+ qer_editorimage gfx/colors/vga-4.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-4.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-5_ink
+{
+ qer_editorimage gfx/colors/vga-5.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-5.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-6_ink
+{
+ qer_editorimage gfx/colors/vga-6.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-6.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-7_ink
+{
+ qer_editorimage gfx/colors/vga-7.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-7.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-8_ink
+{
+ qer_editorimage gfx/colors/vga-8.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-8.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-9_ink
+{
+ qer_editorimage gfx/colors/vga-9.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-9.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-a_ink
+{
+ qer_editorimage gfx/colors/vga-a.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-a.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-b_ink
+{
+ qer_editorimage gfx/colors/vga-b.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-b.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-c_ink
+{
+ qer_editorimage gfx/colors/vga-c.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-c.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-d_ink
+{
+ qer_editorimage gfx/colors/vga-d.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-d.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-e_ink
+{
+ qer_editorimage gfx/colors/vga-e.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-e.tga
+ rgbGen identity
+ }
+}
+textures/cel/vga-f_ink
+{
+ qer_editorimage gfx/colors/vga-f.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/vga-f.tga
+ rgbGen identity
+ }
+}
+textures/cel/white_ink
+{
+ qer_editorimage gfx/colors/white.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/white.tga
+ rgbGen identity
+ }
+}
+textures/cel/yellow_ink
+{
+ qer_editorimage gfx/colors/yellow.tga
+ q3map_notjunc
+ q3map_nonplanar
+ q3map_bounce 0.0
+ q3map_shadeangle 120
+ q3map_texturesize 1 1
+ q3map_invert
+ q3map_offset -2.0
+ surfaceparm nolightmap
+ surfaceparm trans
+ surfaceparm nonsolid
+ surfaceparm nomarks
+ cull back
+ {
+ map gfx/colors/yellow.tga
+ rgbGen identity
+ }
+}
Modified: branches/nexuiz-2.0/data/scripts/shaderlist.txt
===================================================================
--- branches/nexuiz-2.0/data/scripts/shaderlist.txt 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/scripts/shaderlist.txt 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,5 +1,6 @@
accident
blacksky
+cel
common
desertfactory
domination
Modified: branches/nexuiz-2.0/data/turrets.cfg
===================================================================
--- branches/nexuiz-2.0/data/turrets.cfg 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/turrets.cfg 2009-03-22 21:23:04 UTC (rev 6251)
@@ -50,5 +50,5 @@
// not exec'd: gauss
-set g_turrets_reloadcvars 1 // reload when this cfg has been exec'd
+set g_turrets_reloadcvars 0 // reload when this cfg has been exec'd
alias g_turrets_reload "set g_turrets_reloadcvars 1"
Modified: branches/nexuiz-2.0/data/unit_flac.cfg
===================================================================
--- branches/nexuiz-2.0/data/unit_flac.cfg 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/unit_flac.cfg 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,19 +1,19 @@
set g_turrets_unit_flac_std_health 700
set g_turrets_unit_flac_std_respawntime 90
-set g_turrets_unit_flac_std_shot_dmg 50
+set g_turrets_unit_flac_std_shot_dmg 25
set g_turrets_unit_flac_std_shot_refire 0.2
-set g_turrets_unit_flac_std_shot_radius 190
-set g_turrets_unit_flac_std_shot_speed 3000
-set g_turrets_unit_flac_std_shot_spread 0.0125
-set g_turrets_unit_flac_std_shot_force 50
+set g_turrets_unit_flac_std_shot_radius 150
+set g_turrets_unit_flac_std_shot_speed 2500
+set g_turrets_unit_flac_std_shot_spread 0.05
+set g_turrets_unit_flac_std_shot_force 15
set g_turrets_unit_flac_std_shot_volly 0
set g_turrets_unit_flac_std_shot_volly_refire 0
set g_turrets_unit_flac_std_target_range 4000
set g_turrets_unit_flac_std_target_range_min 500
set g_turrets_unit_flac_std_target_range_fire 3900
-set g_turrets_unit_flac_std_target_range_optimal 100
+set g_turrets_unit_flac_std_target_range_optimal 1250
set g_turrets_unit_flac_std_target_select_rangebias 0.25
set g_turrets_unit_flac_std_target_select_samebias 0.25
@@ -25,9 +25,9 @@
set g_turrets_unit_flac_std_ammo 500
set g_turrets_unit_flac_std_ammo_recharge 100
-set g_turrets_unit_flac_std_aim_firetolerance_dist 300
+set g_turrets_unit_flac_std_aim_firetolerance_dist 150
set g_turrets_unit_flac_std_aim_firetolerance_angle 5
-set g_turrets_unit_flac_std_aim_speed 120
+set g_turrets_unit_flac_std_aim_speed 360
set g_turrets_unit_flac_std_aim_maxrot 360
set g_turrets_unit_flac_std_aim_maxpitch 35
Modified: branches/nexuiz-2.0/data/unit_fusreac.cfg
===================================================================
--- branches/nexuiz-2.0/data/unit_fusreac.cfg 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/unit_fusreac.cfg 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,6 +1,7 @@
set g_turrets_unit_fusreac_std_health 700
set g_turrets_unit_fusreac_std_respawntime 90
+set g_turrets_unit_fusreac_std_shot_speed 1
set g_turrets_unit_fusreac_std_shot_dmg 50
set g_turrets_unit_fusreac_std_shot_refire 0.1
Modified: branches/nexuiz-2.0/data/unit_machinegun.cfg
===================================================================
--- branches/nexuiz-2.0/data/unit_machinegun.cfg 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/unit_machinegun.cfg 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,14 +1,14 @@
set g_turrets_unit_machinegun_std_health 256
set g_turrets_unit_machinegun_std_respawntime 60
-set g_turrets_unit_machinegun_std_shot_dmg 15
-set g_turrets_unit_machinegun_std_shot_refire 0.05
-set g_turrets_unit_machinegun_std_shot_spread 0.05
+set g_turrets_unit_machinegun_std_shot_dmg 30
+set g_turrets_unit_machinegun_std_shot_refire 0.2
+set g_turrets_unit_machinegun_std_shot_spread 0.015
set g_turrets_unit_machinegun_std_shot_force 20
set g_turrets_unit_machinegun_std_shot_radius 0
set g_turrets_unit_machinegun_std_shot_speed 34920
-set g_turrets_unit_machinegun_std_shot_volly 5
-set g_turrets_unit_machinegun_std_shot_volly_refire 0.5
+set g_turrets_unit_machinegun_std_shot_volly 0
+set g_turrets_unit_machinegun_std_shot_volly_refire 0.6
set g_turrets_unit_machinegun_std_target_range 4500
set g_turrets_unit_machinegun_std_target_range_min 2
Modified: branches/nexuiz-2.0/data/unit_mlrs.cfg
===================================================================
--- branches/nexuiz-2.0/data/unit_mlrs.cfg 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/unit_mlrs.cfg 2009-03-22 21:23:04 UTC (rev 6251)
@@ -26,7 +26,7 @@
set g_turrets_unit_mlrs_std_ammo 420
set g_turrets_unit_mlrs_std_ammo_recharge 35
-set g_turrets_unit_mlrs_std_aim_firetolerance_dist 50
+set g_turrets_unit_mlrs_std_aim_firetolerance_dist 125
set g_turrets_unit_mlrs_std_aim_firetolerance_angle 5
set g_turrets_unit_mlrs_std_aim_speed 120
set g_turrets_unit_mlrs_std_aim_maxrot 360
Modified: branches/nexuiz-2.0/data/unit_plasma.cfg
===================================================================
--- branches/nexuiz-2.0/data/unit_plasma.cfg 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/unit_plasma.cfg 2009-03-22 21:23:04 UTC (rev 6251)
@@ -63,6 +63,6 @@
set g_turrets_unit_plasma_std_track_type 3
// Following controls how _track_type = 3 works.
set g_turrets_unit_plasma_std_track_accel_pitch 0.25
-set g_turrets_unit_plasma_std_track_accel_rot 0.5
-set g_turrets_unit_plasma_std_track_blendrate 0.25
+set g_turrets_unit_plasma_std_track_accel_rot 0.75
+set g_turrets_unit_plasma_std_track_blendrate 0.2
Modified: branches/nexuiz-2.0/data/unit_walker.cfg
===================================================================
--- branches/nexuiz-2.0/data/unit_walker.cfg 2009-03-22 18:39:18 UTC (rev 6250)
+++ branches/nexuiz-2.0/data/unit_walker.cfg 2009-03-22 21:23:04 UTC (rev 6251)
@@ -1,25 +1,25 @@
set g_turrets_unit_walker_std_health 500
set g_turrets_unit_walker_std_respawntime 60
-// dgr / sec
-set g_turrets_unit_walker_turn_turnrate 90
-set g_turrets_unit_walker_walk_turnrate 45
-set g_turrets_unit_walker_run_turnrate 22.5
+set g_turrets_unit_walker_speed_run 350
+set g_turrets_unit_walker_speed_roam 100
+set g_turrets_unit_walker_speed_walk 250
+set g_turrets_unit_walker_speed_swim 250
+set g_turrets_unit_walker_speed_jump 790
+set g_turrets_unit_walker_speed_stop 200
// Main machineguns prop's
-set g_turrets_unit_walker_std_shot_dmg 10
-set g_turrets_unit_walker_std_shot_refire 0.1
-set g_turrets_unit_walker_std_shot_spread 0.035
+set g_turrets_unit_walker_std_shot_dmg 6
+set g_turrets_unit_walker_std_shot_refire 0.05
+set g_turrets_unit_walker_std_shot_spread 0.015
set g_turrets_unit_walker_std_shot_force 5
set g_turrets_unit_walker_std_shot_radius 0
set g_turrets_unit_walker_std_shot_speed 18000
-set g_turrets_unit_walker_std_shot_volly 5
+set g_turrets_unit_walker_std_shot_volly 10
set g_turrets_unit_walker_std_shot_volly_refire 0.5
-// Note this is the effective range for rocket engagement
-set g_turrets_unit_walker_std_target_range 5500
-
+set g_turrets_unit_walker_std_target_range 5000
set g_turrets_unit_walker_std_target_range_fire 2000
set g_turrets_unit_walker_std_target_range_optimal 100
set g_turrets_unit_walker_std_target_range_min 0
@@ -43,6 +43,8 @@
set g_turrets_unit_walker_std_track_type 1
// "Wobbly" homing rockets that sometimes loop
+set g_turrets_unit_walker_std_rockets_range 4000
+set g_turrets_unit_walker_std_rockets_range_min 500
set g_turrets_unit_walker_std_rocket_refire 10
set g_turrets_unit_walker_std_rocket_dmg 50
set g_turrets_unit_walker_std_rocket_radius 150
@@ -53,5 +55,5 @@
// Meele attack. Only happens when theres a target directly in front
set g_turrets_unit_walker_std_meele_range 150
-set g_turrets_unit_walker_std_meele_dmg 500
+set g_turrets_unit_walker_std_meele_dmg 200
set g_turrets_unit_walker_std_meele_force 600
\ No newline at end of file
More information about the nexuiz-commits
mailing list