Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make monsters avoid vehicles instead of stupidly attacking them. #4338

Closed
wants to merge 13 commits into from

Conversation

Projects
None yet
10 participants
@freezerbunny
Copy link
Contributor

commented Nov 14, 2013

No description provided.

@i2amroy

This comment has been minimized.

Copy link
Member

commented Nov 14, 2013

2 major problems with this:

  1. Monsters can end up moving back and forth in the same place
    Example:
..V
Z.e
..h

The zombie moves up to the vehicle

..V
.Ze
..h

They then do their next move and check for vehicle, rolling the exact spot they just came from as their "avoidance" roll

..V
Z.e
..h

This can trap them as long as they keep getting unlucky. The way this could be overcome would be to have a "check" order (and it would be more efficient to) where you check based on the vehicle location. So if our zed reaches a vehicle as above instead of just randomly picking spots they would check like this:

531
7Z.
642

This would keep them moving around a vehicle (albeit in a counter-clockwise manner), Ideally it would iterate outwards, find the shorter distance around, and then take it.

  1. As best as I can tell this will make it so that if you stand in a car with car spaces all around you zombies will only try to get in if they get very lucky, and then will immediately try to move out. veh_at() is not gonna be the function you want to use here, you need something that not only checks for vehicle location but also checks for impassibility due to the vehicle.
@freezerbunny

This comment has been minimized.

Copy link
Contributor Author

commented Nov 14, 2013

All valid points.

It's true, they have to get lucky. But it's better than the current functionality (them just whacking the vehicle indefinitely) because they only try to move to direct LOS.

If the player is in the vehicle, current functionality makes them whack it. This one does the same, but a check for an open space or door to get in may be too 'smart', given that zombies don't avoid shrubs and would rather smash a fence than go through the open gate (unless they have to rely on scent, in which case they'll follow the path the player took).

As following from your idea, we could:

  • Check if an "obstacle" is in our path
  • Check all around us for a new location that isn't an obstacle and store all of these
  • Iterate through these locations and choose the one that has the closest distance to the player
  • Go to that location
  • If the player is in the vehicle, who cares let's smash it
@i2amroy

This comment has been minimized.

Copy link
Member

commented Nov 14, 2013

Actually, looking further into this I'm seeing some further problems that start to crop up with things like this, notably a nice chunk of the movement code assumes that the monster is following their planned path exactly and will glitch if they don't (which is what this will cause). The obvious answer to this would be to change from straight line planning to a more robust system (A* would be an example choice) but I'm not sure if you want to put in that much work to try to implement this. :P

@freezerbunny

This comment has been minimized.

Copy link
Contributor Author

commented Nov 14, 2013

A* would feel too optimised for zombies, I think.

I've implemented a solution to what you identified (thanks).

In the upcoming monster rewrite I'll consider pathing more fully.

@freezerbunny

This comment has been minimized.

Copy link
Contributor Author

commented Nov 14, 2013

Hmm doesn't solve the problem.

Need to replan fully.

@i2amroy

This comment has been minimized.

Copy link
Member

commented Nov 14, 2013

A* would feel too optimised for zombies, I think.

It's very easy to take an optimized plan and turn it into a less optimized one by adding in stumbling and other inefficiencies. It's much more difficult to take a less optimized plan and turn it into a more optimized one. If we were rewriting planning I'd rather use the most efficient algorithm we have to plan it and then make it return a less efficient plan (thus allowing us to use it for everyone) then take a less efficient one and need to use a whole separate one for anything that was more intelligent. (Plus we need to be able to handle a ton of monster pathfinding simultaneously, so efficiency is kinda key at that point).

@freezerbunny

This comment has been minimized.

Copy link
Contributor Author

commented Nov 14, 2013

Well, I'll consider it. It would be a good system to have but yeah it'll take some work.

I've implemented the shortest route for now, which should be sufficient.

@freezerbunny

This comment has been minimized.

Copy link
Contributor Author

commented Nov 14, 2013

There's a problem. rl_dist returns an integer, and at some angles that distance is going to be the same for multiple locations where for a float it wouldn't be.

@axujen

This comment has been minimized.

Copy link
Contributor

commented Nov 14, 2013

Why are monsters avoiding vehicles in the first place? As far as i know the only intelligent enemies in the game are NPCs and they already avoid vehicles. All monsters know is how to tear the player apart, they don't have the ability to care for their own safety. Maybe animals perhaps but zombies and the rest of the mindless monsters should not be avoiding vehicles in the first place.

@freezerbunny

This comment has been minimized.

Copy link
Contributor Author

commented Nov 14, 2013

Because they can path to avoid walls.

It is ridiculously stupid for mobs to suddenly hit a vehicle as soon as the line to the player and monster is occluded by one.

Ridiculously stupid. And feels really bad when you want to kite something. You'd have to move yourself so the line from you to the mob doesn't intersect a vehicle, then wait for the mob to go towards you, then move away again.

That is stupid tedium and the mob should just go around it in the first place. All natural creatures don't have this behaviour. A bear wouldn't do it. It's stupid.

