]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Bots: move supporting code into bot directory 237/head
authorTimePath <andrew.hardaker1995@gmail.com>
Wed, 7 Oct 2015 23:56:13 +0000 (10:56 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Thu, 8 Oct 2015 00:00:40 +0000 (11:00 +1100)
43 files changed:
qcsrc/client/movelib.qc [deleted file]
qcsrc/client/movelib.qh [deleted file]
qcsrc/client/progs.inc
qcsrc/common/monsters/monster/zombie.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/turrets/turret/walker.qc
qcsrc/dpdefs/csprogsdefs.qh
qcsrc/server/bot/default/navigation.qc
qcsrc/server/bot/impl.qc
qcsrc/server/bot/lib/all.inc [new file with mode: 0644]
qcsrc/server/bot/lib/movelib/all.inc [new file with mode: 0644]
qcsrc/server/bot/lib/movelib/movelib.qc [new file with mode: 0644]
qcsrc/server/bot/lib/movelib/movelib.qh [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/all.inc [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/costs.qc [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/debug.qc [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/expandnode.qc [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/main.qc [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/main.qh [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/movenode.qc [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/path_waypoint.qc [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/pathlib.qh [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/utility.qc [new file with mode: 0644]
qcsrc/server/bot/lib/pathlib/utility.qh [new file with mode: 0644]
qcsrc/server/bot/lib/steerlib/all.inc [new file with mode: 0644]
qcsrc/server/bot/lib/steerlib/steerlib.qc [new file with mode: 0644]
qcsrc/server/bot/lib/steerlib/steerlib.qh [new file with mode: 0644]
qcsrc/server/movelib.qc [deleted file]
qcsrc/server/movelib.qh [deleted file]
qcsrc/server/mutators/mutators_include.qc
qcsrc/server/pathlib/costs.qc [deleted file]
qcsrc/server/pathlib/debug.qc [deleted file]
qcsrc/server/pathlib/expandnode.qc [deleted file]
qcsrc/server/pathlib/main.qc [deleted file]
qcsrc/server/pathlib/main.qh [deleted file]
qcsrc/server/pathlib/movenode.qc [deleted file]
qcsrc/server/pathlib/path_waypoint.qc [deleted file]
qcsrc/server/pathlib/pathlib.qh [deleted file]
qcsrc/server/pathlib/utility.qc [deleted file]
qcsrc/server/pathlib/utility.qh [deleted file]
qcsrc/server/progs.inc
qcsrc/server/steerlib.qc [deleted file]
qcsrc/server/steerlib.qh [deleted file]

diff --git a/qcsrc/client/movelib.qc b/qcsrc/client/movelib.qc
deleted file mode 100644 (file)
index 074f146..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../server/movelib.qc"
diff --git a/qcsrc/client/movelib.qh b/qcsrc/client/movelib.qh
deleted file mode 100644 (file)
index a0634f6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../server/movelib.qh"
index ec5c31844af9a57657c608ce25ad5efdce45e963..4a10ef1969fe7d3544e77164db584e9f72ad79cc 100644 (file)
@@ -19,7 +19,6 @@
 #include "mapvoting.qc"
 #include "miscfunctions.qc"
 #include "modeleffects.qc"
-#include "movelib.qc"
 #include "particles.qc"
 #include "player_skeleton.qc"
 #include "rubble.qc"
@@ -51,6 +50,8 @@
 #include "../common/minigames/minigames.qc"
 #include "../common/minigames/cl_minigames.qc"
 
+#include "../server/bot/lib/all.inc"
+
 #include "../common/buffs/all.qc"
 #include "../common/items/all.qc"
 #include "../common/monsters/all.qc"
index 8425a123add60d29469b219c2d0f3b191a34b7de..05f466621ad185a51b113186cd256d1c752c558d 100644 (file)
@@ -27,6 +27,7 @@ REGISTER_MONSTER(ZOMBIE, NEW(Zombie)) {
 #ifdef IMPLEMENTATION
 
 #ifdef SVQC
+#include "../../../server/bot/lib/movelib/movelib.qh"
 float autocvar_g_monster_zombie_health;
 float autocvar_g_monster_zombie_damageforcescale = 0.55;
 float autocvar_g_monster_zombie_attack_melee_damage;
index 8b05f781d2e395b44a3893474fdc6788501dd40e..75837cf1a0a06309a96fdd85ea998c8f635af08e 100644 (file)
@@ -14,7 +14,6 @@
     #include "../../server/defs.qh"
     #include "../deathtypes.qh"
     #include "../../server/mutators/mutators_include.qh"
-       #include "../../server/steerlib.qh"
        #include "../turrets/sv_turrets.qh"
        #include "../turrets/util.qh"
     #include "../vehicles/all.qh"
index e629ada79853f2a31a96aa27ee334d9f84fa6de0..4a5ed2fc8f382d5dca3428deedf6bda1b103babf 100644 (file)
@@ -631,7 +631,7 @@ spawnfunc(turret_walker) { if(!turret_initialize(TUR_WALKER)) remove(self); }
 #endif // SVQC
 #ifdef CSQC
 
-#include "../../../client/movelib.qh"
+#include "../../../server/bot/lib/movelib/movelib.qh"
 
 void walker_draw(entity this)
 {
index 6ad27242aaf3f6a22161d17db4f4e3bd44d3575a..0daa5dce35914c54ae04aa6bb32ef40f911aee46 100644 (file)
@@ -23,6 +23,8 @@
 #undef particleeffectnum
 #undef setmodel
 
+entity(.entity fld, entity match) findchainentity = #403;
+
 #pragma noref 0
 
 #define ReadFloat() ReadCoord()
index fb196fcc32a3b0da45df1e758ec56797ccad65ec..8898b71632b6c937c2ac70829f7b02a91d1c2ef5 100644 (file)
@@ -1,6 +1,6 @@
 #include "navigation.qh"
 
-#include "../common/triggers/trigger/jumppads.qh"
+#include "../../../common/triggers/trigger/jumppads.qh"
 
 void bot_debug(string input)
 {
index 9f36c4f67996ce55a91715b45dc9b91141a5ad6c..c0b6c8716d25133511add52d0d0bc9186d70c8cc 100644 (file)
@@ -1,3 +1,5 @@
 #include "api.qh"
 
+#include "lib/all.inc"
+
 #include "default/all.inc"
diff --git a/qcsrc/server/bot/lib/all.inc b/qcsrc/server/bot/lib/all.inc
new file mode 100644 (file)
index 0000000..9a92a96
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef BOT_LIB_ALL_H
+#define BOT_LIB_ALL_H
+
+#include "movelib/all.inc"
+#ifdef SVQC
+#include "pathlib/all.inc"
+#endif
+#include "steerlib/all.inc"
+
+#endif
diff --git a/qcsrc/server/bot/lib/movelib/all.inc b/qcsrc/server/bot/lib/movelib/all.inc
new file mode 100644 (file)
index 0000000..c12ce90
--- /dev/null
@@ -0,0 +1 @@
+#include "movelib.qc"
diff --git a/qcsrc/server/bot/lib/movelib/movelib.qc b/qcsrc/server/bot/lib/movelib/movelib.qc
new file mode 100644 (file)
index 0000000..acacba0
--- /dev/null
@@ -0,0 +1,237 @@
+#include "movelib.qh"
+
+#ifdef SVQC
+.vector moveto;
+
+/**
+    Simulate drag
+    self.velocity = movelib_dragvec(self.velocity,0.02,0.5);
+**/
+vector movelib_dragvec(float drag, float exp_)
+{SELFPARAM();
+    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_dragflt(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_inertmove_byspeed(self.velocity,newvel,1000,0.1,0.9);
+**/
+vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
+{SELFPARAM();
+    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)
+{SELFPARAM();
+    return new_vel * new_bias + self.velocity * (1-new_bias);
+}
+
+void movelib_move(vector force,float max_velocity,float drag,float theMass,float breakforce)
+{SELFPARAM();
+    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 (theMass)
+        acceleration = vlen(force) / theMass;
+    else
+        acceleration = vlen(force);
+
+    if (self.flags & FL_ONGROUND)
+    {
+        if (breakforce)
+        {
+            breakvec = (normalize(self.velocity) * (breakforce / theMass) * deltatime);
+            self.velocity = self.velocity - breakvec;
+        }
+
+        self.velocity = self.velocity + force * (acceleration * 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' * autocvar_sv_gravity * deltatime;
+    }
+    else
+        self.velocity = self.velocity + '0 0 -1' * autocvar_sv_gravity * deltatime;
+
+    mspeed = vlen(self.velocity);
+
+    if (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_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      =  (autocvar_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;
+
+}
+*/
+
+void movelib_beak_simple(float force)
+{SELFPARAM();
+    float mspeed;
+    vector mdir;
+    float vz;
+
+    mspeed = max(0,vlen(self.velocity) - force);
+    mdir   = normalize(self.velocity);
+    vz = self.velocity.z;
+    self.velocity = mdir * mspeed;
+    self.velocity_z = vz;
+}
+
+/**
+Pitches and rolls the entity to match the gound.
+Yed need to set v_up and v_forward (generally by calling makevectors) before calling this.
+**/
+#endif
+
+void movelib_groundalign4point(float spring_length, float spring_up, float blendrate, float _max)
+{SELFPARAM();
+    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;
+
+    // Put springs slightly inside bbox
+    ahead = v_forward * (self.maxs.x * 0.8);
+    side  = v_right   * (self.maxs.y * 0.8);
+
+    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;
+
+    push_angle.x = (a.z - c.z) * _max;
+    push_angle.x += (b.z - d.z) * _max;
+
+    push_angle.z = (b.z - a.z) * _max;
+    push_angle.z += (d.z - c.z) * _max;
+
+    //self.angles_x += push_angle_x * 0.95;
+    //self.angles_z += push_angle_z * 0.95;
+
+    self.angles_x = ((1-blendrate) *  self.angles.x)  + (push_angle.x * blendrate);
+    self.angles_z = ((1-blendrate) *  self.angles.z)  + (push_angle.z * blendrate);
+
+    //a = self.origin;
+    setorigin(self,r);
+}
+
diff --git a/qcsrc/server/bot/lib/movelib/movelib.qh b/qcsrc/server/bot/lib/movelib/movelib.qh
new file mode 100644 (file)
index 0000000..8a4bfd4
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef MOVELIB_H
+#define MOVELIB_H
+
+#ifdef SVQC
+.vector moveto;
+
+/**
+    Simulate drag
+    self.velocity = movelib_dragvec(self.velocity,0.02,0.5);
+**/
+vector movelib_dragvec(float drag, float exp_);
+
+/**
+    Simulate drag
+    self.velocity *= movelib_dragflt(somespeed,0.01,0.7);
+**/
+float movelib_dragflt(float fspeed,float drag,float exp_);
+
+/**
+    Do a inertia simulation based on velocity.
+    Basicaly, this allows you to simulate loss of steering with higher speed.
+    self.velocity = movelib_inertmove_byspeed(self.velocity,newvel,1000,0.1,0.9);
+**/
+vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax);
+
+vector movelib_inertmove(vector new_vel,float new_bias);
+
+.float  movelib_lastupdate;
+void movelib_move(vector force,float max_velocity,float drag,float theMass,float breakforce);
+
+/*
+void movelib_move_simple(vector newdir,float velo,float blendrate)
+{
+    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
+}
+*/
+#define movelib_move_simple(newdir,velo,blendrate) \
+    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo
+
+#define movelib_move_simple_gravity(newdir,velo,blendrate) \
+    if(self.flags & FL_ONGROUND) movelib_move_simple(newdir,velo,blendrate)
+
+void movelib_beak_simple(float force);
+
+/**
+Pitches and rolls the entity to match the gound.
+Yed need to set v_up and v_forward (generally by calling makevectors) before calling this.
+**/
+#endif
+
+void movelib_groundalign4point(float spring_length, float spring_up, float blendrate, float _max);
+
+#endif
diff --git a/qcsrc/server/bot/lib/pathlib/all.inc b/qcsrc/server/bot/lib/pathlib/all.inc
new file mode 100644 (file)
index 0000000..8622734
--- /dev/null
@@ -0,0 +1,6 @@
+#include "costs.qc"
+#include "expandnode.qc"
+#include "main.qc"
+#include "movenode.qc"
+#include "path_waypoint.qc"
+#include "utility.qc"
diff --git a/qcsrc/server/bot/lib/pathlib/costs.qc b/qcsrc/server/bot/lib/pathlib/costs.qc
new file mode 100644 (file)
index 0000000..eb885a4
--- /dev/null
@@ -0,0 +1,146 @@
+#include "pathlib.qh"
+
+float pathlib_g_static(entity parent,vector to, float static_cost)
+{
+    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 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);
+}
+
+
+/**
+    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 += 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))
+    float h,x,y;
+
+    x = fabs(a.x - b.x);
+    y = fabs(a.y - b.y);
+    h = pathlib_movecost * max(x,y);
+
+    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;
+
+    /*
+    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;
+}
+
+/**
+    This heuristic consider both stright and disagonal moves,
+    But has a separate cost for diagonal moves.
+**/
+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 = min(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;
+
+    d1 = normalize(preprev - point);
+    d2 = normalize(prev    - point);
+    m = vlen(d1-d2);
+
+    return h * m;
+}
+
+
+float pathlib_h_diagonal3(vector a,vector b)
+{
+    float h_diag,h_str,h,x,y,z;
+
+    x = fabs(a.x - b.x);
+    y = fabs(a.y - b.y);
+    z = fabs(a.z - b.z);
+
+    h_diag = min(x,y,z);
+    h_str = x + y + z;
+
+    h =  pathlib_movecost_diag * h_diag;
+    h += pathlib_movecost * (h_str - 2 * h_diag);
+
+    return h;
+}
diff --git a/qcsrc/server/bot/lib/pathlib/debug.qc b/qcsrc/server/bot/lib/pathlib/debug.qc
new file mode 100644 (file)
index 0000000..37e167a
--- /dev/null
@@ -0,0 +1,123 @@
+#include "pathlib.qh"
+
+MODEL(SQUARE,       "models/pathlib/square.md3");
+MODEL(SQUARE_GOOD,  "models/pathlib/goodsquare.md3");
+MODEL(SQUARE_BAD,   "models/pathlib/badsquare.md3");
+MODEL(EDGE,         "models/pathlib/edge.md3");
+
+#ifdef TURRET_DEBUG
+void mark_error(vector where,float lifetime);
+void mark_info(vector where,float lifetime);
+entity mark_misc(vector where,float lifetime);
+#endif
+
+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()
+{SELFPARAM();
+    pathlib_showpath(self);
+    self.nextthink = time + 1;
+}
+
+void __showpath2_think()
+{SELFPARAM();
+    #ifdef TURRET_DEBUG
+       mark_info(self.origin,1);
+       #endif
+    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;
+}
+
+
+void pathlib_showsquare2(entity node ,vector ncolor,float align)
+{
+
+    node.alpha     = 0.25;
+    node.scale     = pathlib_gridsize / 512.001;
+    node.solid     = SOLID_NOT;
+
+    setmodel(node, MDL_SQUARE);
+    setorigin(node,node.origin);
+    node.colormod = ncolor;
+
+    if(align)
+    {
+        traceline(node.origin + '0 0 32', node.origin - '0 0 128', MOVE_WORLDONLY, node);
+        node.angles = vectoangles(trace_plane_normal);
+        node.angles_x -= 90;
+    }
+}
+
+void SUB_Remove();
+
+void pathlib_showsquare(vector where,float goodsquare,float _lifetime)
+{
+    entity s;
+
+    if(!_lifetime)
+        _lifetime = time + 30;
+    else
+        _lifetime += time;
+
+    s           = spawn();
+    s.alpha     = 0.25;
+    s.think     = SUB_Remove;
+    s.nextthink = _lifetime;
+    s.scale     = pathlib_gridsize / 512.001;
+    s.solid     = SOLID_NOT;
+
+    setmodel(s, goodsquare ? MDL_SQUARE_GOOD : MDL_SQUARE_BAD);
+
+    traceline(where + '0 0 32',where - '0 0 128',MOVE_WORLDONLY,s);
+
+    s.angles = vectoangles(trace_plane_normal);
+    s.angles_x -= 90;
+    setorigin(s,where);
+}
+
+void pathlib_showedge(vector where,float _lifetime,float rot)
+{
+    entity e;
+
+    if(!_lifetime)
+        _lifetime = time + 30;
+    else
+        _lifetime += time;
+
+    e           = spawn();
+    e.alpha     = 0.25;
+    e.think     = SUB_Remove;
+    e.nextthink = _lifetime;
+    e.scale     = pathlib_gridsize / 512;
+    e.solid     = SOLID_NOT;
+    setorigin(e,where);
+    setmodel(e, MDL_EDGE);
+    //traceline(where + '0 0 32',where - '0 0 128',MOVE_WORLDONLY,e);
+    //e.angles = vectoangles(trace_plane_normal);
+    e.angles_y = rot;
+    //e.angles_x += 90;
+
+}
diff --git a/qcsrc/server/bot/lib/pathlib/expandnode.qc b/qcsrc/server/bot/lib/pathlib/expandnode.qc
new file mode 100644 (file)
index 0000000..1f095a7
--- /dev/null
@@ -0,0 +1,235 @@
+#include "pathlib.qh"
+#include "utility.qh"
+
+vector plib_points2[8];
+vector plib_points[8];
+float  plib_fvals[8];
+
+float pathlib_expandnode_starf(entity node, vector start, vector goal)
+{
+    vector where,f,r,t;
+    float fc,c;
+    entity nap;
+
+    where = node.origin;
+
+    f = PLIB_FORWARD * pathlib_gridsize;
+    r = PLIB_RIGHT   * pathlib_gridsize;
+
+    // Forward
+    plib_points[0] = where + f;
+
+    // Back
+    plib_points[1] = where - f;
+
+    // Right
+    plib_points[2] = where + r;
+
+    // Left
+    plib_points[3] = where - r;
+
+    // Forward-right
+    plib_points[4] = where + f + r;
+
+    // Forward-left
+    plib_points[5] = where + f - r;
+
+    // Back-right
+    plib_points[6] = where - f + r;
+
+    // Back-left
+    plib_points[7] = where - f - r;
+
+    for(int i=0;i < 8; ++i)
+    {
+        t = plib_points[i];
+        fc  = pathlib_heuristic(t,goal) + pathlib_cost(node, t, pathlib_gridsize);
+        plib_fvals[i] = fc;
+
+    }
+
+    fc = plib_fvals[0];
+    plib_points2[0] = plib_points[0];
+    vector bp;
+    bp = plib_points[0];
+    int fc2 = 0;
+    for(int i = 0; i < 8; ++i)
+    {
+        c = 0;
+        nap = pathlib_nodeatpoint(plib_points[i]);
+        if(nap)
+            if(nap.owner == openlist)
+                c = 1;
+        else
+            c = 1;
+
+        if(c)
+        if(plib_fvals[i] < fc)
+        {
+            bp = plib_points[i];
+            fc = plib_fvals[i];
+            plib_points2[fc2] = plib_points[i];
+            ++fc2;
+        }
+
+        /*
+        nap = pathlib_nodeatpoint(plib_points[i]);
+        if(nap)
+        if not nap.owner == closedlist)
+        {
+        }
+        */
+    }
+
+    pathlib_makenode(node, start, bp, goal, pathlib_gridsize);
+
+    for(int i = 0; i < 3; ++i)
+    {
+        pathlib_makenode(node, start, plib_points2[i], goal, pathlib_gridsize);
+    }
+
+    return pathlib_open_cnt;
+}
+
+float pathlib_expandnode_star(entity node, vector start, vector goal)
+{
+    vector point, where, f, r;
+
+    where = node.origin;
+
+    f = PLIB_FORWARD * pathlib_gridsize;
+    r = PLIB_RIGHT   * pathlib_gridsize;
+
+    if (node.pathlib_node_edgeflags == pathlib_node_edgeflag_unknown)
+        node.pathlib_node_edgeflags = tile_check_plus2(node.origin);
+
+    if(node.pathlib_node_edgeflags == pathlib_node_edgeflag_none)
+    {
+        LOG_TRACE("Node at ", vtos(node.origin), " not expanable");
+        return pathlib_open_cnt;
+    }
+
+    // Forward
+    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_forward)
+    {
+        point = where + f;
+        pathlib_makenode(node, start, point, goal, pathlib_movecost);
+    }
+
+    // Back
+    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_back)
+    {
+        point = where - f;
+        pathlib_makenode(node, start, point, goal, pathlib_movecost);
+    }
+
+    // Right
+        if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_right)
+    {
+        point = where + r;
+        pathlib_makenode(node, start, point, goal, pathlib_movecost);
+    }
+
+    // Left
+    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_left)
+    {
+        point = where - r;
+        pathlib_makenode(node, start, point, goal, pathlib_movecost);
+
+    }
+
+    // Forward-right
+    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_forwardright)
+    {
+        point = where + f + r;
+        pathlib_makenode(node, start, point, goal, pathlib_movecost_diag);
+    }
+
+    // Forward-left
+    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_forwardleft)
+    {
+        point = where + f - r;
+        pathlib_makenode(node, start, point, goal, pathlib_movecost_diag);
+
+    }
+
+    // Back-right
+    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_backright)
+    {
+        point = where - f + r;
+        pathlib_makenode(node, start, point, goal, pathlib_movecost_diag);
+    }
+
+    // Back-left
+    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_backleft)
+    {
+        point = where - f - r;
+        pathlib_makenode(node, start, point, goal, pathlib_movecost_diag);
+    }
+
+    return pathlib_open_cnt;
+}
+
+float pathlib_expandnode_octagon(entity node, vector start, vector goal)
+{
+    vector point,where,f,r;
+
+    where = node.origin;
+
+    f = PLIB_FORWARD * pathlib_gridsize;
+    r = PLIB_RIGHT   * pathlib_gridsize;
+
+    // Forward
+    point = where + f;
+    pathlib_makenode(node, start, point, goal, pathlib_movecost);
+
+    // Back
+    point = where - f;
+    pathlib_makenode(node, start, point, goal, pathlib_movecost);
+
+    // Right
+    point = where + r;
+    pathlib_makenode(node, start, point, goal, pathlib_movecost);
+
+    // Left
+    point = where - r;
+    pathlib_makenode(node, start, point, goal, pathlib_movecost);
+
+    f = PLIB_FORWARD * pathlib_gridsize * 0.5;
+    r = PLIB_RIGHT   * pathlib_gridsize * 0.5;
+
+    // Forward-right
+    point = where + f + r;
+    pathlib_makenode(node, start, point, goal, pathlib_movecost);
+
+
+    // Forward-left
+    point = where + f - r;
+    pathlib_makenode(node, start, point, goal, pathlib_movecost);
+
+
+    // Back-right
+    point = where - f + r;
+    pathlib_makenode(node, start, point, goal, pathlib_movecost);
+
+    // Back-left
+    point = where - f - r;
+    pathlib_makenode(node, start, point, goal, pathlib_movecost);
+
+    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;
+}
diff --git a/qcsrc/server/bot/lib/pathlib/main.qc b/qcsrc/server/bot/lib/pathlib/main.qc
new file mode 100644 (file)
index 0000000..39e23bd
--- /dev/null
@@ -0,0 +1,566 @@
+#include "pathlib.qh"
+#include "utility.qh"
+
+void pathlib_deletepath(entity start)
+{
+    entity e;
+
+    e = findchainentity(owner, start);
+    while(e)
+    {
+        e.think = SUB_Remove;
+        e.nextthink = time;
+        e = e.chain;
+    }
+}
+
+//#define PATHLIB_NODEEXPIRE 0.05
+const float PATHLIB_NODEEXPIRE = 20;
+
+void dumpnode(entity n)
+{
+    n.is_path_node = false;
+    n.think        = SUB_Remove;
+    n.nextthink    = time;
+}
+
+entity pathlib_mknode(vector where,entity parent)
+{
+    entity node;
+
+    node = pathlib_nodeatpoint(where);
+    if(node)
+    {
+       #ifdef TURRET_DEBUG
+        mark_error(where, 60);
+        #endif
+        return node;
+    }
+
+    node = spawn();
+
+    node.think        = SUB_Remove;
+    node.nextthink    = time + PATHLIB_NODEEXPIRE;
+    node.is_path_node = true;
+    node.owner        = openlist;
+    node.path_prev    = parent;
+
+
+    setsize(node, '0 0 0', '0 0 0');
+
+    setorigin(node, where);
+    node.medium = pointcontents(where);
+    pathlib_showsquare(where, 1 ,15);
+
+    ++pathlib_made_cnt;
+    ++pathlib_open_cnt;
+
+    return node;
+}
+
+float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector goal,float cost)
+{
+    entity node;
+    float h,g,f,doedge = 0;
+    vector where;
+
+    ++pathlib_searched_cnt;
+
+    if(inwater(parent.origin))
+    {
+        LOG_TRACE("FromWater\n");
+        pathlib_expandnode = pathlib_expandnode_box;
+        pathlib_movenode   = pathlib_swimnode;
+    }
+    else
+    {
+        if(inwater(to))
+        {
+            LOG_TRACE("ToWater\n");
+            pathlib_expandnode = pathlib_expandnode_box;
+            pathlib_movenode   = pathlib_walknode;
+        }
+        else
+        {
+            LOG_TRACE("LandToLoand\n");
+            //if(edge_check(parent.origin))
+            //    return 0;
+
+            pathlib_expandnode = pathlib_expandnode_star;
+            pathlib_movenode   = pathlib_walknode;
+            doedge = 1;
+        }
+    }
+
+    node = pathlib_nodeatpoint(to);
+    if(node)
+    {
+        LOG_TRACE("NodeAtPoint\n");
+        ++pathlib_merge_cnt;
+
+        if(node.owner == openlist)
+        {
+            h = pathlib_heuristic(node.origin,goal);
+            g = pathlib_cost(parent,node.origin,cost);
+            f = g + h;
+
+            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 (!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;
+    }
+
+    where = pathlib_movenode(parent.origin, to, 0);
+
+    if (!pathlib_movenode_goodnode)
+    {
+        //pathlib_showsquare(where, 0 ,30);
+        //pathlib_showsquare(parent.origin, 1 ,30);
+        LOG_TRACE("pathlib_movenode_goodnode = 0\n");
+        return 0;
+    }
+
+    //pathlib_showsquare(where, 1 ,30);
+
+    if(pathlib_nodeatpoint(where))
+    {
+        LOG_TRACE("NAP WHERE :",vtos(where),"\n");
+        LOG_TRACE("not NAP TO:",vtos(to),"\n");
+        LOG_TRACE("NAP-NNAP:",ftos(vlen(to-where)),"\n\n");
+        return 0;
+    }
+
+
+    if(doedge)
+        if (!tile_check(where))
+        {
+            LOG_TRACE("tile_check fail\n");
+            pathlib_showsquare(where, 0 ,30);
+            return 0;
+        }
+
+
+    h = pathlib_heuristic(where,goal);
+    g = pathlib_cost(parent,where,cost);
+    f = g + h;
+
+    /*
+    node = findradius(where,pathlib_gridsize * 0.5);
+    while(node)
+    {
+        if(node.is_path_node == true)
+        {
+            ++pathlib_merge_cnt;
+            if(node.owner == openlist)
+            {
+                if(node.pathlib_node_g > g)
+                {
+                    //pathlib_movenode(where,node.origin,0);
+                    //if(pathlib_movenode_goodnode)
+                    //{
+                        //mark_error(node.origin + '0 0 128',30);
+                        node.pathlib_node_h = h;
+                        node.pathlib_node_g = g;
+                        node.pathlib_node_f = f;
+                        node.path_prev = parent;
+                    //}
+                }
+
+                if (!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 (!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)
+    {
+        LOG_TRACE("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)
+    {
+        vector goalmove;
+
+        goalmove = pathlib_walknode(node.origin,goal,1);
+        if(pathlib_movenode_goodnode)
+        {
+            goal_node         = node;
+            pathlib_foundgoal = true;
+        }
+    }
+}
+
+void pathlib_cleanup()
+{
+    best_open_node = world;
+
+    //return;
+
+    entity node;
+
+    node = findfloat(world,is_path_node, true);
+    while(node)
+    {
+        /*
+        node.owner = openlist;
+        node.pathlib_node_g = 0;
+        node.pathlib_node_h = 0;
+        node.pathlib_node_f = 0;
+        node.path_prev = world;
+        */
+
+        dumpnode(node);
+        node = findfloat(node,is_path_node, true);
+    }
+
+    if(openlist)
+        remove(openlist);
+
+    if(closedlist)
+        remove(closedlist);
+
+    openlist       = world;
+    closedlist     = world;
+
+}
+
+float Cosine_Interpolate(float a, float b, float x)
+{
+    float ft,f;
+
+       ft = x * 3.1415927;
+       f = (1 - cos(ft)) * 0.5;
+
+       return  a*(1-f) + b*f;
+}
+
+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)
+    {
+        //mark_error(c,30);
+        return 1;
+    }
+    //mark_info(c,30);
+    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;
+}
+
+float buildpath_nodefilter_none(vector n,vector c,vector p)
+{
+    return 0;
+}
+
+entity path_build(entity next, vector where, entity prev, entity start)
+{
+    entity path;
+
+    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)
+{SELFPARAM();
+    entity path, start, end, open, n, ln;
+    float ptime, ftime, ctime;
+
+    ptime = gettime(GETTIME_REALTIME);
+    pathlib_starttime = ptime;
+
+    pathlib_cleanup();
+
+    // Select water<->land capable node make/link
+    pathlib_makenode     = pathlib_makenode_adaptive;
+
+    // Select XYZ cost estimate
+    //pathlib_heuristic    = pathlib_h_diagonal3;
+    pathlib_heuristic    = pathlib_h_diagonal;
+
+    // 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;
+
+    // Filter tiles with cross pattern
+    tile_check = tile_check_cross;
+
+    // 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 (!openlist)
+        openlist       = spawn();
+
+    if (!closedlist)
+        closedlist     = spawn();
+
+    pathlib_closed_cnt       = 0;
+    pathlib_open_cnt         = 0;
+    pathlib_made_cnt         = 0;
+    pathlib_merge_cnt        = 0;
+    pathlib_searched_cnt     = 0;
+    pathlib_bestopen_seached = 0;
+    pathlib_bestcash_hits    = 0;
+    pathlib_bestcash_saved   = 0;
+
+    pathlib_gridsize       = 128;
+    pathlib_movecost       = pathlib_gridsize;
+    pathlib_movecost_diag  = vlen(('1 1 0' * pathlib_gridsize));
+    pathlib_movecost_waterfactor = 25000000;
+    pathlib_foundgoal      = 0;
+
+    movenode_boxmax   = self.maxs * 1.1;
+    movenode_boxmin   = self.mins * 1.1;
+
+    movenode_stepsize = pathlib_gridsize * 0.25;
+
+    tile_check_size = pathlib_gridsize * 0.5;
+    tile_check_up   = '0 0 2' * pathlib_gridsize;
+    tile_check_up   = '0 0 128';
+    tile_check_down = '0 0 3' * pathlib_gridsize;
+    tile_check_down = '0 0 256';
+
+    //movenode_stepup   = '0 0 128';
+    movenode_stepup   = '0 0 36';
+    movenode_maxdrop  = '0 0 512';
+    //movenode_maxdrop  = '0 0 512';
+    movenode_boxup    = '0 0 72';
+
+    from.x = fsnap(from.x, pathlib_gridsize);
+    from.y = fsnap(from.y, pathlib_gridsize);
+    //from_z += 32;
+
+    to.x = fsnap(to.x, pathlib_gridsize);
+    to.y = fsnap(to.y, pathlib_gridsize);
+    //to_z += 32;
+
+    LOG_TRACE("AStar init\n");
+    path = pathlib_mknode(from, world);
+    pathlib_close_node(path, to);
+    if(pathlib_foundgoal)
+    {
+        LOG_TRACE("AStar: Goal found on first node!\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)
+    {
+        LOG_TRACE("AStar path 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)
+    {
+        if((gettime(GETTIME_REALTIME) - pathlib_starttime) > pathlib_maxtime)
+        {
+            LOG_TRACE("Path took to long to compute!\n");
+            LOG_TRACE("Nodes - created: ", ftos(pathlib_made_cnt),"\n");
+            LOG_TRACE("Nodes -    open: ", ftos(pathlib_open_cnt),"\n");
+            LOG_TRACE("Nodes -  merged: ", ftos(pathlib_merge_cnt),"\n");
+            LOG_TRACE("Nodes -  closed: ", ftos(pathlib_closed_cnt),"\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(n,from,to);
+
+        if(pathlib_foundgoal)
+        {
+            LOG_TRACE("Target found. Rebuilding and filtering path...\n");
+            ftime = gettime(GETTIME_REALTIME);
+            ptime = ftime - ptime;
+
+            start = path_build(world,path.origin,world,world);
+            end   = path_build(world,goal_node.origin,world,start);
+            ln    = end;
+
+            open = goal_node;
+            for(open = goal_node; open.path_prev != path; open = open.path_prev)
+            {
+                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;
+
+            ctime = gettime(GETTIME_REALTIME);
+            pathlib_cleanup();
+            ctime = gettime(GETTIME_REALTIME) - ctime;
+
+
+#ifdef DEBUGPATHING
+            pathlib_showpath2(start);
+
+            LOG_TRACE("Time used -      pathfinding: ", ftos(ptime),"\n");
+            LOG_TRACE("Time used - rebuild & filter: ", ftos(ftime),"\n");
+            LOG_TRACE("Time used -          cleanup: ", ftos(ctime),"\n");
+            LOG_TRACE("Time used -            total: ", ftos(ptime + ftime + ctime),"\n");
+            LOG_TRACE("Time used -         # frames: ", ftos(ceil((ptime + ftime + ctime) / sys_frametime)),"\n\n");
+            LOG_TRACE("Nodes -         created: ", ftos(pathlib_made_cnt),"\n");
+            LOG_TRACE("Nodes -            open: ", ftos(pathlib_open_cnt),"\n");
+            LOG_TRACE("Nodes -          merged: ", ftos(pathlib_merge_cnt),"\n");
+            LOG_TRACE("Nodes -          closed: ", ftos(pathlib_closed_cnt),"\n");
+            LOG_TRACE("Nodes -        searched: ", ftos(pathlib_searched_cnt),"\n");
+            LOG_TRACE("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
+            LOG_TRACE("Nodes bestcash -   hits: ", ftos(pathlib_bestcash_hits),"\n");
+            LOG_TRACE("Nodes bestcash -   save: ", ftos(pathlib_bestcash_saved),"\n");
+            LOG_TRACE("AStar done.\n");
+#endif
+            return start;
+        }
+    }
+
+    LOG_TRACE("A* Faild to find a path! Try a smaller gridsize.\n");
+
+    pathlib_cleanup();
+
+    return world;
+}
diff --git a/qcsrc/server/bot/lib/pathlib/main.qh b/qcsrc/server/bot/lib/pathlib/main.qh
new file mode 100644 (file)
index 0000000..177c432
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef PATHLIB_MAIN_H
+#define PATHLIB_MAIN_H
+float buildpath_nodefilter_none(vector n,vector c,vector p);
+entity path_build(entity next, vector where, entity prev, entity start);
+#endif
diff --git a/qcsrc/server/bot/lib/pathlib/movenode.qc b/qcsrc/server/bot/lib/pathlib/movenode.qc
new file mode 100644 (file)
index 0000000..5326a74
--- /dev/null
@@ -0,0 +1,152 @@
+#include "pathlib.qh"
+#include "utility.qh"
+
+vector pathlib_wateroutnode(vector start,vector end, float doedge)
+{SELFPARAM();
+    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 (!(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;
+    }
+
+    if(pointcontents(surface + '0 0 1') != CONTENT_EMPTY)
+        return end;
+
+    tracebox(start + '0 0 64', movenode_boxmin,movenode_boxmax, end + '0 0 64', MOVE_WORLDONLY, self);
+    if(trace_fraction == 1)
+        pathlib_movenode_goodnode = 1;
+
+    if(fabs(surface.z - end.z) > 32)
+        pathlib_movenode_goodnode = 0;
+
+    return end;
+}
+
+vector pathlib_swimnode(vector start,vector end, float doedge)
+{SELFPARAM();
+    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, doedge);
+
+    tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, self);
+    if(trace_fraction == 1)
+        pathlib_movenode_goodnode = 1;
+
+    return end;
+}
+
+vector pathlib_flynode(vector start,vector end, float doedge)
+{SELFPARAM();
+    pathlib_movenode_goodnode = 0;
+
+    end.x = fsnap(end.x, pathlib_gridsize);
+    end.y = fsnap(end.y, pathlib_gridsize);
+
+    tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, self);
+    if(trace_fraction == 1)
+        pathlib_movenode_goodnode = 1;
+
+    return end;
+}
+
+void a_think()
+{SELFPARAM();
+    te_lightning1(self,self.origin, self.pos1);
+    if(self.cnt < time)
+        remove(self);
+    else
+        self.nextthink = time + 0.2;
+}
+
+vector pathlib_walknode(vector start,vector end,float doedge)
+{SELFPARAM();
+    vector direction,point,last_point,s,e;
+    float steps, distance, i;
+
+    LOG_TRACE("Walking node from ", vtos(start), " to ", vtos(end), "\n");
+
+    pathlib_movenode_goodnode = 0;
+
+    end.x = fsnap(end.x,pathlib_gridsize);
+    end.y = fsnap(end.y,pathlib_gridsize);
+    start.x = fsnap(start.x,pathlib_gridsize);
+    start.y = fsnap(start.y,pathlib_gridsize);
+
+    // Find the floor
+    traceline(start + movenode_stepup, start - movenode_maxdrop, MOVE_WORLDONLY, self);
+    if(trace_fraction == 1.0)
+    {
+        entity a;
+        a = spawn();
+        a.think = a_think;
+        a.nextthink = time;
+        setorigin(a,start + movenode_stepup);
+        a.pos1 = trace_endpos;
+        //start - movenode_maxdrop
+        a.cnt = time + 10;
+
+        LOG_TRACE("I cant walk on air!\n");
+        return trace_endpos;
+    }
+
+    start = trace_endpos;
+
+    // Find the direcion, without Z
+    s   = start; e   = end;
+    //e_z = 0; s_z = 0;
+    direction = normalize(e - s);
+
+    distance  = vlen(start - end);
+    steps     = rint(distance / movenode_stepsize);
+
+    last_point = start;
+    for(i = 1; i < steps; ++i)
+    {
+        point = last_point + (direction * movenode_stepsize);
+        traceline(point + movenode_stepup,point - movenode_maxdrop,MOVE_WORLDONLY,self);
+        if(trace_fraction == 1.0)
+            return trace_endpos;
+
+        last_point = trace_endpos;
+    }
+
+    point = last_point + (direction * movenode_stepsize);
+    point.x = fsnap(point.x,pathlib_gridsize);
+    point.y = fsnap(point.y,pathlib_gridsize);
+
+    //dprint("end_x:  ",ftos(end_x),  "  end_y:  ",ftos(end_y),"\n");
+    //dprint("point_x:",ftos(point_x),"  point_y:",ftos(point_y),"\n\n");
+
+    traceline(point + movenode_stepup, point - movenode_maxdrop,MOVE_WORLDONLY,self);
+    if(trace_fraction == 1.0)
+        return trace_endpos;
+
+    last_point = trace_endpos;
+
+    tracebox(start + movenode_boxup, movenode_boxmin,movenode_boxmax, last_point + movenode_boxup, MOVE_WORLDONLY, self);
+    if(trace_fraction != 1.0)
+        return trace_endpos;
+
+    pathlib_movenode_goodnode = 1;
+    return last_point;
+}
diff --git a/qcsrc/server/bot/lib/pathlib/path_waypoint.qc b/qcsrc/server/bot/lib/pathlib/path_waypoint.qc
new file mode 100644 (file)
index 0000000..615840d
--- /dev/null
@@ -0,0 +1,248 @@
+#include "pathlib.qh"
+#include "main.qh"
+
+var float pathlib_wpp_open(entity wp, entity child, float cost);
+
+void pathlib_wpp_close(entity wp)
+{
+    --pathlib_open_cnt;
+    ++pathlib_closed_cnt;
+
+    wp.pathlib_list = closedlist;
+
+    if(wp == best_open_node)
+        best_open_node = world;
+
+    if(wp == goal_node)
+        pathlib_foundgoal = true;
+}
+
+float pathlib_wpp_opencb(entity wp, entity child, float cost)
+{
+
+    if(child.pathlib_list == closedlist)
+        return false;
+
+       // FIXME! wp.wp##mincost is NOT distance. Make it distance or add a field for distance to be used here (for better speed)
+       cost = vlen(child.origin - wp.origin);
+
+    child.path_prev     = wp;
+    child.pathlib_list   = openlist;
+    child.pathlib_node_g = wp.pathlib_node_g + cost;
+    child.pathlib_node_h = pathlib_heuristic(child.origin, goal_node.origin);
+    child.pathlib_node_c = pathlib_wpp_waypointcallback(child, wp);
+    child.pathlib_node_f = child.pathlib_node_g + child.pathlib_node_h + child.pathlib_node_c;
+
+
+    if(child == goal_node)
+        pathlib_foundgoal = true;
+
+    ++pathlib_open_cnt;
+
+    if(best_open_node.pathlib_node_f > child.pathlib_node_f)
+        best_open_node = child;
+
+    return true;
+}
+
+float pathlib_wpp_openncb(entity wp, entity child, float cost)
+{
+
+    if(child.pathlib_list == closedlist)
+        return false;
+
+       // FIXME! wp.wp##mincost is NOT distance. Make it distance or add a field for distance to be used here (for better speed)
+       cost = vlen(child.origin - wp.origin);
+
+    child.path_prev     = wp;
+    child.pathlib_list   = openlist;
+    child.pathlib_node_g = wp.pathlib_node_g + cost;
+    child.pathlib_node_h = pathlib_heuristic(child.origin, goal_node.origin);
+    child.pathlib_node_f = child.pathlib_node_g + child.pathlib_node_h;
+
+    if(child == goal_node)
+        pathlib_foundgoal = true;
+
+    ++pathlib_open_cnt;
+
+    if(best_open_node.pathlib_node_f > child.pathlib_node_f)
+        best_open_node = child;
+
+    return true;
+}
+
+float pathlib_wpp_expand(entity wp)
+{
+    if(wp.wp00) pathlib_wpp_open(wp,wp.wp00,wp.wp00mincost); else return 0;
+    if(wp.wp01) pathlib_wpp_open(wp,wp.wp01,wp.wp01mincost); else return 1;
+    if(wp.wp02) pathlib_wpp_open(wp,wp.wp02,wp.wp02mincost); else return 2;
+    if(wp.wp03) pathlib_wpp_open(wp,wp.wp03,wp.wp03mincost); else return 3;
+    if(wp.wp04) pathlib_wpp_open(wp,wp.wp04,wp.wp04mincost); else return 4;
+    if(wp.wp05) pathlib_wpp_open(wp,wp.wp05,wp.wp05mincost); else return 5;
+    if(wp.wp06) pathlib_wpp_open(wp,wp.wp06,wp.wp06mincost); else return 6;
+    if(wp.wp07) pathlib_wpp_open(wp,wp.wp07,wp.wp07mincost); else return 7;
+    if(wp.wp08) pathlib_wpp_open(wp,wp.wp08,wp.wp08mincost); else return 8;
+    if(wp.wp09) pathlib_wpp_open(wp,wp.wp09,wp.wp09mincost); else return 9;
+    if(wp.wp10) pathlib_wpp_open(wp,wp.wp10,wp.wp10mincost); else return 10;
+    if(wp.wp11) pathlib_wpp_open(wp,wp.wp11,wp.wp11mincost); else return 11;
+    if(wp.wp12) pathlib_wpp_open(wp,wp.wp12,wp.wp12mincost); else return 12;
+    if(wp.wp13) pathlib_wpp_open(wp,wp.wp13,wp.wp13mincost); else return 13;
+    if(wp.wp14) pathlib_wpp_open(wp,wp.wp14,wp.wp14mincost); else return 14;
+    if(wp.wp15) pathlib_wpp_open(wp,wp.wp15,wp.wp15mincost); else return 15;
+    if(wp.wp16) pathlib_wpp_open(wp,wp.wp16,wp.wp16mincost); else return 16;
+    if(wp.wp17) pathlib_wpp_open(wp,wp.wp17,wp.wp17mincost); else return 17;
+    if(wp.wp18) pathlib_wpp_open(wp,wp.wp18,wp.wp18mincost); else return 18;
+    if(wp.wp19) pathlib_wpp_open(wp,wp.wp19,wp.wp19mincost); else return 19;
+    if(wp.wp20) pathlib_wpp_open(wp,wp.wp20,wp.wp20mincost); else return 20;
+    if(wp.wp21) pathlib_wpp_open(wp,wp.wp21,wp.wp21mincost); else return 21;
+    if(wp.wp22) pathlib_wpp_open(wp,wp.wp22,wp.wp22mincost); else return 22;
+    if(wp.wp23) pathlib_wpp_open(wp,wp.wp23,wp.wp23mincost); else return 23;
+    if(wp.wp24) pathlib_wpp_open(wp,wp.wp24,wp.wp24mincost); else return 24;
+    if(wp.wp25) pathlib_wpp_open(wp,wp.wp25,wp.wp25mincost); else return 25;
+    if(wp.wp26) pathlib_wpp_open(wp,wp.wp26,wp.wp26mincost); else return 26;
+    if(wp.wp27) pathlib_wpp_open(wp,wp.wp27,wp.wp27mincost); else return 27;
+    if(wp.wp28) pathlib_wpp_open(wp,wp.wp28,wp.wp28mincost); else return 28;
+    if(wp.wp29) pathlib_wpp_open(wp,wp.wp29,wp.wp29mincost); else return 29;
+    if(wp.wp30) pathlib_wpp_open(wp,wp.wp30,wp.wp30mincost); else return 30;
+    if(wp.wp31) pathlib_wpp_open(wp,wp.wp31,wp.wp31mincost); else return 31;
+
+    return 32;
+}
+
+entity pathlib_wpp_bestopen()
+{
+    entity n, best;
+
+    if(best_open_node)
+        return best_open_node;
+
+    n = findchainentity(pathlib_list, openlist);
+    best = n;
+    while(n)
+    {
+        if(n.pathlib_node_f < best.pathlib_node_f)
+            best = n;
+
+        n = n.chain;
+    }
+
+    return best;
+
+}
+
+entity pathlib_waypointpath(entity wp_from, entity wp_to, float callback)
+{
+    entity n;
+    float ptime;
+
+    ptime                                      = gettime(GETTIME_REALTIME);
+    pathlib_starttime          = ptime;
+       pathlib_movecost                = 300;
+       pathlib_movecost_diag   = vlen('1 1 0' * pathlib_movecost);
+
+       if (!pathlib_wpp_waypointcallback)
+               callback = false;
+
+       if (callback)
+               pathlib_wpp_open = pathlib_wpp_opencb;
+       else
+               pathlib_wpp_open = pathlib_wpp_openncb;
+
+       pathlib_heuristic = pathlib_h_none;
+
+    if (!openlist)
+        openlist       = spawn();
+
+    if (!closedlist)
+        closedlist     = spawn();
+
+    pathlib_closed_cnt       = 0;
+    pathlib_open_cnt         = 0;
+    pathlib_searched_cnt     = 0;
+    pathlib_foundgoal      = false;
+
+    LOG_TRACE("pathlib_waypointpath init\n");
+
+    // Initialize waypoint grid
+    // FIXME! presisted chain for better preformance
+    for(n = findchain(classname, "waypoint"); n; n = n.chain)
+    {
+        n.pathlib_list = world;
+        n.pathlib_node_g = 0;
+        n.pathlib_node_f = 0;
+        n.pathlib_node_h = 0;
+
+        //setmodel(n, "models/runematch/rune.mdl");
+        //n.effects = EF_LOWPRECISION;
+        //n.colormod = '0 0 0';
+        //n.scale = 1;
+
+    }
+
+    goal_node  = wp_to;
+    start_node = wp_from;
+
+    start_node.pathlib_list = closedlist;
+    LOG_TRACE("Expanding ",ftos(pathlib_wpp_expand(start_node))," links\n");
+    if(pathlib_open_cnt <= 0)
+    {
+        LOG_TRACE("pathlib_waypointpath: Start waypoint not linked! aborting.\n");
+        return world;
+    }
+
+    return world;
+}
+
+entity pathlib_waypointpath_step()
+{
+    entity n;
+
+    n = pathlib_wpp_bestopen();
+    if(!n)
+    {
+        LOG_TRACE("Cannot find best open node, abort.\n");
+        return world;
+    }
+    pathlib_wpp_close(n);
+       LOG_TRACE("Expanding ",ftos(pathlib_wpp_expand(n))," links\n");
+
+    if(pathlib_foundgoal)
+    {
+        entity start, end, open, ln;
+
+        LOG_TRACE("Target found. Rebuilding and filtering path...\n");
+
+               buildpath_nodefilter = buildpath_nodefilter_none;
+               start = path_build(world, start_node.origin, world, world);
+               end   = path_build(world, goal_node.origin, world, start);
+               ln    = end;
+
+               for(open = goal_node; open.path_prev != start_node; open = open.path_prev)
+               {
+                       n    = path_build(ln,open.origin,open.path_prev,start);
+                       ln.path_prev = n;
+                       ln = n;
+               }
+               start.path_next = n;
+               n.path_prev = start;
+
+        return start;
+    }
+
+    return world;
+}
+void plas_think()
+{SELFPARAM();
+    pathlib_waypointpath_step();
+    if(pathlib_foundgoal)
+        return;
+    self.nextthink = time + 0.1;
+}
+
+void pathlib_waypointpath_autostep()
+{
+    entity n;
+    n = spawn();
+    n.think = plas_think;
+    n.nextthink = time + 0.1;
+}
diff --git a/qcsrc/server/bot/lib/pathlib/pathlib.qh b/qcsrc/server/bot/lib/pathlib/pathlib.qh
new file mode 100644 (file)
index 0000000..dbf7852
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef PATHLIB_H
+#define PATHLIB_H
+
+.entity pathlib_list;
+.entity path_next;
+.entity path_prev;
+
+#define inwater(point) (pointcontents(point) == CONTENT_WATER)
+#define medium spawnshieldtime
+
+const vector PLIB_FORWARD = '0 1 0';
+//#define PLIB_BACK    '0 -1 0'
+const vector PLIB_RIGHT = '1 0 0';
+//#define PLIB_LEFT    '-1 0 0'
+
+#define DEBUGPATHING
+#ifdef DEBUGPATHING
+void pathlib_showpath(entity start);
+void pathlib_showpath2(entity path);
+#endif
+
+entity openlist;
+entity closedlist;
+
+entity goal_node;
+entity start_node;
+
+.float is_path_node;
+.float pathlib_node_g;
+.float pathlib_node_h;
+.float pathlib_node_f;
+.float pathlib_node_c;
+
+const float pathlib_node_edgeflag_unknown              = 0;
+const float pathlib_node_edgeflag_left                         = 2;
+const float pathlib_node_edgeflag_right                = 4;
+const float pathlib_node_edgeflag_forward              = 8;
+const float pathlib_node_edgeflag_back                         = 16;
+const float pathlib_node_edgeflag_backleft             = 32;
+const float pathlib_node_edgeflag_backright    = 64;
+const float pathlib_node_edgeflag_forwardleft  = 128;
+const float pathlib_node_edgeflag_forwardright         = 256;
+const float pathlib_node_edgeflag_none                         = 512;
+.float pathlib_node_edgeflags;
+
+float pathlib_open_cnt;
+float pathlib_closed_cnt;
+float pathlib_made_cnt;
+float pathlib_merge_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_foundgoal;
+
+float pathlib_starttime;
+const float pathlib_maxtime = 60;
+
+entity best_open_node;
+
+vector tile_check_up;
+vector tile_check_down;
+float  tile_check_size;
+float     tile_check_cross(vector where);
+float     tile_check_plus(vector where);
+float     tile_check_star(vector where);
+var float tile_check(vector where);
+
+float  movenode_stepsize;
+vector movenode_stepup;
+vector movenode_maxdrop;
+vector movenode_boxup;
+vector movenode_boxmax;
+vector movenode_boxmin;
+float  pathlib_movenode_goodnode;
+
+vector     pathlib_wateroutnode(vector start, vector end, float doedge);
+vector     pathlib_swimnode(vector start, vector end, float doedge);
+vector     pathlib_flynode(vector start, vector end, float doedge);
+vector     pathlib_walknode(vector start, vector end, float doedge);
+var vector pathlib_movenode(vector start, vector end, float doedge);
+
+float      pathlib_expandnode_star(entity node, vector start, vector goal);
+float      pathlib_expandnode_box(entity node, vector start, vector goal);
+float      pathlib_expandnode_octagon(entity node, vector start, vector goal);
+var float  pathlib_expandnode(entity node, vector start, vector goal);
+
+float      pathlib_g_static(entity parent, vector to, float static_cost);
+float      pathlib_g_static_water(entity parent, vector to, float static_cost);
+float      pathlib_g_euclidean(entity parent, vector to, float static_cost);
+float      pathlib_g_euclidean_water(entity parent, vector to, float static_cost);
+var float  pathlib_cost(entity parent, vector to, float static_cost);
+
+float      pathlib_h_manhattan(vector a, vector b);
+float      pathlib_h_diagonal(vector a, vector b);
+float      pathlib_h_euclidean(vector a,vector b);
+float      pathlib_h_diagonal2(vector a, vector b);
+float      pathlib_h_diagonal3(vector a, vector b);
+float      pathlib_h_diagonal2sdp(vector preprev, vector prev, vector point, vector end);
+float      pathlib_h_none(vector preprev, vector prev) { return 0; }
+var float  pathlib_heuristic(vector from, vector to);
+
+var float  pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost);
+var float  buildpath_nodefilter(vector n,vector c,vector p);
+
+var float  pathlib_wpp_waypointcallback(entity wp, entity wp_prev);
+
+#ifdef DEBUGPATHING
+       #include "debug.qc"
+#endif
+
+#endif
diff --git a/qcsrc/server/bot/lib/pathlib/utility.qc b/qcsrc/server/bot/lib/pathlib/utility.qc
new file mode 100644 (file)
index 0000000..9028f85
--- /dev/null
@@ -0,0 +1,245 @@
+#include "utility.qh"
+
+#include "pathlib.qh"
+
+float location_isok(vector point, float water_isok, float air_isok)
+{
+    float pc,pc2;
+
+    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+        return 0;
+
+    pc  = pointcontents(point);
+    pc2 = pointcontents(point - '0 0 1');
+
+    switch(pc)
+    {
+        case CONTENT_SOLID:
+            break;
+
+        case CONTENT_SLIME:
+            break;
+
+        case CONTENT_LAVA:
+            break;
+
+        case CONTENT_SKY:
+            break;
+
+        case CONTENT_EMPTY:
+            if (pc2 == CONTENT_SOLID)
+                return 1;
+
+            if (pc2 == CONTENT_EMPTY)
+                if(air_isok)
+                    return 1;
+
+            if (pc2 == CONTENT_WATER)
+                if(water_isok)
+                    return 1;
+
+            break;
+
+        case CONTENT_WATER:
+            if (water_isok)
+                return 1;
+
+            break;
+    }
+
+    return 0;
+}
+
+entity pathlib_nodeatpoint(vector where)
+{
+    entity node;
+
+    ++pathlib_searched_cnt;
+
+    where.x = fsnap(where.x,pathlib_gridsize);
+    where.y = fsnap(where.y,pathlib_gridsize);
+
+    node = findradius(where,pathlib_gridsize * 0.5);
+    while(node)
+    {
+        if(node.is_path_node == true)
+            return node;
+
+        node = node.chain;
+    }
+
+    return world;
+}
+
+float tile_check_cross(vector where)
+{SELFPARAM();
+    vector p,f,r;
+
+    f = PLIB_FORWARD * tile_check_size;
+    r = PLIB_RIGHT   * tile_check_size;
+
+
+    // forward-right
+    p = where + f + r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
+    if (!location_isok(trace_endpos, 1, 0))
+        return 0;
+
+    // Forward-left
+    p = where + f - r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
+    if (!location_isok(trace_endpos, 1, 0))
+        return 0;
+
+    // Back-right
+    p = where - f + r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
+    if (!location_isok(trace_endpos, 1 ,0))
+        return 0;
+
+    //Back-left
+    p = where - f - r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
+    if (!location_isok(trace_endpos, 1, 0))
+        return 0;
+
+    return 1;
+}
+
+float tile_check_plus(vector where)
+{SELFPARAM();
+    vector p,f,r;
+
+    f = PLIB_FORWARD * tile_check_size;
+    r = PLIB_RIGHT   * tile_check_size;
+
+    // forward
+    p = where + f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if (!location_isok(trace_endpos,1,0))
+        return 0;
+
+
+    //left
+    p = where - r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if (!location_isok(trace_endpos,1,0))
+        return 0;
+
+    // Right
+    p = where + r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if (!location_isok(trace_endpos,1,0))
+        return 0;
+
+    //Back
+    p = where - f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if (!location_isok(trace_endpos,1,0))
+        return 0;
+
+    return 1;
+}
+
+float tile_check_plus2(vector where)
+{SELFPARAM();
+    vector p,f,r;
+    float i = 0, e = 0;
+
+    f = PLIB_FORWARD * pathlib_gridsize;
+    r = PLIB_RIGHT   * pathlib_gridsize;
+
+//#define pathlib_node_edgeflag_left    2
+//#define pathlib_node_edgeflag_right   4
+//#define pathlib_node_edgeflag_forward 8
+//#define pathlib_node_edgeflag_back    16
+
+    // forward
+    p = where + f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if (location_isok(trace_endpos,1,0))
+    {
+       ++i;
+       e |= pathlib_node_edgeflag_forward;
+    }
+
+
+    //left
+    p = where - r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if (location_isok(trace_endpos,1,0))
+    {
+       ++i;
+       e |= pathlib_node_edgeflag_left;
+    }
+
+
+    // Right
+    p = where + r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if (location_isok(trace_endpos,1,0))
+    {
+       ++i;
+       e |= pathlib_node_edgeflag_right;
+    }
+
+    //Back
+    p = where - f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if (location_isok(trace_endpos,1,0))
+    {
+       ++i;
+       e |= pathlib_node_edgeflag_back;
+    }
+
+    // forward-right
+    p = where + f + r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
+    if (location_isok(trace_endpos, 1, 0))
+    {
+       ++i;
+       e |= pathlib_node_edgeflag_forwardright;
+    }
+
+    // Forward-left
+    p = where + f - r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
+    if (location_isok(trace_endpos, 1, 0))
+    {
+       ++i;
+       e |= pathlib_node_edgeflag_forwardleft;
+    }
+
+    // Back-right
+    p = where - f + r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
+    if (location_isok(trace_endpos, 1 ,0))
+    {
+       ++i;
+       e |= pathlib_node_edgeflag_backright;
+    }
+
+    //Back-left
+    p = where - f - r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
+    if (location_isok(trace_endpos, 1, 0))
+    {
+       ++i;
+       e |= pathlib_node_edgeflag_backleft;
+    }
+
+
+    if(i == 0)
+        e = pathlib_node_edgeflag_none;
+
+    return e;
+}
+
+float tile_check_star(vector where)
+{
+    if(tile_check_plus(where))
+        return tile_check_cross(where);
+
+    return 0;
+}
+
diff --git a/qcsrc/server/bot/lib/pathlib/utility.qh b/qcsrc/server/bot/lib/pathlib/utility.qh
new file mode 100644 (file)
index 0000000..bf72549
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef PATHLIB_UTILITY
+#define PATHLIB_UTILITY
+float fsnap(float val,float fsize);
+entity pathlib_nodeatpoint(vector where);
+float tile_check_plus2(vector where);
+#endif
diff --git a/qcsrc/server/bot/lib/steerlib/all.inc b/qcsrc/server/bot/lib/steerlib/all.inc
new file mode 100644 (file)
index 0000000..9e802b5
--- /dev/null
@@ -0,0 +1 @@
+#include "steerlib.qc"
diff --git a/qcsrc/server/bot/lib/steerlib/steerlib.qc b/qcsrc/server/bot/lib/steerlib/steerlib.qc
new file mode 100644 (file)
index 0000000..23b8473
--- /dev/null
@@ -0,0 +1,665 @@
+/**
+    Uniform pull towards a point
+**/
+vector steerlib_pull(vector point)
+{SELFPARAM();
+    return normalize(point - self.origin);
+}
+
+/**
+    Uniform push from a point
+**/
+#define steerlib_push(point) normalize(self.origin - point)
+/*
+vector steerlib_push(vector point)
+{
+    return normalize(self.origin - point);
+}
+*/
+/**
+    Pull toward a point, The further away, the stronger the pull.
+**/
+vector steerlib_arrive(vector point,float maximal_distance)
+{SELFPARAM();
+    float distance;
+    vector direction;
+
+    distance = bound(0.001,vlen(self.origin - point),maximal_distance);
+    direction = normalize(point - self.origin);
+    return  direction * (distance / maximal_distance);
+}
+
+/**
+    Pull toward a point increasing the pull the closer we get
+**/
+vector steerlib_attract(vector point, float maximal_distance)
+{SELFPARAM();
+    float distance;
+    vector direction;
+
+    distance = bound(0.001,vlen(self.origin - point),maximal_distance);
+    direction = normalize(point - self.origin);
+
+    return  direction * (1-(distance / maximal_distance));
+}
+
+vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense)
+{SELFPARAM();
+    float distance;
+    vector direction;
+    float influense;
+
+    distance  = bound(0.00001,vlen(self.origin - point),max_distance);
+    direction = normalize(point - self.origin);
+
+    influense = 1 - (distance / max_distance);
+    influense = min_influense + (influense * (max_influense - min_influense));
+
+    return  direction * influense;
+}
+
+/*
+vector steerlib_attract2(vector point, float maximal_distance,float min_influense,float max_influense,float distance)
+{
+    //float distance;
+    vector current_direction;
+    vector target_direction;
+    float i_target,i_current;
+
+    if(!distance)
+        distance = vlen(self.origin - point);
+
+    distance = bound(0.001,distance,maximal_distance);
+
+    target_direction = normalize(point - self.origin);
+    current_direction = normalize(self.velocity);
+
+    i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
+    i_current = 1 - i_target;
+
+    // i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
+
+    string s;
+    s = ftos(i_target);
+    bprint("IT: ",s,"\n");
+    s = ftos(i_current);
+    bprint("IC  : ",s,"\n");
+
+    return  normalize((target_direction * i_target) + (current_direction * i_current));
+}
+*/
+/**
+    Move away from a point.
+**/
+vector steerlib_repell(vector point,float maximal_distance)
+{SELFPARAM();
+    float distance;
+    vector direction;
+
+    distance = bound(0.001,vlen(self.origin - point),maximal_distance);
+    direction = normalize(self.origin - point);
+
+    return  direction * (1-(distance / maximal_distance));
+}
+
+/**
+    Try to keep at ideal_distance away from point
+**/
+vector steerlib_standoff(vector point,float ideal_distance)
+{SELFPARAM();
+    float distance;
+    vector direction;
+
+    distance = vlen(self.origin - point);
+
+
+    if(distance < ideal_distance)
+    {
+        direction = normalize(self.origin - point);
+        return direction * (distance / ideal_distance);
+    }
+
+    direction = normalize(point - self.origin);
+    return direction * (ideal_distance / distance);
+
+}
+
+/**
+    A random heading in a forward halfcicrle
+
+    use like:
+    self.target = steerlib_wander(256,32,self.target)
+
+    where range is the cicrle radius and tresh is how close we need to be to pick a new heading.
+**/
+vector steerlib_wander(float range,float tresh,vector oldpoint)
+{SELFPARAM();
+    vector wander_point;
+    wander_point = v_forward - oldpoint;
+
+    if (vlen(wander_point) > tresh)
+        return oldpoint;
+
+    range = bound(0,range,1);
+
+    wander_point = self.origin + v_forward * 128;
+    wander_point = wander_point + randomvec() * (range * 128) - randomvec() * (range * 128);
+
+    return normalize(wander_point - self.origin);
+}
+
+/**
+    Dodge a point. dont work to well.
+**/
+vector steerlib_dodge(vector point,vector dodge_dir,float min_distance)
+{SELFPARAM();
+    float distance;
+
+    distance = max(vlen(self.origin - point),min_distance);
+    if (min_distance < distance)
+        return '0 0 0';
+
+    return dodge_dir * (min_distance/distance);
+}
+
+/**
+    flocking by .flock_id
+    Group will move towards the unified direction while keeping close to eachother.
+**/
+.float flock_id;
+vector steerlib_flock(float _radius, float standoff,float separation_force,float flock_force)
+{SELFPARAM();
+    entity flock_member;
+    vector push = '0 0 0', pull = '0 0 0';
+    float ccount = 0;
+
+    flock_member = findradius(self.origin, _radius);
+    while(flock_member)
+    {
+        if(flock_member != self)
+        if(flock_member.flock_id == self.flock_id)
+        {
+            ++ccount;
+            push = push + (steerlib_repell(flock_member.origin,standoff) * separation_force);
+            pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity, _radius) * flock_force);
+        }
+        flock_member = flock_member.chain;
+    }
+    return push + (pull* (1 / ccount));
+}
+
+/**
+    flocking by .flock_id
+    Group will move towards the unified direction while keeping close to eachother.
+    xy only version (for ground movers).
+**/
+vector steerlib_flock2d(float _radius, float standoff,float separation_force,float flock_force)
+{SELFPARAM();
+    entity flock_member;
+    vector push = '0 0 0', pull = '0 0 0';
+    float ccount = 0;
+
+    flock_member = findradius(self.origin,_radius);
+    while(flock_member)
+    {
+        if(flock_member != self)
+        if(flock_member.flock_id == self.flock_id)
+        {
+            ++ccount;
+            push = push + (steerlib_repell(flock_member.origin, standoff) * separation_force);
+            pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity, _radius) * flock_force);
+        }
+        flock_member = flock_member.chain;
+    }
+
+    push.z = 0;
+    pull.z = 0;
+
+    return push + (pull * (1 / ccount));
+}
+
+/**
+    All members want to be in the center, and keep away from eachother.
+    The furtehr form the center the more they want to be there.
+
+    This results in a aligned movement (?!) much like flocking.
+**/
+vector steerlib_swarm(float _radius, float standoff,float separation_force,float swarm_force)
+{SELFPARAM();
+    entity swarm_member;
+    vector force = '0 0 0', center = '0 0 0';
+    float ccount = 0;
+
+    swarm_member = findradius(self.origin,_radius);
+
+    while(swarm_member)
+    {
+        if(swarm_member.flock_id == self.flock_id)
+        {
+            ++ccount;
+            center = center + swarm_member.origin;
+            force = force + (steerlib_repell(swarm_member.origin,standoff) * separation_force);
+        }
+        swarm_member = swarm_member.chain;
+    }
+
+    center = center * (1 / ccount);
+    force = force + (steerlib_arrive(center,_radius) * swarm_force);
+
+    return force;
+}
+
+/**
+    Steer towards the direction least obstructed.
+    Run four tracelines in a forward funnel, bias each diretion negative if something is found there.
+    You need to call makevectors() (or equivalent) before this function to set v_forward and v_right
+**/
+vector steerlib_traceavoid(float pitch,float length)
+{SELFPARAM();
+    vector vup_left,vup_right,vdown_left,vdown_right;
+    float fup_left,fup_right,fdown_left,fdown_right;
+    vector upwish,downwish,leftwish,rightwish;
+    vector v_left,v_down;
+
+
+    v_left = v_right * -1;
+    v_down = v_up * -1;
+
+    vup_left = (v_forward + (v_left * pitch + v_up * pitch)) * length;
+    traceline(self.origin, self.origin +  vup_left,MOVE_NOMONSTERS,self);
+    fup_left = trace_fraction;
+
+    //te_lightning1(world,self.origin, trace_endpos);
+
+    vup_right = (v_forward + (v_right * pitch + v_up * pitch)) * length;
+    traceline(self.origin,self.origin + vup_right ,MOVE_NOMONSTERS,self);
+    fup_right = trace_fraction;
+
+    //te_lightning1(world,self.origin, trace_endpos);
+
+    vdown_left = (v_forward + (v_left * pitch + v_down * pitch)) * length;
+    traceline(self.origin,self.origin + vdown_left,MOVE_NOMONSTERS,self);
+    fdown_left = trace_fraction;
+
+    //te_lightning1(world,self.origin, trace_endpos);
+
+    vdown_right = (v_forward + (v_right * pitch + v_down * pitch)) * length;
+    traceline(self.origin,self.origin + vdown_right,MOVE_NOMONSTERS,self);
+    fdown_right = trace_fraction;
+
+    //te_lightning1(world,self.origin, trace_endpos);
+    upwish    = v_up    * (fup_left   + fup_right);
+    downwish  = v_down  * (fdown_left + fdown_right);
+    leftwish  = v_left  * (fup_left   + fdown_left);
+    rightwish = v_right * (fup_right  + fdown_right);
+
+    return (upwish+leftwish+downwish+rightwish) * 0.25;
+
+}
+
+/**
+    Steer towards the direction least obstructed.
+    Run tracelines in a forward trident, bias each direction negative if something is found there.
+**/
+vector steerlib_traceavoid_flat(float pitch, float length, vector vofs)
+{SELFPARAM();
+    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);
+}
+
+float beamsweep_badpoint(vector point,float waterok)
+{
+    float pc,pc2;
+
+    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+        return 1;
+
+    pc  = pointcontents(point);
+    pc2 = pointcontents(point - '0 0 1');
+
+    switch(pc)
+    {
+        case CONTENT_SOLID: break;
+        case CONTENT_SLIME: break;
+        case CONTENT_LAVA:  break;
+
+        case CONTENT_SKY:
+            return 1;
+
+        case CONTENT_EMPTY:
+            if (pc2 == CONTENT_SOLID)
+                return 0;
+
+            if (pc2 == CONTENT_WATER)
+                if(waterok)
+                    return 0;
+
+            break;
+
+        case CONTENT_WATER:
+            if(waterok)
+                return 0;
+
+            break;
+    }
+
+    return 1;
+}
+
+//#define BEAMSTEER_VISUAL
+float beamsweep(vector from, vector dir,float length, float step,float step_up, float step_down)
+{SELFPARAM();
+    float i;
+    vector a,b,u,d;
+
+    u = '0 0 1' * step_up;
+    d = '0 0 1' * step_down;
+
+    traceline(from + u, from - d,MOVE_NORMAL,self);
+    if(trace_fraction == 1.0)
+        return 0;
+
+    if(beamsweep_badpoint(trace_endpos,0))
+        return 0;
+
+    a = trace_endpos;
+    for(i = 0; i < length; i += step)
+    {
+
+        b = a + dir * step;
+        tracebox(a + u,'-4 -4 -4','4 4 4', b + u,MOVE_NORMAL,self);
+        if(trace_fraction != 1.0)
+            return i / length;
+
+        traceline(b + u, b - d,MOVE_NORMAL,self);
+        if(trace_fraction == 1.0)
+            return i / length;
+
+        if(beamsweep_badpoint(trace_endpos,0))
+            return i / length;
+#ifdef BEAMSTEER_VISUAL
+        te_lightning1(world,a+u,b+u);
+        te_lightning1(world,b+u,b-d);
+#endif
+        a = trace_endpos;
+    }
+
+    return 1;
+}
+
+vector steerlib_beamsteer(vector dir, float length, float step, float step_up, float step_down)
+{SELFPARAM();
+    float bm_forward, bm_right, bm_left,p;
+    vector vr,vl;
+
+    dir.z *= 0.15;
+    vr = vectoangles(dir);
+    //vr_x *= -1;
+
+    tracebox(self.origin + '0 0 1' * step_up, self.mins, self.maxs, ('0 0 1' * step_up) + self.origin +  (dir * length), MOVE_NOMONSTERS, self);
+    if(trace_fraction == 1.0)
+    {
+        //te_lightning1(self,self.origin,self.origin +  (dir * length));
+        return dir;
+    }
+
+
+
+
+    makevectors(vr);
+    bm_forward = beamsweep(self.origin, v_forward, length, step, step_up, step_down);
+
+    vr = normalize(v_forward + v_right * 0.125);
+    vl = normalize(v_forward - v_right * 0.125);
+
+    bm_right = beamsweep(self.origin, vr, length, step, step_up, step_down);
+    bm_left  = beamsweep(self.origin, vl, length, step, step_up, step_down);
+
+
+    p = bm_left + bm_right;
+    if(p == 2)
+    {
+        //te_lightning1(self,self.origin + '0 0 32',self.origin + '0 0 32' + vr * length);
+        //te_lightning1(self.tur_head,self.origin + '0 0 32',self.origin + '0 0 32' + vl * length);
+
+        return v_forward;
+    }
+
+    p = 2 - p;
+
+    vr = normalize(v_forward + v_right * p);
+    vl = normalize(v_forward - v_right * p);
+    bm_right = beamsweep(self.origin, vr, length, step, step_up, step_down);
+    bm_left  = beamsweep(self.origin, vl, length, step, step_up, step_down);
+
+
+    if(bm_left + bm_right < 0.15)
+    {
+        vr = normalize((v_forward*-1) + v_right * 0.75);
+        vl = normalize((v_forward*-1) - v_right * 0.75);
+
+        bm_right = beamsweep(self.origin, vr, length, step, step_up, step_down);
+        bm_left  = beamsweep(self.origin, vl, length, step, step_up, step_down);
+    }
+
+    //te_lightning1(self,self.origin + '0 0 32',self.origin + '0 0 32' + vr * length);
+    //te_lightning1(self.tur_head,self.origin + '0 0 32',self.origin + '0 0 32' + vl * length);
+
+    bm_forward *= bm_forward;
+    bm_right   *= bm_right;
+    bm_left    *= bm_left;
+
+    vr = vr * bm_right;
+    vl = vl * bm_left;
+
+    return normalize(vr + vl);
+
+}
+
+
+//////////////////////////////////////////////
+//     Testting                             //
+// Everything below this point is a mess :D //
+//////////////////////////////////////////////
+//#define TLIBS_TETSLIBS
+#ifdef TLIBS_TETSLIBS
+void flocker_die()
+{SELFPARAM();
+       Send_Effect(EFFECT_ROCKET_EXPLODE, self.origin, '0 0 0', 1);
+
+    self.owner.cnt += 1;
+    self.owner = world;
+
+    self.nextthink = time;
+    self.think = SUB_Remove;
+}
+
+
+void flocker_think()
+{SELFPARAM();
+    vector dodgemove,swarmmove;
+    vector reprellmove,wandermove,newmove;
+
+    self.angles_x = self.angles.x * -1;
+    makevectors(self.angles);
+    self.angles_x = self.angles.x * -1;
+
+    dodgemove   = steerlib_traceavoid(0.35,1000);
+    swarmmove   = steerlib_flock(500,75,700,500);
+    reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,2000) * 700;
+
+    if(vlen(dodgemove) == 0)
+    {
+        self.pos1 = steerlib_wander(0.5,0.1,self.pos1);
+        wandermove  = self.pos1 * 50;
+    }
+    else
+        self.pos1 = normalize(self.velocity);
+
+    dodgemove = dodgemove * vlen(self.velocity) * 5;
+
+    newmove = swarmmove + reprellmove + wandermove + dodgemove;
+    self.velocity = movelib_inertmove_byspeed(newmove,300,0.2,0.9);
+    //self.velocity  = movelib_inertmove(dodgemove,0.65);
+
+    self.velocity = movelib_dragvec(0.01,0.6);
+
+    self.angles = vectoangles(self.velocity);
+
+    if(self.health <= 0)
+        flocker_die();
+    else
+        self.nextthink = time + 0.1;
+}
+
+MODEL(FLOCKER, "models/turrets/rocket.md3");
+
+void spawn_flocker()
+{SELFPARAM();
+    entity flocker;
+
+    flocker = spawn ();
+
+    setorigin(flocker, self.origin + '0 0 32');
+    setmodel (flocker, MDL_FLOCKER);
+    setsize (flocker, '-3 -3 -3', '3 3 3');
+
+    flocker.flock_id   = self.flock_id;
+    flocker.classname  = "flocker";
+    flocker.owner      = self;
+    flocker.think      = flocker_think;
+    flocker.nextthink  = time + random() * 5;
+    PROJECTILE_MAKETRIGGER(flocker);
+    flocker.movetype   = MOVETYPE_BOUNCEMISSILE;
+    flocker.effects    = EF_LOWPRECISION;
+    flocker.velocity   = randomvec() * 300;
+    flocker.angles     = vectoangles(flocker.velocity);
+    flocker.health     = 10;
+    flocker.pos1      = normalize(flocker.velocity + randomvec() * 0.1);
+
+    self.cnt = self.cnt -1;
+
+}
+
+void flockerspawn_think()
+{SELFPARAM();
+
+
+    if(self.cnt > 0)
+        spawn_flocker();
+
+    self.nextthink = time + self.delay;
+
+}
+
+void flocker_hunter_think()
+{SELFPARAM();
+    vector dodgemove,attractmove,newmove;
+    entity e,ee;
+    float d,bd;
+
+    self.angles_x = self.angles.x * -1;
+    makevectors(self.angles);
+    self.angles_x = self.angles.x * -1;
+
+    if(self.enemy)
+    if(vlen(self.enemy.origin - self.origin) < 64)
+    {
+        ee = self.enemy;
+        ee.health = -1;
+        self.enemy = world;
+
+    }
+
+    if(!self.enemy)
+    {
+        e = findchainfloat(flock_id,self.flock_id);
+        while(e)
+        {
+            d = vlen(self.origin - e.origin);
+
+            if(e != self.owner)
+            if(e != ee)
+            if(d > bd)
+            {
+                self.enemy = e;
+                bd = d;
+            }
+            e = e.chain;
+        }
+    }
+
+    if(self.enemy)
+        attractmove = steerlib_attract(self.enemy.origin+self.enemy.velocity * 0.1,5000) * 1250;
+    else
+        attractmove = normalize(self.velocity) * 200;
+
+    dodgemove = steerlib_traceavoid(0.35,1500) * vlen(self.velocity);
+
+    newmove = dodgemove + attractmove;
+    self.velocity = movelib_inertmove_byspeed(newmove,1250,0.3,0.7);
+    self.velocity = movelib_dragvec(0.01,0.5);
+
+
+    self.angles = vectoangles(self.velocity);
+    self.nextthink = time + 0.1;
+}
+
+
+float globflockcnt;
+spawnfunc(flockerspawn)
+{SELFPARAM();
+    ++globflockcnt;
+
+    if(!self.cnt)      self.cnt = 20;
+    if(!self.delay)    self.delay = 0.25;
+    if(!self.flock_id) self.flock_id = globflockcnt;
+
+    self.think     = flockerspawn_think;
+    self.nextthink = time + 0.25;
+
+    self.enemy = spawn();
+
+    setmodel(self.enemy, MDL_FLOCKER);
+    setorigin(self.enemy,self.origin + '0 0 768' + (randomvec() * 128));
+
+    self.enemy.classname = "FLock Hunter";
+    self.enemy.scale     = 3;
+    self.enemy.effects   = EF_LOWPRECISION;
+    self.enemy.movetype  = MOVETYPE_BOUNCEMISSILE;
+    PROJECTILE_MAKETRIGGER(self.enemy);
+    self.enemy.think     = flocker_hunter_think;
+    self.enemy.nextthink = time + 10;
+    self.enemy.flock_id  = self.flock_id;
+    self.enemy.owner     = self;
+}
+#endif
+
+
+
diff --git a/qcsrc/server/bot/lib/steerlib/steerlib.qh b/qcsrc/server/bot/lib/steerlib/steerlib.qh
new file mode 100644 (file)
index 0000000..fcd35ba
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef STEERLIB_H
+#define STEERLIB_H
+
+.vector steerto;
+
+vector steerlib_arrive(vector point,float maximal_distance);
+vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense);
+vector steerlib_pull(vector point);
+
+#endif
diff --git a/qcsrc/server/movelib.qc b/qcsrc/server/movelib.qc
deleted file mode 100644 (file)
index acacba0..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-#include "movelib.qh"
-
-#ifdef SVQC
-.vector moveto;
-
-/**
-    Simulate drag
-    self.velocity = movelib_dragvec(self.velocity,0.02,0.5);
-**/
-vector movelib_dragvec(float drag, float exp_)
-{SELFPARAM();
-    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_dragflt(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_inertmove_byspeed(self.velocity,newvel,1000,0.1,0.9);
-**/
-vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
-{SELFPARAM();
-    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)
-{SELFPARAM();
-    return new_vel * new_bias + self.velocity * (1-new_bias);
-}
-
-void movelib_move(vector force,float max_velocity,float drag,float theMass,float breakforce)
-{SELFPARAM();
-    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 (theMass)
-        acceleration = vlen(force) / theMass;
-    else
-        acceleration = vlen(force);
-
-    if (self.flags & FL_ONGROUND)
-    {
-        if (breakforce)
-        {
-            breakvec = (normalize(self.velocity) * (breakforce / theMass) * deltatime);
-            self.velocity = self.velocity - breakvec;
-        }
-
-        self.velocity = self.velocity + force * (acceleration * 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' * autocvar_sv_gravity * deltatime;
-    }
-    else
-        self.velocity = self.velocity + '0 0 -1' * autocvar_sv_gravity * deltatime;
-
-    mspeed = vlen(self.velocity);
-
-    if (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_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      =  (autocvar_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;
-
-}
-*/
-
-void movelib_beak_simple(float force)
-{SELFPARAM();
-    float mspeed;
-    vector mdir;
-    float vz;
-
-    mspeed = max(0,vlen(self.velocity) - force);
-    mdir   = normalize(self.velocity);
-    vz = self.velocity.z;
-    self.velocity = mdir * mspeed;
-    self.velocity_z = vz;
-}
-
-/**
-Pitches and rolls the entity to match the gound.
-Yed need to set v_up and v_forward (generally by calling makevectors) before calling this.
-**/
-#endif
-
-void movelib_groundalign4point(float spring_length, float spring_up, float blendrate, float _max)
-{SELFPARAM();
-    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;
-
-    // Put springs slightly inside bbox
-    ahead = v_forward * (self.maxs.x * 0.8);
-    side  = v_right   * (self.maxs.y * 0.8);
-
-    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;
-
-    push_angle.x = (a.z - c.z) * _max;
-    push_angle.x += (b.z - d.z) * _max;
-
-    push_angle.z = (b.z - a.z) * _max;
-    push_angle.z += (d.z - c.z) * _max;
-
-    //self.angles_x += push_angle_x * 0.95;
-    //self.angles_z += push_angle_z * 0.95;
-
-    self.angles_x = ((1-blendrate) *  self.angles.x)  + (push_angle.x * blendrate);
-    self.angles_z = ((1-blendrate) *  self.angles.z)  + (push_angle.z * blendrate);
-
-    //a = self.origin;
-    setorigin(self,r);
-}
-
diff --git a/qcsrc/server/movelib.qh b/qcsrc/server/movelib.qh
deleted file mode 100644 (file)
index 8a4bfd4..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef MOVELIB_H
-#define MOVELIB_H
-
-#ifdef SVQC
-.vector moveto;
-
-/**
-    Simulate drag
-    self.velocity = movelib_dragvec(self.velocity,0.02,0.5);
-**/
-vector movelib_dragvec(float drag, float exp_);
-
-/**
-    Simulate drag
-    self.velocity *= movelib_dragflt(somespeed,0.01,0.7);
-**/
-float movelib_dragflt(float fspeed,float drag,float exp_);
-
-/**
-    Do a inertia simulation based on velocity.
-    Basicaly, this allows you to simulate loss of steering with higher speed.
-    self.velocity = movelib_inertmove_byspeed(self.velocity,newvel,1000,0.1,0.9);
-**/
-vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax);
-
-vector movelib_inertmove(vector new_vel,float new_bias);
-
-.float  movelib_lastupdate;
-void movelib_move(vector force,float max_velocity,float drag,float theMass,float breakforce);
-
-/*
-void movelib_move_simple(vector newdir,float velo,float blendrate)
-{
-    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
-}
-*/
-#define movelib_move_simple(newdir,velo,blendrate) \
-    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo
-
-#define movelib_move_simple_gravity(newdir,velo,blendrate) \
-    if(self.flags & FL_ONGROUND) movelib_move_simple(newdir,velo,blendrate)
-
-void movelib_beak_simple(float force);
-
-/**
-Pitches and rolls the entity to match the gound.
-Yed need to set v_up and v_forward (generally by calling makevectors) before calling this.
-**/
-#endif
-
-void movelib_groundalign4point(float spring_length, float spring_up, float blendrate, float _max);
-
-#endif
index 8564d34c59cb2a0b06e31df6bc93a78dd84f0d69..67bb246b07dfe582543e5ee9f74158f2285a214d 100644 (file)
@@ -70,7 +70,6 @@
     #include "../playerdemo.qh"
     #include "../round_handler.qh"
     #include "../item_key.qh"
-    #include "../pathlib/pathlib.qh"
     #include "../../common/vehicles/all.qh"
 #endif
 
diff --git a/qcsrc/server/pathlib/costs.qc b/qcsrc/server/pathlib/costs.qc
deleted file mode 100644 (file)
index 3e452f6..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-#include "pathlib.qh"
-
-float pathlib_g_static(entity parent,vector to, float static_cost)
-{
-    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 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);
-}
-
-
-/**
-    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 += 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))
-    float h,x,y;
-
-    x = fabs(a.x - b.x);
-    y = fabs(a.y - b.y);
-    h = pathlib_movecost * max(x,y);
-
-    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;
-
-    /*
-    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;
-}
-
-/**
-    This heuristic consider both stright and disagonal moves,
-    But has a separate cost for diagonal moves.
-**/
-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;
-
-    d1 = normalize(preprev - point);
-    d2 = normalize(prev    - point);
-    m = vlen(d1-d2);
-
-    return h * m;
-}
-
-
-float pathlib_h_diagonal3(vector a,vector b)
-{
-    float h_diag,h_str,h,x,y,z;
-
-    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);
-
-    return h;
-}
diff --git a/qcsrc/server/pathlib/debug.qc b/qcsrc/server/pathlib/debug.qc
deleted file mode 100644 (file)
index 37e167a..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#include "pathlib.qh"
-
-MODEL(SQUARE,       "models/pathlib/square.md3");
-MODEL(SQUARE_GOOD,  "models/pathlib/goodsquare.md3");
-MODEL(SQUARE_BAD,   "models/pathlib/badsquare.md3");
-MODEL(EDGE,         "models/pathlib/edge.md3");
-
-#ifdef TURRET_DEBUG
-void mark_error(vector where,float lifetime);
-void mark_info(vector where,float lifetime);
-entity mark_misc(vector where,float lifetime);
-#endif
-
-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()
-{SELFPARAM();
-    pathlib_showpath(self);
-    self.nextthink = time + 1;
-}
-
-void __showpath2_think()
-{SELFPARAM();
-    #ifdef TURRET_DEBUG
-       mark_info(self.origin,1);
-       #endif
-    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;
-}
-
-
-void pathlib_showsquare2(entity node ,vector ncolor,float align)
-{
-
-    node.alpha     = 0.25;
-    node.scale     = pathlib_gridsize / 512.001;
-    node.solid     = SOLID_NOT;
-
-    setmodel(node, MDL_SQUARE);
-    setorigin(node,node.origin);
-    node.colormod = ncolor;
-
-    if(align)
-    {
-        traceline(node.origin + '0 0 32', node.origin - '0 0 128', MOVE_WORLDONLY, node);
-        node.angles = vectoangles(trace_plane_normal);
-        node.angles_x -= 90;
-    }
-}
-
-void SUB_Remove();
-
-void pathlib_showsquare(vector where,float goodsquare,float _lifetime)
-{
-    entity s;
-
-    if(!_lifetime)
-        _lifetime = time + 30;
-    else
-        _lifetime += time;
-
-    s           = spawn();
-    s.alpha     = 0.25;
-    s.think     = SUB_Remove;
-    s.nextthink = _lifetime;
-    s.scale     = pathlib_gridsize / 512.001;
-    s.solid     = SOLID_NOT;
-
-    setmodel(s, goodsquare ? MDL_SQUARE_GOOD : MDL_SQUARE_BAD);
-
-    traceline(where + '0 0 32',where - '0 0 128',MOVE_WORLDONLY,s);
-
-    s.angles = vectoangles(trace_plane_normal);
-    s.angles_x -= 90;
-    setorigin(s,where);
-}
-
-void pathlib_showedge(vector where,float _lifetime,float rot)
-{
-    entity e;
-
-    if(!_lifetime)
-        _lifetime = time + 30;
-    else
-        _lifetime += time;
-
-    e           = spawn();
-    e.alpha     = 0.25;
-    e.think     = SUB_Remove;
-    e.nextthink = _lifetime;
-    e.scale     = pathlib_gridsize / 512;
-    e.solid     = SOLID_NOT;
-    setorigin(e,where);
-    setmodel(e, MDL_EDGE);
-    //traceline(where + '0 0 32',where - '0 0 128',MOVE_WORLDONLY,e);
-    //e.angles = vectoangles(trace_plane_normal);
-    e.angles_y = rot;
-    //e.angles_x += 90;
-
-}
diff --git a/qcsrc/server/pathlib/expandnode.qc b/qcsrc/server/pathlib/expandnode.qc
deleted file mode 100644 (file)
index 1f095a7..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-#include "pathlib.qh"
-#include "utility.qh"
-
-vector plib_points2[8];
-vector plib_points[8];
-float  plib_fvals[8];
-
-float pathlib_expandnode_starf(entity node, vector start, vector goal)
-{
-    vector where,f,r,t;
-    float fc,c;
-    entity nap;
-
-    where = node.origin;
-
-    f = PLIB_FORWARD * pathlib_gridsize;
-    r = PLIB_RIGHT   * pathlib_gridsize;
-
-    // Forward
-    plib_points[0] = where + f;
-
-    // Back
-    plib_points[1] = where - f;
-
-    // Right
-    plib_points[2] = where + r;
-
-    // Left
-    plib_points[3] = where - r;
-
-    // Forward-right
-    plib_points[4] = where + f + r;
-
-    // Forward-left
-    plib_points[5] = where + f - r;
-
-    // Back-right
-    plib_points[6] = where - f + r;
-
-    // Back-left
-    plib_points[7] = where - f - r;
-
-    for(int i=0;i < 8; ++i)
-    {
-        t = plib_points[i];
-        fc  = pathlib_heuristic(t,goal) + pathlib_cost(node, t, pathlib_gridsize);
-        plib_fvals[i] = fc;
-
-    }
-
-    fc = plib_fvals[0];
-    plib_points2[0] = plib_points[0];
-    vector bp;
-    bp = plib_points[0];
-    int fc2 = 0;
-    for(int i = 0; i < 8; ++i)
-    {
-        c = 0;
-        nap = pathlib_nodeatpoint(plib_points[i]);
-        if(nap)
-            if(nap.owner == openlist)
-                c = 1;
-        else
-            c = 1;
-
-        if(c)
-        if(plib_fvals[i] < fc)
-        {
-            bp = plib_points[i];
-            fc = plib_fvals[i];
-            plib_points2[fc2] = plib_points[i];
-            ++fc2;
-        }
-
-        /*
-        nap = pathlib_nodeatpoint(plib_points[i]);
-        if(nap)
-        if not nap.owner == closedlist)
-        {
-        }
-        */
-    }
-
-    pathlib_makenode(node, start, bp, goal, pathlib_gridsize);
-
-    for(int i = 0; i < 3; ++i)
-    {
-        pathlib_makenode(node, start, plib_points2[i], goal, pathlib_gridsize);
-    }
-
-    return pathlib_open_cnt;
-}
-
-float pathlib_expandnode_star(entity node, vector start, vector goal)
-{
-    vector point, where, f, r;
-
-    where = node.origin;
-
-    f = PLIB_FORWARD * pathlib_gridsize;
-    r = PLIB_RIGHT   * pathlib_gridsize;
-
-    if (node.pathlib_node_edgeflags == pathlib_node_edgeflag_unknown)
-        node.pathlib_node_edgeflags = tile_check_plus2(node.origin);
-
-    if(node.pathlib_node_edgeflags == pathlib_node_edgeflag_none)
-    {
-        LOG_TRACE("Node at ", vtos(node.origin), " not expanable");
-        return pathlib_open_cnt;
-    }
-
-    // Forward
-    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_forward)
-    {
-        point = where + f;
-        pathlib_makenode(node, start, point, goal, pathlib_movecost);
-    }
-
-    // Back
-    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_back)
-    {
-        point = where - f;
-        pathlib_makenode(node, start, point, goal, pathlib_movecost);
-    }
-
-    // Right
-        if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_right)
-    {
-        point = where + r;
-        pathlib_makenode(node, start, point, goal, pathlib_movecost);
-    }
-
-    // Left
-    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_left)
-    {
-        point = where - r;
-        pathlib_makenode(node, start, point, goal, pathlib_movecost);
-
-    }
-
-    // Forward-right
-    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_forwardright)
-    {
-        point = where + f + r;
-        pathlib_makenode(node, start, point, goal, pathlib_movecost_diag);
-    }
-
-    // Forward-left
-    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_forwardleft)
-    {
-        point = where + f - r;
-        pathlib_makenode(node, start, point, goal, pathlib_movecost_diag);
-
-    }
-
-    // Back-right
-    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_backright)
-    {
-        point = where - f + r;
-        pathlib_makenode(node, start, point, goal, pathlib_movecost_diag);
-    }
-
-    // Back-left
-    if (node.pathlib_node_edgeflags & pathlib_node_edgeflag_backleft)
-    {
-        point = where - f - r;
-        pathlib_makenode(node, start, point, goal, pathlib_movecost_diag);
-    }
-
-    return pathlib_open_cnt;
-}
-
-float pathlib_expandnode_octagon(entity node, vector start, vector goal)
-{
-    vector point,where,f,r;
-
-    where = node.origin;
-
-    f = PLIB_FORWARD * pathlib_gridsize;
-    r = PLIB_RIGHT   * pathlib_gridsize;
-
-    // Forward
-    point = where + f;
-    pathlib_makenode(node, start, point, goal, pathlib_movecost);
-
-    // Back
-    point = where - f;
-    pathlib_makenode(node, start, point, goal, pathlib_movecost);
-
-    // Right
-    point = where + r;
-    pathlib_makenode(node, start, point, goal, pathlib_movecost);
-
-    // Left
-    point = where - r;
-    pathlib_makenode(node, start, point, goal, pathlib_movecost);
-
-    f = PLIB_FORWARD * pathlib_gridsize * 0.5;
-    r = PLIB_RIGHT   * pathlib_gridsize * 0.5;
-
-    // Forward-right
-    point = where + f + r;
-    pathlib_makenode(node, start, point, goal, pathlib_movecost);
-
-
-    // Forward-left
-    point = where + f - r;
-    pathlib_makenode(node, start, point, goal, pathlib_movecost);
-
-
-    // Back-right
-    point = where - f + r;
-    pathlib_makenode(node, start, point, goal, pathlib_movecost);
-
-    // Back-left
-    point = where - f - r;
-    pathlib_makenode(node, start, point, goal, pathlib_movecost);
-
-    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;
-}
diff --git a/qcsrc/server/pathlib/main.qc b/qcsrc/server/pathlib/main.qc
deleted file mode 100644 (file)
index f097e8a..0000000
+++ /dev/null
@@ -1,569 +0,0 @@
-#include "../_all.qh"
-
-#include "pathlib.qh"
-#include "utility.qh"
-#include "../command/common.qh"
-
-void pathlib_deletepath(entity start)
-{
-    entity e;
-
-    e = findchainentity(owner, start);
-    while(e)
-    {
-        e.think = SUB_Remove;
-        e.nextthink = time;
-        e = e.chain;
-    }
-}
-
-//#define PATHLIB_NODEEXPIRE 0.05
-const float PATHLIB_NODEEXPIRE = 20;
-
-void dumpnode(entity n)
-{
-    n.is_path_node = false;
-    n.think        = SUB_Remove;
-    n.nextthink    = time;
-}
-
-entity pathlib_mknode(vector where,entity parent)
-{
-    entity node;
-
-    node = pathlib_nodeatpoint(where);
-    if(node)
-    {
-       #ifdef TURRET_DEBUG
-        mark_error(where, 60);
-        #endif
-        return node;
-    }
-
-    node = spawn();
-
-    node.think        = SUB_Remove;
-    node.nextthink    = time + PATHLIB_NODEEXPIRE;
-    node.is_path_node = true;
-    node.owner        = openlist;
-    node.path_prev    = parent;
-
-
-    setsize(node, '0 0 0', '0 0 0');
-
-    setorigin(node, where);
-    node.medium = pointcontents(where);
-    pathlib_showsquare(where, 1 ,15);
-
-    ++pathlib_made_cnt;
-    ++pathlib_open_cnt;
-
-    return node;
-}
-
-float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector goal,float cost)
-{
-    entity node;
-    float h,g,f,doedge = 0;
-    vector where;
-
-    ++pathlib_searched_cnt;
-
-    if(inwater(parent.origin))
-    {
-        LOG_TRACE("FromWater\n");
-        pathlib_expandnode = pathlib_expandnode_box;
-        pathlib_movenode   = pathlib_swimnode;
-    }
-    else
-    {
-        if(inwater(to))
-        {
-            LOG_TRACE("ToWater\n");
-            pathlib_expandnode = pathlib_expandnode_box;
-            pathlib_movenode   = pathlib_walknode;
-        }
-        else
-        {
-            LOG_TRACE("LandToLoand\n");
-            //if(edge_check(parent.origin))
-            //    return 0;
-
-            pathlib_expandnode = pathlib_expandnode_star;
-            pathlib_movenode   = pathlib_walknode;
-            doedge = 1;
-        }
-    }
-
-    node = pathlib_nodeatpoint(to);
-    if(node)
-    {
-        LOG_TRACE("NodeAtPoint\n");
-        ++pathlib_merge_cnt;
-
-        if(node.owner == openlist)
-        {
-            h = pathlib_heuristic(node.origin,goal);
-            g = pathlib_cost(parent,node.origin,cost);
-            f = g + h;
-
-            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 (!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;
-    }
-
-    where = pathlib_movenode(parent.origin, to, 0);
-
-    if (!pathlib_movenode_goodnode)
-    {
-        //pathlib_showsquare(where, 0 ,30);
-        //pathlib_showsquare(parent.origin, 1 ,30);
-        LOG_TRACE("pathlib_movenode_goodnode = 0\n");
-        return 0;
-    }
-
-    //pathlib_showsquare(where, 1 ,30);
-
-    if(pathlib_nodeatpoint(where))
-    {
-        LOG_TRACE("NAP WHERE :",vtos(where),"\n");
-        LOG_TRACE("not NAP TO:",vtos(to),"\n");
-        LOG_TRACE("NAP-NNAP:",ftos(vlen(to-where)),"\n\n");
-        return 0;
-    }
-
-
-    if(doedge)
-        if (!tile_check(where))
-        {
-            LOG_TRACE("tile_check fail\n");
-            pathlib_showsquare(where, 0 ,30);
-            return 0;
-        }
-
-
-    h = pathlib_heuristic(where,goal);
-    g = pathlib_cost(parent,where,cost);
-    f = g + h;
-
-    /*
-    node = findradius(where,pathlib_gridsize * 0.5);
-    while(node)
-    {
-        if(node.is_path_node == true)
-        {
-            ++pathlib_merge_cnt;
-            if(node.owner == openlist)
-            {
-                if(node.pathlib_node_g > g)
-                {
-                    //pathlib_movenode(where,node.origin,0);
-                    //if(pathlib_movenode_goodnode)
-                    //{
-                        //mark_error(node.origin + '0 0 128',30);
-                        node.pathlib_node_h = h;
-                        node.pathlib_node_g = g;
-                        node.pathlib_node_f = f;
-                        node.path_prev = parent;
-                    //}
-                }
-
-                if (!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 (!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)
-    {
-        LOG_TRACE("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)
-    {
-        vector goalmove;
-
-        goalmove = pathlib_walknode(node.origin,goal,1);
-        if(pathlib_movenode_goodnode)
-        {
-            goal_node         = node;
-            pathlib_foundgoal = true;
-        }
-    }
-}
-
-void pathlib_cleanup()
-{
-    best_open_node = world;
-
-    //return;
-
-    entity node;
-
-    node = findfloat(world,is_path_node, true);
-    while(node)
-    {
-        /*
-        node.owner = openlist;
-        node.pathlib_node_g = 0;
-        node.pathlib_node_h = 0;
-        node.pathlib_node_f = 0;
-        node.path_prev = world;
-        */
-
-        dumpnode(node);
-        node = findfloat(node,is_path_node, true);
-    }
-
-    if(openlist)
-        remove(openlist);
-
-    if(closedlist)
-        remove(closedlist);
-
-    openlist       = world;
-    closedlist     = world;
-
-}
-
-float Cosine_Interpolate(float a, float b, float x)
-{
-    float ft,f;
-
-       ft = x * 3.1415927;
-       f = (1 - cos(ft)) * 0.5;
-
-       return  a*(1-f) + b*f;
-}
-
-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)
-    {
-        //mark_error(c,30);
-        return 1;
-    }
-    //mark_info(c,30);
-    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;
-}
-
-float buildpath_nodefilter_none(vector n,vector c,vector p)
-{
-    return 0;
-}
-
-entity path_build(entity next, vector where, entity prev, entity start)
-{
-    entity path;
-
-    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)
-{SELFPARAM();
-    entity path, start, end, open, n, ln;
-    float ptime, ftime, ctime;
-
-    ptime = gettime(GETTIME_REALTIME);
-    pathlib_starttime = ptime;
-
-    pathlib_cleanup();
-
-    // Select water<->land capable node make/link
-    pathlib_makenode     = pathlib_makenode_adaptive;
-
-    // Select XYZ cost estimate
-    //pathlib_heuristic    = pathlib_h_diagonal3;
-    pathlib_heuristic    = pathlib_h_diagonal;
-
-    // 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;
-
-    // Filter tiles with cross pattern
-    tile_check = tile_check_cross;
-
-    // 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 (!openlist)
-        openlist       = spawn();
-
-    if (!closedlist)
-        closedlist     = spawn();
-
-    pathlib_closed_cnt       = 0;
-    pathlib_open_cnt         = 0;
-    pathlib_made_cnt         = 0;
-    pathlib_merge_cnt        = 0;
-    pathlib_searched_cnt     = 0;
-    pathlib_bestopen_seached = 0;
-    pathlib_bestcash_hits    = 0;
-    pathlib_bestcash_saved   = 0;
-
-    pathlib_gridsize       = 128;
-    pathlib_movecost       = pathlib_gridsize;
-    pathlib_movecost_diag  = vlen(('1 1 0' * pathlib_gridsize));
-    pathlib_movecost_waterfactor = 25000000;
-    pathlib_foundgoal      = 0;
-
-    movenode_boxmax   = self.maxs * 1.1;
-    movenode_boxmin   = self.mins * 1.1;
-
-    movenode_stepsize = pathlib_gridsize * 0.25;
-
-    tile_check_size = pathlib_gridsize * 0.5;
-    tile_check_up   = '0 0 2' * pathlib_gridsize;
-    tile_check_up   = '0 0 128';
-    tile_check_down = '0 0 3' * pathlib_gridsize;
-    tile_check_down = '0 0 256';
-
-    //movenode_stepup   = '0 0 128';
-    movenode_stepup   = '0 0 36';
-    movenode_maxdrop  = '0 0 512';
-    //movenode_maxdrop  = '0 0 512';
-    movenode_boxup    = '0 0 72';
-
-    from.x = fsnap(from.x, pathlib_gridsize);
-    from.y = fsnap(from.y, pathlib_gridsize);
-    //from_z += 32;
-
-    to.x = fsnap(to.x, pathlib_gridsize);
-    to.y = fsnap(to.y, pathlib_gridsize);
-    //to_z += 32;
-
-    LOG_TRACE("AStar init\n");
-    path = pathlib_mknode(from, world);
-    pathlib_close_node(path, to);
-    if(pathlib_foundgoal)
-    {
-        LOG_TRACE("AStar: Goal found on first node!\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)
-    {
-        LOG_TRACE("AStar path 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)
-    {
-        if((gettime(GETTIME_REALTIME) - pathlib_starttime) > pathlib_maxtime)
-        {
-            LOG_TRACE("Path took to long to compute!\n");
-            LOG_TRACE("Nodes - created: ", ftos(pathlib_made_cnt),"\n");
-            LOG_TRACE("Nodes -    open: ", ftos(pathlib_open_cnt),"\n");
-            LOG_TRACE("Nodes -  merged: ", ftos(pathlib_merge_cnt),"\n");
-            LOG_TRACE("Nodes -  closed: ", ftos(pathlib_closed_cnt),"\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(n,from,to);
-
-        if(pathlib_foundgoal)
-        {
-            LOG_TRACE("Target found. Rebuilding and filtering path...\n");
-            ftime = gettime(GETTIME_REALTIME);
-            ptime = ftime - ptime;
-
-            start = path_build(world,path.origin,world,world);
-            end   = path_build(world,goal_node.origin,world,start);
-            ln    = end;
-
-            open = goal_node;
-            for(open = goal_node; open.path_prev != path; open = open.path_prev)
-            {
-                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;
-
-            ctime = gettime(GETTIME_REALTIME);
-            pathlib_cleanup();
-            ctime = gettime(GETTIME_REALTIME) - ctime;
-
-
-#ifdef DEBUGPATHING
-            pathlib_showpath2(start);
-
-            LOG_TRACE("Time used -      pathfinding: ", ftos(ptime),"\n");
-            LOG_TRACE("Time used - rebuild & filter: ", ftos(ftime),"\n");
-            LOG_TRACE("Time used -          cleanup: ", ftos(ctime),"\n");
-            LOG_TRACE("Time used -            total: ", ftos(ptime + ftime + ctime),"\n");
-            LOG_TRACE("Time used -         # frames: ", ftos(ceil((ptime + ftime + ctime) / sys_frametime)),"\n\n");
-            LOG_TRACE("Nodes -         created: ", ftos(pathlib_made_cnt),"\n");
-            LOG_TRACE("Nodes -            open: ", ftos(pathlib_open_cnt),"\n");
-            LOG_TRACE("Nodes -          merged: ", ftos(pathlib_merge_cnt),"\n");
-            LOG_TRACE("Nodes -          closed: ", ftos(pathlib_closed_cnt),"\n");
-            LOG_TRACE("Nodes -        searched: ", ftos(pathlib_searched_cnt),"\n");
-            LOG_TRACE("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
-            LOG_TRACE("Nodes bestcash -   hits: ", ftos(pathlib_bestcash_hits),"\n");
-            LOG_TRACE("Nodes bestcash -   save: ", ftos(pathlib_bestcash_saved),"\n");
-            LOG_TRACE("AStar done.\n");
-#endif
-            return start;
-        }
-    }
-
-    LOG_TRACE("A* Faild to find a path! Try a smaller gridsize.\n");
-
-    pathlib_cleanup();
-
-    return world;
-}
diff --git a/qcsrc/server/pathlib/main.qh b/qcsrc/server/pathlib/main.qh
deleted file mode 100644 (file)
index 177c432..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef PATHLIB_MAIN_H
-#define PATHLIB_MAIN_H
-float buildpath_nodefilter_none(vector n,vector c,vector p);
-entity path_build(entity next, vector where, entity prev, entity start);
-#endif
diff --git a/qcsrc/server/pathlib/movenode.qc b/qcsrc/server/pathlib/movenode.qc
deleted file mode 100644 (file)
index 6645d71..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-#include "../_all.qh"
-
-#include "pathlib.qh"
-#include "utility.qh"
-
-vector pathlib_wateroutnode(vector start,vector end, float doedge)
-{SELFPARAM();
-    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 (!(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;
-    }
-
-    if(pointcontents(surface + '0 0 1') != CONTENT_EMPTY)
-        return end;
-
-    tracebox(start + '0 0 64', movenode_boxmin,movenode_boxmax, end + '0 0 64', MOVE_WORLDONLY, self);
-    if(trace_fraction == 1)
-        pathlib_movenode_goodnode = 1;
-
-    if(fabs(surface.z - end.z) > 32)
-        pathlib_movenode_goodnode = 0;
-
-    return end;
-}
-
-vector pathlib_swimnode(vector start,vector end, float doedge)
-{SELFPARAM();
-    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, doedge);
-
-    tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, self);
-    if(trace_fraction == 1)
-        pathlib_movenode_goodnode = 1;
-
-    return end;
-}
-
-vector pathlib_flynode(vector start,vector end, float doedge)
-{SELFPARAM();
-    pathlib_movenode_goodnode = 0;
-
-    end.x = fsnap(end.x, pathlib_gridsize);
-    end.y = fsnap(end.y, pathlib_gridsize);
-
-    tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, self);
-    if(trace_fraction == 1)
-        pathlib_movenode_goodnode = 1;
-
-    return end;
-}
-
-void a_think()
-{SELFPARAM();
-    te_lightning1(self,self.origin, self.pos1);
-    if(self.cnt < time)
-        remove(self);
-    else
-        self.nextthink = time + 0.2;
-}
-
-vector pathlib_walknode(vector start,vector end,float doedge)
-{SELFPARAM();
-    vector direction,point,last_point,s,e;
-    float steps, distance, i;
-
-    LOG_TRACE("Walking node from ", vtos(start), " to ", vtos(end), "\n");
-
-    pathlib_movenode_goodnode = 0;
-
-    end.x = fsnap(end.x,pathlib_gridsize);
-    end.y = fsnap(end.y,pathlib_gridsize);
-    start.x = fsnap(start.x,pathlib_gridsize);
-    start.y = fsnap(start.y,pathlib_gridsize);
-
-    // Find the floor
-    traceline(start + movenode_stepup, start - movenode_maxdrop, MOVE_WORLDONLY, self);
-    if(trace_fraction == 1.0)
-    {
-        entity a;
-        a = spawn();
-        a.think = a_think;
-        a.nextthink = time;
-        setorigin(a,start + movenode_stepup);
-        a.pos1 = trace_endpos;
-        //start - movenode_maxdrop
-        a.cnt = time + 10;
-
-        LOG_TRACE("I cant walk on air!\n");
-        return trace_endpos;
-    }
-
-    start = trace_endpos;
-
-    // Find the direcion, without Z
-    s   = start; e   = end;
-    //e_z = 0; s_z = 0;
-    direction = normalize(e - s);
-
-    distance  = vlen(start - end);
-    steps     = rint(distance / movenode_stepsize);
-
-    last_point = start;
-    for(i = 1; i < steps; ++i)
-    {
-        point = last_point + (direction * movenode_stepsize);
-        traceline(point + movenode_stepup,point - movenode_maxdrop,MOVE_WORLDONLY,self);
-        if(trace_fraction == 1.0)
-            return trace_endpos;
-
-        last_point = trace_endpos;
-    }
-
-    point = last_point + (direction * movenode_stepsize);
-    point.x = fsnap(point.x,pathlib_gridsize);
-    point.y = fsnap(point.y,pathlib_gridsize);
-
-    //dprint("end_x:  ",ftos(end_x),  "  end_y:  ",ftos(end_y),"\n");
-    //dprint("point_x:",ftos(point_x),"  point_y:",ftos(point_y),"\n\n");
-
-    traceline(point + movenode_stepup, point - movenode_maxdrop,MOVE_WORLDONLY,self);
-    if(trace_fraction == 1.0)
-        return trace_endpos;
-
-    last_point = trace_endpos;
-
-    tracebox(start + movenode_boxup, movenode_boxmin,movenode_boxmax, last_point + movenode_boxup, MOVE_WORLDONLY, self);
-    if(trace_fraction != 1.0)
-        return trace_endpos;
-
-    pathlib_movenode_goodnode = 1;
-    return last_point;
-}
diff --git a/qcsrc/server/pathlib/path_waypoint.qc b/qcsrc/server/pathlib/path_waypoint.qc
deleted file mode 100644 (file)
index 615840d..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-#include "pathlib.qh"
-#include "main.qh"
-
-var float pathlib_wpp_open(entity wp, entity child, float cost);
-
-void pathlib_wpp_close(entity wp)
-{
-    --pathlib_open_cnt;
-    ++pathlib_closed_cnt;
-
-    wp.pathlib_list = closedlist;
-
-    if(wp == best_open_node)
-        best_open_node = world;
-
-    if(wp == goal_node)
-        pathlib_foundgoal = true;
-}
-
-float pathlib_wpp_opencb(entity wp, entity child, float cost)
-{
-
-    if(child.pathlib_list == closedlist)
-        return false;
-
-       // FIXME! wp.wp##mincost is NOT distance. Make it distance or add a field for distance to be used here (for better speed)
-       cost = vlen(child.origin - wp.origin);
-
-    child.path_prev     = wp;
-    child.pathlib_list   = openlist;
-    child.pathlib_node_g = wp.pathlib_node_g + cost;
-    child.pathlib_node_h = pathlib_heuristic(child.origin, goal_node.origin);
-    child.pathlib_node_c = pathlib_wpp_waypointcallback(child, wp);
-    child.pathlib_node_f = child.pathlib_node_g + child.pathlib_node_h + child.pathlib_node_c;
-
-
-    if(child == goal_node)
-        pathlib_foundgoal = true;
-
-    ++pathlib_open_cnt;
-
-    if(best_open_node.pathlib_node_f > child.pathlib_node_f)
-        best_open_node = child;
-
-    return true;
-}
-
-float pathlib_wpp_openncb(entity wp, entity child, float cost)
-{
-
-    if(child.pathlib_list == closedlist)
-        return false;
-
-       // FIXME! wp.wp##mincost is NOT distance. Make it distance or add a field for distance to be used here (for better speed)
-       cost = vlen(child.origin - wp.origin);
-
-    child.path_prev     = wp;
-    child.pathlib_list   = openlist;
-    child.pathlib_node_g = wp.pathlib_node_g + cost;
-    child.pathlib_node_h = pathlib_heuristic(child.origin, goal_node.origin);
-    child.pathlib_node_f = child.pathlib_node_g + child.pathlib_node_h;
-
-    if(child == goal_node)
-        pathlib_foundgoal = true;
-
-    ++pathlib_open_cnt;
-
-    if(best_open_node.pathlib_node_f > child.pathlib_node_f)
-        best_open_node = child;
-
-    return true;
-}
-
-float pathlib_wpp_expand(entity wp)
-{
-    if(wp.wp00) pathlib_wpp_open(wp,wp.wp00,wp.wp00mincost); else return 0;
-    if(wp.wp01) pathlib_wpp_open(wp,wp.wp01,wp.wp01mincost); else return 1;
-    if(wp.wp02) pathlib_wpp_open(wp,wp.wp02,wp.wp02mincost); else return 2;
-    if(wp.wp03) pathlib_wpp_open(wp,wp.wp03,wp.wp03mincost); else return 3;
-    if(wp.wp04) pathlib_wpp_open(wp,wp.wp04,wp.wp04mincost); else return 4;
-    if(wp.wp05) pathlib_wpp_open(wp,wp.wp05,wp.wp05mincost); else return 5;
-    if(wp.wp06) pathlib_wpp_open(wp,wp.wp06,wp.wp06mincost); else return 6;
-    if(wp.wp07) pathlib_wpp_open(wp,wp.wp07,wp.wp07mincost); else return 7;
-    if(wp.wp08) pathlib_wpp_open(wp,wp.wp08,wp.wp08mincost); else return 8;
-    if(wp.wp09) pathlib_wpp_open(wp,wp.wp09,wp.wp09mincost); else return 9;
-    if(wp.wp10) pathlib_wpp_open(wp,wp.wp10,wp.wp10mincost); else return 10;
-    if(wp.wp11) pathlib_wpp_open(wp,wp.wp11,wp.wp11mincost); else return 11;
-    if(wp.wp12) pathlib_wpp_open(wp,wp.wp12,wp.wp12mincost); else return 12;
-    if(wp.wp13) pathlib_wpp_open(wp,wp.wp13,wp.wp13mincost); else return 13;
-    if(wp.wp14) pathlib_wpp_open(wp,wp.wp14,wp.wp14mincost); else return 14;
-    if(wp.wp15) pathlib_wpp_open(wp,wp.wp15,wp.wp15mincost); else return 15;
-    if(wp.wp16) pathlib_wpp_open(wp,wp.wp16,wp.wp16mincost); else return 16;
-    if(wp.wp17) pathlib_wpp_open(wp,wp.wp17,wp.wp17mincost); else return 17;
-    if(wp.wp18) pathlib_wpp_open(wp,wp.wp18,wp.wp18mincost); else return 18;
-    if(wp.wp19) pathlib_wpp_open(wp,wp.wp19,wp.wp19mincost); else return 19;
-    if(wp.wp20) pathlib_wpp_open(wp,wp.wp20,wp.wp20mincost); else return 20;
-    if(wp.wp21) pathlib_wpp_open(wp,wp.wp21,wp.wp21mincost); else return 21;
-    if(wp.wp22) pathlib_wpp_open(wp,wp.wp22,wp.wp22mincost); else return 22;
-    if(wp.wp23) pathlib_wpp_open(wp,wp.wp23,wp.wp23mincost); else return 23;
-    if(wp.wp24) pathlib_wpp_open(wp,wp.wp24,wp.wp24mincost); else return 24;
-    if(wp.wp25) pathlib_wpp_open(wp,wp.wp25,wp.wp25mincost); else return 25;
-    if(wp.wp26) pathlib_wpp_open(wp,wp.wp26,wp.wp26mincost); else return 26;
-    if(wp.wp27) pathlib_wpp_open(wp,wp.wp27,wp.wp27mincost); else return 27;
-    if(wp.wp28) pathlib_wpp_open(wp,wp.wp28,wp.wp28mincost); else return 28;
-    if(wp.wp29) pathlib_wpp_open(wp,wp.wp29,wp.wp29mincost); else return 29;
-    if(wp.wp30) pathlib_wpp_open(wp,wp.wp30,wp.wp30mincost); else return 30;
-    if(wp.wp31) pathlib_wpp_open(wp,wp.wp31,wp.wp31mincost); else return 31;
-
-    return 32;
-}
-
-entity pathlib_wpp_bestopen()
-{
-    entity n, best;
-
-    if(best_open_node)
-        return best_open_node;
-
-    n = findchainentity(pathlib_list, openlist);
-    best = n;
-    while(n)
-    {
-        if(n.pathlib_node_f < best.pathlib_node_f)
-            best = n;
-
-        n = n.chain;
-    }
-
-    return best;
-
-}
-
-entity pathlib_waypointpath(entity wp_from, entity wp_to, float callback)
-{
-    entity n;
-    float ptime;
-
-    ptime                                      = gettime(GETTIME_REALTIME);
-    pathlib_starttime          = ptime;
-       pathlib_movecost                = 300;
-       pathlib_movecost_diag   = vlen('1 1 0' * pathlib_movecost);
-
-       if (!pathlib_wpp_waypointcallback)
-               callback = false;
-
-       if (callback)
-               pathlib_wpp_open = pathlib_wpp_opencb;
-       else
-               pathlib_wpp_open = pathlib_wpp_openncb;
-
-       pathlib_heuristic = pathlib_h_none;
-
-    if (!openlist)
-        openlist       = spawn();
-
-    if (!closedlist)
-        closedlist     = spawn();
-
-    pathlib_closed_cnt       = 0;
-    pathlib_open_cnt         = 0;
-    pathlib_searched_cnt     = 0;
-    pathlib_foundgoal      = false;
-
-    LOG_TRACE("pathlib_waypointpath init\n");
-
-    // Initialize waypoint grid
-    // FIXME! presisted chain for better preformance
-    for(n = findchain(classname, "waypoint"); n; n = n.chain)
-    {
-        n.pathlib_list = world;
-        n.pathlib_node_g = 0;
-        n.pathlib_node_f = 0;
-        n.pathlib_node_h = 0;
-
-        //setmodel(n, "models/runematch/rune.mdl");
-        //n.effects = EF_LOWPRECISION;
-        //n.colormod = '0 0 0';
-        //n.scale = 1;
-
-    }
-
-    goal_node  = wp_to;
-    start_node = wp_from;
-
-    start_node.pathlib_list = closedlist;
-    LOG_TRACE("Expanding ",ftos(pathlib_wpp_expand(start_node))," links\n");
-    if(pathlib_open_cnt <= 0)
-    {
-        LOG_TRACE("pathlib_waypointpath: Start waypoint not linked! aborting.\n");
-        return world;
-    }
-
-    return world;
-}
-
-entity pathlib_waypointpath_step()
-{
-    entity n;
-
-    n = pathlib_wpp_bestopen();
-    if(!n)
-    {
-        LOG_TRACE("Cannot find best open node, abort.\n");
-        return world;
-    }
-    pathlib_wpp_close(n);
-       LOG_TRACE("Expanding ",ftos(pathlib_wpp_expand(n))," links\n");
-
-    if(pathlib_foundgoal)
-    {
-        entity start, end, open, ln;
-
-        LOG_TRACE("Target found. Rebuilding and filtering path...\n");
-
-               buildpath_nodefilter = buildpath_nodefilter_none;
-               start = path_build(world, start_node.origin, world, world);
-               end   = path_build(world, goal_node.origin, world, start);
-               ln    = end;
-
-               for(open = goal_node; open.path_prev != start_node; open = open.path_prev)
-               {
-                       n    = path_build(ln,open.origin,open.path_prev,start);
-                       ln.path_prev = n;
-                       ln = n;
-               }
-               start.path_next = n;
-               n.path_prev = start;
-
-        return start;
-    }
-
-    return world;
-}
-void plas_think()
-{SELFPARAM();
-    pathlib_waypointpath_step();
-    if(pathlib_foundgoal)
-        return;
-    self.nextthink = time + 0.1;
-}
-
-void pathlib_waypointpath_autostep()
-{
-    entity n;
-    n = spawn();
-    n.think = plas_think;
-    n.nextthink = time + 0.1;
-}
diff --git a/qcsrc/server/pathlib/pathlib.qh b/qcsrc/server/pathlib/pathlib.qh
deleted file mode 100644 (file)
index dbf7852..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-#ifndef PATHLIB_H
-#define PATHLIB_H
-
-.entity pathlib_list;
-.entity path_next;
-.entity path_prev;
-
-#define inwater(point) (pointcontents(point) == CONTENT_WATER)
-#define medium spawnshieldtime
-
-const vector PLIB_FORWARD = '0 1 0';
-//#define PLIB_BACK    '0 -1 0'
-const vector PLIB_RIGHT = '1 0 0';
-//#define PLIB_LEFT    '-1 0 0'
-
-#define DEBUGPATHING
-#ifdef DEBUGPATHING
-void pathlib_showpath(entity start);
-void pathlib_showpath2(entity path);
-#endif
-
-entity openlist;
-entity closedlist;
-
-entity goal_node;
-entity start_node;
-
-.float is_path_node;
-.float pathlib_node_g;
-.float pathlib_node_h;
-.float pathlib_node_f;
-.float pathlib_node_c;
-
-const float pathlib_node_edgeflag_unknown              = 0;
-const float pathlib_node_edgeflag_left                         = 2;
-const float pathlib_node_edgeflag_right                = 4;
-const float pathlib_node_edgeflag_forward              = 8;
-const float pathlib_node_edgeflag_back                         = 16;
-const float pathlib_node_edgeflag_backleft             = 32;
-const float pathlib_node_edgeflag_backright    = 64;
-const float pathlib_node_edgeflag_forwardleft  = 128;
-const float pathlib_node_edgeflag_forwardright         = 256;
-const float pathlib_node_edgeflag_none                         = 512;
-.float pathlib_node_edgeflags;
-
-float pathlib_open_cnt;
-float pathlib_closed_cnt;
-float pathlib_made_cnt;
-float pathlib_merge_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_foundgoal;
-
-float pathlib_starttime;
-const float pathlib_maxtime = 60;
-
-entity best_open_node;
-
-vector tile_check_up;
-vector tile_check_down;
-float  tile_check_size;
-float     tile_check_cross(vector where);
-float     tile_check_plus(vector where);
-float     tile_check_star(vector where);
-var float tile_check(vector where);
-
-float  movenode_stepsize;
-vector movenode_stepup;
-vector movenode_maxdrop;
-vector movenode_boxup;
-vector movenode_boxmax;
-vector movenode_boxmin;
-float  pathlib_movenode_goodnode;
-
-vector     pathlib_wateroutnode(vector start, vector end, float doedge);
-vector     pathlib_swimnode(vector start, vector end, float doedge);
-vector     pathlib_flynode(vector start, vector end, float doedge);
-vector     pathlib_walknode(vector start, vector end, float doedge);
-var vector pathlib_movenode(vector start, vector end, float doedge);
-
-float      pathlib_expandnode_star(entity node, vector start, vector goal);
-float      pathlib_expandnode_box(entity node, vector start, vector goal);
-float      pathlib_expandnode_octagon(entity node, vector start, vector goal);
-var float  pathlib_expandnode(entity node, vector start, vector goal);
-
-float      pathlib_g_static(entity parent, vector to, float static_cost);
-float      pathlib_g_static_water(entity parent, vector to, float static_cost);
-float      pathlib_g_euclidean(entity parent, vector to, float static_cost);
-float      pathlib_g_euclidean_water(entity parent, vector to, float static_cost);
-var float  pathlib_cost(entity parent, vector to, float static_cost);
-
-float      pathlib_h_manhattan(vector a, vector b);
-float      pathlib_h_diagonal(vector a, vector b);
-float      pathlib_h_euclidean(vector a,vector b);
-float      pathlib_h_diagonal2(vector a, vector b);
-float      pathlib_h_diagonal3(vector a, vector b);
-float      pathlib_h_diagonal2sdp(vector preprev, vector prev, vector point, vector end);
-float      pathlib_h_none(vector preprev, vector prev) { return 0; }
-var float  pathlib_heuristic(vector from, vector to);
-
-var float  pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost);
-var float  buildpath_nodefilter(vector n,vector c,vector p);
-
-var float  pathlib_wpp_waypointcallback(entity wp, entity wp_prev);
-
-#ifdef DEBUGPATHING
-       #include "debug.qc"
-#endif
-
-#endif
diff --git a/qcsrc/server/pathlib/utility.qc b/qcsrc/server/pathlib/utility.qc
deleted file mode 100644 (file)
index 9028f85..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-#include "utility.qh"
-
-#include "pathlib.qh"
-
-float location_isok(vector point, float water_isok, float air_isok)
-{
-    float pc,pc2;
-
-    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
-        return 0;
-
-    pc  = pointcontents(point);
-    pc2 = pointcontents(point - '0 0 1');
-
-    switch(pc)
-    {
-        case CONTENT_SOLID:
-            break;
-
-        case CONTENT_SLIME:
-            break;
-
-        case CONTENT_LAVA:
-            break;
-
-        case CONTENT_SKY:
-            break;
-
-        case CONTENT_EMPTY:
-            if (pc2 == CONTENT_SOLID)
-                return 1;
-
-            if (pc2 == CONTENT_EMPTY)
-                if(air_isok)
-                    return 1;
-
-            if (pc2 == CONTENT_WATER)
-                if(water_isok)
-                    return 1;
-
-            break;
-
-        case CONTENT_WATER:
-            if (water_isok)
-                return 1;
-
-            break;
-    }
-
-    return 0;
-}
-
-entity pathlib_nodeatpoint(vector where)
-{
-    entity node;
-
-    ++pathlib_searched_cnt;
-
-    where.x = fsnap(where.x,pathlib_gridsize);
-    where.y = fsnap(where.y,pathlib_gridsize);
-
-    node = findradius(where,pathlib_gridsize * 0.5);
-    while(node)
-    {
-        if(node.is_path_node == true)
-            return node;
-
-        node = node.chain;
-    }
-
-    return world;
-}
-
-float tile_check_cross(vector where)
-{SELFPARAM();
-    vector p,f,r;
-
-    f = PLIB_FORWARD * tile_check_size;
-    r = PLIB_RIGHT   * tile_check_size;
-
-
-    // forward-right
-    p = where + f + r;
-    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
-    if (!location_isok(trace_endpos, 1, 0))
-        return 0;
-
-    // Forward-left
-    p = where + f - r;
-    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
-    if (!location_isok(trace_endpos, 1, 0))
-        return 0;
-
-    // Back-right
-    p = where - f + r;
-    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
-    if (!location_isok(trace_endpos, 1 ,0))
-        return 0;
-
-    //Back-left
-    p = where - f - r;
-    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
-    if (!location_isok(trace_endpos, 1, 0))
-        return 0;
-
-    return 1;
-}
-
-float tile_check_plus(vector where)
-{SELFPARAM();
-    vector p,f,r;
-
-    f = PLIB_FORWARD * tile_check_size;
-    r = PLIB_RIGHT   * tile_check_size;
-
-    // forward
-    p = where + f;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if (!location_isok(trace_endpos,1,0))
-        return 0;
-
-
-    //left
-    p = where - r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if (!location_isok(trace_endpos,1,0))
-        return 0;
-
-    // Right
-    p = where + r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if (!location_isok(trace_endpos,1,0))
-        return 0;
-
-    //Back
-    p = where - f;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if (!location_isok(trace_endpos,1,0))
-        return 0;
-
-    return 1;
-}
-
-float tile_check_plus2(vector where)
-{SELFPARAM();
-    vector p,f,r;
-    float i = 0, e = 0;
-
-    f = PLIB_FORWARD * pathlib_gridsize;
-    r = PLIB_RIGHT   * pathlib_gridsize;
-
-//#define pathlib_node_edgeflag_left    2
-//#define pathlib_node_edgeflag_right   4
-//#define pathlib_node_edgeflag_forward 8
-//#define pathlib_node_edgeflag_back    16
-
-    // forward
-    p = where + f;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if (location_isok(trace_endpos,1,0))
-    {
-       ++i;
-       e |= pathlib_node_edgeflag_forward;
-    }
-
-
-    //left
-    p = where - r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if (location_isok(trace_endpos,1,0))
-    {
-       ++i;
-       e |= pathlib_node_edgeflag_left;
-    }
-
-
-    // Right
-    p = where + r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if (location_isok(trace_endpos,1,0))
-    {
-       ++i;
-       e |= pathlib_node_edgeflag_right;
-    }
-
-    //Back
-    p = where - f;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if (location_isok(trace_endpos,1,0))
-    {
-       ++i;
-       e |= pathlib_node_edgeflag_back;
-    }
-
-    // forward-right
-    p = where + f + r;
-    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
-    if (location_isok(trace_endpos, 1, 0))
-    {
-       ++i;
-       e |= pathlib_node_edgeflag_forwardright;
-    }
-
-    // Forward-left
-    p = where + f - r;
-    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
-    if (location_isok(trace_endpos, 1, 0))
-    {
-       ++i;
-       e |= pathlib_node_edgeflag_forwardleft;
-    }
-
-    // Back-right
-    p = where - f + r;
-    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
-    if (location_isok(trace_endpos, 1 ,0))
-    {
-       ++i;
-       e |= pathlib_node_edgeflag_backright;
-    }
-
-    //Back-left
-    p = where - f - r;
-    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, self);
-    if (location_isok(trace_endpos, 1, 0))
-    {
-       ++i;
-       e |= pathlib_node_edgeflag_backleft;
-    }
-
-
-    if(i == 0)
-        e = pathlib_node_edgeflag_none;
-
-    return e;
-}
-
-float tile_check_star(vector where)
-{
-    if(tile_check_plus(where))
-        return tile_check_cross(where);
-
-    return 0;
-}
-
diff --git a/qcsrc/server/pathlib/utility.qh b/qcsrc/server/pathlib/utility.qh
deleted file mode 100644 (file)
index bf72549..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef PATHLIB_UTILITY
-#define PATHLIB_UTILITY
-float fsnap(float val,float fsize);
-entity pathlib_nodeatpoint(vector where);
-float tile_check_plus2(vector where);
-#endif
index 75c00833f4c5b9819a5d6e505cf2aa1a04ef78a2..ad1e855e50c0a3138b40c70fb6d5c734fd89991a 100644 (file)
@@ -7,6 +7,8 @@
 
 #include "../lib/_all.inc"
 
+#include "bot/lib/steerlib/steerlib.qh"
+
 #include "anticheat.qc"
 #include "antilag.qc"
 #include "campaign.qc"
@@ -29,7 +31,6 @@
 #include "item_key.qc"
 #include "mapvoting.qc"
 #include "miscfunctions.qc"
-#include "movelib.qc"
 #include "playerdemo.qc"
 #include "portals.qc"
 #include "race.qc"
 #include "scores.qc"
 #include "scores_rules.qc"
 #include "spawnpoints.qc"
-#include "steerlib.qc"
 #include "sv_main.qc"
 #include "teamplay.qc"
+
+#include "bot/lib/all.inc"
+
 #include "t_halflife.qc"
 #include "t_items.qc"
 #include "t_quake3.qc"
 #include "mutators/mutators_include.qc"
 #include "mutators/mutators.qc"
 
-#include "pathlib/costs.qc"
-#include "pathlib/expandnode.qc"
-#include "pathlib/main.qc"
-#include "pathlib/movenode.qc"
-#include "pathlib/path_waypoint.qc"
-#include "pathlib/utility.qc"
-
 #include "weapons/accuracy.qc"
 #include "weapons/common.qc"
 #include "weapons/csqcprojectile.qc" // TODO
diff --git a/qcsrc/server/steerlib.qc b/qcsrc/server/steerlib.qc
deleted file mode 100644 (file)
index fbf84da..0000000
+++ /dev/null
@@ -1,672 +0,0 @@
-#if defined(CSQC)
-#elif defined(MENUQC)
-#elif defined(SVQC)
-    #include "../dpdefs/progsdefs.qh"
-    #include "../dpdefs/dpextensions.qh"
-#endif
-
-/**
-    Uniform pull towards a point
-**/
-vector steerlib_pull(vector point)
-{SELFPARAM();
-    return normalize(point - self.origin);
-}
-
-/**
-    Uniform push from a point
-**/
-#define steerlib_push(point) normalize(self.origin - point)
-/*
-vector steerlib_push(vector point)
-{
-    return normalize(self.origin - point);
-}
-*/
-/**
-    Pull toward a point, The further away, the stronger the pull.
-**/
-vector steerlib_arrive(vector point,float maximal_distance)
-{SELFPARAM();
-    float distance;
-    vector direction;
-
-    distance = bound(0.001,vlen(self.origin - point),maximal_distance);
-    direction = normalize(point - self.origin);
-    return  direction * (distance / maximal_distance);
-}
-
-/**
-    Pull toward a point increasing the pull the closer we get
-**/
-vector steerlib_attract(vector point, float maximal_distance)
-{SELFPARAM();
-    float distance;
-    vector direction;
-
-    distance = bound(0.001,vlen(self.origin - point),maximal_distance);
-    direction = normalize(point - self.origin);
-
-    return  direction * (1-(distance / maximal_distance));
-}
-
-vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense)
-{SELFPARAM();
-    float distance;
-    vector direction;
-    float influense;
-
-    distance  = bound(0.00001,vlen(self.origin - point),max_distance);
-    direction = normalize(point - self.origin);
-
-    influense = 1 - (distance / max_distance);
-    influense = min_influense + (influense * (max_influense - min_influense));
-
-    return  direction * influense;
-}
-
-/*
-vector steerlib_attract2(vector point, float maximal_distance,float min_influense,float max_influense,float distance)
-{
-    //float distance;
-    vector current_direction;
-    vector target_direction;
-    float i_target,i_current;
-
-    if(!distance)
-        distance = vlen(self.origin - point);
-
-    distance = bound(0.001,distance,maximal_distance);
-
-    target_direction = normalize(point - self.origin);
-    current_direction = normalize(self.velocity);
-
-    i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
-    i_current = 1 - i_target;
-
-    // i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
-
-    string s;
-    s = ftos(i_target);
-    bprint("IT: ",s,"\n");
-    s = ftos(i_current);
-    bprint("IC  : ",s,"\n");
-
-    return  normalize((target_direction * i_target) + (current_direction * i_current));
-}
-*/
-/**
-    Move away from a point.
-**/
-vector steerlib_repell(vector point,float maximal_distance)
-{SELFPARAM();
-    float distance;
-    vector direction;
-
-    distance = bound(0.001,vlen(self.origin - point),maximal_distance);
-    direction = normalize(self.origin - point);
-
-    return  direction * (1-(distance / maximal_distance));
-}
-
-/**
-    Try to keep at ideal_distance away from point
-**/
-vector steerlib_standoff(vector point,float ideal_distance)
-{SELFPARAM();
-    float distance;
-    vector direction;
-
-    distance = vlen(self.origin - point);
-
-
-    if(distance < ideal_distance)
-    {
-        direction = normalize(self.origin - point);
-        return direction * (distance / ideal_distance);
-    }
-
-    direction = normalize(point - self.origin);
-    return direction * (ideal_distance / distance);
-
-}
-
-/**
-    A random heading in a forward halfcicrle
-
-    use like:
-    self.target = steerlib_wander(256,32,self.target)
-
-    where range is the cicrle radius and tresh is how close we need to be to pick a new heading.
-**/
-vector steerlib_wander(float range,float tresh,vector oldpoint)
-{SELFPARAM();
-    vector wander_point;
-    wander_point = v_forward - oldpoint;
-
-    if (vlen(wander_point) > tresh)
-        return oldpoint;
-
-    range = bound(0,range,1);
-
-    wander_point = self.origin + v_forward * 128;
-    wander_point = wander_point + randomvec() * (range * 128) - randomvec() * (range * 128);
-
-    return normalize(wander_point - self.origin);
-}
-
-/**
-    Dodge a point. dont work to well.
-**/
-vector steerlib_dodge(vector point,vector dodge_dir,float min_distance)
-{SELFPARAM();
-    float distance;
-
-    distance = max(vlen(self.origin - point),min_distance);
-    if (min_distance < distance)
-        return '0 0 0';
-
-    return dodge_dir * (min_distance/distance);
-}
-
-/**
-    flocking by .flock_id
-    Group will move towards the unified direction while keeping close to eachother.
-**/
-.float flock_id;
-vector steerlib_flock(float _radius, float standoff,float separation_force,float flock_force)
-{SELFPARAM();
-    entity flock_member;
-    vector push = '0 0 0', pull = '0 0 0';
-    float ccount = 0;
-
-    flock_member = findradius(self.origin, _radius);
-    while(flock_member)
-    {
-        if(flock_member != self)
-        if(flock_member.flock_id == self.flock_id)
-        {
-            ++ccount;
-            push = push + (steerlib_repell(flock_member.origin,standoff) * separation_force);
-            pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity, _radius) * flock_force);
-        }
-        flock_member = flock_member.chain;
-    }
-    return push + (pull* (1 / ccount));
-}
-
-/**
-    flocking by .flock_id
-    Group will move towards the unified direction while keeping close to eachother.
-    xy only version (for ground movers).
-**/
-vector steerlib_flock2d(float _radius, float standoff,float separation_force,float flock_force)
-{SELFPARAM();
-    entity flock_member;
-    vector push = '0 0 0', pull = '0 0 0';
-    float ccount = 0;
-
-    flock_member = findradius(self.origin,_radius);
-    while(flock_member)
-    {
-        if(flock_member != self)
-        if(flock_member.flock_id == self.flock_id)
-        {
-            ++ccount;
-            push = push + (steerlib_repell(flock_member.origin, standoff) * separation_force);
-            pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity, _radius) * flock_force);
-        }
-        flock_member = flock_member.chain;
-    }
-
-    push.z = 0;
-    pull.z = 0;
-
-    return push + (pull * (1 / ccount));
-}
-
-/**
-    All members want to be in the center, and keep away from eachother.
-    The furtehr form the center the more they want to be there.
-
-    This results in a aligned movement (?!) much like flocking.
-**/
-vector steerlib_swarm(float _radius, float standoff,float separation_force,float swarm_force)
-{SELFPARAM();
-    entity swarm_member;
-    vector force = '0 0 0', center = '0 0 0';
-    float ccount = 0;
-
-    swarm_member = findradius(self.origin,_radius);
-
-    while(swarm_member)
-    {
-        if(swarm_member.flock_id == self.flock_id)
-        {
-            ++ccount;
-            center = center + swarm_member.origin;
-            force = force + (steerlib_repell(swarm_member.origin,standoff) * separation_force);
-        }
-        swarm_member = swarm_member.chain;
-    }
-
-    center = center * (1 / ccount);
-    force = force + (steerlib_arrive(center,_radius) * swarm_force);
-
-    return force;
-}
-
-/**
-    Steer towards the direction least obstructed.
-    Run four tracelines in a forward funnel, bias each diretion negative if something is found there.
-    You need to call makevectors() (or equivalent) before this function to set v_forward and v_right
-**/
-vector steerlib_traceavoid(float pitch,float length)
-{SELFPARAM();
-    vector vup_left,vup_right,vdown_left,vdown_right;
-    float fup_left,fup_right,fdown_left,fdown_right;
-    vector upwish,downwish,leftwish,rightwish;
-    vector v_left,v_down;
-
-
-    v_left = v_right * -1;
-    v_down = v_up * -1;
-
-    vup_left = (v_forward + (v_left * pitch + v_up * pitch)) * length;
-    traceline(self.origin, self.origin +  vup_left,MOVE_NOMONSTERS,self);
-    fup_left = trace_fraction;
-
-    //te_lightning1(world,self.origin, trace_endpos);
-
-    vup_right = (v_forward + (v_right * pitch + v_up * pitch)) * length;
-    traceline(self.origin,self.origin + vup_right ,MOVE_NOMONSTERS,self);
-    fup_right = trace_fraction;
-
-    //te_lightning1(world,self.origin, trace_endpos);
-
-    vdown_left = (v_forward + (v_left * pitch + v_down * pitch)) * length;
-    traceline(self.origin,self.origin + vdown_left,MOVE_NOMONSTERS,self);
-    fdown_left = trace_fraction;
-
-    //te_lightning1(world,self.origin, trace_endpos);
-
-    vdown_right = (v_forward + (v_right * pitch + v_down * pitch)) * length;
-    traceline(self.origin,self.origin + vdown_right,MOVE_NOMONSTERS,self);
-    fdown_right = trace_fraction;
-
-    //te_lightning1(world,self.origin, trace_endpos);
-    upwish    = v_up    * (fup_left   + fup_right);
-    downwish  = v_down  * (fdown_left + fdown_right);
-    leftwish  = v_left  * (fup_left   + fdown_left);
-    rightwish = v_right * (fup_right  + fdown_right);
-
-    return (upwish+leftwish+downwish+rightwish) * 0.25;
-
-}
-
-/**
-    Steer towards the direction least obstructed.
-    Run tracelines in a forward trident, bias each direction negative if something is found there.
-**/
-vector steerlib_traceavoid_flat(float pitch, float length, vector vofs)
-{SELFPARAM();
-    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);
-}
-
-float beamsweep_badpoint(vector point,float waterok)
-{
-    float pc,pc2;
-
-    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
-        return 1;
-
-    pc  = pointcontents(point);
-    pc2 = pointcontents(point - '0 0 1');
-
-    switch(pc)
-    {
-        case CONTENT_SOLID: break;
-        case CONTENT_SLIME: break;
-        case CONTENT_LAVA:  break;
-
-        case CONTENT_SKY:
-            return 1;
-
-        case CONTENT_EMPTY:
-            if (pc2 == CONTENT_SOLID)
-                return 0;
-
-            if (pc2 == CONTENT_WATER)
-                if(waterok)
-                    return 0;
-
-            break;
-
-        case CONTENT_WATER:
-            if(waterok)
-                return 0;
-
-            break;
-    }
-
-    return 1;
-}
-
-//#define BEAMSTEER_VISUAL
-float beamsweep(vector from, vector dir,float length, float step,float step_up, float step_down)
-{SELFPARAM();
-    float i;
-    vector a,b,u,d;
-
-    u = '0 0 1' * step_up;
-    d = '0 0 1' * step_down;
-
-    traceline(from + u, from - d,MOVE_NORMAL,self);
-    if(trace_fraction == 1.0)
-        return 0;
-
-    if(beamsweep_badpoint(trace_endpos,0))
-        return 0;
-
-    a = trace_endpos;
-    for(i = 0; i < length; i += step)
-    {
-
-        b = a + dir * step;
-        tracebox(a + u,'-4 -4 -4','4 4 4', b + u,MOVE_NORMAL,self);
-        if(trace_fraction != 1.0)
-            return i / length;
-
-        traceline(b + u, b - d,MOVE_NORMAL,self);
-        if(trace_fraction == 1.0)
-            return i / length;
-
-        if(beamsweep_badpoint(trace_endpos,0))
-            return i / length;
-#ifdef BEAMSTEER_VISUAL
-        te_lightning1(world,a+u,b+u);
-        te_lightning1(world,b+u,b-d);
-#endif
-        a = trace_endpos;
-    }
-
-    return 1;
-}
-
-vector steerlib_beamsteer(vector dir, float length, float step, float step_up, float step_down)
-{SELFPARAM();
-    float bm_forward, bm_right, bm_left,p;
-    vector vr,vl;
-
-    dir.z *= 0.15;
-    vr = vectoangles(dir);
-    //vr_x *= -1;
-
-    tracebox(self.origin + '0 0 1' * step_up, self.mins, self.maxs, ('0 0 1' * step_up) + self.origin +  (dir * length), MOVE_NOMONSTERS, self);
-    if(trace_fraction == 1.0)
-    {
-        //te_lightning1(self,self.origin,self.origin +  (dir * length));
-        return dir;
-    }
-
-
-
-
-    makevectors(vr);
-    bm_forward = beamsweep(self.origin, v_forward, length, step, step_up, step_down);
-
-    vr = normalize(v_forward + v_right * 0.125);
-    vl = normalize(v_forward - v_right * 0.125);
-
-    bm_right = beamsweep(self.origin, vr, length, step, step_up, step_down);
-    bm_left  = beamsweep(self.origin, vl, length, step, step_up, step_down);
-
-
-    p = bm_left + bm_right;
-    if(p == 2)
-    {
-        //te_lightning1(self,self.origin + '0 0 32',self.origin + '0 0 32' + vr * length);
-        //te_lightning1(self.tur_head,self.origin + '0 0 32',self.origin + '0 0 32' + vl * length);
-
-        return v_forward;
-    }
-
-    p = 2 - p;
-
-    vr = normalize(v_forward + v_right * p);
-    vl = normalize(v_forward - v_right * p);
-    bm_right = beamsweep(self.origin, vr, length, step, step_up, step_down);
-    bm_left  = beamsweep(self.origin, vl, length, step, step_up, step_down);
-
-
-    if(bm_left + bm_right < 0.15)
-    {
-        vr = normalize((v_forward*-1) + v_right * 0.75);
-        vl = normalize((v_forward*-1) - v_right * 0.75);
-
-        bm_right = beamsweep(self.origin, vr, length, step, step_up, step_down);
-        bm_left  = beamsweep(self.origin, vl, length, step, step_up, step_down);
-    }
-
-    //te_lightning1(self,self.origin + '0 0 32',self.origin + '0 0 32' + vr * length);
-    //te_lightning1(self.tur_head,self.origin + '0 0 32',self.origin + '0 0 32' + vl * length);
-
-    bm_forward *= bm_forward;
-    bm_right   *= bm_right;
-    bm_left    *= bm_left;
-
-    vr = vr * bm_right;
-    vl = vl * bm_left;
-
-    return normalize(vr + vl);
-
-}
-
-
-//////////////////////////////////////////////
-//     Testting                             //
-// Everything below this point is a mess :D //
-//////////////////////////////////////////////
-//#define TLIBS_TETSLIBS
-#ifdef TLIBS_TETSLIBS
-void flocker_die()
-{SELFPARAM();
-       Send_Effect(EFFECT_ROCKET_EXPLODE, self.origin, '0 0 0', 1);
-
-    self.owner.cnt += 1;
-    self.owner = world;
-
-    self.nextthink = time;
-    self.think = SUB_Remove;
-}
-
-
-void flocker_think()
-{SELFPARAM();
-    vector dodgemove,swarmmove;
-    vector reprellmove,wandermove,newmove;
-
-    self.angles_x = self.angles.x * -1;
-    makevectors(self.angles);
-    self.angles_x = self.angles.x * -1;
-
-    dodgemove   = steerlib_traceavoid(0.35,1000);
-    swarmmove   = steerlib_flock(500,75,700,500);
-    reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,2000) * 700;
-
-    if(vlen(dodgemove) == 0)
-    {
-        self.pos1 = steerlib_wander(0.5,0.1,self.pos1);
-        wandermove  = self.pos1 * 50;
-    }
-    else
-        self.pos1 = normalize(self.velocity);
-
-    dodgemove = dodgemove * vlen(self.velocity) * 5;
-
-    newmove = swarmmove + reprellmove + wandermove + dodgemove;
-    self.velocity = movelib_inertmove_byspeed(newmove,300,0.2,0.9);
-    //self.velocity  = movelib_inertmove(dodgemove,0.65);
-
-    self.velocity = movelib_dragvec(0.01,0.6);
-
-    self.angles = vectoangles(self.velocity);
-
-    if(self.health <= 0)
-        flocker_die();
-    else
-        self.nextthink = time + 0.1;
-}
-
-MODEL(FLOCKER, "models/turrets/rocket.md3");
-
-void spawn_flocker()
-{SELFPARAM();
-    entity flocker;
-
-    flocker = spawn ();
-
-    setorigin(flocker, self.origin + '0 0 32');
-    setmodel (flocker, MDL_FLOCKER);
-    setsize (flocker, '-3 -3 -3', '3 3 3');
-
-    flocker.flock_id   = self.flock_id;
-    flocker.classname  = "flocker";
-    flocker.owner      = self;
-    flocker.think      = flocker_think;
-    flocker.nextthink  = time + random() * 5;
-    PROJECTILE_MAKETRIGGER(flocker);
-    flocker.movetype   = MOVETYPE_BOUNCEMISSILE;
-    flocker.effects    = EF_LOWPRECISION;
-    flocker.velocity   = randomvec() * 300;
-    flocker.angles     = vectoangles(flocker.velocity);
-    flocker.health     = 10;
-    flocker.pos1      = normalize(flocker.velocity + randomvec() * 0.1);
-
-    self.cnt = self.cnt -1;
-
-}
-
-void flockerspawn_think()
-{SELFPARAM();
-
-
-    if(self.cnt > 0)
-        spawn_flocker();
-
-    self.nextthink = time + self.delay;
-
-}
-
-void flocker_hunter_think()
-{SELFPARAM();
-    vector dodgemove,attractmove,newmove;
-    entity e,ee;
-    float d,bd;
-
-    self.angles_x = self.angles.x * -1;
-    makevectors(self.angles);
-    self.angles_x = self.angles.x * -1;
-
-    if(self.enemy)
-    if(vlen(self.enemy.origin - self.origin) < 64)
-    {
-        ee = self.enemy;
-        ee.health = -1;
-        self.enemy = world;
-
-    }
-
-    if(!self.enemy)
-    {
-        e = findchainfloat(flock_id,self.flock_id);
-        while(e)
-        {
-            d = vlen(self.origin - e.origin);
-
-            if(e != self.owner)
-            if(e != ee)
-            if(d > bd)
-            {
-                self.enemy = e;
-                bd = d;
-            }
-            e = e.chain;
-        }
-    }
-
-    if(self.enemy)
-        attractmove = steerlib_attract(self.enemy.origin+self.enemy.velocity * 0.1,5000) * 1250;
-    else
-        attractmove = normalize(self.velocity) * 200;
-
-    dodgemove = steerlib_traceavoid(0.35,1500) * vlen(self.velocity);
-
-    newmove = dodgemove + attractmove;
-    self.velocity = movelib_inertmove_byspeed(newmove,1250,0.3,0.7);
-    self.velocity = movelib_dragvec(0.01,0.5);
-
-
-    self.angles = vectoangles(self.velocity);
-    self.nextthink = time + 0.1;
-}
-
-
-float globflockcnt;
-spawnfunc(flockerspawn)
-{SELFPARAM();
-    ++globflockcnt;
-
-    if(!self.cnt)      self.cnt = 20;
-    if(!self.delay)    self.delay = 0.25;
-    if(!self.flock_id) self.flock_id = globflockcnt;
-
-    self.think     = flockerspawn_think;
-    self.nextthink = time + 0.25;
-
-    self.enemy = spawn();
-
-    setmodel(self.enemy, MDL_FLOCKER);
-    setorigin(self.enemy,self.origin + '0 0 768' + (randomvec() * 128));
-
-    self.enemy.classname = "FLock Hunter";
-    self.enemy.scale     = 3;
-    self.enemy.effects   = EF_LOWPRECISION;
-    self.enemy.movetype  = MOVETYPE_BOUNCEMISSILE;
-    PROJECTILE_MAKETRIGGER(self.enemy);
-    self.enemy.think     = flocker_hunter_think;
-    self.enemy.nextthink = time + 10;
-    self.enemy.flock_id  = self.flock_id;
-    self.enemy.owner     = self;
-}
-#endif
-
-
-
diff --git a/qcsrc/server/steerlib.qh b/qcsrc/server/steerlib.qh
deleted file mode 100644 (file)
index fcd35ba..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef STEERLIB_H
-#define STEERLIB_H
-
-.vector steerto;
-
-vector steerlib_arrive(vector point,float maximal_distance);
-vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense);
-vector steerlib_pull(vector point);
-
-#endif