//====================================================================================================================== // // Selects the resource for extraction // void ObjectController::_handleHarvesterSelectResource(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { CreatureObject* creature = dynamic_cast<CreatureObject*>(mObject); PlayerObject* player = creature->GetGhost(); if(!player) { return; } //do we have a valid structure ??? uint64 id = targetId; Object* object = gWorldManager->getObjectById(id); PlayerStructure* structure = dynamic_cast<PlayerStructure*>(object); if(!structure) { //gMessageLib->sendSystemMessage(player,L"","player_structure","command_no_building"); return; } //is the structure in Range??? float fTransferDistance = gWorldConfig->getConfiguration<float>("Player_Structure_Operate_Distance",(float)10.0); if(glm::distance(player->GetCreature()->mPosition, structure->mPosition) > fTransferDistance) { DLOG(info) << " ObjectController::_handleHarvesterSelectResource Structure not in Range"; return; } HarvesterObject* harvester = dynamic_cast<HarvesterObject*>(structure); //get the relevant Resource BString dataStr; message->getStringUnicode16(dataStr); uint64 resourceId; swscanf(dataStr.getUnicode16(),L"%"WidePRIu64,&resourceId); Resource* tmpResource = gResourceManager->getResourceById(resourceId); if((!tmpResource)||(!tmpResource->getCurrent())) { DLOG(info) << " ObjectController::_handleHarvesterSelectResource No valid resource!"; return; } harvester->setCurrentResource(resourceId); // update the current resource in the db mDatabase->executeSqlAsync(0,0,"UPDATE %s.harvesters SET ResourceID=%"PRIu64" WHERE id=%"PRIu64" ",mDatabase->galaxy(),resourceId,harvester->getId()); CurrentResource* cR = reinterpret_cast<CurrentResource*>(tmpResource); //resource = reinterpret_cast<CurrentResource*>(gResourceManager->getResourceByNameCRC(resourceName.getCrc())); float posX, posZ; float ratio = 0.0; posX = harvester->mPosition.x; posZ = harvester->mPosition.z; if(cR) { ratio = cR->getDistribution((int)posX + 8192,(int)posZ + 8192); if(ratio > 1.0) { ratio = 1.0; } } float ber = harvester->getSpecExtraction(); harvester->setCurrentExtractionRate(ber*ratio); // now enter the new resource in the hoppers resource list if its isnt already in there // TODO keep the list up to date by removing unnecessary resources // to this end read the list anew and delete every resource with zero amount // have a stored function do this if(!harvester->checkResourceList(resourceId)) { //do *not* add to list - otherwise we get a racecondition with the asynch update from db !!! //harvester->getResourceList()->push_back(std::make_pair(resourceId,float(0.0))); //add to db mDatabase->executeSqlAsync(0,0,"INSERT INTO %s.harvester_resources VALUES(%"PRIu64",%"PRIu64",0,0)",mDatabase->galaxy(),harvester->getId(),resourceId); } // update the current extractionrate in the db for the stored procedure handling the harvesting mDatabase->executeSqlAsync(0,0,"UPDATE %s.harvesters SET rate=%f WHERE id=%"PRIu64" ",mDatabase->galaxy(),(ber*ratio),harvester->getId()); //now send the updates gMessageLib->sendCurrentResourceUpdate(harvester,player); gMessageLib->sendCurrentExtractionRate(harvester,player); }
bool ArtisanManager::handleRequestCoreSample(Object* player,Object* target, Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(player); if(cmdProperties) // unfortunately it's not in this opcode // hardcode for now //mSampleActionCost = cmdProperties->mActionCost; mSampleActionCost = 150; if(playerObject->GetCreature()->getPerformingState() != PlayerPerformance_None || playerObject->checkIfMounted() || playerObject->GetCreature()->isDead() || playerObject->GetCreature()->states.checkState(CreatureState_Combat)) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "wrong_state"), playerObject); return false; } // can't sample while surveying if(playerObject->getSurveyState()) { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_survey"), playerObject); return false; } // don't allow sampling in buildings if(playerObject->getParentId()) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "survey_in_structure"), playerObject); return false; } uint64 localTime = Anh_Utils::Clock::getSingleton()->getLocalTime(); // don't allow more than one sample at a time if(playerObject->getSamplingState()) { playerObject->getSampleData()->mPendingSample = false; playerObject->setNextSampleTime(localTime + 18000); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "tool_recharge_time", 0, 0, 0, (int32)(playerObject->getNextSampleTime() - localTime) / 1000), playerObject); return false; } if(!playerObject->getNextSampleTime() || (int32)(playerObject->getNextSampleTime() - localTime) <= 0) { playerObject->getSampleData()->mPendingSample = false; playerObject->setNextSampleTime(localTime + 18000); } else { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "tool_recharge_time", 0, 0, 0, (int32)(playerObject->getNextSampleTime() - localTime) / 1000), playerObject); return false; } SurveyTool* tool = dynamic_cast<SurveyTool*>(target); CurrentResource* resource = NULL; BString resourceName; message->getStringUnicode16(resourceName); resourceName.convert(BSTRType_ANSI); resource = reinterpret_cast<CurrentResource*>(gResourceManager->getResourceByNameCRC(resourceName.getCrc())); if(resource == NULL || tool == NULL) { gMessageLib->SendSystemMessage(::common::OutOfBand("ui","survey_noresource"), playerObject); return false; } if((resource->getType()->getCategoryId() == 903)||(resource->getType()->getCategoryId() == 904)) { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "must_have_harvester"), playerObject); return false; } playerObject->setSamplingState(true); auto terrain = gWorldManager->getKernel()->GetServiceManager()->GetService<swganh::terrain::TerrainService>("TerrainService"); if(terrain->IsWater(gWorldManager->getZoneId(), playerObject->mPosition.x, playerObject->mPosition.z)) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "survey_swimming"), playerObject); return false; } resourceName.convert(BSTRType_Unicode16); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "start_sampling", L"", L"", resourceName.getUnicode16()), playerObject); // change posture gStateManager.setCurrentPostureState(playerObject->GetCreature(), CreaturePosture_Crouched); // play animation gWorldManager->getClientEffect(tool->getInternalAttribute<uint32>("sample_effect")); // schedule execution std::shared_ptr<SimpleEvent> start_sample_event = nullptr; start_sample_event = std::make_shared<SimpleEvent>(EventType("start_sample"), 0, 2000, std::bind(&ArtisanManager::sampleEvent,this, playerObject, resource, tool)); // notify any listeners gEventDispatcher.Notify(start_sample_event); return true; }
void ResourceManager::handleDatabaseJobComplete(void* ref,DatabaseResult* result) { RMAsyncContainer* asyncContainer = reinterpret_cast<RMAsyncContainer*>(ref); switch(asyncContainer->mQueryType) { case RMQuery_ResourceTypes: { ResourceType* resType; uint64 count = result->getRowCount(); for(uint64 i = 0; i < count; i++) { resType = new ResourceType(); result->getNextRow(mResourceTypebinding,resType); mResourceTypeMap.insert(std::make_pair(resType->mId,resType)); } // query categories mDatabase->executeSqlAsync(this,new(mDBAsyncPool.ordered_malloc()) RMAsyncContainer(RMQuery_Categories),"SELECT * FROM %s.resource_categories ORDER BY id",mDatabase->galaxy()); } break; case RMQuery_Categories: { ResourceCategory* category; uint64 count = result->getRowCount(); for(uint64 i = 0; i < count; i++) { category = new ResourceCategory(); result->getNextRow(mResourceCategorybinding,category); (getResourceCategoryById(category->mParentId))->insertCategory(category); mResourceCategoryMap.insert(std::make_pair(category->mId,category)); } mDatabase->executeSqlAsync(this,new(mDBAsyncPool.ordered_malloc()) RMAsyncContainer(RMQuery_CurrentResources), "SELECT resources.id,resources.name,resources.type_id," "resources.er,resources.cr,resources.cd,resources.dr,resources.fl,resources.hr," "resources.ma,resources.oq,resources.sr,resources.ut,resources.pe," "resources_spawn_config.noiseMapBoundsX1,resources_spawn_config.noiseMapBoundsX2," "resources_spawn_config.noiseMapBoundsY1,resources_spawn_config.noiseMapBoundsY2," "resources_spawn_config.noiseMapOctaves,resources_spawn_config.noiseMapFrequency," "resources_spawn_config.noiseMapPersistence,resources_spawn_config.noiseMapScale," "resources_spawn_config.noiseMapBias," "resources_spawn_config.unitsTotal,resources_spawn_config.unitsLeft" " FROM %s.resources" " INNER JOIN %s.resources_spawn_config ON (resources.id = resources_spawn_config.resource_id)" " WHERE" " (resources_spawn_config.planet_id = %u) AND" " (resources.active = 1)",mDatabase->galaxy(),mDatabase->galaxy(),mZoneId); } break; case RMQuery_OldResources: { Resource* resource; uint64 count = result->getRowCount(); //gLogger->log(LogManager::INFORMATION,"Loading %u Old Resources",count); for(uint64 i = 0; i < count; i++) { resource = new Resource(); result->getNextRow(mResourceBinding,resource); if(getResourceById(resource->mId) == NULL) { resource->mType = getResourceTypeById(resource->mTypeId); resource->mCurrent = 0; mResourceIdMap.insert(std::make_pair(resource->mId,resource)); mResourceCRCNameMap.insert(std::make_pair(resource->mName.getCrc(),resource)); (getResourceCategoryById(resource->mType->mCatId))->insertResource(resource); } else delete(resource); } if (count) { LOG(INFO) << "Loaded " << count << " resources"; } } break; case RMQuery_CurrentResources: { CurrentResource* resource; uint64 count = result->getRowCount(); for(uint64 i = 0; i < count; i++) { resource = new CurrentResource(mWriteResourceMaps, mZoneName); result->getNextRow(mCurrentResourceBinding,resource); resource->mType = getResourceTypeById(resource->mTypeId); resource->mCurrent = 1; resource->buildDistributionMap(); mResourceIdMap.insert(std::make_pair(resource->mId,resource)); mResourceCRCNameMap.insert(std::make_pair(resource->mName.getCrc(),resource)); (getResourceCategoryById(resource->mType->mCatId))->insertResource(resource); } if (count) { LOG(INFO) << "Generated " << count << " resource maps"; } // query old and current resources not from this planet mDatabase->executeSqlAsync(this,new(mDBAsyncPool.ordered_malloc()) RMAsyncContainer(RMQuery_OldResources), "SELECT * FROM %s.resources " " INNER JOIN %s.resources_spawn_config ON (resources.id = resources_spawn_config.resource_id)" " WHERE (NOT (" " (resources_spawn_config.planet_id = %u) AND" " (resources.active = 1)))",mDatabase->galaxy(),mDatabase->galaxy(),mZoneId); // dont load the active resources of this zone again!!! } break; case RMQuery_DepleteResources: { // do we have a return? // if the return is 0 we need to do nothing else // if it is 1, we need to execute sql async to set the active resource to 0 // this means the resource is depleted. (can we do this via a stored proc?) uint32 returnId = 0; DataBinding* binding = mDatabase->createDataBinding(1); binding->addField(DFT_uint32,0,4); result->getNextRow(binding,&returnId); mDatabase->destroyDataBinding(binding); if (returnId == 1) { // remove from map Resource* resource = asyncContainer->mCurrentResource; mResourceCRCNameMap.erase(resource->mName.getCrc()); mResourceIdMap.erase(resource->getId()); (getResourceCategoryById(resource->mType->mCatId))->removeResource(resource); } } default: break; } mDBAsyncPool.ordered_free(asyncContainer); }
bool ArtisanManager::handleRequestCoreSample(Object* player,Object* target, Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(player); if(cmdProperties) // unfortunately it's not in this opcode // hardcode for now //mSampleActionCost = cmdProperties->mActionCost; mSampleActionCost = 150; if(playerObject->getPerformingState() != PlayerPerformance_None || playerObject->checkIfMounted() || playerObject->isDead()) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "wrong_state"), playerObject); return false; } // can't sample while surveying if(playerObject->getSurveyState()) { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_survey"), playerObject); return false; } // don't allow sampling in buildings if(playerObject->getParentId()) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "survey_in_structure"), playerObject); return false; } uint64 localTime = Anh_Utils::Clock::getSingleton()->getLocalTime(); // don't allow more than one sample at a time if(playerObject->getSamplingState()) { playerObject->getSampleData()->mPendingSample = false; playerObject->setNextSampleTime(localTime + 18000); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "tool_recharge_time", 0, 0, 0, (int32)(playerObject->getNextSampleTime() - localTime) / 1000), playerObject); return false; } if(!playerObject->getNextSampleTime() || (int32)(playerObject->getNextSampleTime() - localTime) <= 0) { playerObject->getSampleData()->mPendingSample = false; playerObject->setNextSampleTime(localTime + 18000); } else { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "tool_recharge_time", 0, 0, 0, (int32)(playerObject->getNextSampleTime() - localTime) / 1000), playerObject); return false; } SurveyTool* tool = dynamic_cast<SurveyTool*>(target); CurrentResource* resource = NULL; BString resourceName; message->getStringUnicode16(resourceName); resourceName.convert(BSTRType_ANSI); resource = reinterpret_cast<CurrentResource*>(gResourceManager->getResourceByNameCRC(resourceName.getCrc())); if(resource == NULL || tool == NULL) { gMessageLib->SendSystemMessage(::common::OutOfBand("ui","survey_noresource"), playerObject); return false; } if((resource->getType()->getCategoryId() == 903)||(resource->getType()->getCategoryId() == 904)) { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "must_have_harvester"), playerObject); return false; } playerObject->setSamplingState(true); ArtisanHeightmapAsyncContainer* container = new ArtisanHeightmapAsyncContainer(this, HeightmapCallback_ArtisanSurvey); container->addToBatch(playerObject->mPosition.x,playerObject->mPosition.z); container->playerObject = playerObject; container->resource = resource; container->resourceName = resourceName; container->tool = tool; gHeightmap->addNewHeightMapJob(container); return true; }