Most obstacles (can't move on its tile) block LOS thus meaning they will path around it. Vehicles are the exception.

@i2amroy

This comment has been minimized.

Copy link
Member

commented Nov 14, 2013

There's a problem. rl_dist returns an integer, and at some angles that distance is going to be the same for multiple locations where for a float it wouldn't be.

IIRC we have another type of distance function which returns a float.

@freezerbunny

This comment has been minimized.

Copy link
Contributor Author

commented Nov 14, 2013

@i2amroy
Not that I could find in the line.h headers. I defined one.

Should probably just define a shortest_path function that returns location that is shortest to the player.

@Nickboom1

This comment has been minimized.

Copy link
Contributor

commented Nov 14, 2013

I agree but maybe you should add some sort of thing where if the zombies come across a impassible object they try to smash it first and maybe after a turn or 2 they will stop trying and find another path.

@freezerbunny

This comment has been minimized.

Copy link
Contributor Author

commented Nov 14, 2013

@Nickboom1 Good idea.

@JimQuaid

This comment has been minimized.

Copy link

commented Nov 15, 2013

"All natural creatures don't have this behaviour. A bear wouldn't do it. It's stupid."
Zombies aren't natural creatures. Isn't that the whole point? Zombies will happily leap through fire and jump into pits if that's the shortest way as the crow flies. Wolves and bears just run around it. Zombies should be dumb. They should stop looking for a door on the other side of the building if they step out of your scent cloud and can't hear you anymore (if you're behind a wall that is).

@dwarfkoala

This comment has been minimized.

Copy link

commented Nov 15, 2013

The biggest reason this makes sense is that zombies ALREADY avoid walls in houses. They don't barge up to the walls and try to smash them down uselessly. Why should vehicles be any different? I think it just makes it easier to move around cities if this was implemented. NOthing makes me less happy than when I constantly have to move around the cars to get the zombies to stop smashing them and making a racket.

@ianestrachan

This comment has been minimized.

Copy link
Contributor

commented Nov 15, 2013

They don't barge up to the walls and try to smash them down uselessly. Why should vehicles be any different?

Because they can't see/smell the survivor through walls; they can see/smell the survivor past cars.

Still, as much as I enjoy seeing zombies smashing vehicles and sending scrap metal flying everywhere, they probably shouldn't do it for more than a couple turns. If hulks ever gain the ability to shove cars around, they'll need to try smashing them at least once.

@Falconne

This comment has been minimized.

Copy link
Contributor

commented Nov 16, 2013

map::route already paths around vehicles and finds the cheapest route. You could make a "dumber" version of the method for zombies, that can path around obstacles but not consider terrain movement costs.. and maybe add some random stumbling.

@@ -67,6 +67,10 @@ int trig_dist(int x1, int y1, int x2, int y2)
return int( sqrt( double( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) ) );
}

float float_dist (int x1, int y1, int x2, int y2) {
return sqrt( double( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );

This comment has been minimized.

Copy link
@kevingranade

kevingranade Nov 17, 2013

Member

This is wrong when we're using roguelike distance, it's only accurate for trig dist.

@GlyphGryph

This comment has been minimized.

Copy link
Contributor

commented Nov 19, 2013

Personally, the only thing stopping me from merging this is the technical issue kevingranade mentioned. We don't want our zombies to be smart, but unless we add some way for them to actually crawl /over/ the cars (like I remember they used to do mostly), rather than nonsensically attacking them (they don't smash up bushes or window sills!) I think going around them is the best choice.

@ianestrachan

This comment has been minimized.

Copy link
Contributor

commented Nov 19, 2013

They do smash shrubs, but only for a couple turns - which sets a precedent for having them do something similar here.

monmove.cpp Outdated
// If the player is in the vehicle, we don't care. Smash it. But check if he's far away.
if (!g->m.veh_at(g->u.posx, g->u.posy) || rl_dist(posx(), posy(), g->u.posx, g->u.posy) > 6) {
// Try to go around.
int newx [8] = {-1, 0, 1, -1, 1, -1, 0, 1}; // x positions from top left.

This comment has been minimized.

Copy link
@Falconne

Falconne Nov 19, 2013

Contributor

I'd suggest using map::route() here to ask for a route around the vehicle, so you can re-use existing code.

@GlyphGryph

This comment has been minimized.

Copy link
Contributor

commented Nov 19, 2013

@ianestrachan Is that new behaviour? I can't recall having seen it, but then I haven't actually bush juggled any zombies since before 0.9

@ianestrachan

This comment has been minimized.

Copy link
Contributor

commented Nov 19, 2013

It's been around for a while, 0.8 at least, maybe even before that - sometimes I'll just get a couple "from the (direction) you hear brush!" messages, sometimes they'll actually smash a shrub into underbrush.

Sometimes they also move directly onto the shrub. I think it happens with some other furniture that's passable with an increased move cost, like picket fences.

@freezerbunny freezerbunny deleted the freezerbunny:monsters-avoid-vehicles branch Dec 2, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.