void ObjectController::sendAdminFeedback(BString reply) const { PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); if ((player) && (player->isConnected())) { if (reply.getLength()) { gLogger->log(LogManager::NOTICE,"Admin (%s): %s", player->getFirstName().getAnsi(), reply.getAnsi()); reply.convert(BSTRType_Unicode16); gMessageLib->SendSystemMessage(reply.getUnicode16(), player, true); } else { gLogger->log(LogManager::NOTICE,"Admin (%s):", player->getFirstName().getAnsi()); } } else { if (reply.getDataLength()) { gLogger->log(LogManager::NOTICE,"Admin (anon): %s", reply.getAnsi()); } else { gLogger->log(LogManager::NOTICE,"Admin (anon):"); } } }
void MessageFactory::addString(const BString& data) { // Make sure we've called StartMessage() assert(mCurrentMessage && "Must call StartMessage before adding data"); // Adjust start bounds if necessary. _adjustHeapStartBounds(data.getDataLength()); // Insert our data and move our end pointer. switch(data.getType()) { case BSTRType_UTF8: case BSTRType_ANSI: { // First insert the string length *((uint16*)mCurrentMessageEnd) = data.getLength(); mCurrentMessageEnd += 2; memcpy(mCurrentMessageEnd, data.getAnsi(), data.getLength()); mCurrentMessageEnd += data.getLength(); } break; case BSTRType_Unicode16: { // First insert the string length *((uint32*)mCurrentMessageEnd) = data.getLength(); mCurrentMessageEnd += 4; memcpy(mCurrentMessageEnd, data.getUnicode16(), data.getLength() * 2); mCurrentMessageEnd += data.getLength() * 2; } break; } }
BString ObjectController::handleBroadcast(BString message) const { int8 rawData[128]; int8* replyStr = "OK"; if (message.getLength()) { // Any valid message? int32 elementCount = sscanf(message.getAnsi(), "%80s", rawData); if (elementCount > 0) { message.convert(BSTRType_Unicode16); PlayerAccMap::const_iterator it = gWorldManager->getPlayerAccMap()->begin(); while(it != gWorldManager->getPlayerAccMap()->end()) { const PlayerObject* const player = (*it).second; if (player->isConnected()) { gMessageLib->SendSystemMessage(message.getUnicode16(), player); } ++it; } } else { replyStr = "No broadcast supplied"; } } else { replyStr = "No broadcast supplied"; } return replyStr; }
void AdminManager::cancelAdminRequest(uint64 requestType, BString message) { // We will only handle one request at the time for each type. gWorldManager->cancelAdminRequest(static_cast<uint8>(requestType)); // Even though map's fix duplicate issues, the lower level implementation may change. AdminRequests::iterator adminRequestIterator = mAdminRequests.find(requestType); if (adminRequestIterator != mAdminRequests.end()) { delete ((*adminRequestIterator).second); mAdminRequests.erase(adminRequestIterator); message.convert(BSTRType_Unicode16); PlayerAccMap::const_iterator it = gWorldManager->getPlayerAccMap()->begin(); while (it != gWorldManager->getPlayerAccMap()->end()) { const PlayerObject* const player = (*it).second; if (player->isConnected()) { gMessageLib->SendSystemMessage(L"", player); if (message.getLength()) { gMessageLib->SendSystemMessage(message.getUnicode16(), player); } } ++it; } } mPendingShutdown = false; }
void ObjectController::sendAdminFeedback(BString reply) const { PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); if ((player) && (player->isConnected())) { if (reply.getLength()) { reply.convert(BSTRType_Unicode16); gMessageLib->SendSystemMessage(reply.getUnicode16(), player, true); } else { DLOG(info) << "Admin :" << player->getFirstName().getAnsi(); } } else { if (reply.getDataLength()) { DLOG(info) << "Admin (anon): " << reply.getAnsi(); } else { } } }
void ObjectController::_handleNPCConversationSelect(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); BString dataStr; uint32 selectId = 0; message->getStringUnicode16(dataStr); if(swscanf(dataStr.getUnicode16(),L"%u",&selectId) != 1) { DLOG(info) << "ObjController::handleNPCConversationSelect: Error in parameters"; return; } gConversationManager->updateConversation(selectId,playerObject); }
void Instrument::sendAttributes(PlayerObject* playerObject) { if(!(playerObject->isConnected())) return; Message* newMessage; gMessageFactory->StartMessage(); gMessageFactory->addUint32(opAttributeListMessage); gMessageFactory->addUint64(mId); gMessageFactory->addUint32(1 + mAttributeMap.size()); BString tmpValueStr = BString(BSTRType_Unicode16,64); BString value; tmpValueStr.setLength(swprintf(tmpValueStr.getUnicode16(),50,L"%u/%u",mMaxCondition - mDamage,mMaxCondition)); gMessageFactory->addString(BString("condition")); gMessageFactory->addString(tmpValueStr); AttributeMap::iterator mapIt; AttributeOrderList::iterator orderIt = mAttributeOrderList.begin(); while(orderIt != mAttributeOrderList.end()) { mapIt = mAttributeMap.find(*orderIt); gMessageFactory->addString(gWorldManager->getAttributeKey((*mapIt).first)); value = (*mapIt).second.c_str(); value.convert(BSTRType_Unicode16); gMessageFactory->addString(value); ++orderIt; } //gMessageFactory->addUint32(0xffffffff); newMessage = gMessageFactory->EndMessage(); (playerObject->getClient())->SendChannelAUnreliable(newMessage, playerObject->getAccountId(), CR_Client, 9); }
bool CraftingManager::HandleSelectDraftSchematic(Object* object,Object* target,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(object); CraftingSession* session = playerObject->getCraftingSession(); //DraftSchematic* schematic = NULL; BString dataStr; uint32 schematicIndex = 0; message->getStringUnicode16(dataStr); if(session) { if(swscanf(dataStr.getUnicode16(),L"%u",&schematicIndex) != 1 || !session->selectDraftSchematic(schematicIndex)) { gCraftingSessionFactory->destroySession(session); } } return true; }
void GroupObject::createChannel() { int8 channelName[64]; Channel* channel = new Channel(); channel->setId(((uint32)(mId)) + 0xf0000000); channel->setCreator(gSystemAvatar); sprintf(channelName, "%"PRIu64".GroupChat", mId); channel->setName(BString(channelName)); channel->setGalaxy(gChatManager->getGalaxyName()); BString tmpValueStr = BString(BSTRType_Unicode16,64); tmpValueStr.setLength(swprintf(tmpValueStr.getUnicode16(),64,L"%"WidePRIu64, mId)); channel->setTitle(tmpValueStr); gLogger->log(LogManager::DEBUG,"Group channel created: '%s' with id %u.", channel->getName().getAnsi(), channel->getId()); channel->setOwner(gSystemAvatar); mChannel = channel; gChatManager->registerChannel(mChannel); }
bool CraftingManager::HandleCreatePrototype(Object* object, Object* target,Message* message, ObjectControllerCmdProperties* cmdProperties) { PlayerObject* player = dynamic_cast<PlayerObject*>(object); CraftingSession* session = player->getCraftingSession(); BString dataStr; uint32 mode,counter; if(!session) return false; message->getStringUnicode16(dataStr); if(swscanf(dataStr.getUnicode16(),L"%u %u",&counter,&mode) != 2) { gCraftingSessionFactory->destroySession(player->getCraftingSession()); return false; } session->createPrototype(mode,counter); return true; }
void ObjectController::_handleMatch(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* matchObject = dynamic_cast<PlayerObject*>(mObject); BString matchfield; uint32 i1,i2,i3,i4,i5; message->getStringUnicode16(matchfield); swscanf(matchfield.getUnicode16(),L"%u %u %u %u %u",&i1,&i2,&i3,&i4,&i5); mDatabase->executeSqlAsync(this,new(mDBAsyncContainerPool.malloc()) ObjControllerAsyncContainer(OCQuery_Nope), "UPDATE %s.character_matchmaking set match_1 = %u, match_2 = %u, match_3 = %u, match_4 = %u where character_id = %" PRIu64 "",mDatabase->galaxy(), i2, i3, i4, i5, matchObject->getId()); // update the players Object matchObject->setPlayerMatch(0,i2); matchObject->setPlayerMatch(1,i3); matchObject->setPlayerMatch(2,i4); matchObject->setPlayerMatch(3,i5); // now send the delta gMessageLib->sendMatchPlay3(matchObject); }
bool CraftingManager::HandleCreateManufactureSchematic(Object* object, Object* target,Message* message, ObjectControllerCmdProperties* cmdProperties) { PlayerObject* player = dynamic_cast<PlayerObject*>(object); CraftingSession* session = player->getCraftingSession(); BString dataStr; uint32 counter; if(!session) return false; message->getStringUnicode16(dataStr); if(swscanf(dataStr.getUnicode16(),L"%u",&counter) != 1) { gCraftingSessionFactory->destroySession(player->getCraftingSession()); return false; } //gLogger->hexDump(message->getData(),message->getSize()); session->createManufactureSchematic(counter); return true; }
void FactoryCrate::sendAttributes(PlayerObject* playerObject) { if(!(playerObject->isConnected())) return; AttributeMap* iAttributeMap = this->getLinkedObject()->getAttributeMap(); AttributeOrderList* iAttributeOrderList = this->getLinkedObject()->getAttributeOrder(); Message* newMessage; gMessageFactory->StartMessage(); gMessageFactory->addUint32(opAttributeListMessage); gMessageFactory->addUint64(mId); gMessageFactory->addUint32(2 + mAttributeMap.size()+iAttributeMap->size()); BString tmpValueStr = BString(BSTRType_Unicode16,64); BString value,aStr; tmpValueStr.setLength(swprintf(tmpValueStr.getUnicode16(),50,L"%u/%u",mMaxCondition - mDamage,mMaxCondition)); gMessageFactory->addString(BString("condition")); gMessageFactory->addString(tmpValueStr); AttributeMap::iterator mapIt; AttributeOrderList::iterator orderIt = mAttributeOrderList.begin(); while(orderIt != mAttributeOrderList.end()) { mapIt = mAttributeMap.find(*orderIt); gMessageFactory->addString(gWorldManager->getAttributeKey((*mapIt).first)); value = (*mapIt).second.c_str(); value.convert(BSTRType_Unicode16); gMessageFactory->addString(value); ++orderIt; } gMessageFactory->addString(BString("factory_attribs")); aStr = "\\#"SOE_RED" --------------"; aStr.convert(BSTRType_Unicode16); gMessageFactory->addString(aStr); orderIt = iAttributeOrderList->begin(); while(orderIt != iAttributeOrderList->end()) { mapIt = iAttributeMap->find(*orderIt); gMessageFactory->addString(gWorldManager->getAttributeKey((*mapIt).first)); value = (*mapIt).second.c_str(); value.convert(BSTRType_Unicode16); gMessageFactory->addString(value); ++orderIt; } newMessage = gMessageFactory->EndMessage(); (playerObject->getClient())->SendChannelAUnreliable(newMessage, playerObject->getAccountId(), CR_Client, 9); }
void TreasuryManager::bankTipOnline(int32 amount, PlayerObject* playerObject, PlayerObject* targetObject ) { //check if we have enough money int32 surcharge = (int32)((amount/100)*5); if((amount+surcharge) > dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))->getCredits()) { BString s; s = targetObject->getFirstName(); s.convert(BSTRType_Unicode16); gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "prose_tip_nsf_cash", L"", s.getUnicode16(), L"", amount), playerObject); return; } Bank* playerBank = dynamic_cast<Bank*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Bank)); Bank* targetBank = dynamic_cast<Bank*>(targetObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Bank)); playerBank->setCredits(playerBank->getCredits() - (amount+surcharge)); targetBank->setCredits(targetBank->getCredits() + amount); saveAndUpdateBankCredits(playerObject); saveAndUpdateBankCredits(targetObject); gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "prose_tip_pass_self", 0, targetObject->getId(), 0, amount), playerObject); gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "prose_tip_pass_target", 0, playerObject->getId(), 0, amount), targetObject); gMessageLib->sendBanktipMail(playerObject,targetObject,amount); }
void TreasuryManager::bankTipOffline(uint32 amount,PlayerObject* player,BString targetName) { //============================================ //check whether we have sufficient funds //dont forget the surcharge auto equip_service = gWorldManager->getKernel()->GetServiceManager()->GetService<swganh::equipment::EquipmentService>("EquipmentService"); //auto inventory = dynamic_cast<Inventory*>(equip_service->GetEquippedObject(player, "inventory")); auto bank = dynamic_cast<Bank*>(equip_service->GetEquippedObject(player->GetCreature(), "bank")); if(!bank) { LOG (error) << "TreasuryManager::bankJoin No bank for " << player->getId(); return; } int32 credits = bank->getCredits(); int32 surcharge = (int32)((amount/100)*5); if((amount + surcharge) > credits) { BString uniName = targetName; uniName.convert(BSTRType_Unicode16); gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "prose_tip_nsf_bank", L"", L"", uniName.getUnicode16(), amount), player); return; } //now get the player int8 name[50]; mDatabase->escapeString(name,targetName.getAnsi(),targetName.getLength()); int8 sql[256]; sprintf(sql,"SELECT id FROM %s.characters WHERE firstname like '%s'",mDatabase->galaxy(),name); TreasuryManagerAsyncContainer* asyncContainer; asyncContainer = new TreasuryManagerAsyncContainer(TREMQuery_BankTipgetId,player->getClient()); asyncContainer->amount = amount; asyncContainer->surcharge = surcharge; asyncContainer->targetName = targetName; asyncContainer->player = player; mDatabase->executeSqlAsync(this,asyncContainer,sql); }
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 ObjectController::_handleSitServer(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); if(playerObject) { BString data; glm::vec3 chair_position; uint64 chairCell = 0; uint32 elementCount = 0; if(playerObject->checkPlayerCustomFlag(PlayerCustomFlag_LogOut)) { playerObject->togglePlayerFlagOff(PlayerCustomFlag_LogOut); gMessageLib->SendSystemMessage(::common::OutOfBand("logout", "aborted"), playerObject); } // see if we need to get out of sampling mode if(playerObject->getSamplingState()) { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_cancel"), playerObject); playerObject->setSamplingState(false); } message->getStringUnicode16(data); //Should be okay even if data is null! (I hope) // sitting on chair if(data.getLength()) { elementCount = swscanf(data.getUnicode16(), L"%f,%f,%f,%"WidePRIu64, &chair_position.x, &chair_position.y, &chair_position.z, &chairCell); if(elementCount == 4) { // outside playerObject->updatePosition(chairCell,chair_position); //this->mDirection = Anh_Math::Quaternion(); if(chairCell) { gMessageLib->sendDataTransformWithParent053(playerObject); } else { gMessageLib->sendDataTransform053(playerObject); } //gMessageLib->sendUpdateMovementProperties(playerObject); //gMessageLib->sendPostureAndStateUpdate(playerObject); gMessageLib->sendSitOnObject(playerObject); } } // sitting on ground else { //gMessageLib->sendPostureUpdate(playerObject); //gMessageLib->sendSelfPostureUpdate(playerObject); } gStateManager.setCurrentPostureState(playerObject, CreaturePosture_Sitting); } }
void ObjectController::_handleAdminWarpSelf(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); BString dataStr; BString planet; int32 planetId = 0; int32 x,z; message->getStringUnicode16(dataStr); int32 elementCount = swscanf(dataStr.getUnicode16(),L"%i %i %s",&x,&z,planet.getAnsi()); switch(elementCount) { // warp on current planet case 2: { // make sure we in bounds if(x < -8192 || x > 8192 || z < -8192 || z > 8192) break; gWorldManager->warpPlanet(player, glm::vec3(static_cast<float>(x),0.0f,static_cast<float>(z)),0); } return; // warp to other or current planet case 3: { // make sure we in bounds if(x < -8192 || x > 8192 || z < -8192 || z > 8192) break; planetId = gWorldManager->getPlanetIdByName(planet); if(planetId == -1) break; // warp on this planet if(static_cast<uint32>(planetId) == gWorldManager->getZoneId()) { gWorldManager->warpPlanet(player, glm::vec3(static_cast<float>(x),0.0f,static_cast<float>(z)),0); } // zone transfer request else { gMessageLib->SendSystemMessage(L"Requesting zone transfer...", player); gMessageLib->sendClusterZoneTransferRequestByPosition(player, glm::vec3(static_cast<float>(x),0.0f,static_cast<float>(z)),planetId); } } return; default: { gMessageLib->SendSystemMessage(L"[SYNTAX] /admin_warp_self <x> <z> <planet>", player); } return; } gMessageLib->SendSystemMessage(L"Error parsing parameters.", player); }
bool CraftingManager::HandleNextCraftingStage(Object* object, Object* target,Message* message, ObjectControllerCmdProperties* cmdProperties) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(object); CraftingSession* session = playerObject->getCraftingSession(); BString dataStr; uint32 counter = 1; if(!session) return false; message->getStringUnicode16(dataStr); if(dataStr.getLength() == 0) { //Command Line Entry counter = session->getCounter(); } else { uint32 resultCount = swscanf(dataStr.getUnicode16(),L"%u",&counter); if(resultCount != 1) { gCraftingSessionFactory->destroySession(session); return false; } } switch(session->getStage()) { case 1: { //Player's Macro is wrong! :p } break; case 2: { session->assemble(counter); } break; case 3: { session->experimentationStage(counter); } break; case 4: { session->customizationStage(counter); //session->creationStage(counter); } break; case 5: { session->creationStage(counter); } break; default: { } break; } return true; }
void ObjectController::_handleTransferItemMisc(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { //we need to make sure that ONLY equipped items are contained by the player //all other items are contained by the inventory!!!!!!!! PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); Object* itemObject = gWorldManager->getObjectById(targetId); Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); BString dataStr; uint64 targetContainerId; uint32 linkType; float x,y,z; CellObject* cell; message->getStringUnicode16(dataStr); if(swscanf(dataStr.getUnicode16(),L"%" WidePRIu64 L" %u %f %f %f",&targetContainerId,&linkType,&x,&y,&z) != 5) { DLOG(info) << "ObjController::_handleTransferItemMisc: Error in parameters"; return; } if (!itemObject) { DLOG(warning) << "ObjController::_handleTransferItemMisc: No Object to transfer :("; return; } TangibleObject* tangible = dynamic_cast<TangibleObject*>(itemObject); if(!tangible) { //no tagible - get out of here DLOG(warning) << "ObjController::_handleTransferItemMisc: No tangible to transfer :("; return; } //get our containers Object* newContainer = gWorldManager->getObjectById(targetContainerId); Object* oldContainer = gWorldManager->getObjectById(tangible->getParentId()); DLOG(info) << "ObjController::_handleTransferItemMisc: parameters"; DLOG(info) << "ObjController::_handleTransferItemMisc: newcontainer : " << targetContainerId; DLOG(info) << "ObjController::_handleTransferItemMisc: oldcontainer : " << tangible->getParentId(); DLOG(info) << "ObjController::_handleTransferItemMisc: linktype : " << linkType; // We may want to transfer other things than items...basically tangibleObjects! // resourcecontainers / factory crates // first check whether its an instrument with persistant copy - thats a special case! Item* item = dynamic_cast<Item*>(itemObject); if (item) { //check if its only temporarily placed if(item->getItemFamily() == ItemFamily_Instrument) { if(item->getPersistantCopy()) { // gMessageLib->sendSystemMessage(playerObject,L"you cannot pick this up"); // You bet, I can! Remove the temp instrument from the world. // Do I have access to this instrument? if (item->getOwner() == playerObject->getId()) { playerObject->getController()->destroyObject(targetId); } return; } } } // A FYI: When we drop items, we use player pos. itemObject->mPosition = glm::vec3(x,y,z); if (!targetContainerId) { DLOG(info) << "ObjController::_handleTransferItemMisc:TargetContainer is 0 :("; //return; } //ok how to tackle this ... : //basically I want to use ObjectContainer as standard access point for item handling! //so far we have different accesses for Objects on the player and for the inventory and for ContainerObjects and for cells ... //lets begin by getting the target Object if(!checkTargetContainer(targetContainerId,itemObject)) { DLOG(info) << "ObjController::_handleTransferItemMisc:TargetContainer is not valid :("; return; } if(!checkContainingContainer(tangible->getParentId(), playerObject->getId())) { DLOG(info) << "ObjController::_handleTransferItemMisc:ContainingContainer is not allowing the transfer :("; return; } // Remove the object from whatever contains it. if(!removeFromContainer(targetContainerId, targetId)) { DLOG(info) << "ObjectController::_handleTransferItemMisc: removeFromContainer failed :( this might be caused by looting a corpse though"; return; } //we need to destroy the old radial ... our item now gets a new one //delete(itemObject->getRadialMenu()); itemObject->ResetRadialMenu(); itemObject->setParentId(targetContainerId); //Now update the registered watchers!! gContainerManager->updateObjectPlayerRegistrations(newContainer, oldContainer, tangible, linkType); //now go and move it to wherever it belongs cell = dynamic_cast<CellObject*>(newContainer); if (cell) { // drop in a cell //special case temp instrument if (item&&item->getItemFamily() == ItemFamily_Instrument) { if (playerObject->getPlacedInstrumentId()) { // We do have a placed instrument. uint32 instrumentType = item->getItemType(); if ((instrumentType == ItemType_Nalargon) || (instrumentType == ItemType_omni_box) || (instrumentType == ItemType_nalargon_max_reebo)) { // We are about to drop the real thing, remove any copied instrument. // item->setOwner(playerObject->getId(); playerObject->getController()->destroyObject(playerObject->getPlacedInstrumentId()); } } } itemObject->mPosition = playerObject->mPosition; //do the db update manually because of the position - unless we get an automated position save in itemObject->setParentId(targetContainerId); ResourceContainer* rc = dynamic_cast<ResourceContainer*>(itemObject); if(rc) mDatabase->executeSqlAsync(0,0,"UPDATE %s.resource_containers SET parent_id ='%I64u', oX='%f', oY='%f', oZ='%f', oW='%f', x='%f', y='%f', z='%f' WHERE id='%I64u'",mDatabase->galaxy(),itemObject->getParentId(), itemObject->mDirection.x, itemObject->mDirection.y, itemObject->mDirection.z, itemObject->mDirection.w, itemObject->mPosition.x, itemObject->mPosition.y, itemObject->mPosition.z, itemObject->getId()); else mDatabase->executeSqlAsync(0,0,"UPDATE %s.items SET parent_id ='%I64u', oX='%f', oY='%f', oZ='%f', oW='%f', x='%f', y='%f', z='%f' WHERE id='%I64u'",mDatabase->galaxy(),itemObject->getParentId(), itemObject->mDirection.x, itemObject->mDirection.y, itemObject->mDirection.z, itemObject->mDirection.w, itemObject->mPosition.x, itemObject->mPosition.y, itemObject->mPosition.z, itemObject->getId()); cell->addObjectSecure(itemObject); gMessageLib->sendDataTransformWithParent053(itemObject); itemObject->updateWorldPosition(); return; } PlayerObject* player = dynamic_cast<PlayerObject*>(newContainer); if(player) { //equip / unequip handles the db side, too if(!player->getEquipManager()->EquipItem(item)) { LOG(warning) << "ObjectController::_handleTransferItemMisc: Error equipping " << item->getId(); //panik!!!!!! } itemObject->setParentIdIncDB(newContainer->getId()); return; } //***************************************************************** //All special cases have been handled - now its just our generic ObjectContainer Type //some other container ... hopper backpack chest inventory etc if(newContainer) { newContainer->addObjectSecure(itemObject); itemObject->setParentIdIncDB(newContainer->getId()); return; } }
//====================================================================================================================== void ArtisanManager::sampleEvent(PlayerObject* player, CurrentResource* resource, SurveyTool* tool) { if (!player->isConnected()) return; //==================================================== //check whether we are able to sample in the first place // if (stopSampling(player, resource, tool)) return; std::string effect = gWorldManager->getClientEffect(tool->getInternalAttribute<uint32>("sample_effect")); float ratio = (resource->getDistribution((int)player->mPosition.x + 8192,(int)player->mPosition.z + 8192)); int32 surveyMod = player->GetCreature()->getSkillModValue(SMod_surveying); uint32 sampleAmount = 0; BString resName = resource->getName().getAnsi(); uint32 resType = resource->getType()->getCategoryId(); uint16 resPE = resource->getAttribute(ResAttr_PE); bool successSample = false; bool resAvailable = true; resName.convert(BSTRType_Unicode16); if (getRadioactiveSample(player, resource, tool)) { // now we're done sampling for this go around, finish up or set a flag so we know to finish up if(stopSampling(player, resource, tool)) { return; } } // calculate sample size if concentration >0 and surveyMod exists for player //original implementation sampleAmount = (uint32)floor((double)((15.0f * ratio) * (surveyMod / 100.0f))); float ratio_100 = ratio*100; float successChance = static_cast<float>((surveyMod/4)+45); // float maxSuccessChance = 70; // == 70, but showing the formula so it is obvious where it comes from float failureChance = 100-successChance; float dieRoll = static_cast<float>((gRandom->getRand()%100)+1); // random value from 1 to 100 float adjSkill = surveyMod/successChance; //100 skill == 1; 85 skill = 0.9464; etc float minSample = ratio_100/20*adjSkill; float maxSample = ratio_100/10*adjSkill; float minConcentration = static_cast<float>(-1.12*successChance+88); // attempting to simplify this to "-1*sC+90" or whatever will break it uint32 actionCost = mSampleActionCost; if(player->getSampleData()->mSampleNodeFlag) { if(setupForNodeSampleRecovery(player)) { ratio = 100.0; dieRoll = 200; } else { stopSampling(player, resource, tool); return; } } // let's make sure their ratio is good enough to sample this if(ratio <= 0.0f) { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "density_below_threshold", L"", L"", resName.getUnicode16()), player); player->getSampleData()->mPendingSample = false; return; } //If previous call triggered a sample event, set the roll to ensure critical success if(player->getSampleData()->mSampleEventFlag) { player->getSampleData()->mSampleEventFlag = false; //set so a critical success happens -- A critical failure can also happen. In either case, this took a significant amount of action (300 points???) // This appears to have been what the commented out gambling code below was supposed to do. dieRoll = 100; } if(ratio_100 >= minConcentration) { //inside calculation section if(dieRoll <= failureChance) { // FAILED ATTEMPT sampleAmount = 0; successSample = false; gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_failed", L"", L"", resName.getUnicode16()), player); } else if((dieRoll > 96)&&(dieRoll < 98)) { //Sample event if (setupSampleEvent(player, resource, tool)) return; } else { successSample = true; if(dieRoll == 200) { sampleAmount = (static_cast<uint32>(3*maxSample)); sampleAmount = std::max<uint>(sampleAmount,static_cast<uint>(1)); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "node_recovery"), player); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_located", L"", L"", resName.getUnicode16(), sampleAmount), player); player->getSampleData()->mSampleEventFlag = false; player->getSampleData()->mSampleNodeFlag = false; } else // was set to == 100 if(dieRoll >= 99) { if(player->getSampleData()->mSampleGambleFlag) { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "gamble_success"), player); sampleAmount = (static_cast<uint32>(3*maxSample)); sampleAmount = std::max<uint>(sampleAmount, static_cast<uint>(1)); actionCost = 300; //300 action gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_located", L"", L"", resName.getUnicode16(), sampleAmount), player); player->getSampleData()->mSampleGambleFlag = false; player->getSampleData()->mSampleEventFlag = false; } else { //CRITICAL SUCCESS sampleAmount = (static_cast<uint32>(2*maxSample)); sampleAmount = std::max<uint>(sampleAmount, static_cast<uint>(1)); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "critical_success", L"", L"", resName.getUnicode16()), player); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_located", L"", L"", resName.getUnicode16(), sampleAmount), player); } } else { //NORMAL SUCCESS sampleAmount = (static_cast<uint32>(floor(static_cast<float>((maxSample-minSample)*(dieRoll-failureChance)/(90-failureChance)+minSample)))); // floor == round down, so 9.9 == 9 sampleAmount = std::max<uint>(sampleAmount, static_cast<uint>(1)); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_located", L"", L"", resName.getUnicode16(), sampleAmount), player); } } } else { gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "density_below_threshold", L"", L"", resName.getUnicode16()), player); player->setSamplingState(false); return; } // show the effects always gContainerManager->sendToRegisteredWatchers(player, [effect, player] (PlayerObject* const recipient) { gMessageLib->sendPlayClientEffectLocMessage(effect, player->mPosition,recipient); }); if (sampleAmount > 0 && successSample) { finishSampling(player, resource, tool, sampleAmount); } // check our ham and keep sampling if(!stopSampling(player, resource, tool)) { player->getSampleData()->mNextSampleTime = Anh_Utils::Clock::getSingleton()->getLocalTime() + 18000; std::shared_ptr<SimpleEvent> start_sample_event = std::make_shared<SimpleEvent>(EventType("start_sample"),0, 18000, std::bind(&ArtisanManager::sampleEvent,this, player, resource, tool)); gEventDispatcher.Notify(start_sample_event); } auto ham = gWorldManager->getKernel()->GetServiceManager()->GetService<swganh::ham::HamService>("HamService"); ham->ApplyModifiedHamCosts(player->GetCreature(), 0, actionCost, 0); }
void TreasuryManager::bankTipOffline(int32 amount,PlayerObject* playerObject,BString targetName) { //============================================ //check whether we have sufficient funds //dont forget the surcharge Bank* bank = dynamic_cast<Bank*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Bank)); int32 credits = bank->getCredits(); int32 surcharge = (int32)((amount/100)*5); if((amount + surcharge) > credits) { BString uniName = targetName; uniName.convert(BSTRType_Unicode16); gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "prose_tip_nsf_bank", L"", L"", uniName.getUnicode16(), amount), playerObject); return; } //now get the player int8 name[50]; mDatabase->Escape_String(name,targetName.getAnsi(),targetName.getLength()); int8 sql[256]; sprintf(sql,"SELECT id FROM characters WHERE firstname like '%s'",name); TreasuryManagerAsyncContainer* asyncContainer; asyncContainer = new TreasuryManagerAsyncContainer(TREMQuery_BankTipgetId,playerObject->getClient()); asyncContainer->amount = amount; asyncContainer->surcharge = surcharge; asyncContainer->targetName = targetName; asyncContainer->player = playerObject; mDatabase->ExecuteSqlAsync(this,asyncContainer,sql); }
void ObjectController::_handleRequestCharacterMatch(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); BString dataStr; PlayerList playersMatched; PlayerList* matchReference; uint32 masksCount = 0; uint32 playerFlags = 0; uint32 mask2 = 0; uint32 mask3 = 0; uint32 mask4 = 0; uint32 factionCrc = 0; int32 raceId = 0; int8 titleStr[128]; int8 unknown[64]; uint32 elementCount = 0; Skill* skill = NULL; int8* pTitle; pTitle = titleStr; message->getStringUnicode16(dataStr); if(dataStr.getLength()) elementCount = swscanf(dataStr.getUnicode16(),L"%u %u %u %u %u %u %i %s %s",&masksCount,&playerFlags,&mask2,&mask3,&mask4,&factionCrc,&raceId,titleStr,unknown); if(elementCount != 9) { DLOG(INFO) << "ObjController::_handleRequestCharacterMatch: argument mismatch " << player->getId(); return; } if(strcmp(titleStr,"\"\"") != 0) { skill = gSkillManager->getSkillByName(titleStr); if(skill == NULL) { DLOG(INFO) << "ObjController::_handleRequestCharacterMatch: could not find matching skill for " << titleStr; return; } } // for now check players in viewing range // and ourselves =) playersMatched.push_back(player); //for our practical purpose were not sending to them but merely iterating through them gContainerManager->sendToRegisteredPlayers(player,[playerFlags, raceId, factionCrc, skill, pTitle, matchReference, this] ( PlayerObject* const inRangePlayer) { if(((playerFlags & inRangePlayer->getPlayerFlags()) == playerFlags) &&(raceId == -1 || raceId == inRangePlayer->getRaceId()) &&(factionCrc == 0 || factionCrc == 1 || factionCrc == inRangePlayer->getFaction().getCrc())) { if(skill == NULL) { matchReference->push_back(inRangePlayer); } else { if((skill->mIsProfession && strstr(inRangePlayer->getTitle().getAnsi(),pTitle)) || (strcmp(pTitle,inRangePlayer->getTitle().getAnsi()) == 0)) { matchReference->push_back(inRangePlayer); } } } } ); gMessageLib->sendCharacterMatchResults(&playersMatched,player); }
bool ArtisanManager::handleRequestSurvey(Object* playerObject,Object* target,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* player = dynamic_cast<PlayerObject*>(playerObject); std::shared_ptr<SimpleEvent> start_survey_event = nullptr; if(cmdProperties) mSurveyMindCost = cmdProperties->mMindCost; // don't allow survey in buildings if(player->getParentId()) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "survey_in_structure"), player); return false; } if(player->GetCreature()->getPerformingState() != PlayerPerformance_None) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "wrong_state"), player); return false; } if(player->getSurveyState()) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "survey_cant"), player); return false; } if(player->getSamplingState()) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "survey_sample"), player); return false; } // checks if we are in combat, dead or incapacitated if (player->GetCreature()->states.checkState(CreatureState_Combat) || player->GetCreature()->states.checkPosture(CreaturePosture_Dead) || player->GetCreature()->states.checkLocomotion(CreatureLocomotion_Incapacitated)) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "wrong_state"), player); 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(tool && resource) { player->setSurveyState(true); // play effect std::string effect = gWorldManager->getClientEffect(tool->getInternalAttribute<uint32>("survey_effect")); gMessageLib->sendPlayClientEffectLocMessage(effect,player->mPosition,player); gContainerManager->sendToRegisteredWatchers(player, [effect, player] (PlayerObject* const recipient) { gMessageLib->sendPlayClientEffectLocMessage(effect, player->mPosition, recipient); }); auto ham = gWorldManager->getKernel()->GetServiceManager()->GetService<swganh::ham::HamService>("HamService"); uint32 survey_cost = mSurveyMindCost; //are we able to sample in the first place ?? if(!ham->ApplyModifiedHamCosts(player->GetCreature(), 0, 0, survey_cost)) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "sample_mind"), player); //message for stop sampling gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_cancel"), player); player->getSampleData()->mPendingSurvey = false; player->GetCreature()->updateMovementProperties(); return false; } // send system message resourceName.convert(BSTRType_Unicode16); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "start_survey", L"", L"", resourceName.getUnicode16()), player); // schedule execution start_survey_event = std::make_shared<SimpleEvent>(EventType("start_survey"),0, 5000, std::bind(&ArtisanManager::surveyEvent, this, player, resource, tool)); } else { gMessageLib->SendSystemMessage(::common::OutOfBand("ui","survey_nothingfound")); return false; } // notify any listeners if (start_survey_event) gEventDispatcher.Notify(start_survey_event); return true; }
bool MessageLib::sendBaselinesTYCF_3(FactoryCrate* crate,PlayerObject* targetObject) { if(!(targetObject->isConnected())) return(false); BString customName; BString NameFile; BString Name; TangibleObject* tO = crate->getLinkedObject(); if(!tO) { customName = crate->getCustomName(); NameFile = crate->getNameFile(); Name = crate->getName(); } else { customName = tO->getCustomName(); NameFile = tO->getNameFile(); Name = tO->getName(); } customName.convert(BSTRType_Unicode16); mMessageFactory->StartMessage(); mMessageFactory->addUint16(11); //op count mMessageFactory->addFloat(1.0);//tangibleObject->getComplexity()); mMessageFactory->addString(NameFile.getAnsi()); mMessageFactory->addUint32(0); // unknown mMessageFactory->addString(Name.getAnsi()); mMessageFactory->addString(customName.getUnicode16()); uint32 uses = 0; mMessageFactory->addUint32(1);//volume gives the volume taken up in the inventory!!!!!!!! //mMessageFactory->addString(crate->getCustomizationStr()); mMessageFactory->addUint16(0);//crate customization mMessageFactory->addUint64(0); // unknown list might be defender list mMessageFactory->addUint32(0);//crate->getTypeOptions());bitmask - insured etc if(crate->hasAttribute("factory_count")) { uses = crate->getAttribute<int>("factory_count"); } mMessageFactory->addUint32(uses);// mMessageFactory->addUint32(0); mMessageFactory->addUint32(0); //1 when not moveable mMessageFactory->addUint8(0); // mMessageFactory->addUint64(0); // Message* data = mMessageFactory->EndMessage(); mMessageFactory->StartMessage(); mMessageFactory->addUint32(opBaselinesMessage); mMessageFactory->addUint64(crate->getId()); mMessageFactory->addUint32(opFCYT); mMessageFactory->addUint8(3); mMessageFactory->addUint32(data->getSize()); mMessageFactory->addData(data->getData(), data->getSize()); data->setPendingDelete(true); (targetObject->getClient())->SendChannelA(mMessageFactory->EndMessage(), targetObject->getAccountId(), CR_Client, 5); return(true); }
void ChatMessageLib::sendSystemMessageProper(Player* playerObject,uint8 system, BString customMessage,BString mainFile,BString mainVar,BString toFile,BString toVar,BString toCustom,int32 di,BString ttFile,BString ttVar,BString ttCustom,uint64 ttId,uint64 toId,uint64 tuId,BString tuFile,BString tuVar,BString tuCustom) const { gMessageFactory->StartMessage(); gMessageFactory->addUint32(opChatSystemMessage); if(system) system = 2; gMessageFactory->addUint8(system); if(customMessage.getType() != BSTRType_Unicode16) customMessage.convert(BSTRType_Unicode16); if(toCustom.getType() != BSTRType_Unicode16) toCustom.convert(BSTRType_Unicode16); if(tuCustom.getType() != BSTRType_Unicode16) tuCustom.convert(BSTRType_Unicode16); if(ttCustom.getType() != BSTRType_Unicode16) ttCustom.convert(BSTRType_Unicode16); // simple message if(customMessage.getLength()) { gMessageFactory->addString(customMessage.getUnicode16()); gMessageFactory->addUint32(0); } // templated message else { gMessageFactory->addUint32(0); uint32 realSize = mainFile.getLength() + mainVar.getLength() + toFile.getLength() + toVar.getLength() + ttFile.getLength() + ttVar.getLength()+ tuFile.getLength() + tuVar.getLength(); gMessageFactory->addUint32(42 + ((uint32)ceil(((double)realSize) / 2.0)) + toCustom.getLength() + ttCustom.getLength()+ tuCustom.getLength()); if(realSize % 2) gMessageFactory->addUint16(1); else gMessageFactory->addUint16(0); gMessageFactory->addUint8(1); gMessageFactory->addUint32(0xFFFFFFFF); gMessageFactory->addString(mainFile); gMessageFactory->addUint32(0); gMessageFactory->addString(mainVar); gMessageFactory->addUint64(tuId); gMessageFactory->addString(tuFile); gMessageFactory->addUint32(0); gMessageFactory->addString(tuVar); gMessageFactory->addString(tuCustom.getUnicode16()); gMessageFactory->addUint64(ttId); gMessageFactory->addString(ttFile); gMessageFactory->addUint32(0); gMessageFactory->addString(ttVar); gMessageFactory->addString(ttCustom.getUnicode16()); gMessageFactory->addUint64(toId); gMessageFactory->addString(toFile); gMessageFactory->addUint32(0); gMessageFactory->addString(toVar); gMessageFactory->addString(toCustom.getUnicode16()); gMessageFactory->addInt32(di); gMessageFactory->addUint32(0); gMessageFactory->addUint8(0); if(realSize % 2) gMessageFactory->addUint8(0); } (playerObject->getClient())->SendChannelA(gMessageFactory->EndMessage(), playerObject->getClient()->getAccountId(), CR_Client, 5); }
//====================================================================================================================== // // 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::handleRequestSurvey(Object* playerObject,Object* target,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* player = dynamic_cast<PlayerObject*>(playerObject); std::shared_ptr<SimpleEvent> start_survey_event = nullptr; if(cmdProperties) mSurveyMindCost = cmdProperties->mMindCost; // don't allow survey in buildings if(player->getParentId()) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "survey_in_structure"), player); return false; } if(player->getPerformingState() != PlayerPerformance_None) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "wrong_state"), player); return false; } if(player->getSurveyState()) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "survey_cant"), player); return false; } if(player->getSamplingState()) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "survey_sample"), player); 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(tool && resource) { player->setSurveyState(true); // play effect std::string effect = gWorldManager->getClientEffect(tool->getInternalAttribute<uint32>("survey_effect")); gMessageLib->sendPlayClientEffectLocMessage(effect,player->mPosition,player); PlayerObjectSet* playerList = player->getKnownPlayers(); PlayerObjectSet::iterator it = playerList->begin(); while(it != playerList->end()) { gMessageLib->sendPlayClientEffectLocMessage(effect,player->mPosition,(*it)); ++it; } uint32 mindCost = mSurveyMindCost; Ham* hamz = player->getHam(); //are we able to sample in the first place ?? if(!hamz->checkMainPools(0,0,mindCost)) { int32 myMind = hamz->mAction.getCurrentHitPoints(); //return message for sampling cancel based on HAM if(myMind < (int32)mindCost) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "sample_mind"), player); } //message for stop sampling gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "sample_cancel"), player); player->getSampleData()->mPendingSurvey = false; hamz->updateRegenRates(); player->updateMovementProperties(); return false; } hamz->performSpecialAction(0,0,(float)mindCost,HamProperty_CurrentHitpoints); // send system message resourceName.convert(BSTRType_Unicode16); gMessageLib->SendSystemMessage(::common::OutOfBand("survey", "start_survey", L"", L"", resourceName.getUnicode16()), player); // schedule execution start_survey_event = std::make_shared<SimpleEvent>(EventType("start_survey"),0, 5000, std::bind(&ArtisanManager::surveyEvent, this, player, resource, tool)); } else { gMessageLib->SendSystemMessage(::common::OutOfBand("ui","survey_nothingfound")); return false; } // notify any listeners if (start_survey_event) gEventDispatcher.Notify(start_survey_event); return true; }