Example #1
0
    static bool HandleMmapPathCommand(ChatHandler* handler, char const* args)
    {
        if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId(), handler->GetSession()->GetPlayer()->GetTerrainSwaps()))
        {
            handler->PSendSysMessage("NavMesh not loaded for current map.");
            return true;
        }

        handler->PSendSysMessage("mmap path:");

        // units
        Player* player = handler->GetSession()->GetPlayer();
        Unit* target = handler->getSelectedUnit();
        if (!player || !target)
        {
            handler->PSendSysMessage("Invalid target/source selection.");
            return true;
        }

        char* para = strtok((char*)args, " ");

        bool useStraightPath = false;
        if (para && strcmp(para, "true") == 0)
            useStraightPath = true;

        bool useStraightLine = false;
        if (para && strcmp(para, "line") == 0)
            useStraightLine = true;

        // unit locations
        float x, y, z;
        player->GetPosition(x, y, z);

        // path
        PathGenerator path(target);
        path.SetUseStraightPath(useStraightPath);
        bool result = path.CalculatePath(x, y, z, false, useStraightLine);

        Movement::PointsArray const& pointPath = path.GetPath();
        handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str());
        handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : useStraightLine ? "Raycast" : "SmoothPath");
        handler->PSendSysMessage("Result: %s - Length: %zu - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());

        G3D::Vector3 const &start = path.GetStartPosition();
        G3D::Vector3 const &end = path.GetEndPosition();
        G3D::Vector3 const &actualEnd = path.GetActualEndPosition();

        handler->PSendSysMessage("StartPosition     (%.3f, %.3f, %.3f)", start.x, start.y, start.z);
        handler->PSendSysMessage("EndPosition       (%.3f, %.3f, %.3f)", end.x, end.y, end.z);
        handler->PSendSysMessage("ActualEndPosition (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z);

        if (!player->IsGameMaster())
            handler->PSendSysMessage("Enable GM mode to see the path points.");

        for (uint32 i = 0; i < pointPath.size(); ++i)
            player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000);

        return true;
    }
Example #2
0
    static bool HandleMmapPathCommand(ChatHandler* handler, const char* args)
    {
        if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()))
        {
            handler->PSendSysMessage("NavMesh not loaded for current map.");
            return true;
        }

        handler->PSendSysMessage("mmap path:");

// units
        Player* player = handler->GetSession()->GetPlayer();
        Unit* target = handler->getSelectedUnit();
        if (!player || !target)
        {
            handler->PSendSysMessage("Invalid target/source selection.");
            return true;
        }

        char* para = strtok((char*)args, " ");

        bool useStraightPath = false;
        if (para && strcmp(para, "true") == 0)
            useStraightPath = true;

// unit locations
        float x, y, z;
        player->GetPosition(x, y, z);

// path
        PathInfo path(target, x, y, z, useStraightPath);
        PointPath pointPath = path.getFullPath();
        handler->PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName());
        handler->PSendSysMessage("Building %s", useStraightPath ? "StraightPath" : "SmoothPath");
        handler->PSendSysMessage("length %i type %u", pointPath.size(), path.getPathType());

        PathNode start = path.getStartPosition();
        PathNode next = path.getNextPosition();
        PathNode end = path.getEndPosition();
        PathNode actualEnd = path.getActualEndPosition();

        handler->PSendSysMessage("start (%.3f, %.3f, %.3f)", start.x, start.y, start.z);
        handler->PSendSysMessage("next (%.3f, %.3f, %.3f)", next.x, next.y, next.z);
        handler->PSendSysMessage("end (%.3f, %.3f, %.3f)", end.x, end.y, end.z);
        handler->PSendSysMessage("actual end (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z);

        if (!player->isGameMaster())
            handler->PSendSysMessage("Enable GM mode to see the path points.");

// this entry visible only to GM's with "gm on"
        static const uint32 WAYPOINT_NPC_ENTRY = 1;
        for (uint32 i = 0; i < pointPath.size(); ++i)
            player->SummonCreature(WAYPOINT_NPC_ENTRY, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000);

        return true;
    }
