Пример #1
0
void ThreatMap::removeAll(bool forceRemoveAll) {
	Locker locker(&lockMutex);

	removeObservers();

	for (int i = size() - 1; i >= 0; i--) {
		VectorMapEntry<ManagedReference<CreatureObject*> , ThreatMapEntry> *entry = &elementAt(i);

		ManagedReference<CreatureObject*> key = entry->getKey();
		ThreatMapEntry *value = &entry->getValue();

		ManagedReference<TangibleObject*> selfStrong = self.get();

		// these checks will determine if we should store the damage from the dropped aggressor
		Zone* keyZone = (key != NULL ? key->getZone() : NULL);
		Zone* selfZone = (selfStrong != NULL ? selfStrong->getZone() : NULL);

		uint32 keyPlanetCRC = (keyZone != NULL ? keyZone->getPlanetCRC() : 0);
		uint32 selfPlanetCRC = (selfZone != NULL ? selfZone->getPlanetCRC() : 0);

		if (key == NULL || selfStrong == NULL || key->isDead() || !key->isOnline() || keyPlanetCRC != selfPlanetCRC || forceRemoveAll) {
			remove(i);

			if (threatMapObserver != NULL)
				key->dropObserver(ObserverEventType::HEALINGPERFORMED, threatMapObserver);
		} else {
			value->setNonAggroDamage(value->getTotalDamage());
			value->addHeal(-value->getHeal()); // don't need to store healing
			value->clearAggro();
		}
	}

	currentThreat = NULL;
	threatMatrix.clear();
}
Пример #2
0
void SchematicMap::buildSchematicGroups() {

	while(iffGroupMap.size() > 0) {
		VectorMapEntry<uint32, String> entry = iffGroupMap.remove(0);
		String groupName = entry.getValue();

		DraftSchematic* schematic = schematicCrcMap.get(entry.getKey());

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

			schematic->setGroupName(groupName);

			DraftSchematicGroup* group = groupMap.get(groupName);

			if (group == NULL) {
				group = new DraftSchematicGroup();
				groupMap.put(groupName, group);
			}

			if(!group->contains(schematic))
				group->add(schematic);
		}
	}
}
void CraftingSessionImplementation::addSkillMods() {
	ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get();
	ManagedReference<TangibleObject*> prototype = this->prototype.get();

	ManagedReference<DraftSchematic*> draftSchematic = manufactureSchematic->getDraftSchematic();

	VectorMap<String, int>* skillMods = draftSchematic->getDraftSchematicTemplate()->getSkillMods();

	for (int i = 0; i < skillMods->size(); i++) {
		VectorMapEntry<String, int> mod = skillMods->elementAt(i);
		prototype->addSkillMod(SkillModManager::WEARABLE, mod.getKey(), mod.getValue(), false);
	}
}
void TangibleObjectImplementation::removeTemplateSkillMods(TangibleObject* targetObject) {
	SharedTangibleObjectTemplate* tano = dynamic_cast<SharedTangibleObjectTemplate*>(templateObject.get());

	if (tano == NULL)
		return;

	VectorMap<String, int>* mods = tano->getSkillMods();

	for (int i = 0; i < mods->size(); ++i) {
		VectorMapEntry<String, int> entry = mods->elementAt(i);

		targetObject->removeSkillMod(SkillModManager::TEMPLATE, entry.getKey(), entry.getValue());
	}
}
Пример #5
0
void SkillManager::surrenderAllSkills(CreatureObject* creature, bool notifyClient) {
	ManagedReference<PlayerObject*> ghost = creature->getPlayerObject();

	SkillList* skillList = creature->getSkillList();

	Vector<String> listOfNames;
	skillList->getStringList(listOfNames);
	SkillList copyOfList;

	copyOfList.loadFromNames(listOfNames);

	for (int i = 0; i < copyOfList.size(); i++) {
		Skill* skill = copyOfList.get(i);

		if (skill->getSkillPointsRequired() > 0) {
			creature->removeSkill(skill, notifyClient);

			//Remove skill modifiers
			VectorMap<String, int>* skillModifiers = skill->getSkillModifiers();

			for (int i = 0; i < skillModifiers->size(); ++i) {
				VectorMapEntry<String, int>* entry = &skillModifiers->elementAt(i);
				creature->removeSkillMod(SkillModManager::SKILLBOX, entry->getKey(), entry->getValue(), notifyClient);

			}

			SkillModManager::instance()->verifySkillBoxSkillMods(creature);

			if (ghost != NULL) {
				//Give the player the used skill points back.
				ghost->addSkillPoints(skill->getSkillPointsRequired());

				//Remove abilities
				Vector<String>* abilityNames = skill->getAbilities();
				removeAbilities(ghost, *abilityNames, notifyClient);

				//Remove draft schematic groups
				Vector<String>* schematicsGranted = skill->getSchematicsGranted();
				SchematicMap::instance()->removeSchematics(ghost, *schematicsGranted, notifyClient);

				/// update force
				ghost->setForcePowerMax(creature->getSkillMod("jedi_force_power_max"), true);
			}
		}
	}
}
Пример #6
0
void BuffImplementation::removeAttributeModifiers() {
	if (creature.get() == NULL)
		return;

	int size = attributeModifiers.size();

	if (size <= 0)
		return;

	for (int i = 0; i < size; ++i) {
		VectorMapEntry<uint8, int>* entry = &attributeModifiers.elementAt(i);

		uint8 attribute = entry->getKey();
		int value = entry->getValue();

		if (value == 0)
			continue;

		try {

			int attributemax = creature.get()->getMaxHAM(attribute) - value;

			int currentVal = creature.get()->getHAM(attribute);

			creature.get()->setMaxHAM(attribute, attributemax);

			if (currentVal >= attributemax) {
				//creature.get()->inflictDamage(creature.get(), attribute, currentVal - attributemax, isSpiceBuff());

				if (attribute % 3 == 0) {
					creature.get()->inflictDamage(creature.get(), attribute, currentVal - attributemax, false);
				} // else setMaxHam sets secondaries to max
			}

		} catch (Exception& e) {
			error(e.getMessage());
			e.printStackTrace();
		}


		/*int attributeval = MIN(attributemax, creature.get()->getHAM(attribute) - value);

		creature.get()->setHAM(attribute, attributeval);*/
	}

}
void CraftingSessionImplementation::addSkillMods() {
	ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get();
	ManagedReference<TangibleObject*> prototype = this->prototype.get();

	ManagedReference<DraftSchematic*> draftSchematic = manufactureSchematic->getDraftSchematic();

	VectorMap<String, int>* skillMods = draftSchematic->getDraftSchematicTemplate()->getSkillMods();

	for (int i = 0; i < skillMods->size(); i++) {
		VectorMapEntry<String, int> mod = skillMods->elementAt(i);

		if (prototype->isWearableObject()) {
			WearableObject* wearable = prototype.castTo<WearableObject*>();
			VectorMap<String, int>* wearableMods = wearable->getWearableSkillMods();

			if (wearableMods->contains(mod.getKey())) {
				int oldValue = wearableMods->get(mod.getKey());
				int newValue = mod.getValue() + oldValue;

				if (newValue > 25)
					newValue = 25;

				wearableMods->put(mod.getKey(), newValue);
				continue;
			}
		}

		prototype->addSkillMod(SkillModManager::WEARABLE, mod.getKey(), mod.getValue(), false);
	}
}
Пример #8
0
void BuffImplementation::applySkillModifiers() {
	if (creature.get() == NULL)
		return;

	int size = skillModifiers.size();

	for (int i = 0; i < size; ++i) {
		VectorMapEntry<String, int>* entry = &skillModifiers.elementAt(i);

		String key = entry->getKey();
		int value = entry->getValue();

		creature.get()->addSkillMod(SkillModManager::BUFF, key, value, true);
	}

	// if there was a speed or acceleration mod change, this will take care of immediately setting them.
	// the checks for if they haven't changed are in these methods
	creature.get()->updateSpeedAndAccelerationMods();
}
void SpiceBuffImplementation::setDownerAttributes(CreatureObject* creature, Buff* buff) {
	for (int i = 0; i < attributeModifiers.size(); ++i) {
		VectorMapEntry<uint8, int>* entry = &attributeModifiers.elementAt(i);

		uint8 attribute = entry->getKey();
		int value = entry->getValue();

		if (value <= 0)
			continue;

		int attributemax = creature->getMaxHAM(attribute) - creature->getWounds(attribute);

		int projvalue = attributemax - value;

		if (projvalue < 1)
			value += projvalue - 1;

		buff->setAttributeModifier(attribute, -value);
	}
}
Пример #10
0
void BuffImplementation::applyAttributeModifiers() {
	if (creature.get() == NULL)
		return;

	int size = attributeModifiers.size();

	if (size <= 0)
		return;

	for (int i = 0; i < size; ++i) {
		VectorMapEntry<uint8, int>* entry = &attributeModifiers.elementAt(i);

		uint8 attribute = entry->getKey();
		int value = entry->getValue();

		if (value == 0)
			continue;

		try {
			int attributemax = creature.get()->getMaxHAM(attribute) + value;
			int attributeval = MAX(attributemax, creature.get()->getHAM(attribute) + value);

			creature.get()->setMaxHAM(attribute, attributemax);

			if (!creature.get()->isDead() && !creature.get()->isIncapacitated()) {
				if (fillAttributesOnBuff) {
					//creature.get()->setHAM(attribute, attributeval - creature.get()->getWounds(attribute));
					creature.get()->healDamage(creature.get(), attribute, attributeval, true);
				} else if (value >= 0)
					creature.get()->healDamage(creature.get(), attribute, value);
			}
		} catch (Exception& e) {
			error(e.getMessage());
			e.printStackTrace();
		}
	}

}
void CustomizationVariables::getVariable(int idx, uint8& type, int16& value) {
	VectorMapEntry<uint8, int16> entry = SortedVector<VectorMapEntry<uint8, int16> >::get(idx);

	type = entry.getKey();
	value = entry.getValue();
}
Пример #12
0
bool SkillManager::surrenderSkill(const String& skillName, CreatureObject* creature, bool notifyClient) {
	Skill* skill = skillMap.get(skillName.hashCode());

	if (skill == NULL)
		return false;

	Locker locker(creature);

	SkillList* skillList = creature->getSkillList();

	if(skillName == "force_title_jedi_novice" && getForceSensitiveSkillCount(creature, true) > 0) {
		return false;
	}

	if(skillName.beginsWith("force_sensitive_") &&
		getForceSensitiveSkillCount(creature, false) <= 24 &&
		creature->hasSkill("force_title_jedi_rank_01"))
		return false;

	for (int i = 0; i < skillList->size(); ++i) {
		Skill* checkSkill = skillList->get(i);

		if (checkSkill->isRequiredSkillOf(skill))
			return false;
	}

	if(creature->hasSkill("force_title_jedi_rank_03") && skillName.contains("force_discipline_") && !knightPrereqsMet(creature, skillName)) {
		return false;
	}

	//If they have already surrendered the skill, then return true.
	if (!creature->hasSkill(skill->getSkillName()))
		return true;

	creature->removeSkill(skill, notifyClient);

	//Remove skill modifiers
	VectorMap<String, int>* skillModifiers = skill->getSkillModifiers();

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

	for (int i = 0; i < skillModifiers->size(); ++i) {
		VectorMapEntry<String, int>* entry = &skillModifiers->elementAt(i);
		creature->removeSkillMod(SkillModManager::SKILLBOX, entry->getKey(), entry->getValue(), notifyClient);

	}

	if (ghost != NULL) {
		//Give the player the used skill points back.
		ghost->addSkillPoints(skill->getSkillPointsRequired());

		//Remove abilities but only if the creature doesn't still have a skill that grants the
		//ability.  Some abilities are granted by multiple skills. For example Dazzle for dancers
		//and musicians.
		Vector<String>* skillAbilities = skill->getAbilities();
		if (skillAbilities->size() > 0) {
			SortedVector<String> abilitiesLost;
			for (int i = 0; i < skillAbilities->size(); i++) {
				abilitiesLost.put(skillAbilities->get(i));
			}
			for (int i = 0; i < skillList->size(); i++) {
				Skill* remainingSkill = skillList->get(i);
				Vector<String>* remainingAbilities = remainingSkill->getAbilities();
				for(int j = 0; j < remainingAbilities->size(); j++) {
					if (abilitiesLost.contains(remainingAbilities->get(j))) {
						abilitiesLost.drop(remainingAbilities->get(j));
						if (abilitiesLost.size() == 0) {
							break;
						}
					}
				}
			}
			if (abilitiesLost.size() > 0) {
				removeAbilities(ghost, abilitiesLost, notifyClient);
			}
		}

		//Remove draft schematic groups
		Vector<String>* schematicsGranted = skill->getSchematicsGranted();
		SchematicMap::instance()->removeSchematics(ghost, *schematicsGranted, notifyClient);

		//Update maximum experience.
		updateXpLimits(ghost);

		/// Update Force Power Max
		ghost->setForcePowerMax(creature->getSkillMod("jedi_force_power_max"), true);

		SkillList* list = creature->getSkillList();

		int totalSkillPointsWasted = 250;

		for (int i = 0; i < list->size(); ++i) {
			Skill* skill = list->get(i);

			totalSkillPointsWasted -= skill->getSkillPointsRequired();
		}

		if (ghost->getSkillPoints() != totalSkillPointsWasted) {
			creature->error("skill points mismatch calculated: " + String::valueOf(totalSkillPointsWasted) + " found: " + String::valueOf(ghost->getSkillPoints()));
			ghost->setSkillPoints(totalSkillPointsWasted);
		}

		ManagedReference<PlayerManager*> playerManager = creature->getZoneServer()->getPlayerManager();
		if (playerManager != NULL) {
			creature->setLevel(playerManager->calculatePlayerLevel(creature));
		}
	}

	/// Update client with new values for things like Terrain Negotiation
	CreatureObjectDeltaMessage4* msg4 = new CreatureObjectDeltaMessage4(creature);
	msg4->updateAccelerationMultiplierBase();
	msg4->updateAccelerationMultiplierMod();
	msg4->updateSpeedMultiplierBase();
	msg4->updateSpeedMultiplierMod();
	msg4->updateRunSpeed();
	msg4->updateTerrainNegotiation();
	msg4->close();
	creature->sendMessage(msg4);

	SkillModManager::instance()->verifySkillBoxSkillMods(creature);

	return true;
}
Пример #13
0
bool SkillManager::awardSkill(const String& skillName, CreatureObject* creature, bool notifyClient, bool awardRequiredSkills, bool noXpRequired) {
	Skill* skill = skillMap.get(skillName.hashCode());

	if (skill == NULL)
		return false;

	Locker locker(creature);

	//Check for required skills.
	Vector<String>* requiredSkills = skill->getSkillsRequired();
	for (int i = 0; i < requiredSkills->size(); ++i) {
		String requiredSkillName = requiredSkills->get(i);
		Skill* requiredSkill = skillMap.get(requiredSkillName.hashCode());

		if (requiredSkill == NULL)
			continue;

		if (awardRequiredSkills)
			awardSkill(requiredSkillName, creature, notifyClient, awardRequiredSkills, noXpRequired);

		if (!creature->hasSkill(requiredSkillName))
			return false;
	}

	if (!canLearnSkill(skillName, creature, noXpRequired)) {
		return false;
	}

	//If they already have the skill, then return true.
	if (creature->hasSkill(skill->getSkillName()))
		return true;

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

	if (ghost != NULL) {
		//Withdraw skill points.
		ghost->addSkillPoints(-skill->getSkillPointsRequired());

		//Witdraw experience.
		if (!noXpRequired) {
			ghost->addExperience(skill->getXpType(), -skill->getXpCost(), true);
		}

		creature->addSkill(skill, notifyClient);

		//Add skill modifiers
		VectorMap<String, int>* skillModifiers = skill->getSkillModifiers();

		for (int i = 0; i < skillModifiers->size(); ++i) {
			VectorMapEntry<String, int>* entry = &skillModifiers->elementAt(i);
			creature->addSkillMod(SkillModManager::SKILLBOX, entry->getKey(), entry->getValue(), notifyClient);

		}

		//Add abilities
		Vector<String>* abilityNames = skill->getAbilities();
		addAbilities(ghost, *abilityNames, notifyClient);
		if (skill->isGodOnly()) {
			for (int i = 0; i < abilityNames->size(); ++i) {
				String ability = abilityNames->get(i);
				StringIdChatParameter params;
				params.setTU(ability);
				params.setStringId("ui", "skill_command_acquired_prose");

				creature->sendSystemMessage(params);
			}
		}

		//Add draft schematic groups
		Vector<String>* schematicsGranted = skill->getSchematicsGranted();
		SchematicMap::instance()->addSchematics(ghost, *schematicsGranted, notifyClient);

		//Update maximum experience.
		updateXpLimits(ghost);


		// Update Force Power Max.
		ghost->setForcePowerMax(creature->getSkillMod("jedi_force_power_max"), true);

		if (skillName.contains("master")) {
			ManagedReference<PlayerManager*> playerManager = creature->getZoneServer()->getPlayerManager();
			if (playerManager != NULL) {
				const Badge* badge = BadgeList::instance()->get(skillName);

				if (badge == NULL && skillName == "crafting_shipwright_master") {
					badge = BadgeList::instance()->get("crafting_shipwright");
				}

				if (badge != NULL) {
					playerManager->awardBadge(ghost, badge);
				}
			}
		}

		SkillList* list = creature->getSkillList();

		int totalSkillPointsWasted = 250;

		for (int i = 0; i < list->size(); ++i) {
			Skill* skill = list->get(i);

			totalSkillPointsWasted -= skill->getSkillPointsRequired();
		}

		if (ghost->getSkillPoints() != totalSkillPointsWasted) {
			creature->error("skill points mismatch calculated: " + String::valueOf(totalSkillPointsWasted) + " found: " + String::valueOf(ghost->getSkillPoints()));
			ghost->setSkillPoints(totalSkillPointsWasted);
		}

		ManagedReference<PlayerManager*> playerManager = creature->getZoneServer()->getPlayerManager();
		if (playerManager != NULL) {
			creature->setLevel(playerManager->calculatePlayerLevel(creature));
		}
	}

	/// Update client with new values for things like Terrain Negotiation
	CreatureObjectDeltaMessage4* msg4 = new CreatureObjectDeltaMessage4(creature);
	msg4->updateAccelerationMultiplierBase();
	msg4->updateAccelerationMultiplierMod();
	msg4->updateSpeedMultiplierBase();
	msg4->updateSpeedMultiplierMod();
	msg4->updateRunSpeed();
	msg4->updateTerrainNegotiation();
	msg4->close();
	creature->sendMessage(msg4);

	SkillModManager::instance()->verifySkillBoxSkillMods(creature);

	return true;
}
String QuestVectorMapImplementation::getMapKeyAtIndex(int idx) {
	VectorMapEntry<String, String>* entry = &questMap.elementAt(idx);

	return entry->getKey();
}
Пример #15
0
void ConsumableImplementation::fillAttributeList(AttributeListMessage* alm, CreatureObject* player) {

	if (maxCondition > 0) {
		StringBuffer cond;
		cond << (maxCondition-(int)conditionDamage) << "/" << maxCondition;

		alm->insertAttribute("condition", cond);
	}

	alm->insertAttribute("volume", volume);

	if (!isAttributeEffect() && !isSpiceEffect()) {
		if (useCount > 0)
			alm->insertAttribute("counter_uses_remaining", useCount);
	} else {
		if (useCount > 0)
			alm->insertAttribute("quantity", useCount);
	}

	if (!craftersName.isEmpty()){
		alm->insertAttribute("crafter", craftersName);
	}

	if (!objectSerial.isEmpty()){
		alm->insertAttribute("serial_number", objectSerial);
	}

	switch (effectType) {
	case EFFECT_HEALING: {

		if (filling > 0) {
			if (isFood())
				alm->insertAttribute("stomach_food", filling);
			else if (isDrink())
				alm->insertAttribute("stomach_drink", filling);
		}

		for (int i = 0; i < modifiers.size(); ++i) {
			VectorMapEntry<String, float>* entry = &modifiers.elementAt(i);;
			alm->insertAttribute(entry->getKey() + "_heal", nutrition);
		}

		break;
	}
	case EFFECT_ATTRIBUTE: {

		if (filling > 0) {
			if (isFood())
				alm->insertAttribute("stomach_food", filling);
			else if (isDrink())
				alm->insertAttribute("stomach_drink", filling);
		}

		if (duration <= 0)
			return;

		StringBuffer durationstring;

		int minutes = (int) floor(duration / 60.0f);
		int seconds = duration % 60;

		if (minutes > 0)
			durationstring << minutes << "m ";

		durationstring << seconds << "s";

		int mods = modifiers.size();

		if (mods > 0) {
			alm->insertAttribute("attribmods", mods);

			for (int i = 0; i < mods; ++i) {
				VectorMapEntry<String, float>* entry = &modifiers.elementAt(i);
				StringBuffer nutritionstring;

				if (!isForagedFood())
					nutritionstring << ((nutrition > 0) ? "+" : "") << nutrition << " for " << durationstring.toString();
				else
					nutritionstring << ((entry->getValue() > 0) ? "+" : "") << entry->getValue() << ", " << durationstring.toString();

				alm->insertAttribute("attr_" + entry->getKey(), nutritionstring.toString());
			}
		}
		break;
	}
	case EFFECT_SPICE: {
		int mods = modifiers.size();

		if (mods > 0) {
			StringBuffer durationstring;
			durationstring << duration << "s";

			alm->insertAttribute("attribmods", mods);

			for (int i = 0; i < mods; ++i) {
				VectorMapEntry<String, float>* entry = &modifiers.elementAt(i);
				StringBuffer nutritionstring;
				nutritionstring << ((entry->getValue() > 0) ? "+" : "") << entry->getValue() << ", " << durationstring.toString();
				alm->insertAttribute("attr_" + entry->getKey(), nutritionstring.toString());
			}
		}

		break;
	}
	case EFFECT_SKILL: {

		if (filling > 0) {
			if (isFood())
				alm->insertAttribute("stomach_food", filling);
			else if (isDrink())
				alm->insertAttribute("stomach_drink", filling);
		}

		for (int i = 0; i < modifiers.size(); ++i) {
			VectorMapEntry<String, float>* entry = &modifiers.elementAt(i);
			alm->insertAttribute("skill", "@stat_n:" + entry->getKey());
		}

		StringBuffer nutritionstring;
		nutritionstring << ((nutrition > 0) ? "+" : "") << nutrition;

		alm->insertAttribute("modifier", nutritionstring.toString());

		StringBuffer durationstring;

		int minutes = (int) floor(duration / 60.0f);
		int seconds = duration % 60;

		if (minutes > 0)
			durationstring << minutes << "m ";

		durationstring << seconds << "s";

		alm->insertAttribute("duration", durationstring.toString());

		break;
	}
	case EFFECT_DURATION: {

		if (filling > 0) {
			if (isFood())
				alm->insertAttribute("stomach_food", filling);
			else if (isDrink())
				alm->insertAttribute("stomach_drink", filling);
		}

		for (int i = 0; i < modifiers.size(); ++i) {
			VectorMapEntry<String, float>* entry = &modifiers.elementAt(i);

			String key = entry->getKey();
			float value = entry->getValue();

			alm->insertAttribute("duration_effect", "@obj_attr_n:" + key + "_d");

			alm->insertAttribute(key + "_eff", nutrition);

			StringBuffer durationstring;

			int minutes = (int) floor(duration / 60.0f);
			int seconds = duration % 60;

			if (minutes > 0)
				durationstring << minutes << "m ";

			durationstring << seconds << "s";

			alm->insertAttribute("duration", durationstring.toString());
		}

		break;
	}
	case EFFECT_DELAYED: {

		if (filling > 0) {
			if (isFood())
				alm->insertAttribute("stomach_food", filling);
			else if (isDrink())
				alm->insertAttribute("stomach_drink", filling);
		}

		for (int i = 0; i < modifiers.size(); ++i) {
			VectorMapEntry<String, float>* entry = &modifiers.elementAt(i);

			String key = entry->getKey();
			float value = entry->getValue();

			alm->insertAttribute("delay_effect", "@obj_attr_n:" + key + "_d");

			alm->insertAttribute(key + "_eff", nutrition);

			if (duration > 1)
				alm->insertAttribute(key + "_dur", duration);
		}

		break;
	}
	case EFFECT_INSTANT: {

		if (filling > 0) {
			if (isFood())
				alm->insertAttribute("stomach_food", filling);
			else if (isDrink())
				alm->insertAttribute("stomach_drink", filling);
		}

		for (int i = 0; i < modifiers.size(); ++i) {
			VectorMapEntry<String, float>* entry = &modifiers.elementAt(i);

			String key = entry->getKey();
			float value = entry->getValue();

			alm->insertAttribute("instant_effect", "@obj_attr_n:" + key + "_d");
			alm->insertAttribute(key + "_v1", nutrition);

			if (duration > 1)
				alm->insertAttribute(key + "_v2", duration);
		}
		break;
	}
	}

	if (!speciesRestriction.isEmpty()) {
		if (speciesRestriction == "pets")
			alm->insertAttribute("race_restriction", "@obj_attr_n:speciespet"); //Pets
		else
			alm->insertAttribute("race_restriction", "@obj_attr_n:species" + speciesRestriction);
	}
}
void ImageDesignSessionImplementation::updateImageDesign(CreatureObject* updater, uint64 designer, uint64 targetPlayer, uint64 tent, int type, const ImageDesignData& data) {
	ManagedReference<CreatureObject*> strongReferenceTarget = targetCreature.get();
	ManagedReference<CreatureObject*> strongReferenceDesigner = designerCreature.get();

	if (strongReferenceTarget == NULL || strongReferenceDesigner == NULL)
		return;

	Locker locker(strongReferenceDesigner);
	Locker clocker(strongReferenceTarget, strongReferenceDesigner);

	imageDesignData = data;

	CreatureObject* targetObject = NULL;

	if (updater == strongReferenceDesigner)
		targetObject = strongReferenceTarget;
	else
		targetObject = strongReferenceDesigner;

	//ManagedReference<SceneObject*> obj = targetObject->getParentRecursively(SceneObjectType::SALONBUILDING);
	//tent = obj != NULL ? obj->getObjectID()

	ImageDesignChangeMessage* message = new ImageDesignChangeMessage(targetObject->getObjectID(), designer, targetPlayer, tent, type);

	imageDesignData.insertToMessage(message);

	bool commitChanges = false;

	if (imageDesignData.isAcceptedByDesigner()) {
		commitChanges = true;

		if (strongReferenceDesigner != strongReferenceTarget && !imageDesignData.isAcceptedByTarget()) {
			commitChanges = false;

			if (idTimeoutEvent == NULL)
				idTimeoutEvent = new ImageDesignTimeoutEvent(_this.get());

			if (!idTimeoutEvent->isScheduled())
				idTimeoutEvent->schedule(120000); //2 minutes
		} else {
			commitChanges = doPayment();
		}
	}

	//System::out << h << endl;
	if (commitChanges) {
		//TODO: set XP Values

		int xpGranted = 0; // Minimum Image Design XP granted (base amount).

		//if (imageDesignData.mi)

		String hairTemplate = imageDesignData.getHairTemplate();

		bool statMig = imageDesignData.isStatMigrationRequested();

		if (statMig && strongReferenceDesigner->getParentRecursively(SceneObjectType::SALONBUILDING).get().get()
				&& strongReferenceDesigner->getParentRecursively(SceneObjectType::SALONBUILDING).get().get() && strongReferenceDesigner != strongReferenceTarget) {

			ManagedReference<Facade*> facade = strongReferenceTarget->getActiveSession(SessionFacadeType::MIGRATESTATS);
			ManagedReference<MigrateStatsSession*> session = dynamic_cast<MigrateStatsSession*>(facade.get());

			if (session != NULL) {
				session->migrateStats();
				xpGranted = 2000;
			}
		}

		VectorMap<String, float>* bodyAttributes = imageDesignData.getBodyAttributesMap();
		VectorMap<String, uint32>* colorAttributes = imageDesignData.getColorAttributesMap();

		ImageDesignManager* imageDesignManager = ImageDesignManager::instance();

		hairObject = strongReferenceTarget->getSlottedObject("hair").castTo<TangibleObject*>();

		if (type == 1) {
			String oldCustomization;

			if (hairObject != NULL)
				hairObject->getCustomizationString(oldCustomization);

			hairObject = imageDesignManager->createHairObject(strongReferenceDesigner, strongReferenceTarget, imageDesignData.getHairTemplate(), imageDesignData.getHairCustomizationString());

			if (hairObject != NULL)
				hairObject->setCustomizationString(oldCustomization);

			if (xpGranted < 100)
				xpGranted = 100;
		}

		if (bodyAttributes->size() > 0) {
			if (xpGranted < 300)
				xpGranted = 300;
			for (int i = 0; i < bodyAttributes->size(); ++i) {
				VectorMapEntry<String, float>* entry = &bodyAttributes->elementAt(i);
				imageDesignManager->updateCustomization(strongReferenceDesigner, entry->getKey(), entry->getValue(), strongReferenceTarget);
			}
		}


		if (colorAttributes->size() > 0) {
			if(xpGranted < 100)
				xpGranted = 100;
			for (int i = 0; i < colorAttributes->size(); ++i) {
				VectorMapEntry<String, uint32>* entry = &colorAttributes->elementAt(i);
				imageDesignManager->updateColorCustomization(strongReferenceDesigner, entry->getKey(), entry->getValue(), hairObject, strongReferenceTarget);
			}
		}

		imageDesignManager->updateHairObject(strongReferenceTarget, hairObject);

		// Add holo emote
		String holoemote = imageDesignData.getHoloEmote();
		if( !holoemote.isEmpty() ){

			PlayerObject* ghost = strongReferenceTarget->getPlayerObject();
			ghost->setInstalledHoloEmote( holoemote );  // Also resets number of uses available

			strongReferenceTarget->sendSystemMessage("@image_designer:new_holoemote"); //"Congratulations! You have purchased a new Holo-Emote generator. Type '/holoemote help' for instructions."

			if(xpGranted < 100)
				xpGranted = 100;

		}

		// Drop the Session for both the designer and the targetCreature;
		strongReferenceDesigner->dropActiveSession(SessionFacadeType::IMAGEDESIGN);
		strongReferenceTarget->dropActiveSession(SessionFacadeType::IMAGEDESIGN);

		// Award XP.
		PlayerManager* playerManager = strongReferenceDesigner->getZoneServer()->getPlayerManager();

		if (playerManager != NULL && xpGranted > 0) {
			if(strongReferenceDesigner == strongReferenceTarget)
				xpGranted /= 2;
			playerManager->awardExperience(strongReferenceDesigner, "imagedesigner", xpGranted, true);
		}

		if (idTimeoutEvent != NULL && idTimeoutEvent->isScheduled())
			dequeueIdTimeoutEvent();
	}

	targetObject->sendMessage(message);
}