void PetControlDeviceImplementation::callObject(CreatureObject* player) { if (player->isInCombat() || player->isDead() || player->isIncapacitated() || player->getPendingTask("tame_pet") != NULL) { player->sendSystemMessage("@pet/pet_menu:cant_call"); // You cannot call this pet right now. return; } if (player->isRidingMount()) { player->sendSystemMessage("@pet/pet_menu:mounted_call_warning"); // You cannot call a pet while mounted or riding a vehicle. return; } if (player->getParent() != NULL) { ManagedReference<SceneObject*> strongRef = player->getRootParent().get(); ManagedReference<BuildingObject*> building = NULL; if (strongRef != NULL) building = strongRef.castTo<BuildingObject*>(); if (building == NULL || building->isPrivateStructure()) { player->sendSystemMessage("@pet/pet_menu:private_house"); // You cannot call pets in a private building. return; } } if (!isASubChildOf(player)) return; ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get(); if (controlledObject == NULL || !controlledObject->isAiAgent()) return; ManagedReference<AiAgent*> pet = cast<AiAgent*>(controlledObject.get()); ManagedReference<PlayerObject*> ghost = player->getPlayerObject(); if (ghost->hasActivePet(pet)) return; if (vitality <= 0) { player->sendSystemMessage("@pet/pet_menu:dead_pet"); // This pet is dead. Select DESTROY from the radial menu to delete this pet control device. return; } if (!pet->getCooldownTimerMap()->isPast("call_cooldown")) { if (petType == PetManager::DROIDPET) player->sendSystemMessage("@pet/droid_modules:droid_maint_on_maint_run"); //You cannot call that droid. It is currently on a maintenance run. else player->sendSystemMessage("@pet/pet_menu:cant_call"); // cant call pet right now return; } assert(pet->isLockedByCurrentThread()); unsigned int petFaction = pet->getFaction(); if (petFaction != 0) { if (player->getFaction() == 0) { StringIdChatParameter message("@faction_perk:prose_be_declared"); // You must be declared to a faction to use %TT. message.setTT(pet->getDisplayedName()); player->sendSystemMessage(message); return; } if (player->getFaction() != petFaction || ghost->getFactionStatus() == FactionStatus::ONLEAVE) { StringIdChatParameter message("@faction_perk:prose_be_declared_faction"); // You must be a declared %TO to use %TT. message.setTO(pet->getFactionString()); message.setTT(pet->getDisplayedName()); player->sendSystemMessage(message); return; } } if(player->getPendingTask("call_pet") != NULL) { StringIdChatParameter waitTime("pet/pet_menu", "call_delay_finish_pet"); // Already calling a Pet: Call will be finished in %DI seconds. Time nextExecution; Core::getTaskManager()->getNextExecutionTime(player->getPendingTask("call_pet"), nextExecution); int timeLeft = (nextExecution.getMiliTime() / 1000) - System::getTime(); waitTime.setDI(timeLeft); player->sendSystemMessage(waitTime); return; } if (!growPet(player)) return; if (petType == PetManager::CREATUREPET && !isValidPet(pet)) { ManagedReference<SuiMessageBox*> box = new SuiMessageBox(player,SuiWindowType::PET_FIX_DIALOG); box->setCallback(new PetFixSuiCallback(player->getZoneServer(), _this.getReferenceUnsafeStaticCast())); box->setPromptText("@bio_engineer:pet_sui_text"); box->setPromptTitle("@bio_engineer:pet_sui_title"); box->setOkButton(true,"@bio_engineer:pet_sui_fix_stats"); box->setCancelButton(true,"@bio_engineer:pet_sui_abort"); box->setOtherButton(true,"@bio_engineer:pet_sui_fix_level"); box->setUsingObject(_this.getReferenceUnsafeStaticCast()); player->getPlayerObject()->addSuiBox(box); player->sendMessage(box->generateMessage()); return; } int currentlySpawned = 0; int spawnedLevel = 0; int maxPets = 1; int maxLevelofPets = 10; int level = pet->getLevel(); if (petType == PetManager::CREATUREPET) { ManagedReference<Creature*> creaturePet = cast<Creature*>(pet.get()); if (creaturePet == NULL) return; bool ch = player->hasSkill("outdoors_creaturehandler_novice"); if (ch) { maxPets = player->getSkillMod("keep_creature"); maxLevelofPets = player->getSkillMod("tame_level"); } if (creaturePet->getAdultLevel() > maxLevelofPets) { player->sendSystemMessage("@pet/pet_menu:control_exceeded"); // Calling this pet would exceed your Control Level ability. return; } if (creaturePet->isVicious() && (player->getSkillMod("tame_aggro") <= 0 || !ch)) { player->sendSystemMessage("@pet/pet_menu:lack_skill"); // You lack the skill to call a pet of this type. return; } } else if (petType == PetManager::FACTIONPET){ maxPets = 3; } for (int i = 0; i < ghost->getActivePetsSize(); ++i) { ManagedReference<AiAgent*> object = ghost->getActivePet(i); if (object != NULL) { if (object->isCreature() && petType == PetManager::CREATUREPET) { ManagedReference<CreatureTemplate*> activePetTemplate = object->getCreatureTemplate(); if (activePetTemplate == NULL || activePetTemplate->getTemplateName() == "at_st") continue; if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } spawnedLevel += object->getLevel(); if ((spawnedLevel + level) > maxLevelofPets) { player->sendSystemMessage("@pet/pet_menu:control_exceeded"); // Calling this pet would exceed your Control Level ability. return; } } else if (object->isNonPlayerCreatureObject() && petType == PetManager::FACTIONPET) { if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } } else if (object->isCreature() && petType == PetManager::FACTIONPET) { ManagedReference<CreatureTemplate*> activePetTemplate = object->getCreatureTemplate(); ManagedReference<CreatureTemplate*> callingPetTemplate = pet->getCreatureTemplate(); if (activePetTemplate == NULL || callingPetTemplate == NULL || activePetTemplate->getTemplateName() != "at_st") continue; if (++currentlySpawned >= maxPets || (activePetTemplate->getTemplateName() == "at_st" && callingPetTemplate->getTemplateName() == "at_st")) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } } else if (object->isDroidObject() && petType == PetManager::DROIDPET) { if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } } } } ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>(); if (tradeContainer != NULL) { server->getZoneServer()->getPlayerManager()->handleAbortTradeMessage(player); } if(player->getCurrentCamp() == NULL && player->getCityRegion() == NULL) { Reference<CallPetTask*> callPet = new CallPetTask(_this.getReferenceUnsafeStaticCast(), player, "call_pet"); StringIdChatParameter message("pet/pet_menu", "call_pet_delay"); // Calling pet in %DI seconds. Combat will terminate pet call. message.setDI(15); player->sendSystemMessage(message); player->addPendingTask("call_pet", callPet, 15 * 1000); if (petControlObserver == NULL) { petControlObserver = new PetControlObserver(_this.getReferenceUnsafeStaticCast()); petControlObserver->deploy(); } player->registerObserver(ObserverEventType::STARTCOMBAT, petControlObserver); } else { // Player is in a city or camp, spawn pet immediately if( player->getCooldownTimerMap() == NULL ) return; // Check cooldown if( !player->getCooldownTimerMap()->isPast("petCallOrStoreCooldown") ){ player->sendSystemMessage("@pet/pet_menu:cant_call_1sec"); //"You cannot CALL for 1 second." return; } spawnObject(player); // Set cooldown player->getCooldownTimerMap()->updateToCurrentAndAddMili("petCallOrStoreCooldown", 1000); // 1 sec } EnqueuePetCommand* enqueueCommand = new EnqueuePetCommand(pet, String("petFollow").toLowerCase().hashCode(), String::valueOf(player->getObjectID()), player->getObjectID(), 1); enqueueCommand->execute(); }
void PetControlDeviceImplementation::callObject(CreatureObject* player) { if (player->isInCombat() || player->isDead() || player->isIncapacitated() || player->getPendingTask("tame_pet") != NULL) { player->sendSystemMessage("@pet/pet_menu:cant_call"); // You cannot call this pet right now. return; } if (player->isRidingMount()) { player->sendSystemMessage("@pet/pet_menu:mounted_call_warning"); // You cannot call a pet while mounted or riding a vehicle. return; } if (player->getParent() != NULL) { ManagedReference<SceneObject*> strongRef = player->getParentRecursively(SceneObjectType::BUILDING); ManagedReference<BuildingObject*> building; if (strongRef != NULL) building = strongRef.castTo<BuildingObject*>(); if (building == NULL || building->isPrivateStructure()) { player->sendSystemMessage("@pet/pet_menu:private_house"); // You cannot call pets in a private building. return; } } if (!isASubChildOf(player)) return; ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get(); if (controlledObject == NULL || !controlledObject->isAiAgent()) return; ManagedReference<AiAgent*> pet = cast<AiAgent*>(controlledObject.get()); ManagedReference<PlayerObject*> ghost = player->getPlayerObject(); if (ghost->hasActivePet(pet)) return; if (vitality <= 0) { player->sendSystemMessage("@pet/pet_menu:dead_pet"); // This pet is dead. Select DESTROY from the radial menu to delete this pet control device. return; } unsigned int petFaction = pet->getFaction(); if (petFaction != 0) { if (player->getFaction() == 0) { StringIdChatParameter message("@faction_perk:prose_be_declared"); // You must be declared to a faction to use %TT. message.setTT(pet->getDisplayedName()); player->sendSystemMessage(message); return; } if (player->getFaction() != petFaction || ghost->getFactionStatus() == FactionStatus::ONLEAVE) { StringIdChatParameter message("@faction_perk:prose_be_declared_faction"); // You must be a declared %TO to use %TT. message.setTO(pet->getFactionString()); message.setTT(pet->getDisplayedName()); player->sendSystemMessage(message); return; } } if(player->getPendingTask("call_pet") != NULL) { StringIdChatParameter waitTime("pet/pet_menu", "call_delay_finish_pet"); // Already calling a Pet: Call will be finished in %DI seconds. Time nextExecution; Core::getTaskManager()->getNextExecutionTime(player->getPendingTask("call_pet"), nextExecution); int timeLeft = (nextExecution.getMiliTime() / 1000) - System::getTime(); waitTime.setDI(timeLeft); player->sendSystemMessage(waitTime); return; } if (!growPet(player)) return; int currentlySpawned = 0; int spawnedLevel = 0; int maxPets = 1; int maxLevelofPets = 10; int level = pet->getLevel(); if (petType == PetManager::CREATUREPET) { bool ch = player->hasSkill("outdoors_creaturehandler_novice"); if (ch) { maxPets = player->getSkillMod("keep_creature"); maxLevelofPets = player->getSkillMod("tame_level"); } if (level > maxLevelofPets) { player->sendSystemMessage("@pet/pet_menu:control_exceeded"); // Calling this pet would exceed your Control Level ability. return; } ManagedReference<Creature*> creaturePet = cast<Creature*>(pet.get()); if (creaturePet != NULL && creaturePet->isVicious() && (player->getSkillMod("tame_aggro") <= 0 || !ch)) { player->sendSystemMessage("@pet/pet_menu:lack_skill"); // You lack the skill to call a pet of this type. return; } } else if (petType == PetManager::FACTIONPET){ maxPets = 3; } for (int i = 0; i < ghost->getActivePetsSize(); ++i) { ManagedReference<AiAgent*> object = ghost->getActivePet(i); if (object != NULL) { if (object->isCreature() && petType == PetManager::CREATUREPET) { if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } spawnedLevel += object->getLevel(); if ((spawnedLevel + level) > maxLevelofPets) { player->sendSystemMessage("@pet/pet_menu:control_exceeded"); // Calling this pet would exceed your Control Level ability. return; } } else if (object->isNonPlayerCreatureObject() && petType == PetManager::FACTIONPET) { if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } } else if (object->isDroidObject() && petType == PetManager::DROIDPET) { if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } } } } ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>(); if (tradeContainer != NULL) { server->getZoneServer()->getPlayerManager()->handleAbortTradeMessage(player); } if(player->getCurrentCamp() == NULL && player->getCityRegion() == NULL) { Reference<CallPetTask*> callPet = new CallPetTask(_this.get(), player, "call_pet"); StringIdChatParameter message("pet/pet_menu", "call_pet_delay"); // Calling pet in %DI seconds. Combat will terminate pet call. message.setDI(15); player->sendSystemMessage(message); player->addPendingTask("call_pet", callPet, 15 * 1000); if (petControlObserver == NULL) { petControlObserver = new PetControlObserver(_this.get()); petControlObserver->deploy(); } player->registerObserver(ObserverEventType::STARTCOMBAT, petControlObserver); } else { // Player is in a city or camp, spawn pet immediately if( player->getCooldownTimerMap() == NULL ) return; // Check cooldown if( !player->getCooldownTimerMap()->isPast("petCallOrStoreCooldown") ){ player->sendSystemMessage("@pet/pet_menu:cant_call_1sec"); //"You cannot CALL for 1 second." return; } Locker clocker(controlledObject, player); spawnObject(player); // Set cooldown player->getCooldownTimerMap()->updateToCurrentAndAddMili("petCallOrStoreCooldown", 1000); // 1 sec } }