Files
2019-12-30 17:23:05 +01:00

1091 lines
27 KiB
Plaintext

/*================================================================================
waypoints.qc
each waypoint can have up to 4 other waypoints it can link to
if a waypoint is linked, the link does not have to be 2-way, it can just point
in one direction
the waypoints are held in a linked list (way_head, way_foot) for speed to avoid
using find() with classname's as this is slow
many thanks to FrikaC for the FrikBot, whose code this is heavily based upon
================================================================================*/
float waypoint_mode;
float WM_UNINIT = 0; // waypoints not loaded
float WM_LOADING = 1; // waypoints are loading
float WM_LOADED = 2; // waypoints are loaded (also set when there's no waypoints in the map)
float WM_EDITOR = 3; // editor is currently active
float scr_centertime;
.float menu, menuopt, menutime, menubuttonreleased;
float MENU_MAIN = 0; // main menu
float MENU_WAYS = 1; // waypoint sub menu
float MENU_LINKS = 2; // link sub menu
float MENU_LINKS_C = 3; // create link
float MENU_LINKS_D = 4; // delete link
float MENU_LINKS_C2 = 5; // create link x2
float MENU_LINKS_D2 = 6; // delete link x2
entity way_head, way_foot;
float waypoints;
entity fixer;
.entity target1, target2, target3, target4;
.entity _next, _last;
.entity current_way, last_way;
/*==========
wisible
==========*/
float (entity monster, entity way) wisible =
{
vector spot1 = monster.origin + monster.view_ofs;
vector spot2 = way.origin;
traceline (spot1, spot2, TRUE, monster);
if (trace_fraction == 1 || trace_ent == way)
return TRUE;
else
return FALSE;
};
/*==========
PrintQCWaypoint
use thinks to avoid tripping runaway loop counter
==========*/
void() PrintQCWaypoint =
{
// go to next waypoint in list
entity t;
if (self.enemy == world)
t = way_head;
else
t = self.enemy._next;
// reached last waypoint
if (t == world)
{
remove(self);
fixer = world;
bprint("};\n// End dump\n");
return;
}
// dump current waypoint
bprint("\tSpawnWaypoint(");
t.origin_x = rint(t.origin_x);
t.origin_y = rint(t.origin_y);
t.origin_z = rint(t.origin_z);
string h = vtos(t.origin);
bprint(h);
bprint(", ");
h = ftos(t.target1.count);
bprint(h);
bprint(", ");
h = ftos(t.target2.count);
bprint(h);
bprint(", ");
h = ftos(t.target3.count);
bprint(h);
bprint(", ");
h = ftos(t.target4.count);
bprint(h);
bprint(");\n");
self.nextthink = time + 0.01;
self.enemy = t;
};
/*==========
DumpWaypoints
==========*/
void() DumpWaypoints =
{
if (!waypoints)
{
bprint("No waypoints to dump!\n");
return;
}
bprint("// Waypoint Dump - ");
bprint(mapname);
bprint(".qc\n");
bprint("void() waypoints_");
bprint(mapname);
bprint(" =\n{\n");
if (!fixer)
fixer = spawn();
fixer.nextthink = time + 0.01;
fixer.think = PrintQCWaypoint;
fixer.enemy = world;
};
/*==========
CheckLinked
returns TRUE if ways are linked
==========*/
float (entity e1, entity e2) CheckLinked =
{
if ((e1 == e2) || (e2 == world) || (e1 == world))
return FALSE;
else if (e1.target1 == e2)
return TRUE;
else if (e1.target2 == e2)
return TRUE;
else if (e1.target3 == e2)
return TRUE;
else if (e1.target4 == e2)
return TRUE;
else
return FALSE;
};
/*==========
LinkWays
links e1 to e2 (each way has max of 4 links)
==========*/
float (entity e1, entity e2) LinkWays =
{
if ((e1 == e2) || (e2 == world) || (e1 == world))
{
bprint("tried to link waypoint to itself, or nothing!\n");
return FALSE;
}
else if (CheckLinked(e1, e2))
{
bprint("waypoints are already linked!\n");
return FALSE; // already linked
}
if (e1.target1 == world)
{
e1.target1 = e2;
return TRUE;
}
else if (e1.target2 == world)
{
e1.target2 = e2;
return TRUE;
}
else if (e1.target3 == world)
{
e1.target3 = e2;
return TRUE;
}
else if (e1.target4 == world)
{
e1.target4 = e2;
return TRUE;
}
else
{
bprint("waypoint already has max (4) links!\n");
return FALSE;
}
};
/*==========
UnlinkWays
unlinks e1 from e2 (one direction only)
==========*/
void(entity e1, entity e2) UnlinkWays =
{
if ((e1 == e2) || (e2 == world) || (e1 == world))
{
bprint("can't unlink waypoint from itself!\n");
return;
}
else if (!CheckLinked(e1, e2))
{
bprint("waypoints are not linked!\n");
return;
}
if (e1.target1 == e2)
e1.target1 = world;
if (e1.target2 == e2)
e1.target2 = world;
if (e1.target3 == e2)
e1.target3 = world;
if (e1.target4 == e2)
e1.target4 = world;
};
/*==========
DeleteWaypoint
==========*/
void(entity what) DeleteWaypoint =
{
if (way_head == what)
way_head = what._next;
if (way_foot == what)
way_foot = what._last;
if (what._last)
what._last._next = what._next;
if (what._next)
what._next._last = what._last;
waypoints = 0;
entity t = way_head;
while(t)
{
waypoints = waypoints + 1;
t.count = waypoints;
if (CheckLinked(t, what))
UnlinkWays(t, what);
t = t._next;
}
if (self.current_way == what)
self.current_way = world;
if (self.last_way == what)
self.last_way = world;
remove(what);
};
/*==========
MakeWaypoint
used in editor to spawn new waypoint
the waypoint loading code uses SpawnWaypoint, not this function
==========*/
entity(vector org) MakeWaypoint =
{
entity way = spawn();
way.classname = "waypoint";
way.solid = SOLID_TRIGGER;
way.movetype = MOVETYPE_NONE;
setorigin(way, org);
setmodel(way, "progs/s_way1.spr");
setsize(way, VEC_HULL_MIN, VEC_HULL_MAX);
waypoints = waypoints + 1;
if (!way_head) // first waypoint
{
way_head = way;
way_foot = way;
}
else
{
way_foot._next = way;
way._last = way_foot;
way_foot = way;
}
way.count = waypoints;
return way;
};
/*==========
FindWayPoint
finds closest wisible way to self
only used to select nearest way in the editor
==========*/
entity(entity start) FindWayPoint =
{
vector org = self.origin;
if (start != world)
{
float dst = vlen(start.origin - org);
entity best = start;
}
else
{
dst = 100000;
best = world;
}
entity t = way_head;
while(t)
{
if (dst < 20)
return best;
float tdst = vlen(t.origin - org);
if (tdst < dst)
{
if (wisible(self, t))
{
dst = tdst;
best = t;
}
}
t = t._next;
}
return best;
};
/*==========
DrawWaypointLinks
==========*/
void() DrawWaypointLinks =
{
// if we're in the linking sub-menus, then draw a helper beam (for creation)
// or lightning (for deletion)
if (self.menu >= MENU_LINKS_C && self.menu <= MENU_LINKS_D2)
{
if (self.current_way && self.last_way)
{
if (self.current_way != self.last_way)
{
if (self.menu == MENU_LINKS_C || self.menu == MENU_LINKS_C2)
te_beam(self.current_way.origin, self.last_way.origin, self.current_way);
else
te_lightning1(self.current_way.origin, self.last_way.origin, self);
}
}
return;
}
if (self.current_way)
{
if (self.current_way.target1)
te_beam(self.current_way.origin, self.current_way.target1.origin, self.current_way);
if (self.current_way.target2)
te_beam(self.current_way.origin, self.current_way.target2.origin, self.current_way);
if (self.current_way.target3)
te_beam(self.current_way.origin, self.current_way.target3.origin, self.current_way);
if (self.current_way.target4)
te_beam(self.current_way.origin, self.current_way.target4.origin, self.current_way);
}
};
/*==========
SelectNearestWaypoint
==========*/
void() SelectNearestWaypoint =
{
entity t = FindWayPoint(self.current_way);
if (t)
{
float dist = vlen(self.origin - t.origin);
if (dist < 64)
{
// new waypoint selected
if (self.current_way != t)
{
// unselect previous waypoint
if (self.current_way)
{
setmodel(self.current_way, "progs/s_way1.spr");
setsize(self.current_way, VEC_HULL_MIN, VEC_HULL_MAX);
}
// select new waypoint
setmodel(t, "progs/s_way2.spr");
setsize(t, VEC_HULL_MIN, VEC_HULL_MAX);
self.current_way = t;
}
}
}
};
/*==========
DisplayMenu
wish i had real string management
==========*/
void() DisplayMenu =
{
// don't constantly re-draw the menu
if (time < self.menutime)
return;
self.menutime = time + scr_centertime;
string s1, s2, s3, s4, s5, s6, s7;
s1 = s2 = s3 = s4 = s5 = s6 = s7 = string_null;
if (self.menu == MENU_MAIN)
{
s1 = "\bWaypoint Editor\b\n\n";
if (self.menuopt == 0) s2 = "\x85 \bWaypoint Management \n"; else s2 = " Waypoint Management \n";
if (self.menuopt == 1) s3 = "\x85 \bLink Management \n"; else s3 = " Link Management \n";
if (self.menuopt == 2) s4 = "\x85 \bDisplay Waypoint Info\n"; else s4 = " Display Waypoint Info\n";
if (self.menuopt == 3) s5 = "\x85 \bDump .qc \n"; else s5 = " Dump .qc \n";
if (self.menuopt == 4) s6 = "\x85 \bExit \n"; else s6 = " Exit \n";
}
else if (self.menu == MENU_WAYS)
{
s1 = "\bWaypoint Editor \x85 Waypoint Management\b\n\n";
if (self.menuopt == 0) s2 = "\x85 \bMove Waypoint \n"; else s2 = " Move Waypoint \n";
if (self.menuopt == 1) s3 = "\x85 \bDelete Waypoint \n"; else s3 = " Delete Waypoint \n";
if (self.menuopt == 2) s4 = "\x85 \bMake Waypoint \n"; else s4 = " Make Waypoint \n";
if (self.menuopt == 3) s5 = "\x85 \bMake Way + Link \n"; else s5 = " Make Way + Link \n";
if (self.menuopt == 4) s6 = "\x85 \bMake Way + Link x2\n"; else s6 = " Make Way + Link x2\n";
if (self.menuopt == 5) s7 = "\x85 \bBack \n"; else s7 = " Back \n";
}
else if (self.menu == MENU_LINKS)
{
s1 = "\bWaypoint Editor \x85 Link Management\b\n\n";
if (self.menuopt == 0) s2 = "\x85 \bUnlink Waypoint\n"; else s2 = " Unlink Waypoint\n";
if (self.menuopt == 1) s3 = "\x85 \bCreate Link \n"; else s3 = " Create Link \n";
if (self.menuopt == 2) s4 = "\x85 \bDelete Link \n"; else s4 = " Delete Link \n";
if (self.menuopt == 3) s5 = "\x85 \bCreate Link x2 \n"; else s5 = " Create Link x2 \n";
if (self.menuopt == 4) s6 = "\x85 \bDelete Link x2 \n"; else s6 = " Delete Link x2 \n";
if (self.menuopt == 5) s7 = "\x85 \bBack \n"; else s7 = " Back \n";
}
else // selection sub menus (link, delete, etc)
{
if (self.menu == MENU_LINKS_C)
s1 = "\bWaypoint Editor \x85 Create link (one way)\b\n\n";
else if (self.menu == MENU_LINKS_D)
s1 = "\bWaypoint Editor \x85 Delete link (one way))\b\n\n";
else if (self.menu == MENU_LINKS_C2)
s1 = "\bWaypoint Editor \x85 Create link (two way))\b\n\n";
else if (self.menu == MENU_LINKS_D2)
s1 = "\bWaypoint Editor \x85 Delete link (two way))\b\n\n";
s2 = "\bPlease select waypoint\n\n";
if (self.menuopt == 0) s3 = "\x85 \bSelect \n"; else s3 = " Select \n";
if (self.menuopt == 1) s4 = "\x85 \bCancel \n"; else s4 = " Cancel \n";
}
centerprint(self, s1, s2, s3, s4, s5, s6, s7);
};
/*==========
ToggleWaypointMenu
==========*/
void() ToggleWaypointMenu =
{
// don't allow until all waypoints loaded
if (waypoint_mode < WM_LOADED)
return;
// reset menu for next use
self.menu = MENU_MAIN;
self.menuopt = 0;
self.menutime = time;
centerprint (self, string_null);
// menu on
if (waypoint_mode == WM_LOADED)
{
stuffcmd(self, "crosshair 0\n");
stuffcmd(self, "viewsize 120\n");
stuffcmd(self, "r_drawviewmodel 0\n");
waypoint_mode = WM_EDITOR;
entity t = way_head;
while (t)
{
setmodel(t, "progs/s_way1.spr");
setsize(t, VEC_HULL_MIN, VEC_HULL_MAX);
t = t._next;
}
if (self.current_way)
{
setmodel(self.current_way, "progs/s_way2.spr");
setsize(self.current_way, VEC_HULL_MIN, VEC_HULL_MAX);
}
}
// menu off
else
{
stuffcmd(self, "crosshair 1\n");
stuffcmd(self, "viewsize 100\n");
stuffcmd(self, "r_drawviewmodel 1\n");
waypoint_mode = WM_LOADED;
t = way_head;
while (t)
{
setmodel(t, "progs/s_null.spr");
setsize(t, VEC_HULL_MIN, VEC_HULL_MAX);
t = t._next;
}
}
};
/*==========
WaypointMenuNavigate
used for scrolling through the menu options
uses the keys bound to "next weapon" and "previous weapon"
==========*/
void(float dir) WaypointMenuNavigate =
{
float options = 0;
if (self.menu == MENU_MAIN)
options = 5;
else if (self.menu == MENU_WAYS || self.menu == MENU_LINKS)
options = 6;
else
options = 2;
self.menuopt = self.menuopt + dir;
if (self.menuopt > options - 1)
self.menuopt = 0;
if (self.menuopt < 0)
self.menuopt = options - 1;
};
/*==========
WaypointMenuBack
==========*/
void() WaypointMenuBack =
{
if (self.menu == MENU_MAIN)
{
ToggleWaypointMenu();
return;
}
self.menuopt = 0;
// go back to the main menu if we're in the waypoint or linking sub-menu
if (self.menu == MENU_WAYS || self.menu == MENU_LINKS)
self.menu = MENU_MAIN;
// otherwise go back to the linking sub-menu
else
self.menu = MENU_LINKS;
};
/*==========
WaypointMenuAction
==========*/
void(float command) WaypointMenuAction =
{
if (!self.menubuttonreleased)
return;
self.menubuttonreleased = FALSE;
self.attack_finished = time + 0.1;
//
// main menu
//
if (self.menu == MENU_MAIN)
{
if (command == 1)
{
self.menu = MENU_WAYS;
self.menuopt = 0;
}
else if (command == 2)
{
self.menu = MENU_LINKS;
self.menuopt = 0;
}
else if (command == 3)
{
if (self.current_way)
{
bprint("Waypoint #");
bprint(ftos(self.current_way.count));
bprint(" - Position ");
bprint(vtos(self.current_way.origin));
bprint(" - Links to ");
if (self.current_way.target1)
{
bprint(ftos(self.current_way.target1.count));
bprint(" ");
}
if (self.current_way.target2)
{
bprint(ftos(self.current_way.target2.count));
bprint(" ");
}
if (self.current_way.target3)
{
bprint(ftos(self.current_way.target3.count));
bprint(" ");
}
if (self.current_way.target4)
bprint(ftos(self.current_way.target4.count));
bprint("\n");
}
}
else if (command == 4)
DumpWaypoints();
else if (command == 5)
WaypointMenuBack();
return;
}
//
// waypoint menu
//
if (self.menu == MENU_WAYS)
{
// move waypoint
if (command == 1)
{
if (self.current_way)
setorigin(self.current_way, self.origin);
else
sprint(self, "No waypoint selected - unable to move!\n");
}
// delete waypoint
else if (command == 2)
{
if (self.current_way)
DeleteWaypoint(self.current_way);
else
sprint(self, "No waypoint selected - unable to delete!\n");
}
// create waypoint - no linking
else if (command == 3)
{
MakeWaypoint(self.origin);
}
// create waypoint + link to last
else if (command == 4)
{
entity way = MakeWaypoint(self.origin);
LinkWays(self.current_way, way);
}
// create waypoint + link two ways to last
else if (command == 5)
{
way = MakeWaypoint(self.origin);
LinkWays(self.current_way, way);
LinkWays(way, self.current_way);
}
else if (command == 6)
WaypointMenuBack();
return;
}
//
// linking menu
//
if (self.menu == MENU_LINKS)
{
if (command == 1) // unlink all
{
if (self.current_way)
self.current_way.target1 = self.current_way.target2 = self.current_way.target3 = self.current_way.target4 = world;
else
sprint(self, "No waypoint selected - unable to unlink!\n");
}
else if (command == 2) // create one way link
{
if (self.current_way)
{
self.menuopt = 0;
self.last_way = self.current_way;
self.menu = MENU_LINKS_C;
}
else
sprint(self, "No waypoint selected!\n");
}
else if (command == 3) // remove one way link
{
if (self.current_way)
{
self.menuopt = 0;
self.last_way = self.current_way;
self.menu = MENU_LINKS_D;
}
else
sprint(self, "No waypoint selected!\n");
}
else if (command == 4) // create two way link
{
if (self.current_way)
{
self.menuopt = 0;
self.last_way = self.current_way;
self.menu = MENU_LINKS_C2;
}
else
sprint(self, "No waypoint selected!\n");
}
else if (command == 5) // remove two way link
{
if (self.current_way)
{
self.menuopt = 0;
self.last_way = self.current_way;
self.menu = MENU_LINKS_D2;
}
else
sprint(self, "No waypoint selected!\n");
}
else if (command == 6)
WaypointMenuBack();
return;
}
//
// linking submenu
//
if (self.menu >= MENU_LINKS_C && self.menu <= MENU_LINKS_D2)
{
if (command == 1)
{
if (self.menu == MENU_LINKS_C) // create one way link
LinkWays(self.last_way, self.current_way);
else if (self.menu == MENU_LINKS_D) // remove one way link
UnlinkWays(self.last_way, self.current_way);
else if (self.menu == MENU_LINKS_C2) // create two way link
{
LinkWays(self.last_way, self.current_way);
LinkWays(self.current_way, self.last_way);
}
else if (self.menu == MENU_LINKS_D2) // remove two way link
{
UnlinkWays(self.last_way, self.current_way);
UnlinkWays(self.current_way, self.last_way);
}
WaypointMenuBack();
}
else if (command == 2)
WaypointMenuBack();
}
};
/*==========
WaypointMenu
==========*/
void() WaypointMenu =
{
DisplayMenu();
// pressing fire will set button0 = TRUE for several frames so we need to track release
if (!self.button0)
self.menubuttonreleased = TRUE;
// use impulses for next weapon/previous weapon to scroll the menu
if (self.impulse == 10)
WaypointMenuNavigate(-1);
else if (self.impulse == 12)
WaypointMenuNavigate(1);
// use fire button to select options
else if (self.button0)
WaypointMenuAction(self.menuopt + 1);
else
return;
self.impulse = 0;
self.menutime = time; // refresh menu immediately
};
/*==========
WaypointForNum
returns the entity for a given waypoint number
returns world if not found
only used in waypoint loading code
==========*/
entity(float num) WaypointForNum =
{
if (num < 1)
return world;
entity t = way_head;
while (t)
{
if (t.count == num)
return t;
t = t._next;
}
return world;
};
/*==========
FixThisWaypoint
use thinks to avoid tripping runaway loop counter
==========*/
void() FixThisWaypoint =
{
self.enemy.target1 = WaypointForNum(self.enemy.ammo_shells);
self.enemy.target2 = WaypointForNum(self.enemy.ammo_nails);
self.enemy.target3 = WaypointForNum(self.enemy.ammo_rockets);
self.enemy.target4 = WaypointForNum(self.enemy.ammo_cells);
self.enemy = self.enemy._next;
self.nextthink = time + 0.01;
// reached last waypoint
if (self.enemy == world)
{
bprint("waypoints loaded\n");
waypoint_mode = WM_LOADED;
remove(self);
fixer = world;
}
};
/*==========
FixWaypoints
once all waypoints have been loaded, link them up
we want to link target1-4 (entities) for speed
ammo_shells is the waypoint number for target1, ammo_nails is target2, etc
==========*/
void() FixWaypoints =
{
if (!fixer)
fixer = spawn();
fixer.nextthink = time + 0.01;
fixer.think = FixThisWaypoint;
fixer.enemy = way_head; // start waypoint
};
/*==========
SpawnWaypoint
used by the hardcoded qc waypoints
==========*/
void(vector org, float t1, float t2, float t3, float t4) SpawnWaypoint =
{
entity way = spawn();
way.classname = "waypoint";
way.solid = SOLID_TRIGGER;
way.movetype = MOVETYPE_NONE;
setorigin(way, org);
setmodel(way, "progs/s_null.spr");
setsize(way, VEC_HULL_MIN, VEC_HULL_MAX);
way.ammo_shells = t1;
way.ammo_nails = t2;
way.ammo_rockets = t3;
way.ammo_cells = t4;
waypoints = waypoints + 1;
way.count = waypoints;
if (!way_head) // first waypoint
{
way_head = way;
way_foot = way;
}
else
{
way_foot._next = way;
way._last = way_foot;
way_foot = way;
}
};
// Waypoint Dump - e1m2.qc
void() waypoints_e1m2 =
{
SpawnWaypoint('1481.0 1670.0 288.0', 2, 13, 15, 0);
SpawnWaypoint('1518.0 1504.0 264.0', 1, 3, 4, 5);
SpawnWaypoint('1711.0 1524.0 264.0', 2, 14, 0, 0);
SpawnWaypoint('1317.0 1521.0 264.0', 2, 0, 0, 0);
SpawnWaypoint('1469.0 1277.0 200.0', 2, 6, 9, 18);
SpawnWaypoint('1679.0 1273.0 200.0', 5, 7, 8, 0);
SpawnWaypoint('1677.0 1406.0 200.0', 6, 8, 0, 0);
SpawnWaypoint('1766.0 1289.0 200.0', 6, 7, 0, 0);
SpawnWaypoint('1368.0 1274.0 200.0', 5, 10, 12, 0);
SpawnWaypoint('1353.0 1441.0 200.0', 9, 11, 0, 0);
SpawnWaypoint('1192.0 1441.0 200.0', 10, 12, 0, 0);
SpawnWaypoint('1201.0 1279.0 200.0', 11, 9, 0, 0);
SpawnWaypoint('1800.0 1720.0 264.0', 1, 14, 0, 0);
SpawnWaypoint('1800.0 1614.0 264.0', 13, 3, 0, 0);
SpawnWaypoint('1310.0 1720.0 264.0', 1, 16, 0, 0);
SpawnWaypoint('1192.0 1720.0 264.0', 15, 17, 0, 0);
SpawnWaypoint('1195.0 1584.0 264.0', 16, 0, 0, 0);
SpawnWaypoint('1484.0 1087.0 204.0', 5, 19, 0, 0);
SpawnWaypoint('1492.0 905.0 200.0', 18, 20, 0, 0);
SpawnWaypoint('1498.0 791.0 248.0', 19, 21, 0, 0);
SpawnWaypoint('1477.0 666.0 264.0', 20, 22, 0, 0);
SpawnWaypoint('1341.0 656.0 296.0', 21, 23, 0, 0);
SpawnWaypoint('1232.0 662.0 312.0', 22, 24, 0, 0);
SpawnWaypoint('1066.0 671.0 312.0', 23, 25, 0, 0);
SpawnWaypoint('1078.0 527.0 312.0', 24, 26, 0, 0);
SpawnWaypoint('1082.0 391.0 308.0', 25, 27, 0, 0);
SpawnWaypoint('1096.0 93.0 308.0', 26, 28, 0, 0);
SpawnWaypoint('1099.0 -133.0 320.0', 27, 29, 95, 0);
SpawnWaypoint('1210.0 -115.0 320.0', 28, 30, 0, 0);
SpawnWaypoint('1373.0 -119.0 320.0', 29, 31, 0, 0);
SpawnWaypoint('1420.0 -25.0 320.0', 30, 32, 0, 0);
SpawnWaypoint('1422.0 89.0 320.0', 31, 33, 0, 0);
SpawnWaypoint('1408.0 337.0 320.0', 32, 34, 0, 0);
SpawnWaypoint('1513.0 391.0 320.0', 33, 35, 0, 0);
SpawnWaypoint('1629.0 394.0 312.0', 34, 36, 0, 0);
SpawnWaypoint('1755.0 391.0 312.0', 35, 37, 0, 0);
SpawnWaypoint('1795.0 315.0 312.0', 36, 38, 0, 0);
SpawnWaypoint('1787.0 165.0 312.0', 37, 39, 0, 0);
SpawnWaypoint('1791.0 43.0 312.0', 38, 40, 0, 0);
SpawnWaypoint('1849.0 -98.0 312.0', 39, 41, 0, 0);
SpawnWaypoint('1907.0 -95.0 312.0', 40, 42, 0, 0);
SpawnWaypoint('1999.0 -109.0 312.0', 41, 43, 0, 0);
SpawnWaypoint('2046.0 -137.0 312.0', 42, 44, 0, 0);
SpawnWaypoint('2044.0 -246.0 312.0', 43, 45, 0, 0);
SpawnWaypoint('2038.0 -360.0 312.0', 44, 46, 0, 0);
SpawnWaypoint('1969.0 -357.0 312.0', 45, 47, 0, 0);
SpawnWaypoint('1847.0 -354.0 312.0', 46, 48, 0, 0);
SpawnWaypoint('1716.0 -359.0 312.0', 47, 49, 0, 0);
SpawnWaypoint('1556.0 -355.0 312.0', 48, 50, 0, 0);
SpawnWaypoint('1259.0 -332.0 312.0', 49, 51, 0, 0);
SpawnWaypoint('1149.0 -391.0 312.0', 50, 52, 0, 0);
SpawnWaypoint('1093.0 -512.0 312.0', 51, 53, 0, 0);
SpawnWaypoint('1116.0 -649.0 312.0', 52, 54, 0, 0);
SpawnWaypoint('1249.0 -730.0 312.0', 53, 55, 0, 0);
SpawnWaypoint('1376.0 -728.0 312.0', 54, 56, 0, 0);
SpawnWaypoint('1503.0 -717.0 312.0', 55, 57, 0, 0);
SpawnWaypoint('1679.0 -705.0 360.0', 56, 58, 0, 0);
SpawnWaypoint('1675.0 -807.0 392.0', 57, 59, 0, 0);
SpawnWaypoint('1670.0 -918.0 408.0', 58, 60, 0, 0);
SpawnWaypoint('1620.0 -916.0 424.0', 59, 61, 0, 0);
SpawnWaypoint('1489.0 -905.0 440.0', 60, 62, 0, 0);
SpawnWaypoint('1369.0 -908.0 440.0', 61, 63, 68, 0);
SpawnWaypoint('1220.0 -911.0 440.0', 62, 64, 0, 0);
SpawnWaypoint('1073.0 -906.0 440.0', 63, 65, 70, 0);
SpawnWaypoint('928.0 -900.0 440.0', 64, 66, 71, 0);
SpawnWaypoint('880.0 -849.0 440.0', 65, 67, 0, 0);
SpawnWaypoint('882.0 -743.0 440.0', 66, 0, 0, 0);
SpawnWaypoint('1410.0 -1183.0 440.0', 62, 69, 0, 0);
SpawnWaypoint('1311.0 -1191.0 440.0', 68, 70, 0, 0);
SpawnWaypoint('1182.0 -1192.0 440.0', 69, 64, 0, 0);
SpawnWaypoint('874.0 -1043.0 440.0', 65, 72, 0, 0);
SpawnWaypoint('870.0 -1130.0 440.0', 71, 73, 0, 0);
SpawnWaypoint('877.0 -1184.0 432.0', 72, 74, 0, 0);
SpawnWaypoint('676.0 -1219.0 432.0', 73, 75, 0, 0);
SpawnWaypoint('586.0 -1199.0 432.0', 74, 76, 97, 0);
SpawnWaypoint('511.0 -1174.0 432.0', 75, 77, 97, 0);
SpawnWaypoint('418.0 -1093.0 432.0', 76, 78, 0, 0);
SpawnWaypoint('391.0 -977.0 432.0', 77, 79, 0, 0);
SpawnWaypoint('450.0 -864.0 432.0', 78, 80, 0, 0);
SpawnWaypoint('587.0 -851.0 432.0', 79, 81, 96, 0);
SpawnWaypoint('612.0 -725.0 432.0', 80, 82, 0, 0);
SpawnWaypoint('558.0 -628.0 392.0', 81, 83, 0, 0);
SpawnWaypoint('562.0 -508.0 350.0', 82, 84, 0, 0);
SpawnWaypoint('567.0 -385.0 320.0', 83, 85, 92, 0);
SpawnWaypoint('484.0 -407.0 320.0', 84, 86, 0, 0);
SpawnWaypoint('395.0 -447.0 320.0', 85, 87, 0, 0);
SpawnWaypoint('267.0 -468.0 320.0', 86, 88, 0, 0);
SpawnWaypoint('170.0 -383.0 320.0', 87, 89, 0, 0);
SpawnWaypoint('269.0 -302.0 320.0', 88, 90, 98, 0);
SpawnWaypoint('403.0 -291.0 320.0', 89, 91, 0, 0);
SpawnWaypoint('559.0 -269.0 320.0', 90, 92, 0, 0);
SpawnWaypoint('580.0 -224.0 320.0', 91, 93, 84, 0);
SpawnWaypoint('613.0 -143.0 320.0', 92, 94, 0, 0);
SpawnWaypoint('688.0 -102.0 320.0', 93, 95, 0, 0);
SpawnWaypoint('802.0 -117.0 320.0', 94, 28, 0, 0);
SpawnWaypoint('585.0 -1005.0 432.0', 80, 97, 0, 0);
SpawnWaypoint('595.0 -1090.0 432.0', 96, 75, 76, 0);
SpawnWaypoint('245.0 -224.0 328.0', 89, 99, 0, 0);
SpawnWaypoint('238.0 -100.0 320.0', 98, 100, 0, 0);
SpawnWaypoint('246.0 55.0 320.0', 99, 101, 102, 0);
SpawnWaypoint('253.0 158.0 320.0', 100, 0, 0, 0);
SpawnWaypoint(' 90.0 59.0 320.0', 100, 103, 111, 0);
SpawnWaypoint(' 47.0 67.0 320.0', 102, 104, 0, 0);
SpawnWaypoint('-92.0 91.0 320.0', 103, 105, 111, 110);
SpawnWaypoint('-243.0 79.0 320.0', 104, 106, 109, 107);
SpawnWaypoint('-366.0 -26.0 320.0', 105, 107, 0, 0);
SpawnWaypoint('-375.0 52.0 320.0', 106, 108, 105, 0);
SpawnWaypoint('-356.0 166.0 320.0', 107, 109, 0, 0);
SpawnWaypoint('-277.0 274.0 320.0', 108, 110, 105, 0);
SpawnWaypoint('-29.0 260.0 320.0', 109, 111, 104, 0);
SpawnWaypoint('121.0 248.0 320.0', 110, 102, 104, 0);
SpawnWaypoint('-107.0 -47.0 320.0', 104, 113, 0, 0);
SpawnWaypoint('-107.0 -121.0 320.0', 112, 114, 0, 0);
SpawnWaypoint('-120.0 -257.0 336.0', 113, 115, 0, 0);
SpawnWaypoint('-122.0 -277.0 336.0', 114, 116, 0, 0);
SpawnWaypoint('-108.0 -403.0 384.0', 115, 117, 0, 0);
SpawnWaypoint('-133.0 -454.0 384.0', 116, 118, 0, 0);
SpawnWaypoint('-208.0 -493.0 384.0', 117, 119, 0, 0);
SpawnWaypoint('-314.0 -493.0 416.0', 118, 120, 0, 0);
SpawnWaypoint('-388.0 -489.0 464.0', 119, 121, 0, 0);
SpawnWaypoint('-479.0 -488.0 480.0', 120, 122, 123, 0);
SpawnWaypoint('-488.0 -363.0 480.0', 121, 125, 0, 0);
SpawnWaypoint('-463.0 -675.0 482.0', 121, 124, 0, 0);
SpawnWaypoint('-283.0 -698.0 480.0', 123, 0, 0, 0);
SpawnWaypoint('-264.0 -290.0 480.0', 122, 0, 0, 0);
};
// End dump
/*==========
LoadWaypoints
==========*/
void() LoadWaypoints =
{
waypoint_mode = WM_LOADING;
if (mapname == "e1m2")
waypoints_e1m2();
if (waypoints)
FixWaypoints();
else
{
waypoint_mode = WM_LOADED;
bprint("no waypoints loaded\n");
}
};
/*==========
WaypointPreFrame
called from PlayerPreThink
==========*/
void() WaypointPreFrame =
{
if (waypoint_mode < WM_EDITOR)
return;
SelectNearestWaypoint();
DrawWaypointLinks();
};
/*==========
WaypointPostFrame
called from PlayerPostThink
==========*/
void() WaypointPostFrame =
{
if (waypoint_mode < WM_LOADED)
return;
if (self.impulse == 100)
{
dprint("ToggleWaypointMenu\n");
ToggleWaypointMenu();
self.impulse = 0;
return;
}
if (waypoint_mode < WM_EDITOR)
return;
WaypointMenu();
};
/*==========
WaypointFrame
called from StartFrame
==========*/
void() WaypointFrame =
{
if (framecount < 5)
return;
if (waypoint_mode == WM_UNINIT)
LoadWaypoints();
};
/*==========
WaypointInit
called from worldspawn
==========*/
void() WaypointInit =
{
precache_model("progs/beam.mdl");
precache_model("progs/s_way1.spr");
precache_model("progs/s_way2.spr");
precache_model("progs/s_null.spr");
waypoint_mode = WM_UNINIT;
way_head = world;
way_foot = world;
waypoints = 0;
// used for the menu refresh timer
scr_centertime = cvar("scr_centertime") - 0.1;
if (scr_centertime < 0)
scr_centertime = 0;
};