Example #1
0
TangibleObject* ImageDesignManager::createHairObject(CreatureObject* imageDesigner, CreatureObject* targetObject, const String& hairTemplate, const String& hairCustomization) {
	Reference<TangibleObject*> oldHair = targetObject->getSlottedObject("hair").castTo<TangibleObject*>();

	HairAssetData* hairAssetData = CustomizationIdManager::instance()->getHairAssetData(hairTemplate);

	if (hairTemplate.isEmpty()) {
		if (!CustomizationIdManager::instance()->canBeBald(getSpeciesGenderString(targetObject)))
			return oldHair;
		else
			return NULL;
	}

	if (hairAssetData == NULL)
		return oldHair;

	int skillMod = hairAssetData->getSkillModValue();

	if (imageDesigner->getSkillMod("hair") < skillMod)
		return oldHair;

	if (hairAssetData->getServerPlayerTemplate() != targetObject->getObjectTemplate()->getFullTemplateString()) {
		error("hair " + hairTemplate + " is not compatible with this creature player " + targetObject->getObjectTemplate()->getFullTemplateString());
		return oldHair;
	}

	ManagedReference<SceneObject*> hair = imageDesigner->getZoneServer()->createObject(hairTemplate.hashCode(), 1);

	//TODO: Validate hairCustomization
	if (hair == NULL || !hair->isTangibleObject()) {
		if (hair != NULL) {
			Locker locker(hair);
			hair->destroyObjectFromDatabase(true);
		}

		return oldHair;
	}

	TangibleObject* tanoHair = cast<TangibleObject*>( hair.get());

	Locker locker(tanoHair);

	tanoHair->setContainerDenyPermission("owner", ContainerPermissions::MOVECONTAINER);
	tanoHair->setContainerDefaultDenyPermission(ContainerPermissions::MOVECONTAINER);

	String appearanceFilename = tanoHair->getObjectTemplate()->getAppearanceFilename();

	CustomizationVariables data;

	data.parseFromClientString(hairCustomization);

	if (validateCustomizationString(&data, appearanceFilename, getSkillLevel(imageDesigner, "hair")))
		tanoHair->setCustomizationString(hairCustomization);

	return tanoHair;
}
void PlayerCreationManager::addCustomization(CreatureObject* creature,
		const String& customizationString, const String& appearanceFilename) {
	//TODO: Validate customizationString
	CustomizationVariables data;

	data.parseFromClientString(customizationString);

	if (ImageDesignManager::validateCustomizationString(&data,
			appearanceFilename, -1))
		creature->setCustomizationString(customizationString);
}
int PetDeedImplementation::handleObjectMenuSelect(CreatureObject* player, byte selectedID) {
	if (selectedID == 21) {
		if(generated || !player->hasSkill("outdoors_bio_engineer_novice") || !isASubChildOf(player))
			return 1;
		if (player->isRidingMount()) {
			player->sendSystemMessage("You cannot sample DNA while mounted");
			return 1;
		}

		if(player->getPendingTask("sampledeed") != NULL) {
			player->sendSystemMessage("@bio_engineer:harvest_dna_already_harvesting");
			return 1;
		}
		int skillMod = player->getSkillMod("dna_harvesting");
		if (skillMod < 1 || level > skillMod + 15) {
			player->sendSystemMessage("@bio_engineer:harvest_dna_skill_too_low");
			return 1;
		}

		Locker clocker(_this.get());

		ManagedReference<SampleDeedTask*> task = new SampleDeedTask(_this.get(), player);
		player->addPendingTask("sampledeed",task,0);
		return 0;
	}
	if (selectedID == 20) {

		if (generated || !isASubChildOf(player))
			return 1;

		if (player->isInCombat() || player->getParentRecursively(SceneObjectType::BUILDING) != NULL) {
			player->sendSystemMessage("@pet/pet_menu:cant_call"); //You can only unpack vehicles while Outside and not in Combat.
			return 1;
		}

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

		if (datapad == NULL) {
			player->sendSystemMessage("Datapad doesn't exist when trying to call pet");
			return 1;
		}
		if (datapad->getContainerObjectsSize() >= datapad->getContainerVolumeLimit()) {
			player->sendSystemMessage("@faction_recruiter:datapad_full"); // Your datapad is full. You must first free some space.
			return 1;
		}
		// Does the player have room
		ManagedReference<PlayerManager*> playerManager = player->getZoneServer()->getPlayerManager();

		int numberStored = 0;
		int maxStoredPets = playerManager->getBaseStoredCreaturePets() + player->getSkillMod("stored_pets");

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

			if (object != NULL && object->isPetControlDevice()) {
				PetControlDevice* device = cast<PetControlDevice*>( object.get());

				if (device->getPetType() == PetManager::CREATUREPET) {
					if (++numberStored >= maxStoredPets) {
						player->sendSystemMessage("@pet/pet_menu:sys_too_many_stored"); // There are too many pets stored in this container. Release some of them to make room for more.
						return 1;
					}

				}
			}
		}
		// Can the player control it
		ManagedReference<PlayerObject*> ghost = player->getPlayerObject();

		int currentlySpawned = 0;
		int spawnedLevel = 0;
		int cLevel = level;
		int maxPets = player->getSkillMod("keep_creature");
		int maxLevelofPets = player->getSkillMod("tame_level");

		for (int i = 0; i < ghost->getActivePetsSize(); ++i) {
			ManagedReference<AiAgent*> object = ghost->getActivePet(i);

			if (object != NULL && object->isCreature()) {
				if (++currentlySpawned >= maxPets) {
					player->sendSystemMessage("@pet/pet_menu:too_many"); // You can't control any more pets. Store one first
					return 1;
				}

				spawnedLevel += object->getLevel();

				if ((spawnedLevel + cLevel) > maxLevelofPets) {
					player->sendSystemMessage("Taming this pet would exceed your control level ability.");
					return 1;
				}
			}
		}

		Reference<CreatureManager*> creatureManager = player->getZone()->getCreatureManager();
		if( creatureManager == NULL ){
			player->sendSystemMessage("Internal Pet Deed Error #307");
			return 1;
		}

		CreatureTemplateManager* creatureTemplateManager = CreatureTemplateManager::instance();
		ManagedReference<CreatureTemplate*> petTemplate = creatureTemplateManager->getTemplate( mobileTemplate.hashCode() );

		if (petTemplate == NULL) {
			player->sendSystemMessage("wrong pet template;mobileTemplate=[" + mobileTemplate + "]" );
			return 1;
		}

		bool isVicious = petTemplate->getPvpBitmask() & CreatureFlag::AGGRESSIVE;

		if (level > 10 || isVicious) {
			if (!player->hasSkill("outdoors_creaturehandler_novice") || (level > maxLevelofPets)) {
				player->sendSystemMessage("@pet/pet_menu:sys_lack_skill"); // You lack the skill to be able to tame that creature.
				return 1;
			}

			if (isVicious && player->getSkillMod("tame_aggro") < 1) {
				player->sendSystemMessage("@pet/pet_menu:sys_lack_skill"); // You lack the skill to be able to tame that creature.
				return 1;
			}
		}

		// All checks complete, lets setup the control device and do it.
		ManagedReference<PetControlDevice*> controlDevice = (server->getZoneServer()->createObject(controlDeviceObjectTemplate.hashCode(), 1)).castTo<PetControlDevice*>();

		if (controlDevice == NULL) {
			player->sendSystemMessage("wrong pet control device;controlDevice=[" + controlDeviceObjectTemplate + "]" );
			return 1;
		}

		Locker locker(controlDevice);

		String templateToSpawn = creatureManager->getTemplateToSpawn(mobileTemplate.hashCode());
		ManagedReference<CreatureObject*> creatureObject = creatureManager->createCreature(templateToSpawn.hashCode(), true, 0 );
		if( creatureObject == NULL ) {
			controlDevice->destroyObjectFromDatabase(true);
			player->sendSystemMessage("wrong pet template;mobileTemplate=[" + mobileTemplate + "]" );
			return 1;
		}

		Locker clocker(creatureObject, player);

		ManagedReference<Creature*> pet = creatureObject.castTo<Creature*>();
		if( pet == NULL ) {
			controlDevice->destroyObjectFromDatabase(true);
			creatureObject->destroyObjectFromDatabase(true);
			player->sendSystemMessage("Internal Pet Deed Error #348" );
			return 1;
		}

		ObjectManager* objectManager = server->getZoneServer()->getObjectManager();
		pet->setPetDeed(_this.get());
		pet->loadTemplateData( petTemplate );
		pet->setCustomObjectName(StringIdManager::instance()->getStringId(*pet->getObjectName()), true);
		pet->createChildObjects();
		pet->setBaby(false);
		// update base stats on the pet now
		// We will store the deed pointer to the aiagent before serialization

		// Copy color customization from deed to pet
		CustomizationVariables* customVars = getCustomizationVariables();
		if( customVars != NULL ){
			for (int i = 0; i < customVars->size(); ++i) {
				uint8 id = customVars->elementAt(i).getKey();
				int16 val = customVars->elementAt(i).getValue();

				String name = CustomizationIdManager::instance()->getCustomizationVariable(id);
				pet->setCustomizationVariable( name, val, true );
			}
		}
		// then this is complete
		StringId s;
		s.setStringId(pet->getObjectName()->getFullPath());
		controlDevice->setControlledObject(pet);
		controlDevice->setObjectName(s);
		controlDevice->setPetType(PetManager::CREATUREPET);
		controlDevice->setMaxVitality(100);
		controlDevice->setVitality(100);
		controlDevice->setGrowthStage(1);
		controlDevice->updateStatus(1);

		if (!datapad->transferObject(controlDevice, -1)) {
			controlDevice->destroyObjectFromDatabase(true);
			return 1;
		}

		datapad->broadcastObject(controlDevice, true);
		controlDevice->growPet(player,true);
		controlDevice->callObject(player);

		//Remove the deed from it's container.
		ManagedReference<SceneObject*> deedContainer = getParent().get();

		if (deedContainer != NULL) {
			destroyObjectFromWorld(true);
		}

		generated = true;
		player->sendSystemMessage("@pet/pet_menu:device_added"); // "A control device has been added to your datapad."
		return 0;
	}

	return DeedImplementation::handleObjectMenuSelect(player, selectedID);
}
void PlayerCreationManager::addHair(CreatureObject* creature,
		const String& hairTemplate, const String& hairCustomization) {
	if (hairTemplate.isEmpty())
		return;

	HairStyleInfo* hairInfo = hairStyleInfo.get(hairTemplate);

	if (hairInfo == NULL)
		hairInfo = hairStyleInfo.get(0);

	HairAssetData* hairAssetData =
			CustomizationIdManager::instance()->getHairAssetData(hairTemplate);

	if (hairAssetData == NULL) {
		error("no hair asset data detected for " + hairTemplate);
		return;
	}

	if (hairAssetData->getServerPlayerTemplate()
			!= creature->getObjectTemplate()->getFullTemplateString()) {
		error(
				"hair " + hairTemplate
						+ " is not compatible with this creature player "
						+ creature->getObjectTemplate()->getFullTemplateString());
		return;
	}

	if (!hairAssetData->isAvailableAtCreation()) {
		error("hair " + hairTemplate + " not available at creation");
		return;
	}

	ManagedReference<SceneObject*> hair = zoneServer->createObject(
			hairTemplate.hashCode(), 1);

	//TODO: Validate hairCustomization
	if (hair == NULL) {
		return;
	}

	Locker locker(hair);

	if (!hair->isTangibleObject()) {
		hair->destroyObjectFromDatabase(true);
		return;
	}

	TangibleObject* tanoHair = cast<TangibleObject*>(hair.get());
	tanoHair->setContainerDenyPermission("owner",
			ContainerPermissions::MOVECONTAINER);
	tanoHair->setContainerDefaultDenyPermission(
			ContainerPermissions::MOVECONTAINER);

	String appearanceFilename =
			tanoHair->getObjectTemplate()->getAppearanceFilename();

	CustomizationVariables data;

	data.parseFromClientString(hairCustomization);

	if (ImageDesignManager::validateCustomizationString(&data,
			appearanceFilename, -1))
		tanoHair->setCustomizationString(hairCustomization);

	creature->transferObject(tanoHair, 4);
}
int DroidDeedImplementation::handleObjectMenuSelect(CreatureObject* player, byte selectedID) {

	if (selectedID == 20) {

		if (generated || !isASubChildOf(player))
			return 1;

		if (player->isInCombat() || player->isRidingMount() || player->isSwimming() || player->isDead() || player->isIncapacitated() ){
			player->sendSystemMessage("@pet/pet_menu:cant_call"); // "You cannot call this pet right now."
			return 1;
		}

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

		if (datapad == NULL) {
			player->sendSystemMessage("Datapad doesn't exist when trying to generate droid");
			return 1;
		}

		// Check if this will exceed maximum number of droids allowed
		ManagedReference<PlayerManager*> playerManager = player->getZoneServer()->getPlayerManager();

		int droidsInDatapad = 0;
		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("You have too many droids in your datapad");
			return 1;
		}

		Reference<CreatureManager*> creatureManager = player->getZone()->getCreatureManager();
		if( creatureManager == NULL )
			return 1;

		CreatureTemplateManager* creatureTemplateManager = CreatureTemplateManager::instance();
		Reference<CreatureTemplate*> creatureTemplate =  creatureTemplateManager->getTemplate( mobileTemplate.hashCode() );
		if( creatureTemplate == NULL ){
			player->sendSystemMessage("wrong droid template;mobileTemplate=[" + mobileTemplate + "]" );
			return 1;
		}

		Reference<PetControlDevice*> controlDevice = (server->getZoneServer()->createObject(controlDeviceObjectTemplate.hashCode(), 1)).castTo<PetControlDevice*>();
		if( controlDevice == NULL ){
			player->sendSystemMessage("wrong droid control device template " + controlDeviceObjectTemplate);
			return 1;
		}

		Locker locker(controlDevice);

		Reference<CreatureObject*> creatureObject = creatureManager->createCreature(generatedObjectTemplate.hashCode(), true, mobileTemplate.hashCode() );
		if( creatureObject == NULL ){
			controlDevice->destroyObjectFromDatabase(true);
			player->sendSystemMessage("wrong droid templates;mobileTemplate=[" + mobileTemplate + "];generatedObjectTemplate=[" + generatedObjectTemplate + "]" );
			return 1;
		}

		Locker clocker(creatureObject, player);

		Reference<DroidObject*> droid = creatureObject.castTo<DroidObject*>();
		if( droid == NULL ) {
			controlDevice->destroyObjectFromDatabase(true);
			creatureObject->destroyObjectFromDatabase(true);
			return 1;
		}

		droid->loadTemplateData( creatureTemplate );
		droid->setCustomObjectName(StringIdManager::instance()->getStringId(*droid->getObjectName()), true);

		// Transfer crafting components from deed to droid
		ManagedReference<SceneObject*> craftingComponents = getSlottedObject("crafted_components");
		if(craftingComponents != NULL) {
			SceneObject* satchel = craftingComponents->getContainerObject(0);
			// remove all items form satchel and add int he new items
			Vector<ManagedReference<SceneObject*> > toRemove;
			for (int i = 0; i < satchel->getContainerObjectsSize(); ++i) {
				ManagedReference<SceneObject*> sceno = satchel->getContainerObject(i);
				if (sceno != NULL) {
					toRemove.add(sceno);
				}
			}
			satchel->removeAllContainerObjects();
			for(int i=0;i<toRemove.size();i++) {
				SceneObject* component = toRemove.get(i);
				Locker componenetLocker(component);
				component->destroyObjectFromWorld(true);
			}
			// this will change to use stacked modules. we wont care about non droid modules as they arent needed.
			String key;
			ManagedReference<DroidComponent*> comp = NULL;
			HashTableIterator<String, ManagedReference<DroidComponent*> > iterator = modules.iterator();
			droid->setResists(0);
			droid->setHitChance(0);
			for(int i = 0; i < modules.size(); ++i) {
				iterator.getNextKeyAndValue(key, comp);
				if (comp) {
					satchel->transferObject(comp, -1, false);
					DataObjectComponentReference* data = comp->getDataObjectComponent();
					BaseDroidModuleComponent* module = NULL;
					if(data != NULL && data->get() != NULL && data->get()->isDroidModuleData()) {
						module = cast<BaseDroidModuleComponent*>(data->get());
						module->initialize(droid);
					}
				}
			}
			droid->transferObject(craftingComponents, 4, false);
			craftingComponents->setSendToClient(false);
		}
		// Copy color customization from deed to droid
		CustomizationVariables* customVars = getCustomizationVariables();
		if( customVars != NULL ){
			for (int i = 0; i < customVars->size(); ++i) {
				uint8 id = customVars->elementAt(i).getKey();
				int16 val = customVars->elementAt(i).getValue();

				String name = CustomizationIdManager::instance()->getCustomizationVariable(id);
				if( name.contains( "color" ) ){
					droid->setCustomizationVariable( name, val, true );
				}
			}
			droid->refreshPaint();
		}

		StringId s;
		s.setStringId(droid->getObjectName()->getFullPath());
		controlDevice->setObjectName(s);
		controlDevice->setPetType(PetManager::DROIDPET);
		controlDevice->setMaxVitality(100);
		controlDevice->setVitality(100);
		droid->createChildObjects();
		controlDevice->setControlledObject(droid);
		controlDevice->setDefaultCommands();

		if (!datapad->transferObject(controlDevice, -1)) {
			controlDevice->destroyObjectFromDatabase(true);
			return 1;
		}

		datapad->broadcastObject(controlDevice, true);

		controlDevice->callObject(player);
		droid->initDroidModules(true);
		float maxHam = DroidMechanics::determineHam(overallQuality,species);
		for (int i = 0; i < 9; ++i) {
			if (i % 3 == 0) {
				droid->setBaseHAM(i,maxHam,true);
				droid->setHAM(i,maxHam,true);
			} else {
				droid->setBaseHAM(i,maxHam/100,true);
				droid->setHAM(i,maxHam/100,true);
			}
		}

		//Remove the deed from its container.
		ManagedReference<SceneObject*> deedContainer = getParent().get();

		if (deedContainer != NULL) {
			destroyObjectFromWorld(true);
		}
		generated = true;
		destroyObjectFromDatabase(true);

		player->sendSystemMessage("@pet/pet_menu:device_added"); // "A control device has been added to your datapad."
		return 0;
	}

	return DeedImplementation::handleObjectMenuSelect(player, selectedID);
}