void PetControlDeviceImplementation::spawnObject(CreatureObject* player) { ZoneServer* zoneServer = getZoneServer(); ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get(); if (controlledObject == NULL) return; assert(controlledObject->isLockedByCurrentThread()); if (!isASubChildOf(player)) return; ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>(); if (tradeContainer != NULL) { server->getZoneServer()->getPlayerManager()->handleAbortTradeMessage(player); } controlledObject->initializePosition(player->getPositionX(), player->getPositionZ(), player->getPositionY()); ManagedReference<CreatureObject*> creature = NULL; if (controlledObject->isCreatureObject()) { creature = cast<CreatureObject*>(controlledObject.get()); creature->setCreatureLink(player); creature->setControlDevice(_this.getReferenceUnsafeStaticCast()); creature->setFaction(player->getFaction()); creature->setObjectMenuComponent("PetMenuComponent"); if (player->getPvpStatusBitmask() & CreatureFlag::PLAYER) creature->setPvpStatusBitmask(player->getPvpStatusBitmask() - CreatureFlag::PLAYER, true); else creature->setPvpStatusBitmask(player->getPvpStatusBitmask(), true); if (trainedAsMount && (creature->getOptionsBitmask() ^ 0x1000)) { creature->setOptionBit(0x1000); } } Zone* zone = player->getZone(); if (zone == NULL) return; ManagedReference<CellObject*> parent = player->getParent().get().castTo<CellObject*>(); if (parent != NULL) parent->transferObject(controlledObject, -1, true); else zone->transferObject(controlledObject, -1, true); updateStatus(1); if (petControlObserver != NULL) player->dropObserver(ObserverEventType::STARTCOMBAT, petControlObserver); AiAgent* pet = cast<AiAgent*>(creature.get()); if (pet == NULL) return; ManagedReference<PlayerObject*> ghost = player->getPlayerObject(); ghost->addToActivePets(pet); bool isDroid = false; if (pet->isDroidObject()) { DroidObject* droid = cast<DroidObject*>(pet); isDroid = true; if( droid == NULL ) return; // Sanity check that there aren't outstanding power/skill mod tasks droid->removePendingTask( "droid_power" ); droid->removePendingTask( "droid_skill_mod" ); droid->initDroidModules(); droid->onCall(); droid->loadSkillMods(player); // Submit new power task Reference<Task*> droidPowerTask = new DroidPowerTask( droid ); droid->addPendingTask("droid_power", droidPowerTask, 120000); // 2 min // Submit new skill mod task Reference<Task*> droidSkillModTask = new DroidSkillModTask( droid, player ); droid->addPendingTask("droid_skill_mod", droidSkillModTask, 3000); // 3 sec } pet->setHomeLocation(player->getPositionX(), player->getPositionZ(), player->getPositionY(), parent); pet->setNextStepPosition(player->getPositionX(), player->getPositionZ(), player->getPositionY(), parent); pet->clearPatrolPoints(); if (petType == PetManager::CREATUREPET) { pet->setCreatureBitmask(CreatureFlag::PET); } if (petType == PetManager::DROIDPET) { pet->setCreatureBitmask(CreatureFlag::DROID_PET); } if (petType == PetManager::FACTIONPET) { pet->setCreatureBitmask(CreatureFlag::FACTION_PET); /** dont know if npc faction pets trained via converse instead of radial if (pet->isNonPlayerCreatureObject() && pet->getDiet() != CreatureFlag::NONE) // show converse to npcs that eat food i.e. not atst pet->setOptionBit(OptionBitmask::CONVERSE,true); **/ } pet->activateLoad(""); pet->activateRecovery(); // Not training any commands trainingCommand = 0; clearPatrolPoints(); }
void CreatureManagerImplementation::tame(Creature* creature, CreatureObject* player, bool force) { Zone* zone = creature->getZone(); if (zone == NULL || !creature->isCreature()) return; if(player->getPendingTask("tame_pet") != NULL) { player->sendSystemMessage("You are already taming a pet"); return; } if(player->getPendingTask("call_pet") != NULL) { player->sendSystemMessage("You cannot tame a pet while another is being called"); return; } if (!creature->canTameMe(player) || !creature->isAttackableBy(player)) { player->sendSystemMessage("@pet/pet_menu:sys_cant_tame"); // You can't tame that return; } CreatureTemplate* creatureTemplate = creature->getCreatureTemplate(); if (creatureTemplate == NULL) return; int templateLevel = creatureTemplate->getLevel(); int maxLevelofPets = player->getSkillMod("tame_level"); if (!player->hasSkill("outdoors_creaturehandler_novice") || (templateLevel > maxLevelofPets)) { player->sendSystemMessage("@pet/pet_menu:sys_lack_skill"); // You lack the skill to be able to tame that creature. return; } if ((creature->isVicious() && player->getSkillMod("tame_aggro") < 1) || creature->getChanceToTame(player) <= 0) { player->sendSystemMessage("@pet/pet_menu:sys_lack_skill"); // You lack the skill to be able to tame that creature. return; } ManagedReference<SceneObject*> datapad = player->getSlottedObject("datapad"); if (datapad == NULL) return; if (datapad->getContainerObjectsSize() >= datapad->getContainerVolumeLimit()) { player->sendSystemMessage("@faction_recruiter:datapad_full"); // Your datapad is full. You must first free some space. return; } ManagedReference<PlayerManager*> playerManager = zoneServer->getPlayerManager(); int numberStored = 0; int maxStoredPets = playerManager->getBaseStoredCreaturePets() + player->getSkillMod("stored_pets"); for (int i = 0; i < datapad->getContainerObjectsSize(); ++i) { ManagedReference<SceneObject*> object = datapad->getContainerObject(i); if (object != NULL && object->isPetControlDevice()) { PetControlDevice* device = cast<PetControlDevice*>( object.get()); if (device->getPetType() == PetManager::CREATUREPET) { if (++numberStored >= maxStoredPets) { player->sendSystemMessage("@pet/pet_menu:sys_too_many_stored"); // There are too many pets stored in this container. Release some of them to make room for more. return; } } } } ManagedReference<PlayerObject*> ghost = player->getPlayerObject(); int currentlySpawned = 0; int spawnedLevel = 0; int level = creature->getLevel(); int maxPets = player->getSkillMod("keep_creature"); for (int i = 0; i < ghost->getActivePetsSize(); ++i) { ManagedReference<AiAgent*> object = ghost->getActivePet(i); if (object != NULL) { ManagedReference<PetControlDevice*> pcd = object->getControlDevice().get().castTo<PetControlDevice*>(); if (pcd == NULL || pcd->getPetType() != PetManager::CREATUREPET) { continue; } if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:too_many"); // You can't control any more pets. Store one first return; } spawnedLevel += object->getLevel(); if ((spawnedLevel + level) >= maxLevelofPets) { player->sendSystemMessage("Taming this pet would exceed your control level ability."); return; } } } if (force && !ghost->isPrivileged()) force = false; ChatManager* chatManager = player->getZoneServer()->getChatManager(); chatManager->broadcastMessage(player, "@hireling/hireling:taming_1"); // Easy. Locker clocker(creature); int mask = creature->getPvpStatusBitmask(); creature->setPvpStatusBitmask(0, true); if (creature->isAiAgent()) { AiAgent* agent = cast<AiAgent*>(creature); agent->activateLoad("wait"); } ManagedReference<TameCreatureTask*> task = new TameCreatureTask(creature, player, mask, force); player->addPendingTask("tame_pet", task, 8000); }
void SpawnAreaMap::loadStaticSpawns() { String planetName = zone->getZoneName(); LuaObject obj = lua->getGlobalObject(planetName + "_static_spawns"); if (!obj.isValidTable()) { obj.pop(); return; } int count = 0; int max = obj.getTableSize(); for (int i = 1; i <= obj.getTableSize(); ++i) { lua_rawgeti(obj.getLuaState(), -1, i); LuaObject spawn(obj.getLuaState()); if (spawn.isValidTable()) { CreatureManager* creatureManager = zone->getCreatureManager(); String name = obj.getStringAt(1); uint32 respawn = obj.getIntAt(2); float x = obj.getFloatAt(3); float z = obj.getFloatAt(4); float y = obj.getFloatAt(5); float heading = obj.getFloatAt(6); uint64 parentID = obj.getLongAt(7); String moodString; UnicodeString customName; String aiString; int junkDealerBuyingType =0; int junkDealerConversationType =0; if (obj.getTableSize() > 7) moodString = obj.getStringAt(8); if (obj.getTableSize() > 8) customName = obj.getStringAt(9); if (obj.getTableSize() > 9) aiString = obj.getStringAt(10); if (obj.getTableSize() > 10) junkDealerBuyingType = obj.getIntAt(11); if (obj.getTableSize() > 11) junkDealerConversationType = obj.getIntAt(12); if (parentID == 0) z = zone->getHeight(x, y); ManagedReference<CreatureObject*> creatureObject = creatureManager->spawnCreature(name.hashCode(), 0, x, z, y, parentID); if (creatureObject != NULL) { Locker objLocker(creatureObject); creatureObject->setDirection(Math::deg2rad(heading)); if (creatureObject->isJunkDealer()){ cast<JunkdealerCreature*>(creatureObject.get())->setJunkDealerConversationType(junkDealerConversationType); cast<JunkdealerCreature*>(creatureObject.get())->setJunkDealerBuyerType(junkDealerBuyingType); } if (!moodString.isEmpty()) { creatureObject->setMoodString(moodString); //TODO: remove after fixing commoners if (moodString == "conversation" || moodString == "calm") { creatureObject->setPvpStatusBitmask(0); creatureObject->setCloseObjects(NULL); } } if (!customName.isEmpty()) creatureObject->setCustomObjectName(customName, true); if (creatureObject->isAiAgent()) { AiAgent* ai = cast<AiAgent*>( creatureObject.get()); ai->setRespawnTimer(respawn); if (!aiString.isEmpty()) { ai->activateLoad(aiString); } } if (name.contains("trainer_")) { Vector3 coords(creatureObject.get()->getWorldPositionX(), creatureObject.get()->getWorldPositionY(), 0); trainerObjects.add(coords); } } else { StringBuffer msg; msg << "could not spawn mobile: " + name; error(msg.toString()); } } spawn.pop(); if (ConfigManager::instance()->isProgressMonitorActivated()) printf("\r\tLoading static spawns: [%d] / [%d]\t", ++count, max); } obj.pop(); //--{"mobile", x, z, y, degrees heading, parentID} //spawnCreature(uint32 templateCRC, uint32 objectCRC, float x, float z, float y, uint64 parentID) }