[nexuiz-commits] r6318 - trunk/data/qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Fri Mar 27 04:57:06 EDT 2009
Author: tzork
Date: 2009-03-27 04:57:06 -0400 (Fri, 27 Mar 2009)
New Revision: 6318
Modified:
trunk/data/qcsrc/server/movelib.qc
trunk/data/qcsrc/server/pathlib.qc
trunk/data/qcsrc/server/steerlib.qc
trunk/data/qcsrc/server/verbstack.qc
Log:
Lib updates
Modified: trunk/data/qcsrc/server/movelib.qc
===================================================================
--- trunk/data/qcsrc/server/movelib.qc 2009-03-27 08:56:37 UTC (rev 6317)
+++ trunk/data/qcsrc/server/movelib.qc 2009-03-27 08:57:06 UTC (rev 6318)
@@ -1,102 +1,104 @@
-/**
- Simulate drag
- self.velocity = movelib_vdrag(self.velocity,0.02,0.5);
-**/
-vector movelib_dragvec(float drag, float exp)
-{
- float lspeed,ldrag;
-
- lspeed = vlen(self.velocity);
- ldrag = lspeed * drag;
- ldrag = ldrag * (drag * exp);
- ldrag = 1 - (ldrag / lspeed);
-
- return self.velocity * ldrag;
-}
-
-/**
- Simulate drag
- self.velocity = movelib_vdrag(somespeed,0.01,0.7);
-**/
-float movelib_dragflt(float fspeed,float drag,float exp)
-{
- float ldrag;
-
- ldrag = fspeed * drag;
- ldrag = ldrag * ldrag * exp;
- ldrag = 1 - (ldrag / fspeed);
-
- return ldrag;
-}
-
-/**
- Do a inertia simulation based on velocity.
- Basicaly, this allows you to simulate 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)
-{
- float influense;
-
- influense = vlen(self.velocity) * (1 / vel_max);
-
- influense = bound(newmin,influense,oldmax);
-
- return (vel_new * (1 - influense)) + (self.velocity * influense);
-}
-
-vector movelib_inertmove(vector new_vel,float new_bias)
-{
- return new_vel * new_bias + self.velocity * (1-new_bias);
-}
-
-.float movelib_lastupdate;
-void movelib_move(vector force,float max_velocity,float drag,float mass,float breakforce)
-{
- float deltatime;
- float acceleration;
+.vector moveto;
+
+/**
+ Simulate drag
+ self.velocity = movelib_vdrag(self.velocity,0.02,0.5);
+**/
+vector movelib_dragvec(float drag, float exp)
+{
+ float lspeed,ldrag;
+
+ lspeed = vlen(self.velocity);
+ ldrag = lspeed * drag;
+ ldrag = ldrag * (drag * exp);
+ ldrag = 1 - (ldrag / lspeed);
+
+ return self.velocity * ldrag;
+}
+
+/**
+ Simulate drag
+ self.velocity = movelib_vdrag(somespeed,0.01,0.7);
+**/
+float movelib_dragflt(float fspeed,float drag,float exp)
+{
+ float ldrag;
+
+ ldrag = fspeed * drag;
+ ldrag = ldrag * ldrag * exp;
+ ldrag = 1 - (ldrag / fspeed);
+
+ return ldrag;
+}
+
+/**
+ Do a inertia simulation based on velocity.
+ Basicaly, this allows you to simulate 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)
+{
+ float influense;
+
+ influense = vlen(self.velocity) * (1 / vel_max);
+
+ influense = bound(newmin,influense,oldmax);
+
+ return (vel_new * (1 - influense)) + (self.velocity * influense);
+}
+
+vector movelib_inertmove(vector new_vel,float new_bias)
+{
+ return new_vel * new_bias + self.velocity * (1-new_bias);
+}
+
+.float movelib_lastupdate;
+void movelib_move(vector force,float max_velocity,float drag,float mass,float breakforce)
+{
+ float deltatime;
+ float acceleration;
float mspeed;
- vector breakvec;
-
- deltatime = time - self.movelib_lastupdate;
- if (deltatime > 0.15) deltatime = 0;
- self.movelib_lastupdate = time;
- if(!deltatime) return;
-
- mspeed = vlen(self.velocity);
-
- if(mass)
- acceleration = vlen(force) / mass;
- else
- acceleration = vlen(force);
-
- if(self.flags & FL_ONGROUND)
- {
- if(breakforce)
+ vector breakvec;
+
+ deltatime = time - self.movelib_lastupdate;
+ if (deltatime > 0.15) deltatime = 0;
+ self.movelib_lastupdate = time;
+ if (!deltatime) return;
+
+ mspeed = vlen(self.velocity);
+
+ if (mass)
+ acceleration = vlen(force) / mass;
+ else
+ acceleration = vlen(force);
+
+ if (self.flags & FL_ONGROUND)
+ {
+ if (breakforce)
{
breakvec = (normalize(self.velocity) * (breakforce / mass) * deltatime);
- self.velocity = self.velocity - breakvec;
+ self.velocity = self.velocity - breakvec;
}
-
- self.velocity = self.velocity + force * (acceleration * deltatime);
+
+ self.velocity = self.velocity + force * (acceleration * deltatime);
}
-
- if(drag)
+
+ if (drag)
self.velocity = movelib_dragvec(drag, 1);
- if(self.waterlevel > 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;
+ else
+ self.velocity = self.velocity + '0 0 -1' * sv_gravity * deltatime;
- mspeed = vlen(self.velocity);
-
- if(max_velocity)
- if(mspeed > max_velocity)
- self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
+ mspeed = vlen(self.velocity);
+
+ if (max_velocity)
+ if (mspeed > max_velocity)
+ self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
}
/*
@@ -117,7 +119,7 @@
self.movelib_lastupdate = time;
}
-
+
void movelib_update(vector dir,float force)
{
vector acceleration;
@@ -158,11 +160,11 @@
}
*/
-
-void movelib_move_simple(vector newdir,float velo,float blendrate)
-{
- self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
-}
+
+void movelib_move_simple(vector newdir,float velo,float blendrate)
+{
+ self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
+}
void movelib_beak_simple(float force)
{
float mspeed;
@@ -176,28 +178,37 @@
void movelib_groundalign4point(float spring_length,float spring_up)
{
- vector a,b,c,d,e,r,push_angle;
+ vector a,b,c,d,e,r,push_angle, ahead,side;
+
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);
+ // Put springs slightly inside bbox
+ ahead = v_forward * (self.maxs_x * 0.85);
+ side = v_right * (self.maxs_y * 0.85);
+ a = r + ahead + side;
+ b = r + ahead - side;
+ c = r - ahead + side;
+ d = r - ahead - side;
+
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;
Modified: trunk/data/qcsrc/server/pathlib.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib.qc 2009-03-27 08:56:37 UTC (rev 6317)
+++ trunk/data/qcsrc/server/pathlib.qc 2009-03-27 08:57:06 UTC (rev 6318)
@@ -7,6 +7,8 @@
.entity path_prev;
#endif
+#define medium spawnshieldtime
+
entity openlist;
entity closedlist;
entity scraplist;
@@ -40,17 +42,13 @@
entity best_open_node;
.float is_path_node;
-
-
-#define DEBUGPATHING
+//#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;
@@ -91,19 +89,6 @@
#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;
@@ -133,16 +118,13 @@
return vret;
}
-
-#define floor_failmask (DPCONTENTS_SLIME | DPCONTENTS_LAVA)
-// | DPCONTENTS_MONSTERCLIP | DPCONTENTS_DONOTENTER
-float walknode_stepsize;
+float walknode_stepsize;
vector walknode_stepup;
vector walknode_maxdrop;
vector walknode_boxup;
vector walknode_boxmax;
vector walknode_boxmin;
-float pathlib_movenode_goodnode;
+float pathlib_movenode_goodnode;
float floor_ok(vector point)
{
@@ -173,15 +155,16 @@
return 0;
}
+#define inwater(point) (pointcontents(point) == CONTENT_WATER)
+/*
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)
{
@@ -245,17 +228,13 @@
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;
@@ -287,13 +266,6 @@
{
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);
@@ -394,24 +366,48 @@
return parent.pathlib_node_g + static_cost;
}
+float pathlib_g_static_water(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);
+ return parent.pathlib_node_g + vlen(parent.origin - to);
}
+float pathlib_g_euclidean_water(entity parent,vector to, float static_cost)
+{
+ if(inwater(to))
+ return parent.pathlib_node_g + vlen(parent.origin - to) * pathlib_movecost_waterfactor;
+ else
+ return parent.pathlib_node_g + vlen(parent.origin - to);
+}
var float(vector from,vector to) pathlib_heuristic;
+
+/**
+ Manhattan Menas we expect to move up,down left or right
+ No diagonal moves espected. (like moving bewteen city blocks)
+**/
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;
+ h = fabs(a_x - b_x);
+ h += fabs(a_y - b_y);
+ h *= pathlib_gridsize;
return h;
}
+/**
+ This heuristic consider both stright and disagonal moves
+ to have teh same cost.
+**/
float pathlib_h_diagonal(vector a,vector b)
{
//h(n) = D * max(abs(n.x-goal.x), abs(n.y-goal.y))
@@ -424,11 +420,20 @@
return h;
}
+/**
+ This heuristic only considers the stright line distance.
+ Will usualy mean a lower H then G meaning A* Will speand more
+ and run slower.
+**/
float pathlib_h_euclidean(vector a,vector b)
{
return vlen(a - b);
}
+/**
+ This heuristic consider both stright and disagonal moves,
+ But has a separate cost for diagonal moves.
+**/
float pathlib_h_diagonal2(vector a,vector b)
{
float h_diag,h_str,h,x,y;
@@ -451,35 +456,12 @@
return h;
}
-float pathlib_h_diagonal2tbs(vector start,vector point,vector end)
-{
- float h_diag,h_str,h,x,y;
+/**
+ This heuristic consider both stright and disagonal moves,
+ But has a separate cost for diagonal moves.
- /*
- 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;
@@ -501,13 +483,11 @@
float m;
vector d1,d2;
- m = 0.999;
- d1 = normalize(preprev - prev);
- d2 = normalize(prev - point);
- if(vlen(d1-d2) > 0.6)
- m = 1;
+ d1 = normalize(preprev - point);
+ d2 = normalize(prev - point);
+ m = vlen(d1-d2);
+ //bprint("pathlib_h_diagonal2sdp-M = ",ftos(m),"\n");
-
return h * m;
}
@@ -530,13 +510,11 @@
h = pathlib_movecost_diag * h_diag;
h += pathlib_movecost * (h_str - 2 * h_diag);
- //if(inwater(a))
- //h =
-
return h;
}
//#define PATHLIB_USE_NODESCRAP
+#define PATHLIB_NODEEXPIRE 0.05
float pathlib_scraplist_cnt;
entity newnode()
{
@@ -557,6 +535,9 @@
#endif
++pathlib_made_cnt;
n = spawn();
+#ifdef PATHLIB_NODEEXPIRE
+ n.think = SUB_Remove;
+ n.nextthink = time + PATHLIB_NODEEXPIRE;
return n;
}
@@ -564,11 +545,15 @@
{
#ifdef PATHLIB_USE_NODESCRAP
++pathlib_scraplist_cnt;
- n.owner = scraplist;
+
+ n.path_next = world;
+ n.path_prev = world;
+ n.is_path_node = FALSE;
+ n.owner = scraplist;
#else
- n.is_path_node = FALSE;
- n.think = SUB_Remove;
- n.nextthink= time;
+ //n.is_path_node = FALSE;
+ n.think = SUB_Remove;
+ n.nextthink = time;
#endif
}
@@ -585,19 +570,17 @@
++pathlib_open_cnt;
- //if(inwater(where))
- //{
- //node.waterlevel = 1;
- //mark_info(where,5);
- //}
- //mark_info(where,30);
+ node.medium = pointcontents(where);
+
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)
+var float pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost);
+float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector goal,float cost)
{
entity node;
float h,g,f,doedge;
@@ -607,32 +590,19 @@
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;
- }
+ 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;
@@ -641,26 +611,16 @@
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);
- */
+ pathlib_h_diagonal2sdp(parent.path_prev.origin,parent.origin,where,goal);
-
- //h = 0;
+ h = pathlib_heuristic(where,goal);
g = pathlib_cost(parent,where,cost);
f = g + h;
@@ -692,7 +652,6 @@
}
node = pathlib_mknode(where,parent);
-
node.pathlib_node_h = h;
node.pathlib_node_g = g;
node.pathlib_node_f = f;
@@ -754,14 +713,14 @@
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;
- }
+ {
+ goal_node = node;
+ pathlib_foundgoal = TRUE;
+ }
}
}
@@ -830,14 +789,9 @@
{
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);
}
@@ -847,20 +801,96 @@
if(closedlist)
remove(closedlist);
+
+ best_open_node = world;
+ openlist = world;
+ closedlist = world;
}
-entity pathlib_astar(vector from,vector to)
+var float buildpath_nodefilter(vector n,vector c,vector p);
+float buildpath_nodefilter_directional(vector n,vector c,vector p)
{
+ vector d1,d2;
+
+ d2 = normalize(p - c);
+ d1 = normalize(c - n);
+
+ if(vlen(d1-d2) < 0.25)
+ return 1;
+
+ return 0;
+}
+
+float buildpath_nodefilter_moveskip(vector n,vector c,vector p)
+{
+ pathlib_walknode(p,n,1);
+ if(pathlib_movenode_goodnode)
+ return 1;
+
+ return 0;
+}
+
+entity path_build(entity next, vector where, entity prev, entity start)
+{
entity path;
- entity open,n;
+ if(prev && next)
+ if(buildpath_nodefilter)
+ if(buildpath_nodefilter(next.origin,where,prev.origin))
+ return next;
+
+
+ path = spawn();
+ path.owner = start;
+ path.path_next = next;
+
+ setorigin(path,where);
+
+ if(!next)
+ path.classname = "path_end";
+ else
+ {
+ if(!prev)
+ path.classname = "path_start";
+ else
+ path.classname = "path_node";
+ }
+
+ return path;
+}
+
+entity pathlib_astar(vector from,vector to)
+{
+ entity path, start, end, open, n, ln;
+ float ptime, ftime, ctime;
+
+ ptime = gettime(GETTIME_REALTIME);
+
pathlib_cleanup();
- pathlib_heuristic = pathlib_h_diagonal3;
- pathlib_cost = pathlib_g_static;
- pathlib_expandnode = pathlib_expandnode_star;
- pathlib_movenode = pathlib_walknode;
+ // Select water<->land capable node make/link
+ pathlib_makenode = pathlib_makenode_adaptive;
+ // Select XYZ cost estimate
+ pathlib_heuristic = pathlib_h_diagonal3;
+ // Select distance + waterfactor cost
+ pathlib_cost = pathlib_g_euclidean_water;
+ // Select star expander
+ pathlib_expandnode = pathlib_expandnode_star;
+ // Select walk simulation movement test
+ pathlib_movenode = pathlib_walknode;
+ // Filter final nodes by direction
+ buildpath_nodefilter = buildpath_nodefilter_directional;
+ // If the start is in water we need diffrent settings
+ if(inwater(from))
+ {
+ // Select volumetric node expaner
+ pathlib_expandnode = pathlib_expandnode_box;
+
+ // Water movement test
+ pathlib_movenode = pathlib_swimnode;
+ }
+
if not(openlist)
openlist = spawn();
@@ -879,7 +909,7 @@
pathlib_bestcash_saved = 0;
pathlib_recycle_cnt = 0;
- pathlib_gridsize = 192;
+ pathlib_gridsize = 128;
pathlib_movecost = pathlib_gridsize;
pathlib_movecost_diag = vlen(('1 1 0' * pathlib_gridsize));
pathlib_movecost_waterfactor = 1.1;
@@ -888,24 +918,31 @@
walknode_boxmax = self.maxs * 1.5;
walknode_boxmin = self.mins * 1.5;
- pathlib_edge_check_size = (vlen(walknode_boxmin - walknode_boxmax) * 0.25);
+ pathlib_edge_check_size = (vlen(walknode_boxmin - walknode_boxmax) * 0.5);
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;
+ from_x = fsnap(from_x,pathlib_gridsize);
+ from_y = fsnap(from_y,pathlib_gridsize);
+
+ to_x = fsnap(to_x,pathlib_gridsize);
+ to_y = fsnap(to_y,pathlib_gridsize);
+
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");
+ dprint("AStar: Goal found on first node!\n");
open = spawn();
open.owner = open;
open.classname = "path_end";
setorigin(open,path.origin);
+
pathlib_cleanup();
return open;
@@ -913,8 +950,9 @@
if(pathlib_expandnode(path,from,to) <= 0)
{
- dprint("A* pathing fail\n");
+ dprint("AStar path fail.\n");
pathlib_cleanup();
+
return world;
}
@@ -939,53 +977,55 @@
if(pathlib_foundgoal)
{
- dprint("Path found, re-tracing...\n");
+ dprint("Target found. Rebuilding and filtering path...\n");
+ ftime = gettime(GETTIME_REALTIME);
+ ptime = ftime - ptime;
- open = goal_node;
- open.is_path_node = FALSE;
- open.classname = "path_end";
- open.owner = path;
- open.path_next = world;
+ start = path_build(world,path.origin,world,world);
+ end = path_build(world,goal_node.origin,world,start);
+ ln = end;
-
- while(open.path_prev != path)
+ open = goal_node;
+ for(open = goal_node; open.path_prev != path; open = open.path_prev)
{
- n = open;
- open = open.path_prev;
- open.owner = path;
- open.path_next = n;
-
- open.is_path_node = FALSE;
- open.classname = "path_node";
+ n = path_build(ln,open.origin,open.path_prev,start);
+ ln.path_prev = n;
+ ln = n;
}
+ start.path_next = n;
+ n.path_prev = start;
+ ftime = gettime(GETTIME_REALTIME) - ftime;
- open.path_prev = path;
- path.path_next = open;
- path.classname = "path_master";
- path.is_path_node = FALSE;
- path.owner = path;
-
+ ctime = gettime(GETTIME_REALTIME);
pathlib_cleanup();
+ ctime = gettime(GETTIME_REALTIME) - ctime;
+
#ifdef DEBUGPATHING
- dprint("Chain done..\n");
- pathlib_showpath2(path);
+ pathlib_showpath2(start);
+ dprint("Time used - pathfinding: ", ftos(ptime),"\n");
+ dprint("Time used - rebuild & filter: ", ftos(ftime),"\n");
+ dprint("Time used - cleanup: ", ftos(ctime),"\n");
+ dprint("Time used - total: ", ftos(ptime + ftime + ctime),"\n");
+ dprint("Time used - # frames: ", ftos(ceil((ptime + ftime + ctime) / sys_ticrate)),"\n\n");
+ dprint("Nodes - created: ", ftos(pathlib_made_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 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");
+ if(pathlib_recycle_cnt)
+ dprint("Nodes - make/reuse: ", ftos(pathlib_made_cnt / pathlib_recycle_cnt),"\n");
+ if(pathlib_recycle_cnt)
+ dprint("Nodes - reused: ", ftos(pathlib_recycle_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("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;
+ return start;
}
}
@@ -996,3 +1036,5 @@
return world;
}
+
+
Modified: trunk/data/qcsrc/server/steerlib.qc
===================================================================
--- trunk/data/qcsrc/server/steerlib.qc 2009-03-27 08:56:37 UTC (rev 6317)
+++ trunk/data/qcsrc/server/steerlib.qc 2009-03-27 08:57:06 UTC (rev 6318)
@@ -1,3 +1,5 @@
+.vector steerto;
+
/**
Uniform pull towards a point
**/
@@ -260,10 +262,48 @@
return (upwish+leftwish+downwish+rightwish) * 0.25;
-}
+}
+/**
+ Steer towards the direction least obstructed.
+ Run two tracelines in a forward trident, bias each diretion negative if something is found there.
+**/
+vector steerlib_traceavoid_flat(float pitch, float length, vector vofs)
+{
+ vector vt_left, vt_right,vt_front;
+ float f_left, f_right,f_front;
+ vector leftwish, rightwish,frontwish, v_left;
+
+ v_left = v_right * -1;
+
+
+ vt_front = v_forward * length;
+ traceline(self.origin + vofs, self.origin + vofs + vt_front,MOVE_NOMONSTERS,self);
+ f_front = trace_fraction;
+
+ vt_left = (v_forward + (v_left * pitch)) * length;
+ traceline(self.origin + vofs, self.origin + vofs + vt_left,MOVE_NOMONSTERS,self);
+ f_left = trace_fraction;
+
+ //te_lightning1(world,self.origin, trace_endpos);
+
+ vt_right = (v_forward + (v_right * pitch)) * length;
+ traceline(self.origin + vofs, self.origin + vofs + vt_right ,MOVE_NOMONSTERS,self);
+ f_right = trace_fraction;
+
+ //te_lightning1(world,self.origin, trace_endpos);
+
+ leftwish = v_left * f_left;
+ rightwish = v_right * f_right;
+ frontwish = v_forward * f_front;
+
+ return normalize(leftwish + rightwish + frontwish);
+
+}
+
+
//////////////////////////////////////////////
// Testting //
// Everything below this point is a mess :D //
Modified: trunk/data/qcsrc/server/verbstack.qc
===================================================================
--- trunk/data/qcsrc/server/verbstack.qc 2009-03-27 08:56:37 UTC (rev 6317)
+++ trunk/data/qcsrc/server/verbstack.qc 2009-03-27 08:57:06 UTC (rev 6318)
@@ -1,21 +1,49 @@
-entity verb;
+/// Some default stacks.
.entity verbs_idle;
.entity verbs_attack;
.entity verbs_move;
-.float(float eval) verb_call;
+/// This global gets set to the verb in question each time the stack manager calls verb_call
+entity verb;
+
+/// Execure this verb
+#define VCM_DO 0
+/// Return teh value of this verb. Return VS_CALL_REMOVE to delete it.
+#define VCM_EVAL 1
+/// This verb is beeing removed NOW (not sent when verb_call returns VS_CALL_REMOVE)
+#define VCM_REMOVE 2
+
+/// Verb callback
+.float(float message) verb_call;
+
+/// Points to this verb's stack.
.entity verbstack;
+
+/// Static value of this verb
.float verb_static_value;
+/// verb_call returns this when a verb in not doable
#define VS_CALL_NO 0
+/// verb_call(VCM_DO) returns this when a verb is executing
#define VS_CALL_YES_DOING -1
+/// verb_call(VCM_DO) returns this when a verb did execure and is done
#define VS_CALL_YES_DONE -2
+/// verb_call(VCM_DO) returns this when a verb should be deleted by the stack manager
#define VS_CALL_REMOVE -3
+/**
+ Push a new verb onto the specified stack. Set vrb_life to make it time-limited.
+**/
entity verbstack_push(entity stack, float(float eval) vrb_call, float val_static, float vrb_life)
{
entity vrb;
+ if not(stack)
+ return world;
+
+ if not(vrb_call)
+ return world;
+
vrb = spawn();
vrb.owner = self;
vrb.verbstack = stack;
@@ -31,43 +59,48 @@
return vrb;
}
+/**
+ Find the best verb in this stack and execurte it.
+ ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL or VCM_DO
+**/
float verbstack_pop(entity stack)
{
- entity vrb;
- entity bestverb,oldself;
- float value,bestvalue;
+ entity vrb, bestverb, oldself;
+ float value, bestvalue;
oldself = self;
vrb = findchainentity(verbstack,stack);
while(vrb)
{
- verb = vrb;
- self = vrb.owner;
- value = vrb.verb_call(TRUE);
+ verb = vrb;
+ vrb = vrb.chain;
+ self = verb.owner;
+ value = verb.verb_call(VCM_EVAL);
+
if(value < 0)
{
if(value == VS_CALL_REMOVE)
- remove(vrb);
+ remove(verb);
}
else
{
if(value > bestvalue)
{
- bestverb = vrb;
+ bestverb = verb;
bestvalue = value;
}
}
- vrb = vrb.chain;
}
if(bestverb)
{
- verb = bestverb;
- self = verb.owner;
- value = bestverb.verb_call(FALSE);
- if(value == VS_CALL_REMOVE)
- remove(bestverb);
+ verb = bestverb;
+ self = verb.owner;
+ value = verb.verb_call(VCM_DO);
+
+ if(value == VS_CALL_REMOVE)
+ remove(bestverb);
}
self = oldself;
@@ -75,11 +108,15 @@
return value;
}
+/**
+ Find the best verb in this stack and return it.
+ ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL.
+**/
entity verbstack_pull(entity stack)
{
entity vrb;
- entity bestverb,oldself;
- float value,bestvalue;
+ entity bestverb, oldself;
+ float value, bestvalue;
oldself = self;
@@ -87,25 +124,50 @@
while(vrb)
{
self = vrb.owner;
- verb = vrb;
- value = vrb.verb_call(TRUE);
+
+ verb = vrb;
+ vrb = vrb.chain;
+ value = verb.verb_call(VCM_EVAL);
+
if(value > 0)
{
if(value == VS_CALL_REMOVE)
- remove(vrb);
+ remove(verb);
}
else
{
if(value > bestvalue)
{
- bestverb = vrb;
+ bestverb = verb;
bestvalue = value;
}
}
- vrb =vrb.chain;
}
self = oldself;
return bestverb;
}
+
+/**
+ Delete every verb on this stack, signaling them with VCM_REMOVE first.
+**/
+void verbstack_flush(entity stack)
+{
+ entity vrb, oldself;
+
+ oldself = self;
+
+ vrb = findchainentity(verbstack,stack);
+ while(vrb)
+ {
+ self = vrb.owner;
+
+ verb = vrb;
+ vrb = vrb.chain;
+ verb.verb_call(VCM_REMOVE);
+ remove(verb);
+ }
+
+ self = oldself;
+}
More information about the nexuiz-commits
mailing list