Exemplo n.º 1
0
void NetCity::Unpacketize(uint16 id, uint8* buf, uint16 size)
{
	Assert(buf[0] == 'C' && buf[1] == 'D');
	Unit uid(getlong(&buf[2]));
	sint32 pos;

	if(g_theUnitPool->IsValid(uid)) {
		DPRINTF(k_DBG_NET, ("Net: received city %lx\n", (uint32)uid));
		UnitData* unitData = g_theUnitPool->AccessUnit(uid);
		uint16 unitSize;
		PLAYER_INDEX oldOwner = unitData->m_owner;

		Assert(unitData->m_city_data != NULL);
		if(unitData->m_city_data == NULL) {
			g_network.RequestResync(RESYNC_INVALID_UNIT);
			return;
		}

		NetUnit::UnpacketizeUnit(&buf[6], unitSize, unitData);

		if(oldOwner != unitData->m_owner) {
			g_player[oldOwner]->RemoveCityReferenceFromPlayer(uid, CAUSE_REMOVE_CITY_UNKNOWN, unitData->m_owner);
			g_player[unitData->m_owner]->AddCityReferenceToPlayer(uid, CAUSE_NEW_CITY_UNKNOWN);
		}
		unitData->m_city_data->m_owner = unitData->m_owner;

		pos = 6 + unitSize;
		CityData* cityData = unitData->m_city_data;

		double oldVision = cityData->GetVisionRadius();

		PULLBYTE(m_isInitialPacket);

		bool resync = false;

#define PLCHK(x) { sint32 tmp = x; PULLLONG(x); if(cityData->GetOwner() == g_network.GetPlayerIndex() && !m_isInitialPacket) { Assert(tmp == x); if(tmp != x) resync = true; }}
#define PSCHK(x) { sint16 tmp = x; PULLSHORT(x); if(cityData->GetOwner() == g_network.GetPlayerIndex() && !m_isInitialPacket) { Assert(tmp == x); if(tmp != x) resync = true; }}
#define PL32CHK(x) { uint32 tmp = x; PULLLONG(x); if(cityData->GetOwner() == g_network.GetPlayerIndex() && !m_isInitialPacket) { Assert(tmp == x); if(tmp != x) resync = true; }}
#define PL64CHK(x) { uint64 tmp = x; PULLLONG64(x); if(cityData->GetOwner() == g_network.GetPlayerIndex() && !m_isInitialPacket) { Assert(tmp == x); if(tmp != x) resync = true; }}
		PL32CHK(cityData->m_slaveBits);
		sint32 shieldstore;
		PULLLONG(shieldstore);
		if(cityData->GetOwner() != g_network.GetPlayerIndex() || m_isInitialPacket) {
			cityData->m_shieldstore = shieldstore;
		}
		PLCHK(cityData->m_shieldstore_at_begin_turn);
		PLCHK(cityData->m_net_gold);
		PLCHK(cityData->m_science);
		PLCHK(cityData->m_luxury);
		PULLLONGTYPE(cityData->m_city_attitude, CITY_ATTITUDE);

		PL64CHK(cityData->m_built_improvements);

		sint32 i;
#ifdef CTP1_TRADE
		uint8 numNonZeroResources;
		PULLBYTE(numNonZeroResources);
		cityData->m_resources.Clear();
		for(i = 0; i < numNonZeroResources; i++) {
			uint8 resource;
			uint16 count;
			PULLBYTE(resource);
			PULLSHORT(count);
			cityData->m_resources.SetResourceCount(resource, count);
		}
#endif

		PLCHK(cityData->m_population);
		for(i = 0; i < (sint32)POP_MAX; i++) {
			PSCHK(cityData->m_numSpecialists[i]);
		}

		PLCHK(cityData->m_partialPopulation);
		PLCHK(cityData->m_sizeIndex);
		PLCHK(cityData->m_workerFullUtilizationIndex);
		PLCHK(cityData->m_workerPartialUtilizationIndex);

		PULLDOUBLE(cityData->m_defensiveBonus);
		PULLBYTE(cityData->m_founder);

		UnpacketizeResources(cityData->m_collectingResources, buf, pos);
		UnpacketizeResources(cityData->m_sellingResources, buf, pos);
		UnpacketizeResources(cityData->m_buyingResources, buf, pos);

		for(sint32 r = 0; r < g_theResourceDB->NumRecords(); r++)
		{
			PULLLONG(cityData->m_distanceToGood[r]);
		}

		cityData->UpdateSprite();

		if(resync)
			g_network.RequestResync(RESYNC_CITY_STATS);
		else if (oldVision != cityData->GetVisionRadius())
		{
			unitData->RemoveOldUnitVision(oldVision);
			unitData->AddUnitVision();
		}
	}
}