示例#1
0
void HouseTile::updateHouse(Item* item)
{
    if (item->getTile() == this)
    {
        Door* door = item->getDoor();

        if (door && door->getDoorId() != 0)
        {
            house->addDoor(door);
        }

        //[ added for beds system
        if (!door)
        {
            BedItem* bed = item->getBed();

            if (bed)
            {
                // next, add it to the house
                house->addBed(bed);
            }
        }

        //]
    }
}
示例#2
0
void HouseTile::updateHouse(Item* item)
{
	if(item->getTile() != this)
		return;

	Door* door = item->getDoor();
	if(door && door->getDoorId())
		house->addDoor(door);
	else if(BedItem* bed = item->getBed())
		house->addBed(bed);
}
示例#3
0
void HouseTile::updateHouse(Item* item)
{
    if(item->getTile() == this)
    {
        Door* door = item->getDoor();
        if(door && door->getDoorId() != 0)
            house->addDoor(door);

        if(!door)
        {
            BedItem* bed = item->getBed();
            if(bed)
                house->addBed(bed);
        }
    }
}
示例#4
0
bool IOMapOTBM::loadMap(Map* map, const std::string& identifier)
{
	int64_t start = OTSYS_TIME();

	FileLoader f;
	if(!f.openFile(identifier.c_str(), false, true)){
    	std::stringstream ss;
		ss << "Could not open the file " << identifier << ".";
		setLastErrorString(ss.str());
		return false;
	}
	
	unsigned long type;
	PropStream propStream;

	NODE root = f.getChildNode((NODE)NULL, type);

	if(!f.getProps(root, propStream)){
		setLastErrorString("Could not read root property.");
		return false;
	}

	OTBM_root_header* root_header;
	if(!propStream.GET_STRUCT(root_header)){
		setLastErrorString("Could not read header.");
		return false;
	}
	
	if(root_header->version > 2){
		setLastErrorString("Unknown OTBM version detected, please update your server.");;
		return false;
	}
	
	if(root_header->majorVersionItems > (unsigned long)Items::dwMajorVersion){
		setLastErrorString("The map was saved with a different items.otb version, an upgraded items.otb is required.");
		return false;
	}

	// Prevent load maps saved with items.otb previous to
	// version 800, because of the change to stackable of 
	// itemid 3965
	if(root_header->minorVersionItems < CLIENT_VERSION_760){
		setLastErrorString("This map needs to be updated.");
		return false;
	}

	if(root_header->minorVersionItems > (unsigned long)Items::dwMinorVersion){
		std::cout << "Warning: [OTBM loader] This map needs an updated items OTB file." <<std::endl;
	}

	std::cout << "Map size: " << root_header->width << "x" << root_header->height << std::endl;
	map->mapWidth = root_header->width;
	map->mapHeight = root_header->height;

	NODE nodeMap = f.getChildNode(root, type);
	
	if(type != OTBM_MAP_DATA){
		setLastErrorString("Could not read data node.");
		return false;
	}

	if(!f.getProps(nodeMap, propStream)){
		setLastErrorString("Could not read map data attributes.");
		return false;
	}

	unsigned char attribute;
	std::string mapDescription;
	std::string tmp;
	while(propStream.GET_UCHAR(attribute)){
		switch(attribute){
		case OTBM_ATTR_DESCRIPTION:
			if(!propStream.GET_STRING(mapDescription)){
				setLastErrorString("Invalid description tag.");
				return false;
			}
			
			std::cout << "Map description: " << mapDescription << std::endl;
			break;
		case OTBM_ATTR_EXT_SPAWN_FILE:
			if(!propStream.GET_STRING(tmp)){
				setLastErrorString("Invalid spawn tag.");
				return false;
			}

			map->spawnfile = identifier.substr(0, identifier.rfind('/') + 1);
			map->spawnfile += tmp;

			break;
		case OTBM_ATTR_EXT_HOUSE_FILE:
			if(!propStream.GET_STRING(tmp)){
				setLastErrorString("Invalid house tag.");
				return false;
			}

			map->housefile = identifier.substr(0, identifier.rfind('/') + 1);
			map->housefile += tmp;
			break;

		default:
			setLastErrorString("Unknown header node.");
			return false;
			break;
		}
	}
	
	Tile* tile = NULL;

	NODE nodeMapData = f.getChildNode(nodeMap, type);
	while(nodeMapData != NO_NODE){
		if(f.getError() != ERROR_NONE){
			setLastErrorString("Invalid map node.");
			return false;
		}

		if(type == OTBM_TILE_AREA){
			if(!f.getProps(nodeMapData, propStream)){
				setLastErrorString("Invalid map node.");
				return false;
			}
			
			OTBM_Tile_area_coords* area_coord;
			if(!propStream.GET_STRUCT(area_coord)){
				setLastErrorString("Invalid map node.");
				return false;
			}
			
			int base_x, base_y, base_z;
			base_x = area_coord->_x;
			base_y = area_coord->_y;
			base_z = area_coord->_z;
			
			NODE nodeTile = f.getChildNode(nodeMapData, type);
			while(nodeTile != NO_NODE){
				if(f.getError() != ERROR_NONE){
					setLastErrorString("Could not read node data.");
					return false;
				}

				if(type == OTBM_TILE || type == OTBM_HOUSETILE){
					if(!f.getProps(nodeTile, propStream)){
						setLastErrorString("Could not read node data.");
						return false;
					}
					
					unsigned short px, py, pz;
					OTBM_Tile_coords* tile_coord;
					if(!propStream.GET_STRUCT(tile_coord)){
						setLastErrorString("Could not read tile position.");
						return false;
					}

					px = base_x + tile_coord->_x;
					py = base_y + tile_coord->_y;
					pz = base_z;
					
					bool isHouseTile = false;
					House* house = NULL;

					if(type == OTBM_TILE){
						tile = new Tile(px, py, pz);
					}
					else if(type == OTBM_HOUSETILE){
						uint32_t _houseid;
						if(!propStream.GET_ULONG(_houseid)){
							std::stringstream ss;
							ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] " << "Could not read house id.";
							setLastErrorString(ss.str());
							return false;
						}

						house = Houses::getInstance().getHouse(_houseid, true);
						if(!house){
							std::stringstream ss;
							ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] " << "Could not create house id: " << _houseid;
							setLastErrorString(ss.str());
							return false;
						}

						tile = new HouseTile(px, py, pz, house);
						house->addTile(static_cast<HouseTile*>(tile));
						isHouseTile = true;
					}

					//read tile attributes
					unsigned char attribute;
					while(propStream.GET_UCHAR(attribute)){
						switch(attribute){
						case OTBM_ATTR_TILE_FLAGS:
						{
							uint32_t flags;
							if(!propStream.GET_ULONG(flags)){
								std::stringstream ss;
								ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] " << "Failed to read tile flags.";
								setLastErrorString(ss.str());
								return false;
							}
								
							if((flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE){
								tile->setFlag(TILESTATE_PROTECTIONZONE);
                            }
                            else if((flags & TILESTATE_NOPVPZONE) == TILESTATE_NOPVPZONE){
                                tile->setFlag(TILESTATE_NOPVPZONE);
                            }
                            else if((flags & TILESTATE_PVPZONE) == TILESTATE_PVPZONE){
                                tile->setFlag(TILESTATE_PVPZONE);
                            }
                            
                            if((flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT){
                                tile->setFlag(TILESTATE_NOLOGOUT);
                            }

							if((flags & TILESTATE_REFRESH) == TILESTATE_REFRESH){
								if(house){
									std::cout << "Warning [x:" << px << ", y:" << py << ", z:" << pz << "] " << " House tile flagged as refreshing!";
								}
								tile->setFlag(TILESTATE_REFRESH);
							}
								
							break;
						}

						case OTBM_ATTR_ITEM:
						{
							Item* item = Item::CreateItem(propStream);
							if(!item){
								std::stringstream ss;
								ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] " << "Failed to create item.";
								setLastErrorString(ss.str());
								return false;
							}

							if(isHouseTile && !item->isNotMoveable()){
								std::cout << "Warning: [OTBM loader] Moveable item in house id = " << house->getHouseId() << " Item type = " << item->getID() << std::endl;
								delete item;
								item = NULL;
							}
							else{
								tile->__internalAddThing(item);
								item->__startDecaying();
							}
							
							break;
						}

						default:
							std::stringstream ss;
							ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] " << "Unknown tile attribute.";
							setLastErrorString(ss.str());
							return false;
							break;
						}
					}

					NODE nodeItem = f.getChildNode(nodeTile, type);
					while(nodeItem){
						if(type == OTBM_ITEM){

							PropStream propStream;
							f.getProps(nodeItem, propStream);
							
							Item* item = Item::CreateItem(propStream);
							if(!item){
								std::stringstream ss;
								ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] " << "Failed to create item.";
								setLastErrorString(ss.str());
								return false;
							}

							if(item->unserializeItemNode(f, nodeItem, propStream)){
								if(isHouseTile && !item->isNotMoveable()){
									std::cout << "Warning: [OTBM loader] Moveable item in house id = " << house->getHouseId() << " Item type = " << item->getID() << std::endl;
									delete item;
								}
								else{
									tile->__internalAddThing(item);
									item->__startDecaying();

									// TESTING
									if(isHouseTile){
										Door* door = item->getDoor();
										if(door && door->getDoorId() != 0){
											house->addDoor(door);
										}
									}
									//
								}
							}
							else{
                                std::stringstream ss;
								ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] " << "Failed to load item " << item->getID() << ".";
								setLastErrorString(ss.str());
								delete item;
								return false;
							}
						}
						else{
							std::stringstream ss;
							ss << "[x:" << px << ", y:" << py << ", z:" << pz << "] " << "Unknown node type.";
							setLastErrorString(ss.str());
						}

						nodeItem = f.getNextNode(nodeItem, type);
					}
					
					map->setTile(px, py, pz, tile);
				}
				else{
					setLastErrorString("Unknown tile node.");
					return false;
				}

				nodeTile = f.getNextNode(nodeTile, type);
			}
		}
		else if(type == OTBM_TOWNS){
			NODE nodeTown = f.getChildNode(nodeMapData, type);
			while(nodeTown != NO_NODE){
				if(type == OTBM_TOWN){
					if(!f.getProps(nodeTown, propStream)){
						setLastErrorString("Could not read town data.");
						return false;
					}
					
					uint32_t townid = 0;
					if(!propStream.GET_ULONG(townid)){
						setLastErrorString("Could not read town id.");
						return false;
					}

					Town* town = Towns::getInstance().getTown(townid);
					if(!town){
						town = new Town(townid);
						Towns::getInstance().addTown(townid, town);
					}

					std::string townName = "";
					if(!propStream.GET_STRING(townName)){
						setLastErrorString("Could not read town name.");
						return false;
					}

					town->setName(townName);

					OTBM_TownTemple_coords *town_coords;
					if(!propStream.GET_STRUCT(town_coords)){
						setLastErrorString("Could not read town coordinates.");
						return false;
					}

					Position pos;
					pos.x = town_coords->_x;
					pos.y = town_coords->_y;
					pos.z = town_coords->_z;
					town->setTemplePos(pos);
				}
				else{
					setLastErrorString("Unknown town node.");
					return false;
				}

				nodeTown = f.getNextNode(nodeTown, type);
			}
		}
		else if(type == OTBM_WAYPOINTS && root_header->version >= 2){
			NODE nodeWaypoint = f.getChildNode(nodeMapData, type);
			while(nodeWaypoint != NO_NODE){
				if(type == OTBM_WAYPOINT){
					if(!f.getProps(nodeWaypoint, propStream)){
						setLastErrorString("Could not read town data.");
						return false;
					}

					std::string name;
					Position pos;

					if(!propStream.GET_STRING(name)){
						setLastErrorString("Could not read waypoint name.");
						return false;
					}

					OTBM_TownTemple_coords* wp_coords;
					if(!propStream.GET_STRUCT(wp_coords)){
						setLastErrorString("Could not read waypoint coordinates.");
						return false;
					}

					pos.x = wp_coords->_x;
					pos.y = wp_coords->_y;
					pos.z = wp_coords->_z;

					Waypoint_ptr wp(new Waypoint(name, pos));
					map->waypoints.addWaypoint(wp);
				}
				else{
					setLastErrorString("Unknown waypoint node.");
					return false;
				}

				nodeWaypoint = f.getNextNode(nodeWaypoint, type);
			}
		}
		else{
			setLastErrorString("Unknown map node.");
			return false;
		}

		nodeMapData = f.getNextNode(nodeMapData, type);
	}
	
	std::cout << "Notice: [OTBM Loader] Loading time : " << (OTSYS_TIME() - start)/(1000.) << " s" << std::endl;
	return true;
}