Browse Source

CGameInfoCallback: add functions that gather information about teleport 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.
ArseniyShestakov 10 years ago
parent
commit
8d7b6d119f
2 changed files with 62 additions and 0 deletions
  1. 55 0
      lib/CGameInfoCallback.cpp
  2. 7 0
      lib/CGameInfoCallback.h

+ 55 - 0
lib/CGameInfoCallback.cpp

@@ -688,6 +688,61 @@ const CGObjectInstance * CGameInfoCallback::getObjInstance( ObjectInstanceID oid
 	return gs->map->objects[oid.num];
 }
 
+std::vector<ObjectInstanceID> CGameInfoCallback::getTeleportChannelEntraces(TeleportChannelID id, ObjectInstanceID excludeId, PlayerColor Player) const
+{
+	std::vector<ObjectInstanceID> ret;
+	auto channel = gs->map->teleportChannels[id];
+	for(auto entrance : channel->entrances)
+	{
+		auto obj = getObj(entrance);
+		if(obj && (Player == PlayerColor::UNFLAGGABLE || isVisible(obj->pos, Player)))
+			ret.push_back(entrance);
+	}
+
+	return ret;
+}
+
+std::vector<ObjectInstanceID> CGameInfoCallback::getTeleportChannelExits(TeleportChannelID id, ObjectInstanceID excludeId, PlayerColor Player) const
+{
+	std::vector<ObjectInstanceID> ret;
+	auto channel = gs->map->teleportChannels[id];
+	for(auto exit : channel->exits)
+	{
+		auto obj = getObj(exit);
+		if(obj && (Player == PlayerColor::UNFLAGGABLE || isVisible(obj->pos, Player)))
+			ret.push_back(exit);
+	}
+
+	return ret;
+}
+
+ETeleportChannelType::ETeleportChannelType CGameInfoCallback::getTeleportChannelType(TeleportChannelID id, PlayerColor Player) const
+{
+	std::vector<ObjectInstanceID> entrances = getTeleportChannelEntraces(id, ObjectInstanceID(), Player);
+	std::vector<ObjectInstanceID> exits = getTeleportChannelExits(id, ObjectInstanceID(), Player);
+	if((!entrances.size() || !exits.size())
+		|| (entrances.size() == 1 && entrances == exits))
+	{
+		return ETeleportChannelType::IMPASSABLE;
+	}
+
+	auto intersection = vstd::intersection(entrances, exits);
+	if(intersection.size() == entrances.size() && intersection.size() == exits.size())
+		return ETeleportChannelType::BIDIRECTIONAL;
+	else if(!intersection.size())
+		return ETeleportChannelType::UNIDIRECTIONAL;
+	else
+		return ETeleportChannelType::MIXED;
+}
+
+bool CGameInfoCallback::isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor Player) const
+{
+	if(obj && obj->isEntrance() && ETeleportChannelType::IMPASSABLE != getTeleportChannelType(obj->channel, Player))
+		return true;
+	else
+		return false;
+}
+
 void IGameEventRealizer::showInfoDialog( InfoWindow *iw )
 {
 	commitPackage(iw);

+ 7 - 0
lib/CGameInfoCallback.h

@@ -25,6 +25,7 @@ struct InfoAboutTown;
 struct UpgradeInfo;
 struct SThievesGuildInfo;
 class CGDwelling;
+class CGTeleport;
 class CMapHeader;
 struct TeamState;
 struct QuestInfo;
@@ -106,6 +107,12 @@ public:
 	const TeamState *getTeam(TeamID teamID) const;
 	const TeamState *getPlayerTeam(PlayerColor color) const;
 	EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
+
+	//teleport
+	std::vector<ObjectInstanceID> getTeleportChannelEntraces(TeleportChannelID id, ObjectInstanceID excludeId = ObjectInstanceID(), PlayerColor Player = PlayerColor::UNFLAGGABLE) const;
+	std::vector<ObjectInstanceID> getTeleportChannelExits(TeleportChannelID id, ObjectInstanceID excludeId = ObjectInstanceID(), PlayerColor Player = PlayerColor::UNFLAGGABLE) const;
+	ETeleportChannelType::ETeleportChannelType getTeleportChannelType(TeleportChannelID id, PlayerColor Player = PlayerColor::UNFLAGGABLE) const;
+	bool isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor Player) const;
 };
 
 class DLL_LINKAGE CPlayerSpecificInfoCallback : public CGameInfoCallback