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

Teleport channels and pathfinding via teleports #93

Merged

Conversation

ArseniyShestakov
Copy link
Member

This one of course break saves compatibility. For now this code is stable except I break something while split changes into more logical commits. I'd tested it on some quite long AI game and they didn't manage to crash it.

There at least one possible problem exist: as in H3 mechanics heroes may start exchange within subterranean gates. Of course this can't happen accidentally because AI not going to explore "busy" gates and may only go there if actually wanted to initiate this exchange, but I have feeling that it's works not the way as AI code expect it.

More detailed discussions may be found there:
http://forum.vcmi.eu/viewtopic.php?t=1051
ArseniyShestakov#2

For pathfinder we usually want to check what object hero staying on.
Hero is always top object so we need option to exclude it.
TeleportChannel is structure that contain two vectors of entrances and exits for certain teleport channel. It's also store passability state independently which almost only useful for Player and AI as they can't know if channel passible or not until enough entrances / exits are visible or server passed them information that certain channel is impassible when they visited entrance.

ETeleportChannelType is determined by checking intersection between entrances and exit vectors or checking their size:
 - IMPASSABLE: one of vectors empty or only one entrance id is same as only one exit id.
 - BIDIRECTIONAL: contents of both vectors is exactly the same.
 - UNIDIRECTIONAL: contents of both vectors do not intersect.
 - MIXED: contents of vectors only partially intersect. Not currently used; added for future modding.
Now CGTeleport is not publicly available handler, but generic class for teleport channels usage.
Teleport channels are stored as part of information about the map.
…rt channels

This code belongs to callback because both player and AI shouldn't directly access information about teleport channels.
For example pathfinder code need to check teleport channel type only based on information about objects player already seen.
TeleportDialog is based off BlockingDialog and it's needed for server to ask client what teleport hero should be teleported to.
It's also contain list of possible exits, identifier of currently used channel and also impassable option.
If impassable set to true then client will remember that current teleport channel is lack of exit point.
Just like TeleportDialog it's based off showBlockingDialog, but as number of package is higher when possible showTeleportDialog will be after other dialogs handling code.
Transit is new option for hero movement. If it passed for movement then hero can get get on tile without visiting of object on it.
Currently it's will be only allowed is object under destination is teleport.
Each kind of teleporter have own function that determine if it's should or shouldn't be used.
For now Monolith with bidirectional channels and Subterranean Gate are united.
When AI going through bidirectional teleport it's always getting list of all available exits.
If some of exits are invisible it's will attempt to visit each of them teleport probing begins.
Now all new objects added to visitableObjs only using addVisitableObj so we can catch them for teleports handling.
I also simplified one of retreiveVisitableObjs functions because it's only used for inserting things into visitableObjs.
Explore will also suggest AI to re-enter bidirectional teleporter in case of one of it's exits is not visible for some reason.

Also now AI won't try to visit teleporters in case if it's know that it's channel is impassable. E.g if map have several entrance monoliths of with same same SubID that don't have exit then AI will only try to visit one of them and later of he'll know that all other monoliths of this subtype is blocked because they all using same channel.
case Obj::MONOLITH_TWO_WAY:
case Obj::SUBTERRANEAN_GATE:
auto tObj = dynamic_cast<const CGTeleport *>(obj);
if(tObj)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really can be nullptr? Can object with ID MONOLITH_ONE_WAY_ENTRANCE,... be not CGTeleport?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course it's impossible. I'm shouldn't left this check there.

std::map<const CGObjectInstance *, const CGObjectInstance *> knownSubterraneanGates;
ObjectInstanceID destinationTeleport;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is not serialized, here should be a comment about that or you missed serialization?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I think the way that after load it's will be set to -1, but as I get constructor probably only executed once. Yeah?

I didn't add it to serialization as it's only set to anything except -1 right before teleportation should occur and then teleportation AI should always occur before end of turn. Or valid game save is possible during AI turn?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or valid game save is possible during AI turn?

Currently it is impossible
Initialization in constructor is not enough, it may need reinit before each movement.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently it is impossible

Sadly it's kind a possible because there is way to unlock UI and use save via hotkey.
Though as I get it's shouldn't be that way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added it to serialization for now: f7a999f

}

//sort by position
std::sort(gatesSplit[0].begin(), gatesSplit[0].end(), [](const CGObjectInstance * a, const CGObjectInstance * b)
std::sort(gatesSplit[0].begin(), gatesSplit[0].end(), [](CGSubterraneanGate * a, CGSubterraneanGate * b)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why "const" was removed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My fault. I made it while turn code to work with mutable objects and map state as I needed to change "channel" of object. Though sorting can work with const just fine. Fixed.

@ArseniyShestakov
Copy link
Member Author

Also just in case. Is there something that have to go into changelog?
If yes any suggestions what to write there?

Originally I removed it when change this code to actually change object.
Though this sorting can work with constant object just fine.
@alexvins
Copy link
Member

alexvins commented Mar 8, 2015

This one of course break saves compatibility.

Missing format number update in Connection.h.

@ArseniyShestakov
Copy link
Member Author

Missing format number update in Connection.h.

I think that if we going to merge this we'll also merge quest fix which have protocol version bump in it.

{
std::vector<ObjectInstanceID> ret = cb->getTeleportChannelEntraces(channel);
if(excludeCurrent)
ret.erase(std::remove(ret.begin(), ret.end(), id), ret.end());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've got vstd::remove_if_present function for that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@DjWarmonger
Copy link
Member

Changelog includes significant changes that are not mentioned on Mantis. So:

  • Pathfinding for monoliths (elaborate)
  • AI support for monoliths

@ArseniyShestakov
Copy link
Member Author

So I added few things into changelog. Though it's looks like develop not currently buildable on Linux.

DjWarmonger pushed a commit that referenced this pull request Mar 10, 2015
@DjWarmonger DjWarmonger merged commit ec87904 into vcmi:develop Mar 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants