浏览代码

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 年之前
父节点
当前提交
8d7b6d119f
共有 2 个文件被更改,包括 62 次插入0 次删除
  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