Exemplo n.º 1
0
void LiveSocket::receiveNode(NetworkMessage& message, Editor& editor, Action* action, int32_t ndx, int32_t ndy, bool underground)
{
	QTreeNode* node = editor.map.getLeaf(ndx * 4, ndy * 4);
	if(!node) {
		log->Message(wxT("Warning: Received update for unknown tile (") + std::to_string(ndx * 4) + wxT("/") + std::to_string(ndy * 4) + wxT("/") + (underground ? "true" : "false") + wxT(")"));
		return;
	}

	node->setRequested(underground, false);
	node->setVisible(underground, true);

	uint16_t floorBits = message.read<uint16_t>();
	if(floorBits == 0) {
		return;
	}

	for(uint_fast8_t z = 0; z < 16; ++z) {
		if(testFlags(floorBits, 1 << z)) {
			receiveFloor(message, editor, action, ndx, ndy, z, node, node->getFloor(z));
		}
	}
}
Exemplo n.º 2
0
void LiveServer::BroadcastNodes(DirtyList& dirty_list)
{
	if(dirty_list.Empty())
		return;

	DirtyList::SetType ds = dirty_list.GetPosList();
	for(DirtyList::SetType::const_iterator iter = ds.begin(); iter != ds.end(); ++iter)
	{
		const DirtyList::ValueType& ind = *iter;

		int ndx = ind.pos >> 18;
		int ndy = (ind.pos >> 4) & 0x3FFF;
		uint32_t floors = ind.floors;

		QTreeNode* node = editor->map.getLeaf(ndx*4, ndy*4);
		if(!node)
			continue;

		for(PeerList::iterator citer = connected_clients.begin(); citer != connected_clients.end(); ++citer)
		{
			if(dirty_list.owner != 0 && dirty_list.owner == (*citer)->GetClientID())
			{
				continue;
			}

			bool seen_ug = node->isVisible((*citer)->GetClientID(), true);
			bool seen_og = node->isVisible((*citer)->GetClientID(), false);
			if(seen_ug)
			{
				SendNode(*citer, node, ndx, ndy, floors & 0xff00);
			}
			if(seen_og)
			{
				SendNode(*citer, node, ndx, ndy, floors & 0x00ff);
			}
		}
	}
}
Exemplo n.º 3
0
void Action::undo(DirtyList* dirty_list)
{
	if(changes.empty())
		return;

	editor.selection.start(Selection::INTERNAL);
	ChangeList::reverse_iterator it = changes.rbegin();

	while(it != changes.rend())
	{
		Change* c = *it;
		switch(c->type)
		{
			case CHANGE_TILE:
			{
				void** data = &c->data;
				Tile* oldtile = reinterpret_cast<Tile*>(*data);
				ASSERT(oldtile);
				Position pos = oldtile->getPosition();
				
				if(editor.IsLiveClient())
				{
					QTreeNode* nd = editor.map.getLeaf(pos.x, pos.y);
					if(!nd || !nd->isVisible(pos.z > 7))
					{
						// Delete all changes that affect tiles outside our view
						c->clear();
						++it;
						continue;
					}
				}

				Tile* newtile = editor.map.swapTile(pos, oldtile);

				// Update server side change list (for broadcast)
				if(editor.IsLiveServer() && dirty_list)
					dirty_list->AddPosition(pos.x, pos.y, pos.z);


				if(oldtile->isSelected())
					editor.selection.addInternal(oldtile);
				if(newtile->isSelected())
					editor.selection.removeInternal(newtile);

				if(newtile->getHouseID() != oldtile->getHouseID())
				{
					// oooooomggzzz we need to remove it from the appropriate house!
					House* house = editor.map.houses.getHouse(newtile->getHouseID());
					if(house)
					{
						house->removeTile(newtile);
					}
					else
					{
						// Set tile house to 0, house has been removed
						newtile->setHouse(nullptr);
					}

					house = editor.map.houses.getHouse(oldtile->getHouseID());
					if(house)
					{
						house->addTile(oldtile);
					}
				}
				if(oldtile->spawn)
				{
					if(newtile->spawn)
					{
						if(*oldtile->spawn != *newtile->spawn)
						{
							editor.map.removeSpawn(newtile);
							editor.map.addSpawn(oldtile);
						}
					}
					else
					{
						editor.map.addSpawn(oldtile);
					}
				}
				else if(newtile->spawn)
				{
					editor.map.removeSpawn(newtile);
				}
				*data = newtile;
				
				
				// Update client dirty list
				if(editor.IsLiveClient() && dirty_list && type != ACTION_REMOTE)
				{
					// Local action, assemble changes
					dirty_list->AddChange(c);
				}
			} break;
			case CHANGE_MOVE_HOUSE_EXIT:
			{
				std::pair<uint32_t, Position>* p = reinterpret_cast<std::pair<uint32_t, Position>* >(c->data);
				ASSERT(p);
				House* whathouse = editor.map.houses.getHouse(p->first);
				if(whathouse)
				{
					Position oldpos = whathouse->getExit();
					whathouse->setExit(p->second);
					p->second = oldpos;
				}
			} break;
			case CHANGE_MOVE_WAYPOINT:
			{
				std::pair<std::string, Position>* p = reinterpret_cast<std::pair<std::string, Position>* >(c->data);
				ASSERT(p);
				Waypoint* wp = editor.map.waypoints.getWaypoint(p->first);

				if(wp)
				{
					// Change the tiles
					TileLocation* oldtile = editor.map.getTileL(wp->pos);
					TileLocation* newtile = editor.map.getTileL(p->second);
					
					// Only need to remove from old if it actually exists
					if(p->second != Position())
						if(oldtile && oldtile->getWaypointCount() > 0)
							oldtile->decreaseWaypointCount();

					newtile->increaseWaypointCount();

					// Update shit
					Position oldpos = wp->pos;
					wp->pos = p->second;
					p->second = oldpos;
				}
			} break;
			default:
			break;
		}
		++it;
	}
	editor.selection.finish(Selection::INTERNAL);
	commited = false;
}
Exemplo n.º 4
0
void Action::commit(DirtyList* dirty_list)
{
	editor.selection.start(Selection::INTERNAL);
	ChangeList::const_iterator it = changes.begin();
	while(it != changes.end())
	{
		Change* c = *it;
		switch(c->type) {
			case CHANGE_TILE:
			{
				void** data = &c->data;
				Tile* newtile = reinterpret_cast<Tile*>(*data);
				ASSERT(newtile);
				Position pos = newtile->getPosition();
				
				if(editor.IsLiveClient())
				{
					QTreeNode* nd = editor.map.getLeaf(pos.x, pos.y);
					if(!nd || !nd->isVisible(pos.z > 7))
					{
						// Delete all changes that affect tiles outside our view
						c->clear();
						++it;
						continue;
					}
				}

				Tile* oldtile = editor.map.swapTile(pos, newtile);
				TileLocation* location = newtile->getLocation();
				
				// Update other nodes in the network
				if(editor.IsLiveServer() && dirty_list)
					dirty_list->AddPosition(pos.x, pos.y, pos.z);


				newtile->update();

				//std::cout << "\tSwitched tile at " << pos.x << ";" << pos.y << ";" << pos.z << " from " << (void*)oldtile << " to " << *data <<  std::endl;
				if(newtile->isSelected())
					editor.selection.addInternal(newtile);

				if(oldtile)
				{
					if(newtile->getHouseID() != oldtile->getHouseID())
					{
						// oooooomggzzz we need to add it to the appropriate house!
						House* house = editor.map.houses.getHouse(oldtile->getHouseID());
						if(house)
							house->removeTile(oldtile);

						house = editor.map.houses.getHouse(newtile->getHouseID());
						if(house)
							house->addTile(newtile);
					}
					if(oldtile->spawn)
					{
						if(newtile->spawn)
						{
							if(*oldtile->spawn != *newtile->spawn)
							{
								editor.map.removeSpawn(oldtile);
								editor.map.addSpawn(newtile);
							}
						}
						else
						{
							// Spawn has been removed
							editor.map.removeSpawn(oldtile);
						}
					}
					else if(newtile->spawn)
					{
						editor.map.addSpawn(newtile);
					}

					//oldtile->update();
					if(oldtile->isSelected())
						editor.selection.removeInternal(oldtile);

					*data = oldtile;
				}
				else
				{
					*data = editor.map.allocator(location);
					if(newtile->getHouseID() != 0)
					{
						// oooooomggzzz we need to add it to the appropriate house!
						House* house = editor.map.houses.getHouse(newtile->getHouseID());
						if(house)
						{
							house->addTile(newtile);
						}
					}

					if(newtile->spawn)
						editor.map.addSpawn(newtile);

				}
				// Mark the tile as modified
				newtile->modify();

				// Update client dirty list
				if(editor.IsLiveClient() && dirty_list && type != ACTION_REMOTE)
				{
					// Local action, assemble changes
					dirty_list->AddChange(c);
				}
			} break;
			case CHANGE_MOVE_HOUSE_EXIT:
			{
				std::pair<uint32_t, Position>* p = reinterpret_cast<std::pair<uint32_t, Position>* >(c->data);
				ASSERT(p);
				House* whathouse = editor.map.houses.getHouse(p->first);

				if(whathouse)
				{
					Position oldpos = whathouse->getExit();
					whathouse->setExit(p->second);
					p->second = oldpos;
				}
			} break;
			case CHANGE_MOVE_WAYPOINT:
			{
				std::pair<std::string, Position>* p = reinterpret_cast<std::pair<std::string, Position>* >(c->data);
				ASSERT(p);
				Waypoint* wp = editor.map.waypoints.getWaypoint(p->first);

				if(wp) {
					// Change the tiles
					TileLocation* oldtile = editor.map.getTileL(wp->pos);
					TileLocation* newtile = editor.map.getTileL(p->second);
					
					// Only need to remove from old if it actually exists
					if(p->second != Position())
						if(oldtile && oldtile->getWaypointCount() > 0)
							oldtile->decreaseWaypointCount();

					newtile->increaseWaypointCount();

					// Update shit
					Position oldpos = wp->pos;
					wp->pos = p->second;
					p->second = oldpos;
				}
			} break;
			default:
				break;
		}
		++it;
	}
	editor.selection.finish(Selection::INTERNAL);
	commited = true;
}