void InventoryFactory::handleObjectReady(Object* object,DispatchClient* client) { //we either have the ID of the inventory or of the player //the inventory of course is stored under its own Id InLoadingContainer* ilc = _getObject(object->getParentId()); assert(ilc && "InventoryFactory::handleObjectReady unable to find InLoadingContainer"); if (! ilc) { return; } Inventory* inventory = dynamic_cast<Inventory*>(ilc->mObject); gWorldManager->addObject(object,true); //for unequipped items only inventory->addObjectSecure(object); if(inventory->getObjectLoadCounter() == (inventory->getObjects())->size()) { gLogger->logMsgF("InventoryFactory: remove inventory %I64u from loadmap",MSG_HIGH,inventory->getId()); inventory->setLoadState(LoadState_Loaded); if(!(_removeFromObjectLoadMap(inventory->getId()))) gLogger->logMsg("InventoryFactory: Failed removing object from loadmap"); ilc->mOfCallback->handleObjectReady(inventory,ilc->mClient); mILCPool.free(ilc); } }
//============================================================================= // // filled components get returned to the inventory // // void CraftingSession::bagComponents(ManufactureSlot* manSlot,uint64 containerId) { //add the components back to the inventory (!!!) manSlot->setFilledType(DST_Empty); //put them into the inventory no matter what - only alternative might be a crafting stations hopper at one point ?? Inventory* inventory = dynamic_cast<Inventory*>(mOwner->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); FilledComponent::iterator compIt = manSlot->mUsedComponentStacks.begin(); while(compIt != manSlot->mUsedComponentStacks.end()) { Item* filledComponent = dynamic_cast<Item*>((*compIt).first); if(!filledComponent) { return; } inventory->addObject(filledComponent); gMessageLib->sendContainmentMessage(filledComponent->getId(),inventory->getId(),0xffffffff,mOwner); filledComponent->setParentIdIncDB(inventory->getId()); compIt = manSlot->mUsedComponentStacks.erase(compIt); continue; } manSlot->mUsedComponentStacks.clear(); manSlot->mFilledResources.clear(); }
//====================================================================================================================== // // create the inventory contents for its owner // void MessageLib::sendInventory(PlayerObject* playerObject) { if(!_checkPlayer(playerObject)) return; Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); //uint64 parentId = inventory->getParentId(); //to stop the server from crashing. if(!inventory) { assert(false && "MessageLib::sendInventory - Player has no inventory ???? :("); return; } inventory->setTypeOptions(256); //todo - just use sendcreate tangible and have it send the children, too!!!! // create the inventory sendCreateObjectByCRC(inventory,playerObject,false); sendContainmentMessage(inventory->getId(),inventory->getParentId(),4,playerObject); sendBaselinesTANO_3(inventory,playerObject); sendBaselinesTANO_6(inventory,playerObject); // create objects contained ObjectIDList* invObjects = inventory->getObjects(); ObjectIDList::iterator objIt = invObjects->begin(); while(objIt != invObjects->end()) { Object* object = gWorldManager->getObjectById((*objIt)); sendCreateObject(object,playerObject,false); ++objIt; } sendEndBaselines(inventory->getId(),playerObject); ObjectList* invEquippedObjects = playerObject->getEquipManager()->getEquippedObjects(); ObjectList::iterator objEIt = invEquippedObjects->begin(); while(objEIt != invEquippedObjects->end()) { if(TangibleObject* tangible = dynamic_cast<TangibleObject*>(*objEIt)) { sendCreateTangible(tangible,playerObject); } ++objEIt; } }
void InventoryDAOMySQL::deleteInventory(Inventory &inventory) { MySQLManager::ConnectionHolder ch(MySQLManager::getInstance()); std::unique_ptr<sql::PreparedStatement> ps(ch.conn->prepareStatement(DELETE_INVENTORY)); ps->setInt(1, inventory.getId()); ps->execute(); }
void InventoryDAOMySQL::updateInventory(const Inventory &inventory) { MySQLManager::ConnectionHolder ch(MySQLManager::getInstance()); std::unique_ptr<sql::PreparedStatement> ps(ch.conn->prepareStatement(UPDATE_INVENTORY)); ps->setInt(1, inventory.getUserId()); ps->setInt(2, inventory.getFoodId()); ps->setString(3, inventory.getUseBy()); ps->setInt(4, inventory.getId()); ps->executeUpdate(); }
void Food::prepareCustomRadialMenu(CreatureObject* creatureObject, uint8 itemCount) { RadialMenu* radial = new RadialMenu(); CreatureObject* unknownCreature; Inventory* creatureInventory; if (this->getParentId() && (unknownCreature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(this->getParentId() - 1))) && (creatureInventory = dynamic_cast<Inventory*>(unknownCreature->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))) && (creatureInventory->getId() == this->getParentId())) { // Its an object in an inventory NPCObject* npcObject = dynamic_cast<NPCObject*>(unknownCreature); if (npcObject) { if ((npcObject->getNpcFamily() == NpcFamily_AttackableCreatures) && npcObject->isDead()) { // I'm pretty sure we are a loot item. radial->addItem(1,0,radId_itemPickup,radAction_ObjCallback,"@ui_radial:loot"); radial->addItem(2,0,radId_examine,radAction_Default); mRadialMenu = RadialMenuPtr(radial); return; } } } // Note: If we are to never use the default "Eat", THEN remove the isTutorial()-condition test. if (gWorldConfig->isTutorial()) { // Tutorial clearly states that we shall use the "Use"-option. radial->addItem(1,0,radId_itemUse,radAction_ObjCallback,"Use"); } else { radial->addItem(1,0,radId_itemUse,radAction_ObjCallback,""); // Default. } radial->addItem(2,0,radId_examine,radAction_ObjCallback,""); radial->addItem(3,0,radId_itemDestroy,radAction_ObjCallback,""); mRadialMenu = RadialMenuPtr(radial); }
void ArtisanManager::finishSampling(PlayerObject* player, CurrentResource* resource, SurveyTool* tool, uint32 sampleAmount) { bool foundSameType = false; //grants 20xp -> 40xp inclusive -- Feature suggestion: Grant less XP for smaller samples, more xp for greater samples. IE: 20 + X*sampleSize gSkillManager->addExperience(XpType_resource_harvesting_inorganic,(int32)((gRandom->getRand()%20) + 20),player); // see if we can add it to an existing container Inventory* inventory = dynamic_cast<Inventory*>(player->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); ObjectIDList* invObjects = inventory->getObjects(); ObjectIDList::iterator listIt = invObjects->begin(); while(listIt != invObjects->end()) { // we are looking for resource containers ResourceContainer* resCont = dynamic_cast<ResourceContainer*>(gWorldManager->getObjectById((*listIt))); if(resCont) { uint32 targetAmount = resCont->getAmount(); uint32 maxAmount = resCont->getMaxAmount(); uint32 newAmount; if(resCont->getResourceId() == resource->getId() && targetAmount < maxAmount) { foundSameType = true; if((newAmount = targetAmount + sampleAmount) <= maxAmount) { // update target container resCont->setAmount(newAmount); gMessageLib->sendResourceContainerUpdateAmount(resCont,player); gWorldManager->getDatabase()->executeSqlAsync(NULL,NULL,"UPDATE resource_containers SET amount=%u WHERE id=%"PRIu64"",newAmount,resCont->getId()); } // target container full, put in what fits, create a new one else if(newAmount > maxAmount) { uint32 selectedNewAmount = newAmount - maxAmount; resCont->setAmount(maxAmount); gMessageLib->sendResourceContainerUpdateAmount(resCont,player); gWorldManager->getDatabase()->executeSqlAsync(NULL,NULL,"UPDATE resource_containers SET amount=%u WHERE id=%"PRIu64"",maxAmount,resCont->getId()); gObjectFactory->requestNewResourceContainer(inventory,resource->getId(),inventory->getId(),99,selectedNewAmount); } break; } } ++listIt; } // or need to create a new one if(!foundSameType) { gObjectFactory->requestNewResourceContainer(inventory,resource->getId(),inventory->getId(),99,sampleAmount); } // deplete resource gResourceManager->setResourceDepletion(resource, sampleAmount); return; }
//====================================================================================================================== // // update busy crafting tools, called every 2 seconds // bool WorldManager::_handleCraftToolTimers(uint64 callTime,void* ref) { CraftTools::iterator it = mBusyCraftTools.begin(); while(it != mBusyCraftTools.end()) { CraftingTool* tool = dynamic_cast<CraftingTool*>(getObjectById((*it))); if(!tool) { LOG(error) << "Missing crafting tool"; it = mBusyCraftTools.erase(it); continue; } PlayerObject* player = dynamic_cast<PlayerObject*>(getObjectById(tool->getParentId() - 1)); Item* item = tool->getCurrentItem(); if(player) { // we done, create the item if(!tool->updateTimer(callTime)) { // add it to the world, if it holds an item if(item) { Inventory* temp = dynamic_cast<Inventory*>(player->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); if(!temp) continue; item->setParentId(temp->getId()); dynamic_cast<Inventory*>(player->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))->addObject(item); gWorldManager->addObject(item,true); gMessageLib->sendCreateTano(item,player); gMessageLib->SendSystemMessage(::common::OutOfBand("system_msg", "prototype_transferred"), player); tool->setCurrentItem(NULL); } //in case of logout/in interplanetary travel it will be in the inventory already gMessageLib->sendUpdateTimer(tool,player); it = mBusyCraftTools.erase(it); tool->setAttribute("craft_tool_status","@crafting:tool_status_ready"); mDatabase->executeSqlAsync(0,0,"UPDATE %s.item_attributes SET value='@crafting:tool_status_ready' WHERE item_id=%" PRIu64 " AND attribute_id=18",mDatabase->galaxy(),tool->getId()); tool->setAttribute("craft_tool_time",boost::lexical_cast<std::string>(tool->getTimer())); gWorldManager->getDatabase()->executeSqlAsync(0,0,"UPDATE %s.item_attributes SET value='%i' WHERE item_id=%" PRIu64 " AND attribute_id=%u",mDatabase->galaxy(),tool->getId(),tool->getTimer(),AttrType_CraftToolTime); continue; } // update the time display gMessageLib->sendUpdateTimer(tool,player); tool->setAttribute("craft_tool_time",boost::lexical_cast<std::string>(tool->getTimer())); //gLogger->log(LogManager::DEBUG,"timer : %i",tool->getTimer()); mDatabase->executeSqlAsync(0,0,"UPDATE %s.item_attributes SET value='%i' WHERE item_id=%" PRIu64 " AND attribute_id=%u",mDatabase->galaxy(),tool->getId(),tool->getTimer(),AttrType_CraftToolTime); } ++it; } return(true); }
void PlayerStructure::handleUIEvent(BString strCharacterCash, BString strHarvesterCash, UIWindow* window) { PlayerObject* player = window->getOwner(); if(!player) { return; } switch(window->getWindowType()) { case SUI_Window_Deposit_Power: { strCharacterCash.convert(BSTRType_ANSI); BString characterPower = strCharacterCash; strHarvesterCash.convert(BSTRType_ANSI); BString harvesterPower = strHarvesterCash; int32 harvesterPowerDelta = atoi(harvesterPower.getAnsi()); gStructureManager->deductPower(player,harvesterPowerDelta); this->setCurrentPower(getCurrentPower()+harvesterPowerDelta); gWorldManager->getDatabase()->executeSqlAsync(0,0,"UPDATE %s.structure_attributes SET value='%u' WHERE structure_id=%" PRIu64 " AND attribute_id=384",gWorldManager->getDatabase()->galaxy(),getCurrentPower(),this->getId()); } break; case SUI_Window_Pay_Maintenance: { strCharacterCash.convert(BSTRType_ANSI); strHarvesterCash.convert(BSTRType_ANSI); Bank* bank = dynamic_cast<Bank*>(player->getEquipManager()->getEquippedObject(CreatureEquipSlot_Bank)); Inventory* inventory = dynamic_cast<Inventory*>(player->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); int32 bankFunds = bank->credits(); int32 inventoryFunds = inventory->getCredits(); int32 funds = inventoryFunds + bankFunds; int32 characterMoneyDelta = atoi(strCharacterCash.getAnsi()) - funds; int32 harvesterMoneyDelta = atoi(strHarvesterCash.getAnsi()) - this->getCurrentMaintenance(); // the amount transfered must be greater than zero if(harvesterMoneyDelta == 0 || characterMoneyDelta == 0) { return; } //lets get the money from the bank first if((bankFunds +characterMoneyDelta)< 0) { characterMoneyDelta += bankFunds; bankFunds = 0; inventoryFunds += characterMoneyDelta; } else { bankFunds += characterMoneyDelta; } if(inventoryFunds < 0) { return; } int32 maintenance = this->getCurrentMaintenance() + harvesterMoneyDelta; if(maintenance < 0) { return; } bank->credits(bankFunds); inventory->setCredits(inventoryFunds); gWorldManager->getDatabase()->destroyResult(gWorldManager->getDatabase()->executeSynchSql("UPDATE %s.banks SET credits=%u WHERE id=%" PRIu64 "",gWorldManager->getDatabase()->galaxy(),bank->credits(),bank->getId())); gWorldManager->getDatabase()->destroyResult(gWorldManager->getDatabase()->executeSynchSql("UPDATE %s.inventories SET credits=%u WHERE id=%" PRIu64 "",gWorldManager->getDatabase()->galaxy(),inventory->getCredits(),inventory->getId())); //send the appropriate deltas. gMessageLib->sendInventoryCreditsUpdate(player); gMessageLib->sendBankCreditsUpdate(player); //get the structures conditiondamage and see whether it needs repair uint32 damage = this->getDamage(); if(damage) { uint32 cost = this->getRepairCost(); uint32 all = cost*damage; if(maintenance <= (int32)all) { all -= (uint32)maintenance; damage = (uint32)(all/cost); maintenance = 0; } if(maintenance > (int32)all) { maintenance -= (int32)all; damage = 0; } //update the remaining damage in the db gWorldManager->getDatabase()->executeSqlAsync(0,0,"UPDATE %s.structures s SET s.condition= %u WHERE s.ID=%" PRIu64 "",gWorldManager->getDatabase()->galaxy(),damage,this->getId()); this->setDamage(damage); //Update the structures Condition gMessageLib->sendHarvesterCurrentConditionUpdate(this); } gWorldManager->getDatabase()->executeSqlAsync(0,0,"UPDATE %s.structure_attributes SET value='%u' WHERE structure_id=%" PRIu64 " AND attribute_id=382",gWorldManager->getDatabase()->galaxy(),maintenance,this->getId()); this->setCurrentMaintenance(maintenance); } break; } }
bool ObjectController::removeFromContainer(uint64 targetContainerId, uint64 targetId) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); Object* itemObject = gWorldManager->getObjectById(targetId); Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); TangibleObject* targetContainer = dynamic_cast<TangibleObject*>(gWorldManager->getObjectById(targetContainerId)); TangibleObject* tangible = dynamic_cast<TangibleObject*>(itemObject); Item* item = dynamic_cast<Item*>(itemObject); // its us if (tangible->getParentId() == playerObject->getId()) { // unequip it return playerObject->getEquipManager()->unEquipItem(itemObject); } //the containerObject is the container used in the tutorial or some random dungeon container Container* container = dynamic_cast<Container*>(gWorldManager->getObjectById(tangible->getParentId())); if (container) { container->removeObject(itemObject); //gContainerManager->destroyObjectToRegisteredPlayers(container, tangible->getId()); if (gWorldConfig->isTutorial()) { playerObject->getTutorial()->transferedItemFromContainer(targetId, tangible->getParentId()); // If object is owned by player (private owned for instancing), we remove the owner from the object. // what is this used for ??? if (itemObject->getPrivateOwner() == playerObject->getId()) { itemObject->setPrivateOwner(0); } } return true; } //creature inventories are a special case - their items are temporary!!! we cannot loot them directly CreatureObject* unknownCreature; Inventory* creatureInventory; if (itemObject->getParentId() && (unknownCreature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(itemObject->getParentId() - INVENTORY_OFFSET))) && (creatureInventory = dynamic_cast<Inventory*>(unknownCreature->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))) && (creatureInventory->getId() == itemObject->getParentId()) && (creatureInventory->getId() != inventory->getId())) { if(!creatureInventory->removeObject(itemObject)) { LOG(warning) << "ObjectController::removeFromContainer: Internal Error could not remove " << itemObject->getId() << " from creature inventory " << creatureInventory->getId(); return false; } // we destroy the item in this case as its a temporary!! // we do not want to clog the db with unlooted items gContainerManager->destroyObjectToRegisteredPlayers(creatureInventory, tangible->getId()); ObjectIDList* invObjList = creatureInventory->getObjects(); if (invObjList->size() == 0) { // Put this creature in the pool of delayed destruction and remove the corpse from scene. gWorldManager->addCreatureObjectForTimedDeletion(creatureInventory->getParentId(), LootedCorpseTimeout); } if (gWorldConfig->isTutorial()) { // TODO: Update tutorial about the loot. playerObject->getTutorial()->transferedItemFromContainer(targetId, creatureInventory->getId()); } //bail out here and request the item over the db - as the item in the NPC has a temporary id and we dont want that in the db // This ensure that we do not use/store any of the temp id's in the database. gObjectFactory->requestNewDefaultItem(inventory, item->getItemFamily(), item->getItemType(), inventory->getId(), 99, glm::vec3(), ""); return false; } //cells are NOT tangibles - thei are static Objects CellObject* cell; if(cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(itemObject->getParentId()))) { // Stop playing if we pick up the (permanently placed) instrument we are playing if (item && (item->getItemFamily() == ItemFamily_Instrument)) { uint32 instrumentType = item->getItemType(); if ((instrumentType == ItemType_Nalargon) || (instrumentType == ItemType_omni_box) || (instrumentType == ItemType_nalargon_max_reebo)) { // It's a placeable original instrument. // Are we targeting the instrument we actually play on? if (playerObject->getActiveInstrumentId() == item->getId()) { gEntertainerManager->stopEntertaining(playerObject); } } } //we *cannot* remove static tangibles like the structureterminal!!!! if(tangible->getStatic()) { return false; } // Remove object from cell. cell->removeObject(itemObject); return true; } //some other container ... hopper backpack chest etc TangibleObject* containingContainer = dynamic_cast<TangibleObject*>(gWorldManager->getObjectById(tangible->getParentId())); if(containingContainer && containingContainer->removeObject(itemObject)) { return true; } return false; }
void ObjectController::_handlePurchaseTicket(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); BString dataStr; BStringVector dataElements; uint16 elements; float purchaseRange = gWorldConfig->getConfiguration<float>("Player_TicketTerminalAccess_Distance",(float)10.0); if(playerObject->states.getPosture() == CreaturePosture_SkillAnimating) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "wrong_state"), playerObject); return; } //however we are able to use the purchaseticket command in starports //without having to use a ticketvendor by just giving commandline parameters //when we are *near* a ticket vendor TravelTerminal* terminal = dynamic_cast<TravelTerminal*> (gWorldManager->getNearestTerminal(playerObject,TanType_TravelTerminal)); // iterate through the results if((!terminal)|| (glm::distance(terminal->mPosition, playerObject->mPosition) > purchaseRange)) { gMessageLib->SendSystemMessage(::common::OutOfBand("travel", "too_far"), playerObject); return; } playerObject->setTravelPoint(terminal); message->getStringUnicode16(dataStr); // Have to convert BEFORE using split, since the conversion done there is removed It will assert().. evil grin... // Either do the conversion HERE, or better fix the split so it handles unicoe also. dataStr.convert(BSTRType_ANSI); elements = dataStr.split(dataElements,' '); if(elements < 4) { gMessageLib->SendSystemMessage(::common::OutOfBand("travel", "route_not_available"), playerObject); return; } // get price and planet ids TicketProperties ticketProperties; gTravelMapHandler->getTicketInformation(dataElements,&ticketProperties); if(!ticketProperties.dstPoint) { gMessageLib->SendSystemMessage(::common::OutOfBand("travel", "route_not_available"), playerObject); return; } uint8 roundTrip = 0; if(elements > 4) roundTrip = atoi(dataElements[4].getAnsi()); if(dataElements[4].getCrc() == BString("single").getCrc()) roundTrip = 0; //how many tickets will it be? uint32 amount = 1; if(roundTrip) amount = 2; Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); Bank* bank = dynamic_cast<Bank*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Bank)); if(!inventory->checkSlots(static_cast<uint8>(amount))) { gMessageLib->SendSystemMessage(::common::OutOfBand("error_message", "inv_full"), playerObject); return; } if(roundTrip == 1) { ticketProperties.price *= 2; } // update bank or inventory credits if(!(inventory->updateCredits(-ticketProperties.price))) { if(!(bank->updateCredits(-ticketProperties.price))) { //gMessageLib->sendSystemMessage(entertainer,L"","travel","route_not_available"); gUIManager->createNewMessageBox(NULL,"ticketPurchaseFailed","The Galactic Travel Commission","You do not have enough money to complete the ticket purchase.",playerObject); return; } } if(playerObject->isConnected()) { gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "prose_pay_acct_success", "", "", "", "", "money/acct_n", "travelsystem", ticketProperties.price), playerObject); gObjectFactory->requestNewTravelTicket(inventory,ticketProperties,inventory->getId(),99); if(roundTrip == 1) { uint32 tmpId = ticketProperties.srcPlanetId; TravelPoint* tmpPoint = ticketProperties.srcPoint; ticketProperties.srcPlanetId = ticketProperties.dstPlanetId; ticketProperties.srcPoint = ticketProperties.dstPoint; ticketProperties.dstPlanetId = static_cast<uint16>(tmpId); ticketProperties.dstPoint = tmpPoint; gObjectFactory->requestNewTravelTicket(inventory,ticketProperties,inventory->getId(),99); } gUIManager->createNewMessageBox(NULL,"handleSUI","The Galactic Travel Commission","@travel:ticket_purchase_complete",playerObject); } }
void Instrument::prepareCustomRadialMenu(CreatureObject* player, uint8 itemCount) { // NOTE: player is also of type CreatureObject* !!! PlayerObject* playerObject = dynamic_cast<PlayerObject*>(player); mRadialMenu.reset(); mRadialMenu = RadialMenuPtr(new RadialMenu()); // RadialMenu* radial = new RadialMenu(); //string mInstrumentString = instrument->getName(); uint32 instrumentNr = this->getItemType(); if ((instrumentNr == ItemType_Nalargon) || (instrumentNr == ItemType_omni_box) || (instrumentNr == ItemType_nalargon_max_reebo)) { uint32 radId = 1; // We have to know if this is the real one or the copy. if (playerObject->getPlacedInstrumentId() == this->getId()) { // We are handling the copy if ((playerObject->getId() == this->getOwner()) && this->getPlaced()) { if ((playerObject->getPerformingState() == PlayerPerformance_Music)) { mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_itemUse,radAction_ObjCallback, "@radial_performance:stop_playing"); } else { mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_itemUse,radAction_ObjCallback, "@radial_performance:play_instrument"); } } else { // radial->addItem(radId++,0,radId_examine,radAction_Default); // radial->addItem(radId++,0,radId_itemPickup,radAction_Default); return; } mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_examine,radAction_Default); mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_itemPickup,radAction_Default); } else { // We may be handling the original instrument. Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); if (inventory) { if (inventory->getId() == this->getParentId()) { // We have our real instrument in the inventory. // We can't drop if outside in the world. if (player->getParentId() == 0) { // Outside mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_examine,radAction_Default); mRadialMenu->addItem(static_cast<uint8>(radId),0,radId_itemDestroy, radAction_Default); } else { mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_examine,radAction_Default); mRadialMenu->addItem(static_cast<uint8>(radId),0,radId_itemDrop,radAction_Default); mRadialMenu->addItem(static_cast<uint8>(radId),0,radId_itemDestroy, radAction_Default); } if (playerObject->getPlacedInstrumentId() == 0) { // We do not have any other placed intrument out. mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_itemUse,radAction_ObjCallback,"Use"); } } else if (dynamic_cast<CellObject*>(gWorldManager->getObjectById(this->getParentId()))) { // It's either a original instrument, or someone else instrument, copy or original. // Time for some dirty... the original instrument does not have an owner. // Let's take advantage of that shortcoming. // Is this my instrument? if (this->getOwner() == player->getId()) { // Yes, are we handling the original instrument. // if (cell->getId() == this->getParentId()) { if ((playerObject->getPerformingState() == PlayerPerformance_Music)) { mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_itemUse,radAction_ObjCallback, "@radial_performance:stop_playing"); } else { mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_itemUse,radAction_ObjCallback, "@radial_performance:play_instrument"); } mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_examine,radAction_Default); mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_itemPickup,radAction_Default); } } else { // This is not my instrument. // gMessageLib->sendSystemMessage(playerObject,L"","error_message","insufficient_permissions"); mRadialMenu->addItem(static_cast<uint8>(radId++),0,radId_examine,radAction_Default); // radial->addItem(radId++,0,radId_itemPickup,radAction_Default); } } } } } // mRadialMenu = RadialMenuPtr(radial); // RadialMenuPtr radialPtr(radial); // mRadialMenu = radialPtr; }
bool ObjectController::checkTargetContainer(uint64 targetContainerId, Object* object) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); TangibleObject* tangibleItem = dynamic_cast<TangibleObject*>(object); //if its a backpack etc we want to know how many items are in it! uint32 objectSize = tangibleItem->getHeadCount(); //******************** //this is a special case as we are equipping the item //so handle it separately if(playerObject->getId() == targetContainerId) { //check for equip restrictions!!!! //we cant drop that check - further down we assume that the transfer is accepted // a failing equip will just loose us our item in the receiving container and crash the server in the end return playerObject->getEquipManager()->CheckEquipable(object); } //***************************** //ok everything else is a tangible Object Object* targetContainer = gWorldManager->getObjectById(targetContainerId); //sanity check - if(!targetContainer) { //inventory is NOT part of the main ObjectMap - everything else should be in there if(inventory && (inventory->getId() != targetContainerId)) { return false; } if(inventory) targetContainer = dynamic_cast<TangibleObject*>(inventory); else { DLOG(info) << "ObjController::_handleTransferItemMisc: TargetContainer is NULL and not an inventory :("; return false; } } //====================================================================00 //check access permissions first bool access = false; bool fit = false; //******************** //The tutorial Container is a special case //so handle it separately Container* container = dynamic_cast<Container*>(targetContainer ); if (container) { if (gWorldConfig->isTutorial()) { // We don't allow users to place item in the container. // gMessageLib->sendSystemMessage(playerObject,L"","event_perk","chest_can_not_add"); gMessageLib->SendSystemMessage(L"",playerObject,"error_message","remove_only"); return false; } } //******************** //Factory Outputhopper is retrieve only //access has been granted through the UI already TangibleObject* tangibleContainer = dynamic_cast<TangibleObject*>(targetContainer); if((tangibleContainer)&&(strcmp(tangibleContainer->getName().getAnsi(),"ingredient_hopper")==0)) { //do we have access rights to the factories hopper?? this would have to be checked asynchronously //for now we can only access the hoppers UI through the client and checking our permission so its proven already //a hacker might in theory exploit this, though factories items should only be in memory when someone accesses the hopper access = true; } //==================================================================================== //get the mainOwner of the container - thats a building or a player or an inventory // uint64 ownerId = gSpatialIndexManager->getObjectMainParent(targetContainer); Object* objectOwner = dynamic_cast<Object*>(gWorldManager->getObjectById(ownerId)); if(BuildingObject* building = dynamic_cast<BuildingObject*>(objectOwner)) { if(building->hasAdminRights(playerObject->getId())) { access = true; //do we have enough room ? if(building->checkCapacity(objectSize)) { //***************************** //if it is the House wé dont need to check a containers capacity further down if(!tangibleContainer) //mainly as the container might not exist if its placed in the house directly return true; if(tangibleContainer->checkCapacity(objectSize,playerObject)) return true; else return false; } else { //This container is full. gMessageLib->SendSystemMessage(L"",playerObject,"container_error_message","container03"); return false; } } else { //You do not have permission to access that container. gMessageLib->SendSystemMessage(L"",playerObject,"container_error_message","container08"); return false; } } //********************************** //the inventory is *NOT* part of the worldmanagers ObjectMap //this is our inventory - we are allowed to put stuff in there - but is there still enough place ? if(inventory&& (inventory->getId() == ownerId)) { //make sure its our inventory!!!!!! access = ((inventory->getId()- INVENTORY_OFFSET) == playerObject->getId()); if(!access) { //You do not have permission to access that container. gMessageLib->SendSystemMessage(L"",playerObject,"container_error_message","container08"); return false; } //check space in inventory fit = inventory->checkCapacity(1,playerObject,true); if(!fit) { //This container is full. gMessageLib->SendSystemMessage(L"",playerObject,"container_error_message","container03"); return false; } } //if this is a tangible container (backpack, satchel) we want to make sure, //that we do not put another backpack in it. //in other words, the contained container MUST be smaller than the containing container //********************** //check capacity - return false if full //we wont get here if its an inventory if(tangibleContainer && (!tangibleContainer->checkCapacity(objectSize,playerObject))) //automatically sends errormsg to player { return false; } uint32 containingContainersize = tangibleContainer->getCapacity(); uint32 containedContainersize = tangibleItem->getCapacity(); //we can only add smaller containers inside other containers if(containedContainersize >= containingContainersize) { //This item is too bulky to fit inside this container. gMessageLib->SendSystemMessage(L"",playerObject,"container_error_message","container12"); return false; } return true; }
void Tutorial::addQuestWeapon(uint32 familyId, uint32 typeId) { // gLogger->log(LogManager::DEBUG,"Tutorial::addItem Invoked",MSG_NORMAL); if (mPlayerObject && mPlayerObject->isConnected()) { Inventory* inventory = dynamic_cast<Inventory*>(mPlayerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); if (inventory) { if ((familyId != 0) && (typeId != 0)) { // Set new default weapon mQuestWeaponFamily = familyId; mQuestWeaponType = typeId; } gObjectFactory->requestNewDefaultItem(inventory,mQuestWeaponFamily,mQuestWeaponType,inventory->getId(),99, glm::vec3(), ""); } } }
void ObjectController::_handleResourceContainerSplit(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); ResourceContainer* selectedContainer = dynamic_cast<ResourceContainer*>(gWorldManager->getObjectById(targetId)); Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); gLogger->logMsgF("ObjectController::_handleResourceContainerSplit: Container : %I64u",MSG_NORMAL,targetId); if(!selectedContainer) { gLogger->logMsg("ObjectController::_handleResourceContainerSplit: Container does not exist!"); return; } string dataStr; message->getStringUnicode16(dataStr); dataStr.convert(BSTRType_ANSI); BStringVector dataElements; uint16 elementCount = dataStr.split(dataElements,' '); if(!elementCount) { gLogger->logMsg("ObjectController::_handleResourceContainerSplit: Error in requestStr"); return; } uint32 splitOffAmount = boost::lexical_cast<uint32>(dataElements[0].getAnsi()); uint64 parentId = boost::lexical_cast<uint64>(dataElements[1].getAnsi()); if(selectedContainer->getParentId() == inventory->getId()) { //check if we can fit an additional resource container in our inventory if(!inventory->checkSlots(1)) { gMessageLib->sendSystemMessage(playerObject,L"","error_message","inv_full"); return; } mDatabase->ExecuteSqlAsync(NULL,NULL,"UPDATE resource_containers SET amount=%u WHERE id=%"PRIu64"",selectedContainer->getAmount(),selectedContainer->getId()); // create a new one // update selected container contents selectedContainer->setAmount(selectedContainer->getAmount() - splitOffAmount); gMessageLib->sendResourceContainerUpdateAmount(selectedContainer,playerObject); gObjectFactory->requestNewResourceContainer(inventory,(selectedContainer->getResource())->getId(),parentId,99,splitOffAmount); return; } Item* item = dynamic_cast<Item*>(gWorldManager->getObjectById(parentId)); if(!item) { gLogger->logMsg("ObjectController::_ExtractObject: resourcecontainers parent does not exist!"); assert(false && "ObjectController::_ExtractObject resourcecontainers parent does not exist"); return; } if(!item->checkCapacity()) { //check if we can fit an additional item in our inventory gMessageLib->sendSystemMessage(playerObject,L"","container_error_message","container3"); return; } // update selected container contents selectedContainer->setAmount(selectedContainer->getAmount() - splitOffAmount); gMessageLib->sendResourceContainerUpdateAmount(selectedContainer,playerObject); gObjectFactory->requestNewResourceContainer(item,(selectedContainer->getResource())->getId(),parentId,99,splitOffAmount); }
void Instrument::handleObjectMenuSelect(uint8 messageType,Object* srcObject) { if(PlayerObject* player = dynamic_cast<PlayerObject*>(srcObject)) { switch(messageType) { case radId_itemUse: { if (player->getPlacedInstrumentId() == this->getId()) { float range = gWorldConfig->getConfiguration<float>("Zone_Player_ItemUse",(float)6.0); if (!gWorldManager->objectsInRange(player->getId(), this->getId(), range)) { // We where out of range. (using 6.0 m as default range,this value not verified). // TODO: Find the proper error-message, the one below is a "made up". gMessageLib->SendSystemMessage(::common::OutOfBand("system_msg", "out_of_range"), player); return; } if ((player->getId() == this->getOwner()) && this->getPlaced()) { if ((player->getPerformingState() == PlayerPerformance_Music)) { gEntertainerManager->stopEntertaining(player); } else { // Start to play the copy. gEntertainerManager->usePlacedInstrument(player,this); } } else { // Create a new copy of the instrument. // gEntertainerManager->useInstrument(player,this); } } else { // We are handling the original instrument. Inventory* inventory = dynamic_cast<Inventory*>(player->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); if (inventory) { if (inventory->getId() == this->getParentId()) { if (player->getPlacedInstrumentId() == 0) { // Create a new copy of the instrument. gEntertainerManager->useInstrument(player,this); } else { gMessageLib->SendSystemMessage(::common::OutOfBand("system_msg", "wrong_state"), player); } } else if (dynamic_cast<CellObject*>(gWorldManager->getObjectById(this->getParentId()))) { // Is this my instrument? if (this->getOwner() == player->getId()) { if (!gWorldManager->objectsInRange(player->getId(), this->getId(), 6.0)) { // We where out of range. (using 6.0 m as default range,this value not verified). // TODO: Find the proper error-message, the one below is a "made up". gMessageLib->SendSystemMessage(::common::OutOfBand("system_msg", "out_of_range"), player); return; } if ((player->getPerformingState() == PlayerPerformance_Music)) { gEntertainerManager->stopEntertaining(player); } else { // Start to play the original. gEntertainerManager->usePlacedInstrument(player,this); } } } } } } break; default: { } break; } } }
void InventoryFactory::handleDatabaseJobComplete(void* ref,DatabaseResult* result) { QueryContainerBase* asyncContainer = reinterpret_cast<QueryContainerBase*>(ref); switch(asyncContainer->mQueryType) { case IFQuery_MainInventoryData: { Inventory* inventory = _createInventory(result); QueryContainerBase* asContainer = new(mQueryContainerPool.ordered_malloc()) QueryContainerBase(asyncContainer->mOfCallback,IFQuery_ObjectCount,asyncContainer->mClient); asContainer->mObject = inventory; mDatabase->ExecuteSqlAsync(this,asContainer,"SELECT sf_getInventoryObjectCount(%"PRIu64")",inventory->getId()); } break; case IFQuery_ObjectCount: { Inventory* inventory = dynamic_cast<Inventory*>(asyncContainer->mObject); uint32 objectCount; DataBinding* binding = mDatabase->CreateDataBinding(1); binding->addField(DFT_uint32,0,4); result->GetNextRow(binding,&objectCount); inventory->setObjectLoadCounter(objectCount); if(objectCount != 0) { uint64 invId = inventory->getId(); inventory->setLoadState(LoadState_Loading); // query contents QueryContainerBase* asContainer = new(mQueryContainerPool.ordered_malloc()) QueryContainerBase(asyncContainer->mOfCallback,IFQuery_Objects,asyncContainer->mClient); asContainer->mObject = inventory; //why would we load the lootcontainers and trashpiles for the inventory ??? //containers are normal items like furniture, lightsabers and stuff mDatabase->ExecuteSqlAsync(this,asContainer, "(SELECT \'containers\',containers.id FROM containers INNER JOIN container_types ON (containers.container_type = container_types.id)" " WHERE (container_types.name NOT LIKE 'unknown') AND (containers.parent_id = %"PRIu64"))" " UNION (SELECT \'items\',items.id FROM items WHERE (parent_id=%"PRIu64"))" " UNION (SELECT \'resource_containers\',resource_containers.id FROM resource_containers WHERE (parent_id=%"PRIu64"))", invId,invId,invId); } else { inventory->setLoadState(LoadState_Loaded); asyncContainer->mOfCallback->handleObjectReady(inventory,asyncContainer->mClient); } mDatabase->DestroyDataBinding(binding); } break; case IFQuery_Objects: { Inventory* inventory = dynamic_cast<Inventory*>(asyncContainer->mObject); Type1_QueryContainer queryContainer; DataBinding* binding = mDatabase->CreateDataBinding(2); binding->addField(DFT_bstring,offsetof(Type1_QueryContainer,mString),64,0); binding->addField(DFT_uint64,offsetof(Type1_QueryContainer,mId),8,1); uint64 count = result->getRowCount(); //InLoadingContainer* ilc = new(mILCPool.ordered_malloc()) InLoadingContainer(inventory,asyncContainer->mOfCallback,asyncContainer->mClient); //ilc->mLoadCounter = count; mObjectLoadMap.insert(std::make_pair(inventory->getId(),new(mILCPool.ordered_malloc()) InLoadingContainer(inventory,asyncContainer->mOfCallback,asyncContainer->mClient,static_cast<uint8>(count)))); for(uint32 i = 0;i < count;i++) { result->GetNextRow(binding,&queryContainer); if(strcmp(queryContainer.mString.getAnsi(),"containers") == 0) mTangibleFactory->requestObject(this,queryContainer.mId,TanGroup_Container,0,asyncContainer->mClient); else if(strcmp(queryContainer.mString.getAnsi(),"items") == 0) mTangibleFactory->requestObject(this,queryContainer.mId,TanGroup_Item,0,asyncContainer->mClient); else if(strcmp(queryContainer.mString.getAnsi(),"resource_containers") == 0) mTangibleFactory->requestObject(this,queryContainer.mId,TanGroup_ResourceContainer,0,asyncContainer->mClient); } mDatabase->DestroyDataBinding(binding); } break; default:break; } mQueryContainerPool.free(asyncContainer); }
void ObjectController::destroyObject(uint64 objectId) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); Datapad* datapad = playerObject->getDataPad(); Object* object = gWorldManager->getObjectById(objectId); //could be a schematic! ManufacturingSchematic* schem = datapad->getManufacturingSchematicById(objectId); if(schem != NULL) { //delete schematic datapad->removeManufacturingSchematic(objectId); //delete schematic object gObjectFactory->deleteObjectFromDB(schem); gMessageLib->sendDestroyObject(objectId,playerObject); return; } // could be a waypoint if(object == NULL) { object = datapad->getWaypointById(objectId); } // or something else if(object == NULL) { gLogger->log(LogManager::DEBUG,"ObjController::destroyObject: could not find object %"PRIu64"",objectId); return; } // waypoint if(object->getType() == ObjType_Waypoint) { // update our datapad if(!(datapad->removeWaypoint(objectId))) { gLogger->log(LogManager::DEBUG,"ObjController::handleDestroyObject: Error removing Waypoint from datapad %"PRIu64"",objectId); } gMessageLib->sendUpdateWaypoint(dynamic_cast<WaypointObject*>(object),ObjectUpdateDelete,playerObject); // delete from db gObjectFactory->deleteObjectFromDB(object); delete(object); } //Inangible Objects if(object->getType() == ObjType_Intangible) { //update the datapad if(!(datapad->removeData(objectId))) { gLogger->log(LogManager::DEBUG,"ObjController::handleDestroyObject: Error removing Data from datapad %"PRIu64"",objectId); } if(VehicleController* vehicle = dynamic_cast<VehicleController*>(object)) { vehicle->Store(); } gObjectFactory->deleteObjectFromDB(object); gMessageLib->sendDestroyObject(objectId,playerObject); delete(object); } // tangible else if(object->getType() == ObjType_Tangible) { TangibleObject* tangibleObject = dynamic_cast<TangibleObject*>(object); BuildingObject* building = dynamic_cast<BuildingObject*>(tangibleObject->getObjectMainParent(tangibleObject)); if(building) { if(!building->hasAdminRights(playerObject->getId())) { return; } } if(tangibleObject->getParentId() == 0) { return; } Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); // items if(Item* item = dynamic_cast<Item*>(tangibleObject)) { // handle any family specifics switch(item->getItemFamily()) { case ItemFamily_CraftingTools: _handleDestroyCraftingTool(dynamic_cast<CraftingTool*>(item)); break; case ItemFamily_Instrument: _handleDestroyInstrument(item); break; default: break; } // update the equiplist, if its an equipable item CreatureObject* creature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(item->getParentId())); if(creature) { // remove from creatures slotmap creature->getEquipManager()->removeEquippedObject(object); //unequip it object->setParentId(inventory->getId()); gMessageLib->sendContainmentMessage_InRange(object->getId(),inventory->getId(),0xffffffff,creature); // send out the new equiplist gMessageLib->sendEquippedListUpdate_InRange(creature); } } //tangible includes items and resourcecontainers if(tangibleObject) { //if(tangible->getObjectMainParent(object) != inventory->getId()) if(tangibleObject->getKnownPlayers()->size()) { //this automatically destroys the object for the players in its vicinity tangibleObject->destroyKnownObjects(); } else { // destroy it for the player gMessageLib->sendDestroyObject(objectId,playerObject); } } // reset pending ui callbacks playerObject->resetUICallbacks(object); // delete from db CAVE :: mark if its an Object saved in the db!!!! // temporary placed instruments are not saved in the db gObjectFactory->deleteObjectFromDB(object); //it might be in a cell or in a container or in the inventory :) ObjectContainer* oc = dynamic_cast<ObjectContainer*>(gWorldManager->getObjectById(object->getParentId())); if(oc) { oc->deleteObject(object); } else { gWorldManager->destroyObject(object); } } }