Entity List?
-
- Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
Entity List?
I know i've asked for help on here before, to no success, but this one I REALLY need help on.
basically, i've been working on a pathfinding system for the zombies of nzp (Nazi Zombies: Portable), and I must say, it works quite nicely, but there is one problem...
when finding a path, it sets each waypoint's .MARK value to TRUE, so the zombie doesn't check that waypoint again, but the problem is,
this is global, per say, if one zombie marks a waypoint, then another zombie can't see that waypoint.(yes, I have gotten' around this, but it still arouses more complex problems)
I need a better way to mark waypoints, specifically
I need a way to store a theoretical list of entities in qc.
with functions such as
add_to_list ( list, entity that is being added)
clear_list (list)
and
check_if_entity_is_on_list (list, entity being checked for)
but now the real problem is, is that I have no clue how to make such a list possible.
any ideas? PLEASE help, i've honestly been' working on this for over 2 weeks, everyday nonstop, and to think that i'm so close...
it's nerve racking.
I know some of you could also use this for a mod of your own as well, so please, help
(for those of you who don't know, this pathfinding system is a way for the zombies to ALWAYS find you, travel to you, (using waypoints) and attack you)
sincerely, Blubswillrule
basically, i've been working on a pathfinding system for the zombies of nzp (Nazi Zombies: Portable), and I must say, it works quite nicely, but there is one problem...
when finding a path, it sets each waypoint's .MARK value to TRUE, so the zombie doesn't check that waypoint again, but the problem is,
this is global, per say, if one zombie marks a waypoint, then another zombie can't see that waypoint.(yes, I have gotten' around this, but it still arouses more complex problems)
I need a better way to mark waypoints, specifically
I need a way to store a theoretical list of entities in qc.
with functions such as
add_to_list ( list, entity that is being added)
clear_list (list)
and
check_if_entity_is_on_list (list, entity being checked for)
but now the real problem is, is that I have no clue how to make such a list possible.
any ideas? PLEASE help, i've honestly been' working on this for over 2 weeks, everyday nonstop, and to think that i'm so close...
it's nerve racking.
I know some of you could also use this for a mod of your own as well, so please, help
(for those of you who don't know, this pathfinding system is a way for the zombies to ALWAYS find you, travel to you, (using waypoints) and attack you)
sincerely, Blubswillrule
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it
-
- Posts: 52
- Joined: Thu Sep 30, 2010 6:46 am
Have you tried something like .float MARKCHECK? That would make every true false value local to the entity.
Here's a little bit of code I made to do a tracker entity. I was sick of seeing a monster not go through a doorway and instead running along the wall on the oppisite side.
void() monster_chase =
{
if(enemy_vis)
{
self.tracker = self.enemy.origin;
self.goalentity = self.enemy;
self.trackcheck = 1;
remove(self.track);
}
else
{
if (self.trackcheck == 1)
{
self.track = spawn();
self.track.origin = self.tracker;
self.track.owner = self;
self.track.solid = SOLID_NOT;
self.track.movetype = MOVETYPE_NONE;
setmodel (self.track, "");
setsize(self.track, '0 0 0', '0 0 0');
self.goalentity = self.track;
self.trackcheck = 0;
}
}
if (vlen(self.track.origin - self.origin) < 50)
{
remove(self.track);
self.goalentity = self.enemy;
}
};
It created a entity at the last place it saw the enemy and went to that origin instead of the enemy origin. It worked alright.
Maybe this can help.
Here's a little bit of code I made to do a tracker entity. I was sick of seeing a monster not go through a doorway and instead running along the wall on the oppisite side.
void() monster_chase =
{
if(enemy_vis)
{
self.tracker = self.enemy.origin;
self.goalentity = self.enemy;
self.trackcheck = 1;
remove(self.track);
}
else
{
if (self.trackcheck == 1)
{
self.track = spawn();
self.track.origin = self.tracker;
self.track.owner = self;
self.track.solid = SOLID_NOT;
self.track.movetype = MOVETYPE_NONE;
setmodel (self.track, "");
setsize(self.track, '0 0 0', '0 0 0');
self.goalentity = self.track;
self.trackcheck = 0;
}
}
if (vlen(self.track.origin - self.origin) < 50)
{
remove(self.track);
self.goalentity = self.enemy;
}
};
It created a entity at the last place it saw the enemy and went to that origin instead of the enemy origin. It worked alright.
Maybe this can help.
-
- Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
hmm, nice code, i'll have to read that in-depth to extract it's juicyness
anyways,as for the .floats, well, I used .floats
but I believe (AND PLEASE CORRECT ME IF I'M WRONG)
that
self.way.MARK ============== self.mark
^^from zombies perspective______^^from waypoints perspective,
and since the waypoints must be global, then it won't nescessarily work :\ ... that is, if i'm right.
the example code that you showed me, (although as awesome as it is), isn't quite what i'm trying to achieve, you see, I need the zombie to be able to go to the player, regardless of whether it has seen the player or not, no matter where the player is on the map.
anyways,as for the .floats, well, I used .floats
but I believe (AND PLEASE CORRECT ME IF I'M WRONG)
that
self.way.MARK ============== self.mark
^^from zombies perspective______^^from waypoints perspective,
and since the waypoints must be global, then it won't nescessarily work :\ ... that is, if i'm right.
the example code that you showed me, (although as awesome as it is), isn't quite what i'm trying to achieve, you see, I need the zombie to be able to go to the player, regardless of whether it has seen the player or not, no matter where the player is on the map.
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it
-
- Posts: 52
- Joined: Thu Sep 30, 2010 6:46 am
-
- Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
ahh, now see, the problem isn't going to the next waypoint, the problem comes in searching for the correct path of waypoints
basically what I have is...
woah, that was long, lol
note: wayenqueB and wayenqueA are the same, they simply loop each other
what this does, is checks the current waypoint to make sure it's not the goal (if it is, end the function and tell the zombie to follow the goals owner)
and if it's not, AND IF IT'S NOT MARKED
it will simply do wayenque with the main way's corresponding link.
the problem comes with the
I would like for each zombie to have it's own list of waypoints that it has checked instead,
actually, it's interesting
how this works, is it starts at the players waypoint (waypoint closest to the player),
and it basically builds a theoretical "tree", by searching the player's waypoint's links, then searching it's link's links, and so on, until it finds the zombies current waypoint, this method actually seems to work fairly well, but... as you may have noticed,
if checks owner1 first, then owner2, then owner3, then owner4
so fine, it will check 1 first, then when it reaches a dead end, it will backtrack through the tree one waypoint at a time, till it finds a linked waypoint THAT IS NOT MARKED (that it hasn't checked), and continues this...
now the problem with this, is marking the waypoints, like I said, I would like for the zombies to keep a list of the waypoints they have checked, but I have no clue on how to make a "entity list"
note: going to the next waypoint is no problem
another note: the setmodel part is so I can simply see which waypoints the zombie has checked, and sure enough, only the link 1's get checked because of m faulty marking system.
basically what I have is...
Code: Select all
void(entity way) wayenqueB =
{
bprint ("wayenque B! \n");
setmodel(way, "progs/radio.mdl");
if (way.owner1 != world)
{
bprint("way.owner1 is not world! \n");
if (way.owner1.MARK == FALSE)
{
if (way.owner1 == self.cway)// USED TO BE == SELF.GOALWAY, BUT WE ARE NOW GOING BACKWARDS WITH FINDING THE TREE, IT WILL BE OF HELP TO US LATER!
{
bprint ("we found the zombie's cway with enque B! \n");
way.owner1.owner = way;
foundgoalway(way.owner1);
return;
}
if(way.owner1 != self.cway)
{
bprint("way.owner1 is not marked! \n");
way.owner1.MARK = TRUE;
way.owner1.owner = way;
wayenqueA (way.owner1);
return;
}
}
}
if (way.owner2 != world)
{
bprint("way.owner2 is not world! \n");
if (way.owner2.MARK == FALSE)
{
if (way.owner2 == self.cway)// USED TO BE == SELF.GOALWAY, BUT WE ARE NOW GOING BACKWARDS WITH FINDING THE TREE, IT WILL BE OF HELP TO US LATER!
{
bprint ("we found the zombie's cway with enque B! \n");
way.owner2.owner = way;
foundgoalway(way.owner2);
return;
}
if(way.owner2 != self.cway)
{
bprint("way.owner2 is not marked! \n");
way.owner2.MARK = TRUE;
way.owner2.owner = way;
wayenqueA (way.owner2);
return;
}
}
}
if (way.owner3 != world)
{
bprint("way.owner3 is not world! \n");
if (way.owner3.MARK == FALSE)
{
if (way.owner3 == self.cway)// USED TO BE == SELF.GOALWAY, BUT WE ARE NOW GOING BACKWARDS WITH FINDING THE TREE, IT WILL BE OF HELP TO US LATER!
{
bprint ("we found the zombie's cway with enque B! \n");
way.owner3.owner = way;
foundgoalway(way.owner3);
return;
}
if(way.owner3 != self.cway)
{
bprint("way.owner3 is not marked! \n");
way.owner3.MARK = TRUE;
way.owner3.owner = way;
wayenqueA (way.owner3);
return;
}
}
}
if (way.owner4 != world)
{
bprint("way.owner4 is not world! \n");
if (way.owner4.MARK == FALSE)
{
if (way.owner4 == self.cway)// USED TO BE == SELF.GOALWAY, BUT WE ARE NOW GOING BACKWARDS WITH FINDING THE TREE, IT WILL BE OF HELP TO US LATER!
{
bprint ("we found the zombie's cway with enque B! \n");
way.owner4.owner = way;
foundgoalway(way.owner4);
return;
}
if(way.owner4 != self.cway)
{
bprint("way.owner4 is not marked! \n");
way.owner4.MARK = TRUE;
way.owner4.owner = way;
if (way.owner4 == self.cway)
wayenqueA (way.owner4);
return;
}
}
}
if (way.owner1 == world || way.owner1.MARK ==TRUE)
{
if (way.owner2 == world || way.owner2.MARK == TRUE)
{
if (way.owner3 == world || way.owner3.MARK == TRUE)
{
if (way.owner4 == world || way.owner4.MARK == TRUE)
{
bprint ("DEAD LINK!, RESTARTING! \n");
if (way.owner != world)
wayenqueA(way.owner);
return;
}
}
}
}
};
note: wayenqueB and wayenqueA are the same, they simply loop each other
what this does, is checks the current waypoint to make sure it's not the goal (if it is, end the function and tell the zombie to follow the goals owner)
and if it's not, AND IF IT'S NOT MARKED
it will simply do wayenque with the main way's corresponding link.
the problem comes with the
Code: Select all
if (way.MARK == FALSE)
actually, it's interesting
how this works, is it starts at the players waypoint (waypoint closest to the player),
and it basically builds a theoretical "tree", by searching the player's waypoint's links, then searching it's link's links, and so on, until it finds the zombies current waypoint, this method actually seems to work fairly well, but... as you may have noticed,
if checks owner1 first, then owner2, then owner3, then owner4
so fine, it will check 1 first, then when it reaches a dead end, it will backtrack through the tree one waypoint at a time, till it finds a linked waypoint THAT IS NOT MARKED (that it hasn't checked), and continues this...
now the problem with this, is marking the waypoints, like I said, I would like for the zombies to keep a list of the waypoints they have checked, but I have no clue on how to make a "entity list"
note: going to the next waypoint is no problem
another note: the setmodel part is so I can simply see which waypoints the zombie has checked, and sure enough, only the link 1's get checked because of m faulty marking system.
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it
-
- Posts: 52
- Joined: Thu Sep 30, 2010 6:46 am
I haven't really messed with entity lists or waypoints. Have you looked at the tutor bot stuff?
Here's a link to adding waypoint
http://www.quakewiki.net/archives/aicaf ... ypoint.htm
Here's the page of tutorials
http://www.quakewiki.net/archives/aicaf ... l/main.htm
Here's a link to adding waypoint
http://www.quakewiki.net/archives/aicaf ... ypoint.htm
Here's the page of tutorials
http://www.quakewiki.net/archives/aicaf ... l/main.htm
-
- Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
sweet, thanks, i'll look into it and see if theres anything on lists, or a better way to do what I want.
Although I think I remember that waypoint tutorial from a while back, that's not to say there isn't anything useful in the rest of it
Although I think I remember that waypoint tutorial from a while back, that's not to say there isn't anything useful in the rest of it
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it
-
- Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
repost, didn't find anything on there
anybody have any ideas on how to have a list of entities in quake?
without regards to AI, just in general.
like, one entity owns a list
you can add entities to that list
you can clear the list
you can check if an entity is on the list.
any ideas on how to make this? I REALLY need help, please
anybody have any ideas on how to have a list of entities in quake?
without regards to AI, just in general.
like, one entity owns a list
you can add entities to that list
you can clear the list
you can check if an entity is on the list.
any ideas on how to make this? I REALLY need help, please
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it
-
- Posts: 2126
- Joined: Sat Nov 25, 2006 1:49 pm
blubswillrule wrote:repost, didn't find anything on there
anybody have any ideas on how to have a list of entities in quake?
without regards to AI, just in general.
like, one entity owns a list
you can add entities to that list
you can clear the list
you can check if an entity is on the list.
any ideas on how to make this? I REALLY need help, please
Pretty much the same way you would in C: using pointers.
Code: Select all
// WARNING: UNTESTED, MAY CONTAIN LOTS OF BUGS,
// USE AT YOUR OWN RISK!!!!!1ONE1.
// let's add some custom entity fields
.entity parent;
.entity link;
// adds a child to p
void (entity p, entity c) addChild =
{
c.parent = p;
if (p.link != world)
{
c.link = p.link;
}
else
{
c.link = world;
}
p.link = c;
};
// clears all p children
void (entity p) clearChildren =
{
local entity ptr = p.link;
while (ptr != world)
{
ptr.parent = world;
ptr = ptr.link;
}
};
// checks if c exists in p children list
float (entity p, entity c) containsChild =
{
return (c.parent == p);
};
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC (LordHavoc)
-
- Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
dude!, oh my god, thank you!
my pathfinding now works now
although it is a little bit slow (mainly because I added delays for things, because I don't want to have a runaway loop counter )
one thing, although not sure if this matters.
I changed this...
to...
the ptr.parent.link line
so it actually kinda' takes off the current ptr, then ptr's parent is linked to ptr's link
otherwise, it would give me a runaway loop counter
well, now, off to fix my one crash-causing bug...
of stack overflows lol
but again, thanks so much
my pathfinding now works now
although it is a little bit slow (mainly because I added delays for things, because I don't want to have a runaway loop counter )
one thing, although not sure if this matters.
I changed this...
Code: Select all
void (entity p) clearChildren =
{
local entity ptr = p.link;
while (ptr != world)
{
ptr.parent = world;
ptr = ptr.link;
}
};
Code: Select all
void (entity p) clearChildren =
{
local entity ptr = p.link;
while (ptr != world)
{
ptr.parent.link = ptr.link;//*******
ptr.parent = world;
ptr = ptr.link;
}
};
so it actually kinda' takes off the current ptr, then ptr's parent is linked to ptr's link
otherwise, it would give me a runaway loop counter
well, now, off to fix my one crash-causing bug...
of stack overflows lol
but again, thanks so much
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it
-
- Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
Sorry for reviving the topic, but looking back at the code you gratefully gave me, made me wonder, do the entities.linklist affect the ACTUAL entities linklist, or the OWNER OF THE LISTS linklist?
I need to have different lists of the same entities. (If they affect the actual objects' linklist, then the different lists would interfere with each other and make this not useable :\ )
I need to have different lists of the same entities. (If they affect the actual objects' linklist, then the different lists would interfere with each other and make this not useable :\ )
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it
-
- Posts: 2126
- Joined: Sat Nov 25, 2006 1:49 pm
if you modify the objects to create the list, you can only add that object to one list.
you can have multiple things refering to the same list, you can have additional lists which lead on to the aforementioned list, but if you have a single 'next' pointer, you only have a single next pointer.
so a list of simple node objects that purely refer to the real object and the next node will work. will take a lot of memory, one per ent, but it'll work.
If you're okay with maximum list sizes, you may wish to consider using some sort of field array in a qcc that supports it.
you can have multiple things refering to the same list, you can have additional lists which lead on to the aforementioned list, but if you have a single 'next' pointer, you only have a single next pointer.
so a list of simple node objects that purely refer to the real object and the next node will work. will take a lot of memory, one per ent, but it'll work.
If you're okay with maximum list sizes, you may wish to consider using some sort of field array in a qcc that supports it.
-
- Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
Yeah, I guess I could just go with maximum entity list sizes, because I'm using this for storing waypoint paths, and I'm pretty sure either a) by the time the ai reaches the end of the list, it will have recalculated it's path, and b) if it just reaches the end, it can just calculate again.
(having the ai check if it's goal is in same relative place, if not, then recalculate path)
thanks for the help!
(having the ai check if it's goal is in same relative place, if not, then recalculate path)
thanks for the help!
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it