void PetControlDeviceImplementation::setTrainingCommand( unsigned int commandID ){

	// we set to 0 to flag completion so skip all this then.
	if (commandID == 0) {
		trainingCommand = 0;
		return;
	}

	ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();
	if (controlledObject == NULL || !controlledObject->isAiAgent())
		return;

	AiAgent* pet = cast<AiAgent*>(controlledObject.get());
	if( pet == NULL )
		return;

	ManagedReference<CreatureObject*> owner = pet->getLinkedCreature().get();
	if (owner == NULL || !owner->isPlayerCreature())
		return;

	if( petType == PetManager::DROIDPET) {
		ManagedReference<DroidObject*> droid = this->controlledObject.get().castTo<DroidObject*>();
		if (droid == NULL)
			return;

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

		if(((commandID == PetManager::ATTACK || commandID == PetManager::GUARD) && !droid->isCombatDroid()) ||
			(commandID == PetManager::RANGED_ATTACK && (!droid->isCombatDroid() || !droid->hasRangedWeapon())) ||
			(commandID == PetManager::RECHARGEOTHER && !droid->isPowerDroid()) ||
			(commandID == PetManager::TRANSFER) ||
			(commandID == PetManager::SPECIAL_ATTACK1) ||
			(commandID == PetManager::SPECIAL_ATTACK2) ||
			(commandID == PetManager::TRICK1) ||
			(commandID == PetManager::TRICK2)){
			return;
		}
	}
	else if(petType == PetManager::CREATUREPET){
		if(((commandID == PetManager::ATTACK || commandID == PetManager::FOLLOW || commandID == PetManager::STORE) && !owner->hasSkill("outdoors_creaturehandler_novice") ) ||
			(commandID == PetManager::STAY && !owner->hasSkill("outdoors_creaturehandler_training_01")) ||
			(commandID == PetManager::GUARD && !owner->hasSkill("outdoors_creaturehandler_training_02")) ||
			(commandID == PetManager::FRIEND && !owner->hasSkill("outdoors_creaturehandler_support_03")) ||
			((commandID == PetManager::PATROL || commandID == PetManager::GETPATROLPOINT || commandID == PetManager::CLEARPATROLPOINTS) && !owner->hasSkill("outdoors_creaturehandler_training_03")) ||
			((commandID == PetManager::FORMATION1 || commandID == PetManager::FORMATION2) && !owner->hasSkill("outdoors_creaturehandler_training_04")) ||
			(commandID == PetManager::TRANSFER && !owner->hasSkill("outdoors_creaturehandler_master")) ||
			(commandID == PetManager::TRICK1 && !owner->hasSkill("outdoors_creaturehandler_healing_01")) ||
			(commandID == PetManager::TRICK2 && !owner->hasSkill("outdoors_creaturehandler_healing_03")) ||
			(commandID == PetManager::GROUP && !owner->hasSkill("outdoors_creaturehandler_support_01")) ||
			(commandID == PetManager::SPECIAL_ATTACK1 && (!owner->hasSkill("outdoors_creaturehandler_taming_03") || !pet->hasSpecialAttack(1))) ||
			(commandID == PetManager::SPECIAL_ATTACK2 && (!owner->hasSkill("outdoors_creaturehandler_taming_04") || !pet->hasSpecialAttack(2))) ||
			(commandID == PetManager::RANGED_ATTACK && (!owner->hasSkill("outdoors_creaturehandler_master") || !pet->hasRangedWeapon())) ||
			(commandID == PetManager::FOLLOWOTHER && !owner->hasSkill("outdoors_creaturehandler_support_02")) ||
			(commandID == PetManager::RECHARGEOTHER))
				return;
	}
	else if(petType == PetManager::FACTIONPET){
		if(commandID == PetManager::RECHARGEOTHER ||
			(commandID == PetManager::TRANSFER) ||
			(commandID == PetManager::SPECIAL_ATTACK1) ||
			(commandID == PetManager::SPECIAL_ATTACK2) ||
			(commandID == PetManager::TRICK1) ||
			(commandID == PetManager::TRICK2))
				return;
	}

	/** Check for converse and if so, get its personalityStf**/
	if (pet->getOptionsBitmask() & OptionBitmask::CONVERSE) {
		String stf = pet->getPersonalityStf();
		StringBuffer message;
		message << stf << ":start_convo_4";
		StringIdChatParameter chat;
		chat.setStringId(message.toString());
		pet->getZoneServer()->getChatManager()->broadcastMessage(pet,chat,0,0,0);
	} else {
		pet->showFlyText("npc_reaction/flytext","alert", 204, 0, 0);  // "?"
	}
	trainingCommand = commandID;
}
void CraftingSessionImplementation::addWeaponDots() {
	ManagedReference<TangibleObject*> prototype = this->prototype.get();

	if (!(prototype->isWeaponObject()))
		return;

	ManagedReference<WeaponObject*> weapon = cast<WeaponObject*>(prototype.get());

	ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get();
	ManagedReference<DraftSchematic*> draftSchematic = manufactureSchematic->getDraftSchematic();

	Vector<VectorMap<String, int> >* weaponDots = draftSchematic->getDraftSchematicTemplate()->getWeaponDots();

	for (int i = 0; i < weaponDots->size(); i++) {
		VectorMap<String, int> dot = weaponDots->elementAt(i);

		for (int j = 0; j < dot.size(); j++) {
			String property = dot.elementAt(j).getKey();
			int value = dot.elementAt(j).getValue();

			if (property == "type")
				weapon->addDotType(value);
			else if (property == "attribute")
				weapon->addDotAttribute(value);
			else if (property == "strength")
				weapon->addDotStrength(value);
			else if (property == "duration")
				weapon->addDotDuration(value);
			else if (property == "potency")
				weapon->addDotPotency(value);
			else if (property == "uses")
				weapon->addDotUses(value);

		}
	}
}
void CraftingSessionImplementation::selectDraftSchematic(int index) {
	ManagedReference<CreatureObject*> crafter = this->crafter.get();
	ManagedReference<PlayerObject*> crafterGhost = this->crafterGhost.get();
	ManagedReference<CraftingTool*> craftingTool = this->craftingTool.get();

	if (index >= currentSchematicList.size()) {
		crafter->sendSystemMessage("Invalid Schematic Index");
		closeCraftingWindow(1);
		cancelSession();
		return;
	}

	DraftSchematic* draftschematic = currentSchematicList.get(index);

	if (draftschematic == NULL) {
		crafter->sendSystemMessage("@ui_craft:err_no_draft_schematic");
		closeCraftingWindow(1);
		cancelSession();
		return;
	}

	clearSession();

	Locker slocker(_this.get());

	if(crafterGhost != NULL && crafterGhost->getDebug()) {
		crafter->sendSystemMessage("Selected DraftSchematic: " + draftschematic->getCustomName());
	}

	state = 2;

	if (craftingTool != NULL) {
		Locker locker(craftingTool);

		if (createSessionObjects(draftschematic)) {

			if (prototype == NULL) {
				crafter->sendSystemMessage("@ui_craft:err_no_prototype");
				closeCraftingWindow(1);
				cancelSession();
				return;
			}

			// Dplay9 ********************************************************
			// Sets the Crafting state to 2, which is the Resource screen
			PlayerObjectDeltaMessage9* dplay9 = new PlayerObjectDeltaMessage9(
					crafter->getPlayerObject());
			dplay9->setExperimentationPoints(0xFFFFFFFF);
			dplay9->setCraftingState(2);
			dplay9->close();

			crafter->sendMessage(dplay9);
			// End Dplay9 *****************************************************

		} else {
			crafter->sendSystemMessage("This type of object has not yet been implemented");
		}
	} else {
		crafter->sendSystemMessage("@ui_craft:err_no_crafting_tool");
		closeCraftingWindow(1);
		cancelSession();
	}
}
Example #4
0
void PermissionsServlet::handlePost(HttpRequest* request, HttpResponse* response) {
	PlayerManager* playerManager = server->getPlayerManager();
	bool applyToAll = false;
	String accountName = request->getParameter("accountName");
	String levelName = request->getParameter("level");
	int level = PermissionLevelList::instance()->getLevelNumber(levelName);

	if(request->getParameter("applyToAll") == "true")
		applyToAll = true;

	ManagedReference<Account*> account = AccountManager::getAccount(accountName);
	if(account == NULL) {
		response->println("HTTP/1.1 200 OK\r\n");
		response->println("Content-Type: text/html\r\n\r\n");
		response->println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN " "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
		response->println("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
		response->println("	<head>");
		response->println("		<title>SWGEmu Web Server Login</title>");
		response->println("		<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />");
		response->println("		<link rel=\"stylesheet\" type=\"text/css\" href=\"css/style.css\" />");
		response->println("	</head>");
		response->println("	<body>");
		response->println("		<div class=\"login_box\">");
		response->println("			<h1>Account doesn't exist.</h1>");
		response->println("			<a href=\"permissions\"> Click here to return </a>");
		response->println("		</div>");
		response->println("	</body>");
		response->println("</html>");
	}

	Locker locker(account);
	account->setAdminLevel(level);
	locker.release();

	if(applyToAll == true) {
		Reference<CharacterList*> characterList = account->getCharacterList();
		for(int i = 0; i < characterList->size(); ++i) {
			ManagedReference<CreatureObject* > targetCreature = NULL;
			CharacterListEntry* entry = &characterList->get(i);

			targetCreature = playerManager->getPlayer(entry->getFirstName());
			playerManager->updatePermissionLevel(targetCreature, level);
		}
	}

	response->println("HTTP/1.1 200 OK\r\n");
	response->println("Content-Type: text/html\r\n\r\n");
	response->println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN " "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
	response->println("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
	response->println("	<head>");
	response->println("		<title>SWGEmu Web Server Login</title>");
	response->println("		<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />");
	response->println("		<link rel=\"stylesheet\" type=\"text/css\" href=\"css/style.css\" />");
	response->println("	</head>");
	response->println("	<body>");
	response->println("		<div class=\"login_box\">");
	response->println("			<h1>Account updated.</h1>");
	response->println("			<a href=\"permissions\"> Click here to return </a>");
	response->println("		</div>");
	response->println("	</body>");
	response->println("</html>");
}
bool PetManagerImplementation::handleCommandTraining(CreatureObject* speaker, AiAgent* pet, const String& message){

	if( speaker == NULL || pet == NULL )
		return false;

	if( message.isEmpty() )
		return false;

	ManagedWeakReference< CreatureObject*> linkedCreature = pet->getLinkedCreature();
	if( linkedCreature == NULL )
		return false;

	// Only owner may train
	if( linkedCreature != speaker)
		return false;

	ManagedReference<PetControlDevice*> pcd = pet->getControlDevice().get().castTo<PetControlDevice*>();

	if( pcd == NULL )
		return false;

	if( pcd->hasTrainedCommandString(message) ){
		pet->showFlyText("npc_reaction/flytext","confused", 204, 0, 0);  // "?!!?!?!"
		return true;
	}

	unsigned int trainingCommand = pcd->getTrainingCommand();
	int petType = pcd->getPetType();

	// Train command
	if (petType == CREATUREPET) {
		bool alreadyTrained = pcd->hasTrainedCommand(trainingCommand);

		if (!alreadyTrained) {
			bool success = false;

			int skill = speaker->getSkillMod("tame_level");
			int roll = System::random(skill + 30);

			if (skill > roll)
				success = true;

			if (!success) {
				pet->showFlyText("npc_reaction/flytext","confused", 204, 0, 0);  // "?!!?!?!"
				speaker->sendSystemMessage("@pet/pet_menu:pet_nolearn"); // Your pet doesn't seem to understand you.
				return true;
			}
		}

		// Success
		pcd->addTrainedCommand( trainingCommand, message );
		pet->showFlyText("npc_reaction/flytext","threaten", 204, 0, 0);  // "!"
		speaker->sendSystemMessage("@pet/pet_menu:pet_learn"); // You teach your pet a new command.

		if (!alreadyTrained) {
			CreatureTemplate* creatureTemplate = pet->getCreatureTemplate();

			if (creatureTemplate == NULL)
				return true;

			PlayerManager* playerManager = zoneServer->getPlayerManager();
			playerManager->awardExperience(speaker, "creaturehandler", 10 * creatureTemplate->getLevel());
		}
	}
	else{
		pcd->addTrainedCommand( trainingCommand, message );
		pet->showFlyText("npc_reaction/flytext","threaten", 204, 0, 0);  // "!"
		speaker->sendSystemMessage("@pet/pet_menu:pet_learn"); // You teach your pet a new command.
	}

	// No renaming of faction pets
	if (petType == FACTIONPET)
		return true;

	// Check for naming string
	StringTokenizer tokenizer(message);
	tokenizer.setDelimeter(" ");
	String parsedName = "";
	int numberOfSubStrings = 0;

	while (tokenizer.hasMoreTokens()) {
		numberOfSubStrings++;

		if (!parsedName.isEmpty())
			break;

		tokenizer.getStringToken(parsedName);
	}

	String futureName = pcd->getFutureName();
	unsigned int namingProgress = pcd->getNamingProgress();

	// Validate and check name
	if (numberOfSubStrings > 1) {
		ZoneProcessServer* zps = pet->getZoneProcessServer();
		NameManager* nameManager = zps->getNameManager();

		if (nameManager->validateName(parsedName) != NameManagerResult::ACCEPTED) {
			return true;
		}
		if (futureName == parsedName  && !pcd->hasUsedNamingCommand(trainingCommand)) {
			pcd->incrementNamingProgress(trainingCommand);
		}
		else {
			pcd->resetNamingProgress();
			pcd->incrementNamingProgress(trainingCommand);
			pcd->setFutureName(parsedName);
			return true;
		}
	} else {
		pcd->resetNamingProgress();
		parsedName = "";
		pcd->setFutureName(parsedName);
		return true;
	}

	// Set name, if applicable
	if (pcd->getNamingProgress() == 4) {
		UnicodeString newName = "(" + futureName + ")";
		pcd->setCustomObjectName(newName, true);
		pet->setCustomObjectName(newName, true);
		pcd->resetNamingProgress();
	}

	return true;
}
int DroidHarvestModuleDataComponent::handleObjectMenuSelect(CreatureObject* player, byte selectedID, PetControlDevice* controller) {

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

		if( !droid->hasPower() ){
			player->sendSystemMessage("@pet/droid_modules:playback_msg_play_out_of_power");
			return 0;
		}

		// popup a ui to choose the correct interest.
		ManagedReference<SuiListBox*> box = new SuiListBox(player, SuiWindowType::DROID_SET_INTEREST, SuiListBox::HANDLETWOBUTTON);
		box->setCallback(new SelectHarvestSuiCallback(player->getZoneServer()));
		box->setPromptText("@pet/droid_modules:set_interest_d");
		box->setPromptTitle("@pet/droid_modules:set_interest_d");
		box->setOkButton(true,"@ok");
		box->setCancelButton(true, "@cancel");
		// Add tracks
		box->addMenuItem("@pet/droid_modules:set_interest_random",INTREST_RANDOM);
		box->addMenuItem("@pet/droid_modules:set_interest_bone",INTREST_BONE);
		box->addMenuItem("@pet/droid_modules:set_interest_meat",INTREST_MEAT);
		box->addMenuItem("@pet/droid_modules:set_interest_hide",INTREST_HIDE);
		box->setUsingObject(droid);
		player->getPlayerObject()->addSuiBox(box);
		player->sendMessage(box->generateMessage());
		return 0;
	}
	// Handle toggle on/off
	if (selectedID == HARVEST_PROGRAM_COMMAND) {
		if( controller == NULL )
			return 0;
		controller->setTrainingCommand( PetManager::HARVEST );
		return 0;
	}
	if( selectedID == HARVEST_TOGGLE ){

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

		Locker dlock( droid, player );

		// Toggle off
		if (active){
			deactivate();
			player->sendSystemMessage("@pet/droid_modules:auto_harvest_off");  // You turn off auto-repair
		}
		else{ // Toggle on

			// Check droid states
			if( droid->isDead() || droid->isIncapacitated())
				return 0;

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

			// Ensure we don't accidentally have another task outstanding
			deactivate();
			player->sendSystemMessage("@pet/droid_modules:auto_harvest_on");  // You turn on auto-repair
			if (observer == NULL) {
				observer = new DroidHarvestObserver(this);
				observer->deploy();
			}
			Locker plock(player);
			player->registerObserver(ObserverEventType::KILLEDCREATURE, observer);
			active = true;
		}

	}
	return 0;
}
void SceneObjectImplementation::broadcastMessagePrivate(BasePacket* message, SceneObject* selfObject, bool lockZone) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get());

		if (grandParent != NULL) {
			grandParent->broadcastMessagePrivate(message, selfObject, lockZone);

			return;
		} else {
			delete message;

			return;
		}
	}

	if (zone == NULL) {
		delete message;

		return;
	}

	//Locker zoneLocker(zone);

	//getZone()->rlock(lockZone);

	//	bool readlock = lockZone && !zone->isLockedByCurrentThread();

	SortedVector<ManagedReference<QuadTreeEntry*> >* closeSceneObjects = NULL;
	SortedVector<ManagedReference<QuadTreeEntry*> >* closeNoneReference = NULL;
	int maxInRangeObjectCount = 0;
	bool deleteVector = true;

	try {
		//		zone->rlock(readlock);

		if (closeobjects == NULL) {
			info(String::valueOf(getObjectID()) + " Null closeobjects vector in SceneObjectImplementation::broadcastMessagePrivate", true);
			closeSceneObjects = new SortedVector<ManagedReference<QuadTreeEntry*> >();
			zone->getInRangeObjects(getPositionX(), getPositionY(), 192, closeSceneObjects, true);

			maxInRangeObjectCount = closeSceneObjects->size();
			deleteVector = true;
		} else {
			//			maxInRangeObjectCount = closeobjects->size();
			//closeSceneObjects = closeobjects;

			closeNoneReference = new SortedVector<ManagedReference<QuadTreeEntry*> >(maxInRangeObjectCount, 50);


			/*			for (int i = 0; i < closeobjects->size(); ++i) {
				closeNoneReference->add(closeobjects->get(i).get());
			}
			 */

			closeobjects->safeCopyTo(*closeNoneReference);
			maxInRangeObjectCount = closeNoneReference->size();

			//closeSceneObjects.removeAll(maxInRangeObjectCount, 10);
			//closeSceneObjects.addAll(*closeobjects);
		}
		/*
		for (int i = 0; i < maxInRangeObjectCount; ++i) {
			SceneObject* scno = cast<SceneObject*>(closeSceneObjects->get(i).get());

			if (selfObject == scno)
				continue;

			ManagedReference<ZoneClientSession*> client = scno->getClient();

			if (client != NULL || scno->isVehicleObject()) {
				scno->sendMessage(message->clone());
			}

		}
		 */

		//zone->runlock(readlock);

	} catch (...) {
		//		zone->runlock(readlock);

		delete message;

		throw;

	}

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno;

		if (closeSceneObjects != NULL)
			scno  = cast<SceneObject*>(closeSceneObjects->get(i).get());
		else
			scno = cast<SceneObject*>(closeNoneReference->get(i).get());

		if (selfObject == scno)
			continue;

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if ((dynamic_cast<VehicleObject*>(scno) != NULL) || client != NULL || scno->isMount())
			scno->sendMessage(message->clone());
	}

	delete message;

	if (closeSceneObjects != NULL)
		delete closeSceneObjects;	
	else
		delete closeNoneReference;
}
bool PetControlDeviceImplementation::canBeTradedTo(CreatureObject* player, CreatureObject* receiver, int numberInTrade) {
	ManagedReference<SceneObject*> datapad = receiver->getSlottedObject("datapad");

	if (datapad == NULL)
		return false;

	if (petType == PetManager::FACTIONPET) {
		player->sendSystemMessage("@pet/pet_menu:bad_type"); // You cannot trade a pet of that type. Transfer failed.
		return false;
	} else if (petType == PetManager::DROIDPET) {
		ManagedReference<PlayerManager*> playerManager = player->getZoneServer()->getPlayerManager();

		int droidsInDatapad = numberInTrade;
		int maxStoredDroids = playerManager->getBaseStoredDroids();

		for (int i = 0; i < datapad->getContainerObjectsSize(); i++) {
			Reference<SceneObject*> obj =  datapad->getContainerObject(i).castTo<SceneObject*>();

			if (obj != NULL && obj->isPetControlDevice() ){
				Reference<PetControlDevice*> petDevice = cast<PetControlDevice*>(obj.get());
				if( petDevice != NULL && petDevice->getPetType() == PetManager::DROIDPET){
					droidsInDatapad++;
				}
			}
		}

		if( droidsInDatapad >= maxStoredDroids){
			player->sendSystemMessage("That person has too many droids in their datapad");
			return false;
		}

		return true;

	} else if (petType == PetManager::CREATUREPET) {
		ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();

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

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

		ManagedReference<PlayerManager*> playerManager = player->getZoneServer()->getPlayerManager();

		int numberStored = numberInTrade;
		int maxStoredPets = playerManager->getBaseStoredCreaturePets();
		int maxLevelofPets = 10;
		int level = pet->getAdultLevel();
		bool ch = receiver->hasSkill("outdoors_creaturehandler_novice");

		if (ch) {
			maxStoredPets += receiver->getSkillMod("stored_pets");
			maxLevelofPets = receiver->getSkillMod("tame_level");
		}

		if (level > maxLevelofPets) {
			player->sendSystemMessage("@pet/pet_menu:no_chance"); // That person has no chance of controlling this creature. Transfer failed.
			receiver->sendSystemMessage("@pet/pet_menu:cannot_control"); // You have no chance of controlling that creature.
			return false;
		}

		if (pet->isVicious() && (receiver->getSkillMod("tame_aggro") <= 0 || !ch)) {
			player->sendSystemMessage("@pet/pet_menu:no_chance"); // That person has no chance of controlling this creature. Transfer failed.
			receiver->sendSystemMessage("@pet/pet_menu:cannot_control"); // You have no chance of controlling that creature.
			return false;
		}

		if (numberStored >= maxStoredPets) {
			player->sendSystemMessage("@pet/pet_menu:targ_too_many_stored"); // That person has too many stored pets. Transfer failed.
			receiver->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 false;
		}

		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:targ_too_many_stored"); // That person has too many stored pets. Transfer failed.
						receiver->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 false;
					}

				}
			}
		}

		return true;
	}

	return false;
}
void PetControlDeviceImplementation::fillAttributeList(AttributeListMessage* alm, CreatureObject* object) {
	SceneObjectImplementation::fillAttributeList(alm, object);

	if (petType == PetManager::DROIDPET) {
		alm->insertAttribute("creature_vitality", String::valueOf(vitality) + "/" + String::valueOf(maxVitality));

		ManagedReference<DroidObject*> droid = this->controlledObject.get().castTo<DroidObject*>();

		if (droid != NULL) {
			alm->insertAttribute("challenge_level", droid->getLevel());
			alm->insertAttribute("creature_health", droid->getBaseHAM(0));
			alm->insertAttribute("creature_action", droid->getBaseHAM(3));
			alm->insertAttribute("creature_mind", droid->getBaseHAM(6));

			droid->fillAttributeList(alm, object);
		}
	} else {
		ManagedReference<AiAgent*> pet = cast<AiAgent*>(this->controlledObject.get().get());

		if (pet != NULL) {
			alm->insertAttribute("challenge_level", pet->getLevel());

			if (petType == PetManager::CREATUREPET)
				alm->insertAttribute("creature_vitality", String::valueOf(vitality) + "/" + String::valueOf(maxVitality));

			alm->insertAttribute("creature_health", pet->getBaseHAM(0));
			alm->insertAttribute("creature_action", pet->getBaseHAM(3));
			alm->insertAttribute("creature_mind", pet->getBaseHAM(6));

			int armor = pet->getArmor();
			if (armor == 0)
				alm->insertAttribute("armor_rating", "None");
			else if (armor == 1)
				alm->insertAttribute("armor_rating", "Light");
			else if (armor == 2)
				alm->insertAttribute("armor_rating", "Medium");
			else if (armor == 3)
				alm->insertAttribute("armor_rating", "Heavy");

			if (pet->getKinetic() < 0)
				alm->insertAttribute("dna_comp_armor_kinetic", "Vulnerable");
			else
				alm->insertAttribute("dna_comp_armor_kinetic", pet->getKinetic());

			if (pet->getEnergy() < 0)
				alm->insertAttribute("dna_comp_armor_energy", "Vulnerable");
			else
				alm->insertAttribute("dna_comp_armor_energy", pet->getEnergy());

			if (pet->getBlast() < 0)
				alm->insertAttribute("dna_comp_armor_blast", "Vulnerable");
			else
				alm->insertAttribute("dna_comp_armor_blast", pet->getBlast());

			if (pet->getHeat() < 0)
				alm->insertAttribute("dna_comp_armor_heat", "Vulnerable");
			else
				alm->insertAttribute("dna_comp_armor_heat", pet->getHeat());

			if (pet->getCold() < 0)
				alm->insertAttribute("dna_comp_armor_cold", "Vulnerable");
			else
				alm->insertAttribute("dna_comp_armor_cold", pet->getCold());

			if (pet->getElectricity() < 0)
				alm->insertAttribute("dna_comp_armor_electric", "Vulnerable");
			else
				alm->insertAttribute("dna_comp_armor_electric", pet->getElectricity());

			if (pet->getAcid() < 0)
				alm->insertAttribute("dna_comp_armor_acid", "Vulnerable");
			else
				alm->insertAttribute("dna_comp_armor_acid", pet->getAcid());

			if (pet->getStun() < 0)
				alm->insertAttribute("dna_comp_armor_stun", "Vulnerable");
			else
				alm->insertAttribute("dna_comp_armor_stun", pet->getStun());

			if (pet->getLightSaber() < 0)
				alm->insertAttribute("dna_comp_armor_saber", "Vulnerable");
			else
				alm->insertAttribute("dna_comp_armor_saber", pet->getLightSaber());

			ManagedReference<WeaponObject*> weapon = pet->getWeapon();
			if (weapon != NULL){
				StringBuffer displayValue;
				displayValue << Math::getPrecision(weapon->getAttackSpeed(), 2);
				alm->insertAttribute("creature_attack", displayValue);
			}
			StringBuffer displayValue;
			displayValue << Math::getPrecision(pet->getChanceHit(), 2);
			alm->insertAttribute("creature_tohit", displayValue);

			alm->insertAttribute("creature_damage", String::valueOf(pet->getDamageMin()) + " - " + String::valueOf(pet->getDamageMax()));

			if (petType == PetManager::CREATUREPET) {
				CreatureAttackMap* attMap = pet->getAttackMap();

				if (attMap != NULL && attMap->size() > 0) {
					String cmd = attMap->getCommand(0);
					if (cmd.isEmpty()) {
						alm->insertAttribute("spec_atk_1", " ---");
					} else {
						String str = StringIdManager::instance()->getStringId(("@combat_effects:" + cmd).hashCode()).toString();
						alm->insertAttribute("spec_atk_1", str);
					}
				} else {
					alm->insertAttribute("spec_atk_1", " ---");
				}

				if (attMap != NULL && attMap->size() > 1) {
					String cmd = attMap->getCommand(1);
					if (cmd.isEmpty()) {
						alm->insertAttribute("spec_atk_1", " ---");
					} else {
						String str = StringIdManager::instance()->getStringId(("@combat_effects:" + cmd).hashCode()).toString();
						alm->insertAttribute("spec_atk_2", str);
					}
				} else {
					alm->insertAttribute("spec_atk_2", " ---");
				}

				// TODO set this up to check for the actual ranged weapon
				if (pet->hasRangedWeapon())
					alm->insertAttribute("dna_comp_ranged_attack", "Yes");
				else
					alm->insertAttribute("dna_comp_ranged_attack", "No");
			}
		}
	}

	// Trained Commands
	if ( trainedCommands.size() > 0) {
		alm->insertAttribute("pet_command", "" );
	}

	if( trainedCommands.contains(PetManager::STAY) ){
		alm->insertAttribute("pet_command_1", trainedCommands.get(PetManager::STAY) );
	}

	if( trainedCommands.contains(PetManager::FOLLOW) ){
		alm->insertAttribute("pet_command_0", trainedCommands.get(PetManager::FOLLOW) );
	}

	if( trainedCommands.contains(PetManager::STORE) ){
		alm->insertAttribute("pet_command_11", trainedCommands.get(PetManager::STORE) );
	}

	if( trainedCommands.contains(PetManager::ATTACK) ){
		alm->insertAttribute("pet_command_4", trainedCommands.get(PetManager::ATTACK) );
	}

	if( trainedCommands.contains(PetManager::GUARD) ){
		alm->insertAttribute("pet_command_2", trainedCommands.get(PetManager::GUARD) );
	}

	if( trainedCommands.contains(PetManager::FRIEND) ){
		alm->insertAttribute("pet_command_3", trainedCommands.get(PetManager::FRIEND) );
	}

	if( trainedCommands.contains(PetManager::FOLLOWOTHER) ){
		alm->insertAttribute("pet_command_17", trainedCommands.get(PetManager::FOLLOWOTHER) );
	}

	if( trainedCommands.contains(PetManager::TRICK1) ){
		alm->insertAttribute("pet_command_12", trainedCommands.get(PetManager::TRICK1) );
	}

	if( trainedCommands.contains(PetManager::TRICK2) ){
		alm->insertAttribute("pet_command_13", trainedCommands.get(PetManager::TRICK2) );
	}

	if( trainedCommands.contains(PetManager::PATROL) ){
		alm->insertAttribute("pet_command_5", trainedCommands.get(PetManager::PATROL) );
	}

	if( trainedCommands.contains(PetManager::GETPATROLPOINT) ){
		alm->insertAttribute("pet_command_6", trainedCommands.get(PetManager::GETPATROLPOINT) );
	}

	if( trainedCommands.contains(PetManager::CLEARPATROLPOINTS) ){
		alm->insertAttribute("pet_command_7", trainedCommands.get(PetManager::CLEARPATROLPOINTS) );
	}

	if( trainedCommands.contains(PetManager::FORMATION1) ){
		alm->insertAttribute("pet_command_8", trainedCommands.get(PetManager::FORMATION1) );
	}

	if( trainedCommands.contains(PetManager::FORMATION2) ){
		alm->insertAttribute("pet_command_9", trainedCommands.get(PetManager::FORMATION2) );
	}

	if( trainedCommands.contains(PetManager::SPECIAL_ATTACK1) ){
		alm->insertAttribute("pet_command_18", trainedCommands.get(PetManager::SPECIAL_ATTACK1) );
	}

	if( trainedCommands.contains(PetManager::SPECIAL_ATTACK2) ){
		alm->insertAttribute("pet_command_19", trainedCommands.get(PetManager::SPECIAL_ATTACK2) );
	}

	if( trainedCommands.contains(PetManager::RANGED_ATTACK) ){
		alm->insertAttribute("pet_command_20", trainedCommands.get(PetManager::RANGED_ATTACK) );
	}

	if( trainedCommands.contains(PetManager::GROUP) ){
		alm->insertAttribute("pet_command_16", trainedCommands.get(PetManager::GROUP) );
	}

	if( trainedCommands.contains(PetManager::RECHARGEOTHER) ){
		alm->insertAttribute("@pet/pet_menu:menu_recharge_other", trainedCommands.get(PetManager::RECHARGEOTHER) );
	}

	if( trainedCommands.contains(PetManager::TRANSFER) ){
		alm->insertAttribute("pet_command_10", trainedCommands.get(PetManager::TRANSFER) );
	}

	if( trainedCommands.contains(PetManager::REPAIR) ){
		alm->insertAttribute("pet_command_13", trainedCommands.get(PetManager::REPAIR) ); // Droid Repair really was listed as Trick 2
	}
	if( trainedCommands.contains(PetManager::THROWTRAP) ){
		alm->insertAttribute("pet_command_22", trainedCommands.get(PetManager::THROWTRAP) );
	}
	if( trainedCommands.contains(PetManager::HARVEST) ){
		alm->insertAttribute("pet_command_21", trainedCommands.get(PetManager::HARVEST) );
	}
}
bool PetControlDeviceImplementation::growPet(CreatureObject* player, bool force, bool adult) {
	if (petType != PetManager::CREATUREPET)
		return true;

	if (growthStage <= 0 || growthStage >= 10)
		return true;

	ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();

	if (controlledObject == NULL || !controlledObject->isCreature())
		return true;
	ManagedReference<Creature*> pet = cast<Creature*>(controlledObject.get());

	ManagedReference<CreatureTemplate*> creatureTemplate = pet->getCreatureTemplate();

	if (creatureTemplate == NULL)
		return true;

	PetManager* petManager = pet->getZoneServer()->getPetManager();
	if (petManager == NULL)
		return true;

	Time currentTime;
	uint32 timeDelta = currentTime.getTime() - lastGrowth.getTime();
	int stagesToGrow = timeDelta / 43200; // 12 hour

	if (adult)
		stagesToGrow = 10;

	if (stagesToGrow == 0 && !force)
		return true;

	int newStage = growthStage + stagesToGrow;
	if (newStage > 10)
		newStage = 10;

	float newLevel = ((float)pet->getAdultLevel() / 10.0) * (float)newStage;
	if (newLevel < 1)
		newLevel = 1;

	float newHeight = creatureTemplate->getScale() * (0.46 + ((float)newStage * 0.06));

	short preEligibility = petManager->checkMountEligibility(_this.getReferenceUnsafeStaticCast());
	short postEligibility = petManager->checkMountEligibility(_this.getReferenceUnsafeStaticCast(), newHeight);

	assert(pet->isLockedByCurrentThread());

	if (preEligibility == PetManager::CANBEMOUNTTRAINED && postEligibility == PetManager::TOOLARGE && !force) {
		if (isTrainedAsMount()) {
			arrestGrowth();
			return true;
		}

		PlayerObject* ghost = player->getPlayerObject();

		if (ghost == NULL){
			return true;
		}

		ManagedReference<SuiListBox*> box = new SuiListBox(player, SuiWindowType::MOUNT_GROWTH_ARREST);
		box->setPromptTitle("@pet/pet_menu:mount_growth_title"); // Pet Growth Arrest
		box->setPromptText("@pet/pet_menu:mount_growth_prompt"); // Your pet could be trained as a mount, but is about to grow too large to serve as one. If you ever plan on training this pet as a mount you must arrest it's growth now. Stop pet's growth?
		box->setUsingObject(_this.getReferenceUnsafeStaticCast());
		box->setCancelButton(true, "@cancel");
		box->setOkButton(true, "@yes");
		box->setOtherButton(true, "@no");
		box->setCallback(new MountGrowthArrestSuiCallback(player->getZoneServer(), _this.getReferenceUnsafeStaticCast()));

		ghost->addSuiBox(box);
		player->sendMessage(box->generateMessage());
		return false;
	}

	if (adult)
		pet->setHeight(newHeight, true);
	else
		pet->setHeight(newHeight, false);

	pet->setPetLevel(newLevel);

	growthStage = newStage;
	lastGrowth.updateToCurrentTime();

	setVitality(getVitality());

	return true;
}
void PetControlDeviceImplementation::arrestGrowth() {
	if (petType != PetManager::CREATUREPET)
		return;

	if (growthStage <= 0 || growthStage >= 10)
		return;

	ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();

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

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

	ManagedReference<CreatureTemplate*> creatureTemplate = pet->getCreatureTemplate();

	if (creatureTemplate == NULL)
		return;

	PetManager* petManager = pet->getZoneServer()->getPetManager();
	if (petManager == NULL)
		return;

	int newStage = growthStage;

	for (int i = (growthStage + 1); i < 11; i++) {
		float newHeight = creatureTemplate->getScale() * (0.46 + ((float)i * 0.06));

		short mountEligibility = petManager->checkMountEligibility(_this.getReferenceUnsafeStaticCast(), newHeight);

		if (mountEligibility == PetManager::TOOLARGE)
			break;
		else if (mountEligibility == PetManager::CANBEMOUNTTRAINED)
			newStage = i;
	}

	if (newStage > growthStage) {
		float newLevel = ((float)pet->getAdultLevel() / 10.0) * (float)newStage;
		if (newLevel < 1)
			newLevel = 1;

		float newHeight = creatureTemplate->getScale() * (0.46 + ((float)newStage * 0.06));

		pet->setHeight(newHeight, false);
		pet->setPetLevel(newLevel);
	}

	setVitality(getVitality());

	growthStage = 10;
	lastGrowth.updateToCurrentTime();
}
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;

	//clear friend list
	friends.removeAll();

	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 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::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<SceneObject*> parent = player->getParent().get();

	if (parent != NULL && parent->isCellObject())
		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 != NULL && parent->isCellObject()) ? parent : NULL);
	pet->setNextStepPosition(player->getPositionX(), player->getPositionZ(), player->getPositionY(), (parent != NULL && parent->isCellObject()) ? parent : NULL);
	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 VehicleObjectImplementation::sendRepairConfirmTo(CreatureObject* player) {
	ManagedReference<SuiListBox*> listbox = new SuiListBox(player, SuiWindowType::GARAGE_REPAIR);
    listbox->setCallback(new RepairVehicleSuiCallback(server->getZoneServer()));
	listbox->setPromptTitle("@pet/pet_menu:confirm_repairs_t"); //Confirm Vehicle Repairs
	listbox->setPromptText("@pet/pet_menu:vehicle_repair_d"); //You have chosen to repair your vehicle. Please review the listed details and confirm your selection.
	listbox->setUsingObject(_this.getReferenceUnsafeStaticCast());
	listbox->setCancelButton(true, "@cancel");

	int repairCost = calculateRepairCost(player);
	int totalFunds = player->getBankCredits();
	int tax = 0;

	ManagedReference<CityRegion*> city = getCityRegion();
	if(city != NULL && city->getGarageTax() > 0){
		repairCost += repairCost * city->getGarageTax() / 100;
	}

	listbox->addMenuItem("@pet/pet_menu:vehicle_prompt " + getDisplayedName()); //Vehicle:
	listbox->addMenuItem("@pet/pet_menu:repair_cost_prompt " + String::valueOf(repairCost)); //Repair Cost:
	listbox->addMenuItem("@pet/pet_menu:total_funds_prompt " + String::valueOf(totalFunds)); //Total Funds Available:

	player->getPlayerObject()->addSuiBox(listbox);
	player->sendMessage(listbox->generateMessage());
}
int ConversationObserverImplementation::notifyObserverEvent(unsigned int eventType, Observable* observable, ManagedObject* arg1, long long arg2) {
	//Verify needed parameters
	if (eventType != ObserverEventType::CONVERSE && eventType != ObserverEventType::STARTCONVERSATION &&
		eventType != ObserverEventType::SELECTCONVERSATION && eventType != ObserverEventType::STOPCONVERSATION &&
		eventType != ObserverEventType::POSITIONCHANGED) {
		//Incorrect event type.
		return 0;
	}

	if (observable == NULL)
		return 0;

	if (arg1 == NULL && eventType != ObserverEventType::POSITIONCHANGED)
		return 0;

	//Try to convert parameters to correct types.
	CreatureObject* npc = NULL;
	CreatureObject* player = NULL;
	int selectedOption;
	try {
		npc = cast<CreatureObject* >(observable);

		if (arg1 != NULL)
			player = cast<CreatureObject* >(arg1);

		if (arg2 < std::numeric_limits<int>::min()) {
			selectedOption = std::numeric_limits<int>::min();
		} else if (arg2 > std::numeric_limits<int>::max()) {
			selectedOption = std::numeric_limits<int>::max();
		} else {
			selectedOption = arg2;
		}
	} catch (...) {
		//Failed to convert parameters. Keep observer.
		return 0;
	}

	switch (eventType) {
	case ObserverEventType::POSITIONCHANGED:
		if (npc != NULL) { //the observable in this case is the player
			ManagedReference<ConversationSession*> session = npc->getActiveSession(SessionFacadeType::CONVERSATION).castTo<ConversationSession*>();

			if (session != NULL) {
				ManagedReference<CreatureObject*> sessionNpc = session->getNPC();

				if (sessionNpc == NULL || npc->getDistanceTo(sessionNpc) > 7.f) {
					cancelConversationSession(npc, session->getNPC().get(), true);
					return 0;
				}
			}

		}

		return 0;

	case ObserverEventType::STOPCONVERSATION:
		cancelConversationSession(player, npc);
		//Keep observer.
		return 0;

	case ObserverEventType::STARTCONVERSATION: {
		//Cancel any existing sessions.
		cancelConversationSession(player, npc);
		//Create a new session.
		createConversationSession(player, npc);
		createPositionObserver(player);
		break;
	}
	default:
		break;
	}

	//Select next conversation screen.
	Reference<ConversationScreen*> conversationScreen = getNextConversationScreen(player, selectedOption, npc);

	if (conversationScreen != NULL) {
		//Modify the conversation screen.
		conversationScreen = runScreenHandlers(player, npc, selectedOption, conversationScreen);
	}

	//Send the conversation screen to the player.
	sendConversationScreenToPlayer(player, npc, conversationScreen);

	if (conversationScreen == NULL)
		cancelConversationSession(player, npc);

	//Keep the observer.
	return 0;
}
void ZoneImplementation::updateActiveAreas(TangibleObject* tano) {
	//Locker locker(_this.getReferenceUnsafeStaticCast());

	Locker _alocker(tano->getContainerLock());

	SortedVector<ManagedReference<ActiveArea* > > areas = *dynamic_cast<SortedVector<ManagedReference<ActiveArea* > >* >(tano->getActiveAreas());

	_alocker.release();

	Vector3 worldPos = tano->getWorldPosition();

	SortedVector<ManagedReference<QuadTreeEntry*> > entryObjects;

	Zone* managedRef = _this.getReferenceUnsafeStaticCast();

	bool readlock = !managedRef->isLockedByCurrentThread();

	managedRef->rlock(readlock);

	try {
		regionTree->inRange(worldPos.getX(), worldPos.getY(), entryObjects);
	} catch (...) {
		error("unexpeted error caught in void ZoneImplementation::updateActiveAreas(SceneObject* object) {");
	}

	managedRef->runlock(readlock);

	//locker.release();


	managedRef->unlock(!readlock);

	try {

		// update old ones
		for (int i = 0; i < areas.size(); ++i) {
			ManagedReference<ActiveArea*> area = areas.get(i);
//			Locker lockerO(object);

//			Locker locker(area, object);

			if (!area->containsPoint(worldPos.getX(), worldPos.getY(), tano->getParentID())) {
				tano->dropActiveArea(area);
				area->enqueueExitEvent(tano);
//				area->notifyExit(object);
			} else {
				area->notifyPositionUpdate(tano);
			}
		}

		// we update the ones in quadtree.
		for (int i = 0; i < entryObjects.size(); ++i) {
			//update in new ones
			ActiveArea* activeArea = dynamic_cast<ActiveArea*>(entryObjects.get(i).get());

			if (!tano->hasActiveArea(activeArea) && activeArea->containsPoint(worldPos.getX(), worldPos.getY(), tano->getParentID())) {
				//Locker lockerO(object);

				//Locker locker(activeArea, object);

				tano->addActiveArea(activeArea);
				activeArea->enqueueEnterEvent(tano);
				//activeArea->notifyEnter(object);
			}
		}

		// update world areas
		if (creatureManager != NULL) {
			Vector<ManagedReference<SpawnArea*> >* worldAreas = creatureManager->getWorldSpawnAreas();

			if (worldAreas != NULL) {
				for (int i = 0; i < worldAreas->size(); ++i) {
					ActiveArea* activeArea = worldAreas->get(i);
					Locker lockerO(tano);

					//			Locker locker(activeArea, object);

					if (!tano->hasActiveArea(activeArea)) {
						tano->addActiveArea(activeArea);
						//activeArea->enqueueEnterEvent(object);
						activeArea->notifyEnter(tano);
					} else {
						activeArea->notifyPositionUpdate(tano);
					}
				}
			}
		}
	} catch (...) {
		error("unexpected exception caught in void ZoneImplementation::updateActiveAreas(SceneObject* object) {");
		managedRef->wlock(!readlock);
		throw;
	}

	managedRef->wlock(!readlock);
}
int DroidMaintenanceModuleDataComponent::handleObjectMenuSelect(CreatureObject* player, byte selectedID, PetControlDevice* controller) {

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

	Locker dlock( droid, player );

	// Perform Maintenance Run
	if( selectedID == MAINT_MODULE_PERFORM ){

		// Init Maintenance Run Session
		//droid->getCooldownTimerMap()->updateToCurrentAndAddMili("Droid_Cooldown",1800000);
		// Interplanetary Time + 1 hour 40 minutes, 33 seconds
		// Local time: distance < 432 == 15 mins + (1s per 3 meters to next structure for that planet @ < 432m from first structure)
		// Local time: distance > 432 == 48 minutes 20 seconds
		// Start a session for the player and this module!
		ManagedReference<DroidMaintenanceSession*> session = new DroidMaintenanceSession(this, player);
		session->initialize();
		player->addActiveSession(SessionFacadeType::DROIDMAINTENANCERUN, session);
		session->sendMaintanceRunBox();
		return 0;
	}
	// Edit Maintenance List
	else if( selectedID == MAINT_MODULE_EDIT ){

		if( assignedStructures.isEmpty() ){
			player->sendSystemMessage( "@pet/droid_modules:droid_maint_empty_list" ); // The maintenance list for this droid is empty. Go to one of your structures and assign this droid to maintain it.
			return 0;
		}

		// Build List of Assigned Structures
		ManagedReference<SuiListBox*> box = new SuiListBox(player, SuiWindowType::DROID_EDIT_ASSIGNED_STRUCTURES, SuiListBox::HANDLETWOBUTTON);
		box->setCallback(new RemoveDroidStructureSuiCallback(player->getZoneServer(), this));
		box->setPromptTitle("@pet/droid_modules:droid_maint_edit_title"); // Edit Maintenance List
		box->setPromptText("@pet/droid_modules:droid_maint_edit_prompt"); // Please select a structure to remove from this droid's maintenance list.

		box->setOkButton(true, "@delete");
		box->setCancelButton(true, "@cancel");

		for (int i = 0; i < assignedStructures.size(); i++) {

			uint64 objectId = assignedStructures.elementAt(i);
			ManagedReference<SceneObject*> obj = player->getZoneServer()->getObject(objectId);
			if( obj != NULL && obj->isStructureObject() ){
				StructureObject* structureObject = cast<StructureObject*>(obj.get());
				if( structureObject != NULL ){
					box->addMenuItem( structureObject->getDisplayedName(), objectId );
				}
			}
		}

		box->setUsingObject(droid);
		player->getPlayerObject()->addSuiBox(box);
		player->sendMessage(box->generateMessage());

	}

	return 0;
}
void SceneObjectImplementation::broadcastDestroyPrivate(SceneObject* object, SceneObject* selfObject) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get());

		if (grandParent != NULL) {
			grandParent->broadcastDestroyPrivate(object, selfObject);

			return;
		} else {
			return;
		}
	}

	if (zone == NULL)
		return;

	//Locker zoneLocker(zone);

	//	bool readlock = !zone->isLockedByCurrentThread();

	SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects;
	int maxInRangeObjectCount = 0;

	//	zone->rlock(readlock);

	try {
		if (closeobjects == NULL) {
			info("Null closeobjects vector in SceneObjectImplementation::broadcastDestroyPrivate", true);
			zone->getInRangeObjects(getPositionX(), getPositionY(), 256, &closeSceneObjects, true);

			maxInRangeObjectCount = closeSceneObjects.size();
		} else {

			CloseObjectsVector* vec = (CloseObjectsVector*) closeobjects;
			closeSceneObjects.removeAll(vec->size(), 10);
			//			closeSceneObjects.addAll(*closeobjects);
			vec->safeCopyTo(closeSceneObjects);

			maxInRangeObjectCount = closeSceneObjects.size();//closeobjects->size();

		}


	} catch (...) {
		//zone->runlock(readlock);

		throw;
	}

	//	zone->runlock(readlock);

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno = cast<SceneObject*>(closeSceneObjects.get(i).get());

		if (selfObject == scno)
			continue;

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if (scno->isVehicleObject() || client != NULL || scno->isMount()) {
			object->sendDestroyTo(scno);
		}
	}
}
void FireworkShowMenuComponent::showData(CreatureObject* player, FireworkObject* fireworkShow) const {
	ManagedReference<PlayerObject*> ghost = player->getPlayerObject();
	if (ghost == NULL || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_ADDEVENT) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_REMOVEEVENT)
			|| ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_REORDERSHOW) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_MODIFYEVENT)
				|| ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_DELAYSELECTION)) {
		return;
	}

	DataObjectComponent* data = fireworkShow->getDataObjectComponent()->get();

	if (data == NULL || !data->isFireworkShowData())
		return;

	FireworkShowDataComponent* fireworkShowData = cast<FireworkShowDataComponent*>(data);

	Locker plocker(player);

	ManagedReference<SuiListBox*> suiBox = new SuiListBox(player, SuiWindowType::FIREWORK_SHOW_ADDEVENT, SuiListBox::HANDLESINGLEBUTTON);
	suiBox->setPromptTitle("@firework:data_title");
	suiBox->setPromptText("@firework:data_prompt");
	suiBox->setOkButton(true, "@ok");
	suiBox->setUsingObject(fireworkShow);

	int totalFireworks = fireworkShowData->getTotalFireworkCount();

	for (int i = 0; i < totalFireworks; i++) {
		ManagedReference<FireworkObject*> firework = fireworkShowData->getFirework(i);
		String fireworkDelay = String::valueOf(float(fireworkShowData->getFireworkDelay(i)) / 1000.f);
		String menuItem = "(" + String::valueOf(i) + ":" + fireworkDelay + "s) " + firework->getDisplayedName();
		suiBox->addMenuItem(menuItem);
	}

	ghost->addSuiBox(suiBox);
	player->sendMessage(suiBox->generateMessage());
}
void SceneObjectImplementation::broadcastMessagesPrivate(Vector<BasePacket*>* messages, SceneObject* selfObject) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get());

		if (grandParent != NULL) {
			grandParent->broadcastMessagesPrivate(messages, selfObject);

			return;
		} else {
			while (!messages->isEmpty()) {
				delete messages->remove(0);
			}

			return;
		}
	}


	if (zone == NULL) {
		while (!messages->isEmpty()) {
			delete messages->remove(0);
		}

		return;
	}

	//getZone()->rlock();
	//Locker zoneLocker(zone);

	bool readlock = !zone->isLockedByCurrentThread();

	SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects;
	int maxInRangeObjectCount = 0;

	//	zone->rlock(readlock);

	try {

		if (closeobjects == NULL) {
			info(String::valueOf(getObjectID()) + " Null closeobjects vector in SceneObjectImplementation::broadcastMessagesPrivate", true);
			zone->getInRangeObjects(getPositionX(), getPositionY(), 192, &closeSceneObjects, true);

			maxInRangeObjectCount = closeSceneObjects.size();
		} else {
			maxInRangeObjectCount = closeobjects->size();

			closeSceneObjects.removeAll(maxInRangeObjectCount, 10);
			//closeSceneObjects.addAll(*closeobjects);
			closeobjects->safeCopyTo(closeSceneObjects);

			maxInRangeObjectCount = closeSceneObjects.size();

		}

	} catch (Exception& e) {

	}

	//getZone()->runlock();
	//zoneLocker.release();
	//	zone->runlock(readlock);

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno = cast<SceneObject*>(closeSceneObjects.get(i).get());

		if (selfObject == scno)
			continue;

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if (scno->isVehicleObject() || client != NULL || scno->isMount()) {
			for (int j = 0; j < messages->size(); ++j) {
				BasePacket* msg = messages->get(j);
				scno->sendMessage(msg->clone());
			}
		}
	}

	while (!messages->isEmpty()) {
		delete messages->remove(0);
	}
}
void FireworkShowMenuComponent::reorderShow(CreatureObject* player, FireworkObject* fireworkShow) const {
	ManagedReference<PlayerObject*> ghost = player->getPlayerObject();
	if (ghost == NULL || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_ADDEVENT) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_REMOVEEVENT)
			|| ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_REORDERSHOW) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_MODIFYEVENT)
				|| ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_DELAYSELECTION)) {
		return;
	}

	DataObjectComponent* data = fireworkShow->getDataObjectComponent()->get();

	if (data == NULL || !data->isFireworkShowData())
		return;

	FireworkShowDataComponent* fireworkShowData = cast<FireworkShowDataComponent*>(data);

	Locker plocker(player);

	ManagedReference<SuiListBox*> suiBox = new SuiListBox(player, SuiWindowType::FIREWORK_SHOW_REORDERSHOW, SuiListBox::HANDLETHREEBUTTON);
	suiBox->setPromptTitle("@firework:modify_index_title"); // Remove Show Event
	suiBox->setPromptText("@firework:modify_index_prompt"); // Select the event index for which you would like to modify the delay time.
	suiBox->setOkButton(true, "@ui:done");
	suiBox->setCancelButton(true, "@ui:moveup");
	suiBox->setOtherButton(true, "@ui:movedown");
	suiBox->setUsingObject(fireworkShow);

	int totalFireworks = fireworkShowData->getTotalFireworkCount();

	for (int i = 0; i < totalFireworks; i++) {
		ManagedReference<FireworkObject*> firework = fireworkShowData->getFirework(i);
		String fireworkDelay = String::valueOf(float(fireworkShowData->getFireworkDelay(i)) / 1000.f);
		String menuItem = "(" + String::valueOf(i) + ":" + fireworkDelay + "s) " + firework->getDisplayedName();
		suiBox->addMenuItem(menuItem, firework->getObjectID());
	}

	suiBox->setCallback(new FireworkShowReorderShowSuiCallback(player->getZoneServer()));
	ghost->addSuiBox(suiBox);
	player->sendMessage(suiBox->generateMessage());
}
void PetManagerImplementation::handleChat(CreatureObject* speaker, AiAgent* pet, const String& message){

	if( speaker == NULL || pet == NULL )
		return;

	if( message.isEmpty() )
		return;

	ManagedReference<PetControlDevice*> pcd = pet->getControlDevice().get().castTo<PetControlDevice*>();

	if( pcd == NULL )
		return;

	// Handle command training
	if( pcd->getTrainingCommand() > 0 ){
		bool ownerChat = handleCommandTraining( speaker, pet, message );
		if (ownerChat)
			pcd->setTrainingCommand(0); // no longer training

		return;
	}

	ManagedWeakReference< CreatureObject*> linkedCreature = pet->getLinkedCreature();
	if( linkedCreature == NULL )
		return;

	// Check if speaker has permission to command pet
	// TODO: Add check for players other than owner that are on pet's friend list
	if( linkedCreature != speaker)
		return;

	ManagedWeakReference<SceneObject*> speakerParent = speaker->getRootParent();
	ManagedWeakReference<SceneObject*> petParent = pet->getRootParent();

	// If speaker is mounted, pet must be outdoors
	if( speaker->isRidingMount() && petParent != NULL )
		return;

	// If speaker is unmounted, pet and speaker must both be outdoors or inside same building
	if( !speaker->isRidingMount() && speakerParent != petParent )
		return;

	// Handle trained command
	if( isTrainedCommand( pcd, STAY, message ) ){
		enqueuePetCommand(speaker, pet, String("petStay").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, FOLLOW, message ) ){
		enqueuePetCommand(speaker, pet, String("petFollow").toLowerCase().hashCode(), "", true);
	}
	else if( isTrainedCommand( pcd, STORE, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, String("petStore").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, ATTACK, message ) ){
		enqueuePetCommand(speaker, pet, String("petAttack").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, GUARD, message ) ){
		speaker->sendSystemMessage("GUARD pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, FRIEND, message ) ){
		speaker->sendSystemMessage("FRIEND pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, FOLLOWOTHER, message ) ){
		enqueuePetCommand(speaker, pet, String("petFollow").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, TRICK1, message ) ){
		enqueuePetCommand(speaker, pet, String("petTrick").toLowerCase().hashCode(), "1", true);
	}
	else if( isTrainedCommand( pcd, TRICK2, message ) ){
		enqueuePetCommand(speaker, pet, String("petTrick").toLowerCase().hashCode(), "2", true);
	}
	else if( isTrainedCommand( pcd, PATROL, message ) ){
		speaker->sendSystemMessage("PATROL pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, FORMATION1, message ) ){
		speaker->sendSystemMessage("FORMATION2 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, FORMATION2, message ) ){
		speaker->sendSystemMessage("FORMATION2 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, SPECIAL_ATTACK1, message ) ){
		speaker->sendSystemMessage("SPECIAL_ATTACK1 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, SPECIAL_ATTACK2, message ) ){
		speaker->sendSystemMessage("SPECIAL_ATTACK2 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, RANGED_ATTACK, message ) ){
		speaker->sendSystemMessage("RANGED_ATTACK pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, GROUP, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, String("petGroup").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, RECHARGEOTHER, message ) ){
		enqueuePetCommand(speaker, pet, String("petRechargeOther").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, TRANSFER, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, String("petTransfer").toLowerCase().hashCode(), "");
	}

}
void FireworkShowMenuComponent::addEvent(CreatureObject* player, FireworkObject* fireworkShow) const {

	DataObjectComponent* data = fireworkShow->getDataObjectComponent()->get();

	if (data == NULL || !data->isFireworkShowData())
		return;

	FireworkShowDataComponent* fireworkShowData = cast<FireworkShowDataComponent*>(data);

	int curFireworks = fireworkShowData->getTotalFireworkCount();
	int showCapacity = fireworkShow->getCapacity();

	ManagedReference<PlayerObject*> ghost = player->getPlayerObject();

	if (ghost == NULL)
		return;

	if (curFireworks >= showCapacity && !ghost->isPrivileged()) {
		player->sendSystemMessage("This firework show is at full capacity.");
		return;
	}

	if (ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_ADDEVENT) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_REMOVEEVENT)
			|| ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_REORDERSHOW) || ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_MODIFYEVENT)
				|| ghost->hasSuiBoxWindowType(SuiWindowType::FIREWORK_SHOW_DELAYSELECTION)) {
		return;
	}

	Locker plocker(player);

	ManagedReference<SuiListBox*> suiBox = new SuiListBox(player, SuiWindowType::FIREWORK_SHOW_ADDEVENT, SuiListBox::HANDLETWOBUTTON);
	suiBox->setPromptTitle("Select Show Addition");
	suiBox->setPromptText("Select the firework to append to the end of the show package.");
	suiBox->setOkButton(true, "@ok");
	suiBox->setCancelButton(true, "@cancel");
	suiBox->setUsingObject(fireworkShow);

	ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");
	SceneObject* sceneObject = NULL;

	for (int i = 0; i < inventory->getContainerObjectsSize(); i++) {
		sceneObject = inventory->getContainerObject(i);
		if (sceneObject == NULL)
			continue;

		FireworkObject* firework = cast<FireworkObject*>(sceneObject);
		if (firework == NULL)
			continue;

		DataObjectComponent* data = firework->getDataObjectComponent()->get();

		if (data != NULL && data->isFireworkShowData())
			continue;

		if (sceneObject->getObjectID() != fireworkShow->getObjectID()) {
			String itemWithUseCount = sceneObject->getDisplayedName() + " (" + firework->getUseCount() + ")";
			suiBox->addMenuItem(itemWithUseCount, sceneObject->getObjectID());
		}
	}

	suiBox->setCallback(new FireworkShowAddEventSuiCallback(player->getZoneServer()));
	ghost->addSuiBox(suiBox);
	player->sendMessage(suiBox->generateMessage());
}
void CraftingSessionImplementation::createManufactureSchematic(int clientCounter) {
	ManagedReference<CraftingTool*> craftingTool = this->craftingTool.get();
	ManagedReference<CreatureObject*> crafter = this->crafter.get();
	ManagedReference<PlayerObject*> crafterGhost = this->crafterGhost.get();
	ManagedReference<CraftingStation*> craftingStation = this->craftingStation.get();
	ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get();
	ManagedReference<TangibleObject*> prototype = this->prototype.get();
	ManagedReference<CraftingManager*> craftingManager = this->craftingManager.get();

	if (manufactureSchematic == NULL) {
		sendSlotMessage(0, IngredientSlot::NOSCHEMATIC);
		return;
	}

	if (prototype == NULL) {
		sendSlotMessage(0, IngredientSlot::PROTOTYPENOTFOUND);
		return;
	}

	if (!craftingManager.get()->allowManufactureSchematic(manufactureSchematic)){
		sendSlotMessage(0, IngredientSlot::NOSCHEMATIC);
		return;
	}

	Locker locker(_this.get());

	if (manufactureSchematic->isAssembled()
			&& !manufactureSchematic->isCompleted()) {

		//Object Controller
		ObjectControllerMessage* objMsg = new ObjectControllerMessage(
				crafter->getObjectID(), 0x1B, 0x010C);
		objMsg->insertInt(0x10B);
		objMsg->insertInt(1);
		objMsg->insertByte(clientCounter);

		crafter->sendMessage(objMsg);

		ManagedReference<SceneObject*> datapad = crafter->getSlottedObject("datapad");

		prototype->destroyObjectFromWorld(0);

		manufactureSchematic->setPersistent(2);
		prototype->setPersistent(2);

		datapad->transferObject(manufactureSchematic, -1, true);
		manufactureSchematic->setPrototype(prototype);

	} else {

		closeCraftingWindow(clientCounter);

		sendSlotMessage(clientCounter, IngredientSlot::WEIRDFAILEDMESSAGE);
	}

	cancelSession();
}
void ReconMissionObjectiveImplementation::activate() {
	MissionObjectiveImplementation::activate();
	ManagedReference<MissionObject* > mission = this->mission.get();

	if (mission == NULL)
		return;

	ManagedReference<ZoneServer*> zoneServer = Core::lookupObject<ZoneServer>("ZoneServer");

	if (locationActiveArea == NULL) {
		locationActiveArea = ( zoneServer->createObject(String("object/mission_recon_area.iff").hashCode(), 1)).castTo<MissionReconActiveArea*>();
		Locker locker(locationActiveArea);
		locationActiveArea->setMissionObjective(_this.get());
	}

	if (!locationActiveArea->isInQuadTree()) {
		String planetName = mission->getStartPlanet();

		Zone* zone = zoneServer->getZone(planetName);

		Locker locker(locationActiveArea);

		locationActiveArea->initializePosition(mission->getStartPositionX(), 0, mission->getStartPositionY());
		locationActiveArea->setRadius(32.f);

		if (zone != NULL) {
			zone->transferObject(locationActiveArea, -1, true);
		} else {
			error("Failed to insert recon location to zone.");
			abort();
			return;
		}
	}

	ManagedReference<WaypointObject*> waypoint = mission->getWaypointToMission();

	if (waypoint == NULL)
		waypoint = mission->createWaypoint();

	waypoint->setPlanetCRC(mission->getStartPlanetCRC());
	waypoint->setPosition(mission->getStartPositionX(), 0, mission->getStartPositionY());
	waypoint->setActive(true);

	mission->updateMissionLocation();
}
int CraftingSessionImplementation::clearSession() {
	Locker slocker(_this.get());

	ManagedReference<CraftingTool*> craftingTool = this->craftingTool.get();
	ManagedReference<CreatureObject*> crafter = this->crafter.get();
	ManagedReference<PlayerObject*> crafterGhost = this->crafterGhost.get();
	ManagedReference<CraftingStation*> craftingStation = this->craftingStation.get();
	ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get();
	ManagedReference<TangibleObject*> prototype = this->prototype.get();

	if (manufactureSchematic != NULL) {

		Locker locker(manufactureSchematic);

		if (manufactureSchematic->getParent() == craftingTool) {
			manufactureSchematic->setDraftSchematic(NULL);
			manufactureSchematic->cleanupIngredientSlots(crafter);
			manufactureSchematic->destroyObjectFromWorld(true);
		}

		this->manufactureSchematic = NULL;
	}

	if (craftingTool != NULL) {
		Locker locker2(craftingTool);

		// Remove all items that aren't the prototype
		while (craftingTool->getContainerObjectsSize() > 1) {
			craftingTool->getContainerObject(1)->destroyObjectFromWorld(true);
		}

		craftingTool->dropSlottedObject("crafted_components");

		if (prototype != NULL) {

			Locker locker3(prototype);

			if (craftingTool->isReady()) {

				if (prototype->getParent() == craftingTool) {
					prototype->destroyObjectFromWorld(true);
				}

				this->prototype = NULL;
			}
		}
	}

	if(crafterGhost != NULL && crafterGhost->getDebug()) {
		crafter->sendSystemMessage("*** Clearing crafting session ***");
	}

	return 0;
}
void PlayerManagementSessionImplementation::completeBan() {
	ManagedReference<CreatureObject*> admin = this->admin.get();

	if (admin == NULL)
		return;

	Reference<PlayerObject*> ghost = admin->getPlayerObject();

	if (ghost == NULL)
		return;

	String message = "";

	/// Update account to check for changes
	Locker locker(targetAccount);
	targetAccount->updateAccount();

	if (banMode == ACCOUNT) {

		/// Check for account status changes
		if ((banType == BAN && targetAccount->isBanned()) ||
				(banType == UNBAN && !targetAccount->isBanned())) {

			admin->sendSystemMessage("This account has been changed since you started modifying it, please check changes and try again");

			admin->sendMessage(accountBox->generateCloseMessage());
			cancelSession();
			return;
		}

		if (targetAccount->isBanned()) {
			StringBuffer reason;
			reason << targetAccount->getBanAdmin() << "=" << targetAccount->getBanReason() << "|" << ghost->getAccountID() << "=" << banReason;
			message = playerManager->unbanAccount(ghost, targetAccount, reason.toString());
		} else
			message = playerManager->banAccount(ghost, targetAccount, banExpiration - time(0), banReason);

	} else if (banMode == GALAXY) {

		GalaxyBanEntry* galaxyBan = targetAccount->getGalaxyBan(galaxyID);

		/// Check for galaxy ban status changes
		if ((banType == BAN && galaxyBan != NULL) ||
				(banType == UNBAN && galaxyBan == NULL)) {

			admin->sendSystemMessage("This account has been changed since you started modifying it, please check changes and try again");

			admin->sendMessage(accountBox->generateCloseMessage());
			cancelSession();
			return;
		}

		if (galaxyBan != NULL) {
			StringBuffer reason;
			reason << galaxyBan->getBanAdmin() << "=" << galaxyBan->getBanReason() << "|" << ghost->getAccountID() << "=" << banReason;
			message = playerManager->unbanFromGalaxy(ghost, targetAccount, galaxyID, reason.toString());
		} else
			message = playerManager->banFromGalaxy(ghost, targetAccount, galaxyID, banExpiration - time(0), banReason);

	} else if (banMode == CHARACTER){

		CharacterListEntry* entry = targetAccount->getCharacterBan(galaxyID, targetName);

		/// Check for player ban status changes
		if ((banType == BAN && entry != NULL) ||
				(banType == UNBAN && entry == NULL)) {

			admin->sendSystemMessage("This account has been changed since you started modifying it, please check changes and try again");

			admin->sendMessage(accountBox->generateCloseMessage());
			cancelSession();
			return;
		}

		if (entry != NULL) {
			StringBuffer reason;
			reason << entry->getBanAdmin() << "=" << entry->getBanReason() << "|" << ghost->getAccountID() << "=" << banReason;
			message = playerManager->unbanCharacter(ghost, targetAccount, targetName, galaxyID, reason.toString());
		} else
			message = playerManager->banCharacter(ghost, targetAccount, targetName, galaxyID, banExpiration - time(0), banReason);

	}

	admin->sendSystemMessage(message);
	//sendAccountInfo();
	admin->sendMessage(accountBox->generateCloseMessage());
	cancelSession();
}
void CraftingSessionImplementation::sendIngredientForUIListen() {
	ManagedReference<CraftingTool*> craftingTool = this->craftingTool.get();
	ManagedReference<CreatureObject*> crafter = this->crafter.get();
	ManagedReference<PlayerObject*> crafterGhost = this->crafterGhost.get();
	ManagedReference<CraftingStation*> craftingStation = this->craftingStation.get();
	ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get();
	ManagedReference<TangibleObject*> prototype = this->prototype.get();

	if (crafter == NULL) {
		return;
	}

	if (craftingTool == NULL) {
		return;
	}

	if (manufactureSchematic == NULL) {
		return;
	}

	if (prototype == NULL) {
		return;
	}
	uint8 allowFactory = 1;
	if (!craftingManager.get()->allowManufactureSchematic(manufactureSchematic)) {
		allowFactory = 0;
	}
	// Object Controller w/ Ingredients ***************************
	ObjectControllerMessage* objMsg = new ObjectControllerMessage(
			crafter->getObjectID(), 0x1B, 0x0103);
	objMsg->insertLong(craftingTool->getObjectID()); // Crafting Tool Object ID
	objMsg->insertLong(manufactureSchematic->getObjectID());// Manufacture Schematic Object ID
	objMsg->insertLong(prototype->getObjectID()); // Crafting Tangible Object ID
	objMsg->insertInt(2);
	objMsg->insertByte(allowFactory); // set to 1 to allow create manufact schematic, 0 to prevent it.

	ManagedReference<DraftSchematic*> draftSchematic = manufactureSchematic->getDraftSchematic();
	int draftSlotCount = draftSchematic->getDraftSlotCount();
	objMsg->insertInt(draftSlotCount);

	// Send all the ingredient data
	for (int i = 0; i < draftSlotCount; i++) {
		DraftSlot* slot = draftSchematic->getDraftSlot(i);

		if (slot != NULL)
			slot->insertToMessage(objMsg);
	}
	objMsg->insertShort(0);

	crafter->sendMessage(objMsg);

	if(crafterGhost != NULL && crafterGhost->getDebug()) {
		crafter->sendSystemMessage("Sent UI Listen");
	}
}
Example #30
0
void VendorManager::handleDisplayStatus(CreatureObject* player, TangibleObject* vendor) {

	if(vendor->getZone() == NULL) {
		error("NULL zone in VendorManager::handleDisplayStatus");
		return;
	}

	DataObjectComponentReference* data = vendor->getDataObjectComponent();
	if(data == NULL || data->get() == NULL || !data->get()->isVendorData()) {
		error("Vendor has no data component");
		return;
	}

	VendorDataComponent* vendorData = cast<VendorDataComponent*>(data->get());
	if(vendorData == NULL) {
		error("Vendor has wrong data component");
		return;
	}

	ManagedReference<SuiListBox*> statusBox = new SuiListBox(player, SuiWindowType::STRUCTURE_VENDOR_STATUS);
	statusBox->setUsingObject(vendor);
	statusBox->setPromptTitle("@player_structure:vendor_status");
	statusBox->setPromptText("Vendor Status");

	ManagedReference<CreatureObject*> owner = server->getZoneServer()->getObject(vendorData->getOwnerId()).castTo<CreatureObject*>();
	String ownerName;

	if (owner == NULL)
		ownerName = "NULL";
	else
		ownerName = owner->getFirstName();

	statusBox->addMenuItem("Owner: " + ownerName);

	int condition = (((float)vendor->getMaxCondition() - (float)vendor->getConditionDamage()) / (float)vendor->getMaxCondition()) * 100;
	statusBox->addMenuItem("Condition: " + String::valueOf(condition) + "%");

	float secsRemaining = 0.f;
	if( vendorData->getMaint() > 0 ){
		secsRemaining = (vendorData->getMaint() / vendorData->getMaintenanceRate())*3600;
	}

	statusBox->addMenuItem("Maintenance Pool: " +
			               String::valueOf(vendorData->getMaint()) +
			               "cr " + getTimeString( (uint32)secsRemaining ) );
	statusBox->addMenuItem("Maintenance Rate: " + String::valueOf((int)vendorData->getMaintenanceRate()) + " cr/hr");

	ManagedReference<AuctionManager*> auctionManager = server->getZoneServer()->getAuctionManager();
	if(auctionManager == NULL) {
		error("null auction manager");
		return;
	}
	ManagedReference<AuctionsMap*> auctionsMap = auctionManager->getAuctionMap();
	if(auctionsMap == NULL) {
		error("null auctionsMap");
		return;
	}

	String planet = vendor->getZone()->getZoneName();
	String region = "@planet_n:" + vendor->getZone()->getZoneName();


	ManagedReference<CityRegion*> regionObject = vendor->getCityRegion();
	if(regionObject != NULL)
		region = regionObject->getRegionName();

	TerminalListVector vendorList = auctionsMap->getVendorTerminalData(planet, region, vendor);

	uint32 itemsForSaleCount = 0;

	if(vendorList.size() > 0) {

		Reference<TerminalItemList*> list = vendorList.get(0);
		if (list != NULL) {

			for (int j = 0; j < list->size(); ++j) {
				ManagedReference<AuctionItem*> item = list->get(j);
				if (item == NULL)
					continue;

				int itemSize = item->getSize();

				if (itemSize > 50)
					itemsForSaleCount += 50;
				else if (itemSize > 0)
					itemsForSaleCount += itemSize;
				else
					itemsForSaleCount++;
			}
		}
	}


	statusBox->addMenuItem("Number of Items For Sale: " + String::valueOf(itemsForSaleCount));

	if (vendorData->isVendorSearchEnabled())
		statusBox->addMenuItem("@player_structure:vendor_search_enabled");
	else
		statusBox->addMenuItem("@player_structure:vendor_search_disabled");

	statusBox->addMenuItem("\\#32CD32Vendor Operating Normally\\#.");

	player->getPlayerObject()->addSuiBox(statusBox);
	player->sendMessage(statusBox->generateMessage());

}