Example #3
0
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
{
    DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
    uint64 Guid;
    recv_data >> Guid;

    Player *player = sObjectMgr.GetPlayer(Guid);
    if(!player)
    {
        WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
        data << uint8(0);                                   // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
        data.appendPackGUID(Guid);
        data << uint32(GROUP_UPDATE_FLAG_STATUS);
        data << uint16(MEMBER_STATUS_OFFLINE);
        SendPacket(&data);
        return;
    }

    Unit *pet = player->GetCharmOrPet();

    WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
    data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
    data << player->GetPackGUID();

    uint32 mask1 = 0x00040BFF;                              // common mask, real flags used 0x000040BFF
    if(pet)
        mask1 = 0xFFFFFFFF;                                 // for hunters and other classes with pets

    Powers powerType = player->getPowerType();
    data << uint32(mask1);                                  // group update mask
    data << uint16(MEMBER_STATUS_ONLINE);                   // member's online status
    data << uint32(player->GetHealth());                    // GROUP_UPDATE_FLAG_CUR_HP
    data << uint32(player->GetMaxHealth());                 // GROUP_UPDATE_FLAG_MAX_HP
    data << uint8(powerType);                               // GROUP_UPDATE_FLAG_POWER_TYPE
    data << uint16(player->GetPower(powerType));            // GROUP_UPDATE_FLAG_CUR_POWER
    data << uint16(player->GetMaxPower(powerType));         // GROUP_UPDATE_FLAG_MAX_POWER
    data << uint16(player->getLevel());                     // GROUP_UPDATE_FLAG_LEVEL
    data << uint16(player->GetZoneId());                    // GROUP_UPDATE_FLAG_ZONE
    data << uint16(player->GetPositionX());                 // GROUP_UPDATE_FLAG_POSITION
    data << uint16(player->GetPositionY());                 // GROUP_UPDATE_FLAG_POSITION

    uint64 auramask = 0;
    size_t maskPos = data.wpos();
    data << uint64(auramask);                               // placeholder
    for(uint8 i = 0; i < MAX_AURAS; ++i)
    {
        if(uint32 aura = player->GetVisibleAura(i))
        {
            auramask |= (uint64(1) << i);
            data << uint32(aura);
            data << uint8(1);
        }
    }
    data.put<uint64>(maskPos, auramask);                    // GROUP_UPDATE_FLAG_AURAS

    if(pet)
    {
        Powers petpowertype = pet->getPowerType();
        data << pet->GetObjectGuid();                       // GROUP_UPDATE_FLAG_PET_GUID
        data << pet->GetName();                             // GROUP_UPDATE_FLAG_PET_NAME
        data << uint16(pet->GetDisplayId());                // GROUP_UPDATE_FLAG_PET_MODEL_ID
        data << uint32(pet->GetHealth());                   // GROUP_UPDATE_FLAG_PET_CUR_HP
        data << uint32(pet->GetMaxHealth());                // GROUP_UPDATE_FLAG_PET_MAX_HP
        data << uint8(petpowertype);                        // GROUP_UPDATE_FLAG_PET_POWER_TYPE
        data << uint16(pet->GetPower(petpowertype));        // GROUP_UPDATE_FLAG_PET_CUR_POWER
        data << uint16(pet->GetMaxPower(petpowertype));     // GROUP_UPDATE_FLAG_PET_MAX_POWER

        uint64 petauramask = 0;
        size_t petMaskPos = data.wpos();
        data << uint64(petauramask);                        // placeholder
        for(uint8 i = 0; i < MAX_AURAS; ++i)
        {
            if(uint32 petaura = pet->GetVisibleAura(i))
            {
                petauramask |= (uint64(1) << i);
                data << uint32(petaura);
                data << uint8(1);
            }
        }
        data.put<uint64>(petMaskPos, petauramask);          // GROUP_UPDATE_FLAG_PET_AURAS
        data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
    }
    else
    {
        data << uint8(0);                                   // GROUP_UPDATE_FLAG_PET_NAME
        data << uint64(0);                                  // GROUP_UPDATE_FLAG_PET_AURAS
    }

    SendPacket(&data);
}
Example #4
0
void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
{
    uint32 mask = player->GetGroupUpdateFlag();

    if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)                // if update power type, update current/max power also
        mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);

    if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)            // same for pets
        mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER);

    uint32 byteCount = 0;
    for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
        if (mask & (1 << i))
            byteCount += GroupUpdateLength[i];

    data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
    *data << player->GetPackGUID();
    *data << uint32(mask);

    if (mask & GROUP_UPDATE_FLAG_STATUS)
    {
        if (player)
        {
            if (player->IsPvP())
                *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP);
            else
                *data << uint16(MEMBER_STATUS_ONLINE);
        }
        else
            *data << uint16(MEMBER_STATUS_OFFLINE);
    }

    if (mask & GROUP_UPDATE_FLAG_CUR_HP)
        *data << uint32(player->GetHealth());

    if (mask & GROUP_UPDATE_FLAG_MAX_HP)
        *data << uint32(player->GetMaxHealth());

    Powers powerType = player->getPowerType();
    if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
        *data << uint8(powerType);

    if (mask & GROUP_UPDATE_FLAG_CUR_POWER)
        *data << uint16(player->GetPower(powerType));

    if (mask & GROUP_UPDATE_FLAG_MAX_POWER)
        *data << uint16(player->GetMaxPower(powerType));

    if (mask & GROUP_UPDATE_FLAG_LEVEL)
        *data << uint16(player->getLevel());

    if (mask & GROUP_UPDATE_FLAG_ZONE)
        *data << uint16(player->GetZoneId());

    if (mask & GROUP_UPDATE_FLAG_POSITION)
        *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY());

    if (mask & GROUP_UPDATE_FLAG_AURAS)
    {
        const uint64& auramask = player->GetAuraUpdateMask();
        *data << uint64(auramask);
        for(uint32 i = 0; i < MAX_AURAS; ++i)
        {
            if(auramask & (uint64(1) << i))
            {
                *data << uint32(player->GetVisibleAura(i));
                *data << uint8(1);
            }
        }
    }

    Unit *pet = player->GetCharmOrPet();
    if (mask & GROUP_UPDATE_FLAG_PET_GUID)
        *data << (pet ? pet->GetObjectGuid() : ObjectGuid());

    if (mask & GROUP_UPDATE_FLAG_PET_NAME)
    {
        if(pet)
            *data << pet->GetName();
        else
            *data << uint8(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID)
    {
        if(pet)
            *data << uint16(pet->GetDisplayId());
        else
            *data << uint16(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
    {
        if(pet)
            *data << uint32(pet->GetHealth());
        else
            *data << uint32(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
    {
        if(pet)
            *data << uint32(pet->GetMaxHealth());
        else
            *data << uint32(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
    {
        if(pet)
            *data << uint8(pet->getPowerType());
        else
            *data << uint8(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER)
    {
        if(pet)
            *data << uint16(pet->GetPower(pet->getPowerType()));
        else
            *data << uint16(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER)
    {
        if(pet)
            *data << uint16(pet->GetMaxPower(pet->getPowerType()));
        else
            *data << uint16(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
    {
        if(pet)
        {
            const uint64& auramask = pet->GetAuraUpdateMask();
            *data << uint64(auramask);
            for(uint32 i = 0; i < MAX_AURAS; ++i)
            {
                if(auramask & (uint64(1) << i))
                {
                    *data << uint32(pet->GetVisibleAura(i));
                    *data << uint8(1);
                }
            }
        }
        else
            *data << uint64(0);
    }

    if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
    {
        *data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
    }
}
        void UpdateAI(const uint32 diff)
        {
            //Inhibitmagic_Timer
            if (Inhibitmagic_Timer <= diff)
            {
                float dist;
                Map* map = me->GetMap();
                Map::PlayerList const &PlayerList = map->GetPlayers();
                for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                    if (Player* i_pl = i->getSource())
                        if (i_pl->isAlive() && (dist = i_pl->IsWithinDist(me, 45)))
                        {
                            i_pl->RemoveAurasDueToSpell(SPELL_INHIBITMAGIC);
                            me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                            if (dist < 35)
                                me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                            if (dist < 25)
                                me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                            if (dist < 15)
                                me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                        }
                Inhibitmagic_Timer = 3000+(rand()%1000);
            } else Inhibitmagic_Timer -= diff;

            //Return since we have no target
            if (!UpdateVictim())
                return;

            //Attractmagic_Timer
            if (Attractmagic_Timer <= diff)
            {
                DoCast(me, SPELL_ATTRACTMAGIC);
                Attractmagic_Timer = 30000;
                Carnivorousbite_Timer = 1500;
            } else Attractmagic_Timer -= diff;

            //Carnivorousbite_Timer
            if (Carnivorousbite_Timer <= diff)
            {
                DoCast(me, SPELL_CARNIVOROUSBITE);
                Carnivorousbite_Timer = 10000;
            } else Carnivorousbite_Timer -= diff;

            //FocusFire_Timer
            if (FocusFire_Timer <= diff)
            {
                // Summon Focus Fire & Emote
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                if (target && target->GetTypeId() == TYPEID_PLAYER && target->isAlive())
                {
                    FocusedTargetGUID = target->GetGUID();
                    me->SummonCreature(ENTRY_FOCUS_FIRE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 5500);

                    // TODO: Find better way to handle emote
                    // Emote
                    std::string emote(EMOTE_FOCUSES_ON);
                    emote.append(target->GetName());
                    emote.push_back('!');
                    me->MonsterTextEmote(emote.c_str(), 0, true);
                }
                FocusFire_Timer = 15000+(rand()%5000);
            } else FocusFire_Timer -= diff;

            DoMeleeAttackIfReady();
        }
    void UpdateAI(const uint32 diff)
    {
        //Inhibitmagic_Timer
        if (Inhibitmagic_Timer < diff)
        {
            float dist;
            Map *map = m_creature->GetMap();
            Map::PlayerList const &PlayerList = map->GetPlayers();
            for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                if (Player* i_pl = i->getSource())
                    if (i_pl->isAlive() && (dist = i_pl->GetDistance(m_creature)) < 45)
                    {
                        i_pl->RemoveAurasDueToSpell(SPELL_INHIBITMAGIC);
                        m_creature->AddAura(SPELL_INHIBITMAGIC, i_pl);
                        if(dist < 35)
                            m_creature->AddAura(SPELL_INHIBITMAGIC, i_pl);
                        if(dist < 25)
                            m_creature->AddAura(SPELL_INHIBITMAGIC, i_pl);
                        if(dist < 15)
                            m_creature->AddAura(SPELL_INHIBITMAGIC, i_pl);
                    }
            Inhibitmagic_Timer = 3000+(rand()%1000);
        }else Inhibitmagic_Timer -= diff;

        //Return since we have no target
        if (!UpdateVictim() )
            return;

        //Attractmagic_Timer
        if (Attractmagic_Timer < diff)
        {
            DoCast(m_creature,SPELL_ATTRACTMAGIC);
            Attractmagic_Timer = 30000;
            Carnivorousbite_Timer = 1500;
        }else Attractmagic_Timer -= diff;

        //Carnivorousbite_Timer
        if (Carnivorousbite_Timer < diff)
        {
            DoCast(m_creature,SPELL_CARNIVOROUSBITE);
            Carnivorousbite_Timer = 10000;
        }else Carnivorousbite_Timer -= diff;

        //FocusFire_Timer
        if (FocusFire_Timer < diff)
        {
            // Summon Focus Fire & Emote
            Unit *target = SelectUnit(SELECT_TARGET_RANDOM,1);
            if (target && target->GetTypeId() == TYPEID_PLAYER && target->isAlive())
            {
                focusedTarget = target;
                m_creature->SummonCreature(ENTRY_FOCUS_FIRE,target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,5500);

                // Emote
                std::string *emote = new std::string("focuses on ");
                emote->append(target->GetName());
                emote->append("!");
                DoTextEmote(emote->c_str(),NULL,true);
                delete emote;
            }
            FocusFire_Timer = 15000+(rand()%5000);
        }else FocusFire_Timer -= diff;

        DoMeleeAttackIfReady();
    }
Example #7
0
void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
{
    if(!GetPlayer()->isAlive())
        return;

    if (!GetPlayer()->CanSpeak())
    {
        std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
        SendNotification(GetMangosString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str());
        return;
    }

    CHECK_PACKET_SIZE(recv_data,4+4+8);

    uint32 text_emote, emoteNum;
    uint64 guid;

    recv_data >> text_emote;
    recv_data >> emoteNum;
    recv_data >> guid;

    const char *nam = 0;
    uint32 namlen = 1;

    Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
    Creature *pCreature = dynamic_cast<Creature *>(unit);
    if(unit)
    {
        nam = unit->GetName();
        namlen = (nam ? strlen(nam) : 0) + 1;
    }

    EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
    if (!em)
        return;

    GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);

    uint32 emote_anim = em->textid;

    WorldPacket data;

    switch(emote_anim)
    {
        case EMOTE_STATE_SLEEP:
        case EMOTE_STATE_SIT:
        case EMOTE_STATE_KNEEL:
        case EMOTE_ONESHOT_NONE:
            break;
        default:
            GetPlayer()->HandleEmoteCommand(emote_anim);
            break;
    }

    data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
    data << GetPlayer()->GetGUID();
    data << (uint32)text_emote;
    data << emoteNum;
    data << (uint32)namlen;
    if( namlen > 1 )
        data.append(nam, namlen);
    else
        data << (uint8)0x00;

    GetPlayer()->SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true);

    //Send scripted event call
    if (pCreature && Script)
        Script->ReceiveEmote(GetPlayer(),pCreature,text_emote);
}
Example #8
0
//----------------------------------------------------------------------------
//
// Name       : UnseenCell::UnseenCell
//
// Description: Constructor
//
// Parameters : point			: The point (RC coordinate)
//
// Globals    : g_theWorld		: World information
//
// Returns    : -
//
// Remark(s)  : The constructor to use normally.
//
//----------------------------------------------------------------------------
UnseenCell::UnseenCell(const MapPoint & point)
:
	m_env                           (0),
	m_terrain_type                  (TERRAIN_UNKNOWN),
	m_move_cost                     (MOVECOST_UNKNOWN),
	m_flags                         (0x0000),
	m_bioInfectedOwner              (0x00), /// @todo Check PLAYER_UNASSIGNED?
	m_nanoInfectedOwner             (0x00),
	m_convertedOwner                (0x00),
	m_franchiseOwner                (0x00),
	m_injoinedOwner                 (0x00),
	m_happinessAttackOwner          (0x00),
	m_citySize                      (0),
	m_cityOwner                     (0),
	m_citySpriteIndex               (-1),
	m_cell_owner                    (PLAYER_UNASSIGNED),
	m_slaveBits                     (0x0000),
#ifdef BATTLE_FLAGS
	m_battleFlags                   (0),
#endif
	m_tileInfo                      (NULL),
	m_point                         (point),
	m_installations                 (new PointerList<UnseenInstallationInfo>),
	m_improvements                  (new PointerList<UnseenImprovementInfo>),
	m_cityName                      (NULL),
	m_actor                         (NULL),
	m_poolIndex                     (-1),
	m_visibleCityOwner              (0)
{
	if (g_theWorld->GetTileInfo(point))
	{
		m_tileInfo = new TileInfo(g_theWorld->GetTileInfo(point));
	}

	Cell * cell = g_theWorld->GetCell(point);
	if (cell)
	{
		m_env = cell->GetEnv();
		m_move_cost = sint16(cell->GetMoveCost());
		m_terrain_type = (sint8)TERRAIN_TYPES(cell->GetTerrain());
#ifdef BATTLE_FLAGS
		m_battleFlags = cell->GetBattleFlags();
#endif

		sint32 i;

		// Same as well information about existing
		// tile improvments, except roadlike ones,
		// so that this information is available
		// later as well.
		// And in order not to break anythink use the existing
		// list for unfinished tile improvements.
		for(i = 0; i < cell->GetNumDBImprovements(); i++) {
			sint32 imp = cell->GetDBImprovement(i);
			m_improvements->AddTail(new UnseenImprovementInfo(imp, 100));
		}
		for(i = 0; i < cell->GetNumImprovements(); i++) {
			TerrainImprovement imp = cell->AccessImprovement(i);
			if (imp.IsValid())
			{
				m_improvements->AddTail(new UnseenImprovementInfo(imp.GetType(),
															      imp.PercentComplete()));
			}
		}

		DynamicArray<Installation> instArray;
		g_theInstallationTree->GetAt(point, instArray);
		for(i = 0; i < instArray.Num(); i++) {
			m_installations->AddTail(new UnseenInstallationInfo(instArray[i].GetType(),
														       instArray[i].GetVisibility()));
		}

		m_cell_owner = (sint8) cell->GetOwner();

		// Store the city that controlls this tile.
		m_visibleCityOwner = cell->GetCityOwner().m_id;

		Unit    city = cell->GetCity();

		if (city.IsValid())
		{
			m_citySize = (sint16)city.PopCount();
			m_citySpriteIndex = (sint16)city.CD()->GetDesiredSpriteIndex();
			const MBCHAR *name = city.GetName();
			m_cityName = new MBCHAR[strlen(name) + 1];
			strcpy(m_cityName, name);

			m_cityOwner = static_cast<sint16>(city.GetCityData()->GetOwner());

			CityData *cityData = city.GetData()->GetCityData();

			UnitActor *actor = city.GetActor();

			if (actor) {

				SpriteState *newSS = new SpriteState(city.GetSpriteState()->GetIndex());

				UnitActor *newActor = new UnitActor(newSS,
												    city,
												    city.GetType(),
												    point,
												    city.GetOwner(),
												    TRUE,
												    city.GetVisionRange(),
												    city.CD()->GetDesiredSpriteIndex());

				newActor->SetUnitVisibility((1 << g_selected_item->GetVisiblePlayer())
										    | actor->GetUnitVisibility());
				newActor->SetPos(point);

				newActor->SetIsFortified(actor->IsFortified());
				newActor->SetIsFortifying(actor->IsFortifying());
				newActor->SetHasCityWalls(actor->HasCityWalls());
				newActor->SetHasForceField(actor->HasForceField());

				newActor->SetSize(m_citySize);

				newActor->ChangeImage(newSS, city.GetType(), city);

				newActor->AddIdle();
				newActor->GetNextAction();

				m_actor = newActor;
			} // actor

			SetIsBioInfected(cityData->IsBioInfected());
			SetIsNanoInfected(cityData->IsNanoInfected());
			SetIsConverted(cityData->IsConverted());
			SetIsFranchised(cityData->IsFranchised());
			SetIsInjoined(cityData->IsInjoined());
			SetWasHappinessAttacked(cityData->WasHappinessAttacked());
			SetIsRioting(cityData->GetIsRioting());
			SetHasAirport(cityData->HasAirport());
			SetHasSleepingUnits(cityData->HasSleepingUnits());
			SetIsWatchful(cityData->IsWatchful());
			SetIsCapitol(cityData->IsCapitol()); //emod
			SetIsReligionIcon(cityData->HasReligionIcon()); //emod
			m_bioInfectedOwner = (sint8)cityData->GetBioInfectedBy();
			m_nanoInfectedOwner = (sint8)cityData->GetNanoInfectedBy();
			m_convertedOwner = (sint8)cityData->IsConvertedTo();
			m_franchiseOwner = (sint8)cityData->GetFranchiseOwner();
			m_injoinedOwner = (sint8)cityData->InjoinedBy();
			m_happinessAttackOwner = (sint8)cityData->GetHappinessAttackedBy();
			m_slaveBits = cityData->GetSlaveBits();
			SetIsSpecialIcon(cityData->HasSpecialIcon()); //emod

		    sint32 pollution = cityData->GetPollution();
			SetIsPollutionRisk(pollution > g_theConstDB->Get(0)->GetLocalPollutionLevel());

		} // city.IsValid
	} // cell

	SetHasHut(NULL != g_theWorld->GetGoodyHut(point));
}