bool StructureManager::isInStructureFootprint(StructureObject* structure, float positionX, float positionY, int extraFootprintMargin){ if(structure == NULL) return false; if(structure->getObjectTemplate() == NULL) return false; Reference<SharedStructureObjectTemplate*> serverTemplate = dynamic_cast<SharedStructureObjectTemplate*>(structure->getObjectTemplate()); float placingFootprintLength0, placingFootprintWidth0, placingFootprintLength1, placingFootprintWidth1; if (getStructureFootprint(serverTemplate, structure->getDirectionAngle(), placingFootprintLength0, placingFootprintWidth0, placingFootprintLength1, placingFootprintWidth1) != 0) return false; float x0 = structure->getPositionX() + placingFootprintWidth0 + (placingFootprintWidth0 >= 0 ? extraFootprintMargin : (extraFootprintMargin * -1)); float y0 = structure->getPositionY() + placingFootprintLength0 + (placingFootprintLength0 >= 0 ? extraFootprintMargin : (extraFootprintMargin * -1)); float x1 = structure->getPositionX() + placingFootprintWidth1 + (placingFootprintWidth1 >= 0 ? extraFootprintMargin : (extraFootprintMargin * -1)); float y1 = structure->getPositionY() + placingFootprintLength1 + (placingFootprintLength1 >= 0 ? extraFootprintMargin : (extraFootprintMargin * -1)); BoundaryRectangle structureFootprint(x0, y0, x1, y1); return structureFootprint.containsPoint(positionX, positionY); }
StructureObject* StructureManager::placeStructure(CreatureObject* creature, const String& structureTemplatePath, float x, float y, int angle, int persistenceLevel) { ManagedReference<Zone*> zone = creature->getZone(); if (zone == NULL) return NULL; TerrainManager* terrainManager = zone->getPlanetManager()->getTerrainManager(); SharedStructureObjectTemplate* serverTemplate = dynamic_cast<SharedStructureObjectTemplate*>(templateManager->getTemplate( structureTemplatePath.hashCode())); if (serverTemplate == NULL) { info("server template is null"); return NULL; } float z = zone->getHeight(x, y); float floraRadius = serverTemplate->getClearFloraRadius(); bool snapToTerrain = serverTemplate->getSnapToTerrain(); Reference<StructureFootprint*> structureFootprint = serverTemplate->getStructureFootprint(); float w0 = -5; //Along the x axis. float l0 = -5; //Along the y axis. float l1 = 5; float w1 = 5; float zIncreaseWhenNoAvailableFootprint = 0.f; //TODO: remove this when it has been verified that all buildings have astructure footprint. if (structureFootprint != NULL) { //If the angle is odd, then swap them. getStructureFootprint(serverTemplate, angle, l0, w0, l1, w1); } else { if (!serverTemplate->isCampStructureTemplate()) warning( "Structure with template '" + structureTemplatePath + "' has no structure footprint."); zIncreaseWhenNoAvailableFootprint = 5.f; } if (floraRadius > 0 && !snapToTerrain) z = terrainManager->getHighestHeight(x + w0, y + l0, x + w1, y + l1, 1) + zIncreaseWhenNoAvailableFootprint; String strDatabase = "playerstructures"; bool bIsFactionBuilding = (serverTemplate->getGameObjectType() == SceneObjectType::FACTIONBUILDING); if (bIsFactionBuilding || serverTemplate->getGameObjectType() == SceneObjectType::TURRET) { strDatabase = "playerstructures"; } ManagedReference<SceneObject*> obj = ObjectManager::instance()->createObject( structureTemplatePath.hashCode(), persistenceLevel, strDatabase); if (obj == NULL || !obj->isStructureObject()) { if (obj != NULL) obj->destroyObjectFromDatabase(true); error( "Failed to create structure with template: " + structureTemplatePath); return NULL; } StructureObject* structureObject = cast<StructureObject*>(obj.get()); structureObject->setOwnerObjectID(creature->getObjectID()); structureObject->grantPermission("ADMIN", creature->getFirstName()); structureObject->setOwnerName(creature->getFirstName()); if(structureObject->isTurret() || structureObject->isMinefield()){ structureObject->setFaction(creature->getFaction()); } BuildingObject* buildingObject = NULL; if (structureObject->isBuildingObject()) { buildingObject = cast<BuildingObject*>(structureObject); if (buildingObject != NULL) buildingObject->createCellObjects(); } structureObject->setPublicStructure(serverTemplate->isPublicStructure()); structureObject->initializePosition(x, z, y); structureObject->rotate(angle); //structureObject->insertToZone(zone); zone->transferObject(structureObject, -1, true); structureObject->createChildObjects(); structureObject->notifyStructurePlaced(creature); return structureObject; }
int StructureManager::placeStructureFromDeed(CreatureObject* creature, StructureDeed* deed, float x, float y, int angle) { ManagedReference<Zone*> zone = creature->getZone(); //Already placing a structure? if (zone == NULL || creature->containsActiveSession( SessionFacadeType::PLACESTRUCTURE)) return 1; ManagedReference<PlanetManager*> planetManager = zone->getPlanetManager(); String serverTemplatePath = deed->getGeneratedObjectTemplate(); if (deed->getFaction() != 0 && creature->getFaction() != deed->getFaction()) { creature->sendSystemMessage("You are not the correct faction"); return 1; } Reference<SharedStructureObjectTemplate*> serverTemplate = dynamic_cast<SharedStructureObjectTemplate*>(templateManager->getTemplate( serverTemplatePath.hashCode())); //Check to see if this zone allows this structure. if (serverTemplate == NULL || !serverTemplate->isAllowedZone(zone->getZoneName())) { creature->sendSystemMessage("@player_structure:wrong_planet"); //That deed cannot be used on this planet. return 1; } if (!planetManager->isBuildingPermittedAt(x, y, creature)) { creature->sendSystemMessage("@player_structure:not_permitted"); //Building is not permitted here. return 1; } SortedVector<ManagedReference<ActiveArea*> > objects; zone->getInRangeActiveAreas(x, y, &objects, true); ManagedReference<CityRegion*> city; for (int i = 0; i < objects.size(); ++i) { ActiveArea* area = objects.get(i).get(); if (!area->isRegion()) continue; city = dynamic_cast<Region*>(area)->getCityRegion(); if (city != NULL) break; } SortedVector<ManagedReference<QuadTreeEntry*> > inRangeObjects; zone->getInRangeObjects(x, y, 128, &inRangeObjects, true); float placingFootprintLength0, placingFootprintWidth0, placingFootprintLength1, placingFootprintWidth1; if (!getStructureFootprint(serverTemplate, angle, placingFootprintLength0, placingFootprintWidth0, placingFootprintLength1, placingFootprintWidth1)) { float x0 = x + placingFootprintWidth0; float y0 = y + placingFootprintLength0; float x1 = x + placingFootprintWidth1; float y1 = y + placingFootprintLength1; BoundaryRectangle placingFootprint(x0, y0, x1, y1); //info("placing center x:" + String::valueOf(x) + " y:" + String::valueOf(y), true); //info("placingFootprint x0:" + String::valueOf(x0) + " y0:" + String::valueOf(y0) + " x1:" + String::valueOf(x1) + " y1:" + String::valueOf(y1), true); for (int i = 0; i < inRangeObjects.size(); ++i) { SceneObject* scene = inRangeObjects.get(i).castTo<SceneObject*>(); if (scene == NULL) continue; float l0 = -5; //Along the x axis. float w0 = -5; //Along the y axis. float l1 = 5; float w1 = 5; if (getStructureFootprint(scene->getObjectTemplate(), scene->getDirectionAngle(), l0, w0, l1, w1)) continue; float xx0 = scene->getPositionX() + (w0 + 0.1); float yy0 = scene->getPositionY() + (l0 + 0.1); float xx1 = scene->getPositionX() + (w1 - 0.1); float yy1 = scene->getPositionY() + (l1 - 0.1); BoundaryRectangle rect(xx0, yy0, xx1, yy1); //info("existing footprint xx0:" + String::valueOf(xx0) + " yy0:" + String::valueOf(yy0) + " xx1:" + String::valueOf(xx1) + " yy1:" + String::valueOf(yy1), true); // check 4 points of the current rect if (rect.containsPoint(x0, y0) || rect.containsPoint(x0, y1) || rect.containsPoint(x1, y0) || rect.containsPoint(x1, y1) ) { //info("existing footprint contains placing point", true); creature->sendSystemMessage("@player_structure:no_room"); //there is no room to place the structure here.. return 1; } if (placingFootprint.containsPoint(xx0, yy0) || placingFootprint.containsPoint(xx0, yy1) || placingFootprint.containsPoint(xx1, yy0) || placingFootprint.containsPoint(xx1, yy1) || (xx0 == x0 && yy0 == y0 && xx1 == x1 && yy1 == y1)) { //info("placing footprint contains existing point", true); creature->sendSystemMessage("@player_structure:no_room"); //there is no room to place the structure here. return 1; } } } int rankRequired = serverTemplate->getCityRankRequired(); if (city == NULL && rankRequired > 0) { creature->sendSystemMessage("@city/city:build_no_city"); return 1; } if (city != NULL) { if (city->isZoningEnabled() && !city->hasZoningRights(creature->getObjectID())) { creature->sendSystemMessage("@player_structure:no_rights"); //You don't have the right to place that structure in this city. The mayor or one of the city milita must grant you zoning rights first. return 1; } if (rankRequired != 0 && city->getCityRank() < rankRequired) { StringIdChatParameter param("city/city", "rank_req"); param.setDI(rankRequired); param.setTO("city/city", "rank" + String::valueOf(rankRequired)); creature->sendSystemMessage(param); return 1; } if (serverTemplate->isCivicStructure() && !city->isMayor(creature->getObjectID()) ) { creature->sendSystemMessage("@player_structure:cant_place_civic");//"This structure must be placed within the borders of the city in which you are mayor." return 1; } if (serverTemplate->isUniqueStructure() && city->hasUniqueStructure( serverTemplate->getServerObjectCRC())) { creature->sendSystemMessage("@player_structure:cant_place_unique"); //This city can only support a single structure of this type. return 1; } } Locker _lock(deed, creature); if(serverTemplate->isDerivedFrom("object/building/faction_perk/base/shared_factional_building_base.iff")){ Zone* zone = creature->getZone(); if(zone == NULL) return 1; GCWManager* gcwMan = zone->getGCWManager(); if(gcwMan == NULL) return 1; if(!gcwMan->canPlaceMoreBases(creature)) return 1; } //Ensure that it is the correct deed, and that it is in a container in the creature's inventory. if (deed == NULL || !deed->isASubChildOf(creature)) { creature->sendSystemMessage("@player_structure:no_possession"); //You no longer are in possession of the deed for this structure. Aborting construction. return 1; } TemplateManager* templateManager = TemplateManager::instance(); ManagedReference<PlayerObject*> ghost = creature->getPlayerObject(); if (ghost != NULL) { String abilityRequired = serverTemplate->getAbilityRequired(); if (!abilityRequired.isEmpty() && !ghost->hasAbility(abilityRequired)) { creature->sendSystemMessage("@player_structure:" + abilityRequired); return 1; } int lots = serverTemplate->getLotSize(); if (!ghost->hasLotsRemaining(lots)) { StringIdChatParameter param("@player_structure:not_enough_lots"); param.setDI(lots); creature->sendSystemMessage(param); return 1; } } //Validate that the structure can be placed at the given coordinates: //Ensure that no other objects impede on this structures footprint, or overlap any city regions or no build areas. //Make sure that the player has zoning rights in the area. ManagedReference<PlaceStructureSession*> session = new PlaceStructureSession(creature, deed); creature->addActiveSession(SessionFacadeType::PLACESTRUCTURE, session); //Construct the structure. session->constructStructure(x, y, angle); //Remove the deed from it's container. deed->destroyObjectFromWorld(true); return 0; }