void PetControlDeviceImplementation::storeObject(CreatureObject* player, bool force) {
	ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();

	if (controlledObject == NULL || !controlledObject->isAiAgent())
		return;

	ManagedReference<AiAgent*> pet = cast<AiAgent*>(controlledObject.get());

	assert(pet->isLockedByCurrentThread());

	if (!force && (pet->isInCombat() || player->isInCombat()))
		return;

	if (player->isRidingMount() && player->getParent() == pet) {

		if (!force && !player->checkCooldownRecovery("mount_dismount"))
			return;

		player->executeObjectControllerAction(STRING_HASHCODE("dismount"));

		if (player->isRidingMount())
			return;
	}

	if( player->getCooldownTimerMap() == NULL )
		return;

	// Check cooldown
	if( !player->getCooldownTimerMap()->isPast("petCallOrStoreCooldown") && !force ){
		player->sendSystemMessage("@pet/pet_menu:cant_store_1sec"); //"You cannot STORE for 1 second."
		return;
	}

	// Not training any commands
	trainingCommand = 0;

	Reference<StorePetTask*> task = new StorePetTask(player, pet);

	// Store non-faction pets immediately.  Store faction pets after 60sec delay.
	if( petType != PetManager::FACTIONPET || force || player->getPlayerObject()->isPrivileged()){
		task->execute();
	}
	else{
		if(pet->getPendingTask("store_pet") == NULL) {
			player->sendSystemMessage( "Storing pet in 60 seconds");
			pet->addPendingTask("store_pet", task, 60 * 1000);
		}
		else{
			Time nextExecution;
			Core::getTaskManager()->getNextExecutionTime(pet->getPendingTask("store_pet"), nextExecution);
			int timeLeft = (nextExecution.getMiliTime() / 1000) - System::getTime();
			player->sendSystemMessage( "Pet will store in " + String::valueOf(timeLeft) + " seconds." );
			return;
		}

	}

	// Set cooldown
	player->getCooldownTimerMap()->updateToCurrentAndAddMili("petCallOrStoreCooldown", 1000); // 1 sec
}
void DroidHarvestModuleDataComponent::onCall(){
	deactivate();
	ManagedReference<DroidObject*> droid = getDroidObject();
	if( droid == NULL ){
		info( "Droid is null");
		return;
	}
	if (observer == NULL) {
		observer = new DroidHarvestObserver(this);
		observer->deploy();
	}
	Locker dlock( droid );
	// add observer for the droid
	//droid->registerObserver(ObserverEventType::DESTINATIONREACHED, observer);
	Reference<Task*> task = new DroidHarvestTask( this );
	droid->addPendingTask("droid_harvest", task, 1000); // 1 sec
}
int DroidDetonationModuleDataComponent::handleObjectMenuSelect(CreatureObject* player, byte selectedID, PetControlDevice* controller) {

	if (selectedID == DETONATE_DROID) {
		ManagedReference<DroidObject*> droid = getDroidObject();
		if (droid == NULL) {
			info("Droid is null");
			return 0;
		}

		Locker dlock(droid, player);

		if (droid->isDead()) {
			player->sendSystemMessage("@pet/droid_modules:droid_bomb_failed");
			return 0;
		}

		// Droid must have power
		if (!droid->hasPower()) {
			droid->showFlyText("npc_reaction/flytext","low_power", 204, 0, 0);  // "*Low Power*"
			return 0;
		}

		// if the droid is already in detonation countdown we need to ignore this command
		if (droid->getPendingTask("droid_detonation") != NULL) {
			if (countdownInProgress())
				player->sendSystemMessage("@pet/droid_modules:countdown_already_started");
			else
				player->sendSystemMessage("@pet/droid_modules:detonation_warmup");
			return 0;
		}

		// droid has power and is not dead we can fire off the task
		Reference<Task*> task = new DroidDetonationTask(this, player);
		droid->addPendingTask("droid_detonation", task, 0); // queue the task for the droid to occur in 0 MS the task will handle init phase
	}

	return 0;
}
int DroidStimpackModuleDataComponent::handleObjectMenuSelect(CreatureObject* player, byte selectedID, PetControlDevice* controller) {
	ManagedReference<DroidObject*> droid = getDroidObject();
	DroidComponent* droidComponent = cast<DroidComponent*>(getParent());
	if (droid == NULL || droidComponent == NULL) {
		player->sendSystemMessage("@pet/droid_modules:stimpack_error");
		return 0;
	}
	
	if (selectedID == LOAD_STIMPACK) {
		Locker crossLoker(droid, player);
		
		ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");
		if (inventory == NULL) {
			player->sendSystemMessage("@pet/droid_modules:no_stimpacks");
			return 0;
		}

		int foundStims = 0;

		for (int i = 0; i < inventory->getContainerObjectsSize(); ++i) {
			ManagedReference<SceneObject*> item = inventory->getContainerObject(i);

			if (!item->isPharmaceuticalObject())
				continue;

			// check it they have atleast 1 stim pack
			PharmaceuticalObject* pharma = item.castTo<PharmaceuticalObject*>();

			if (pharma->isStimPack()) {
				StimPack* stim = cast<StimPack*>(pharma);

				if (stim->isClassA()) {
					foundStims += 1;
				}
			}
		}

		if (foundStims == 0) {
			player->sendSystemMessage("@pet/droid_modules:no_stimpacks");
			return 0;
		} else {
			sendLoadUI(player);
			return 0;
		}

	} else if (selectedID == REQUEST_STIMPACK) {
		// we need to check cooldown on droid
		if (droid->isDead() || droid->isIncapacitated() || player->isDead()) {
			return 0;
		}

		// Droid must have power
		if (!droid->hasPower()) {
			droid->showFlyText("npc_reaction/flytext","low_power", 204, 0, 0);  // "*Low Power*"
			return 0;
		}

		if (droid->getPendingTask("droid_request_stimpack") != NULL) {
			player->sendSystemMessage("@pet/droid_modules:stimpack_not_ready");
			return 0;
		}

		// Submit stimpack task
		Reference<Task*> task = new DroidStimpackTask( droid,player,controller->getCustomObjectName().toString() );
		droid->addPendingTask("droid_request_stimpack", task, 1); // rte determines when it will fire it
	}

	return 0;
}