void PlanetManagerImplementation::loadPlanetObjects(LuaObject* luaObject) {
	if (!luaObject->isValidTable())
		return;

	for (int i = 1; i <= luaObject->getTableSize(); ++i) {
		lua_State* L = luaObject->getLuaState();
		lua_rawgeti(L, -1, i);

		LuaObject planetObject(L);

		String templateFile = planetObject.getStringField("templateFile");

		ManagedReference<SceneObject*> obj = ObjectManager::instance()->createObject(templateFile.hashCode(), 0, "");

		if (obj != NULL) {
			Locker objLocker(obj);

			float x = planetObject.getFloatField("x");
			float y = planetObject.getFloatField("y");
			float z = planetObject.getFloatField("z");
			float ox = planetObject.getFloatField("ox");
			float oy = planetObject.getFloatField("oy");
			float oz = planetObject.getFloatField("oz");
			float ow = planetObject.getFloatField("ow");
			uint64 parentID = planetObject.getLongField("parent");

			if (obj->isBuildingObject()) {
				BuildingObject* building = obj->asBuildingObject();

				building->createCellObjects();
			}

			obj->initializePosition(x, z, y);
			obj->setDirection(ow, ox, oy, oz);

			ManagedReference<SceneObject*> parent = zone->getZoneServer()->getObject(parentID);

			if (parent != NULL)
				parent->transferObject(obj, -1, true);
			else
				zone->transferObject(obj, -1, true);

			obj->createChildObjects();
		}

		planetObject.pop();
	}
}
SceneObject* CreatureManagerImplementation::spawnDynamicSpawn(unsigned int lairTemplate, int difficulty, float x, float z, float y, float size) {
	LairTemplate* lairTmpl = creatureTemplateManager->getLairTemplate(lairTemplate);

	if (lairTmpl == NULL || lairTmpl->getBuildingType() != LairTemplate::NONE)
		return NULL;

	Vector<String>* mobiles = lairTmpl->getWeightedMobiles();

	if (mobiles->size() == 0)
		return NULL;

	ManagedReference<TheaterObject*> theater = zoneServer->createObject(STRING_HASHCODE("object/intangible/theater/base_theater.iff"), 0).castTo<TheaterObject*>();

	if (theater == NULL) {
		error("error creating intangible theater");
		return NULL;
	}

	Locker blocker(theater);

	theater->initializePosition(x, z, y);
	theater->setDespawnOnNoPlayersInRange(true);

	ManagedReference<DynamicSpawnObserver*> dynamicObserver = new DynamicSpawnObserver();
	dynamicObserver->deploy();
	dynamicObserver->setLairTemplate(lairTmpl);
	dynamicObserver->setDifficulty(difficulty);
	dynamicObserver->setObserverType(ObserverType::LAIR);
	dynamicObserver->setSize(size);

	theater->registerObserver(ObserverEventType::CREATUREDESPAWNED, dynamicObserver);
	theater->registerObserver(ObserverEventType::OBJECTREMOVEDFROMZONE, dynamicObserver);

	zone->transferObject(theater, -1, false);

	theater->createChildObjects();
	dynamicObserver->spawnInitialMobiles(theater);

	return theater;
}
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);
}
Example #4
0
void SuiManager::handleCharacterBuilderSelectItem(CreatureObject* player, SuiBox* suiBox, uint32 cancel, Vector<UnicodeString>* args) {
	ZoneServer* zserv = player->getZoneServer();

	if (args->size() < 1)
		return;

	bool otherPressed = false;
	int index = 0;

	if(args->size() > 1) {
		otherPressed = Bool::valueOf(args->get(0).toString());
		index = Integer::valueOf(args->get(1).toString());
	} else {
		index = Integer::valueOf(args->get(0).toString());
	}

	if (!suiBox->isCharacterBuilderBox())
		return;

	ManagedReference<SuiCharacterBuilderBox*> cbSui = cast<SuiCharacterBuilderBox*>( suiBox);

	CharacterBuilderMenuNode* currentNode = cbSui->getCurrentNode();

	PlayerObject* ghost = player->getPlayerObject();

	//If cancel was pressed then we kill the box/menu.
	if (cancel != 0)
		return;

	//Back was pressed. Send the node above it.
	if (otherPressed) {
		CharacterBuilderMenuNode* parentNode = currentNode->getParentNode();

		if(parentNode == NULL)
			return;

		cbSui->setCurrentNode(parentNode);

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

	CharacterBuilderMenuNode* node = currentNode->getChildNodeAt(index);

	//Node doesn't exist or the index was out of bounds. Should probably resend the menu here.
	if (node == NULL) {
		ghost->addSuiBox(cbSui);
		player->sendMessage(cbSui->generateMessage());
		return;
	}

	if (node->hasChildNodes()) {
		//If it has child nodes, display them.
		cbSui->setCurrentNode(node);
		ghost->addSuiBox(cbSui);
		player->sendMessage(cbSui->generateMessage());
	} else {

		String templatePath = node->getTemplatePath();

		if (templatePath.indexOf(".iff") < 0) { // Non-item selections

			if (templatePath == "unlearn_all_skills") {

				SkillManager::instance()->surrenderAllSkills(player);
				player->sendSystemMessage("All skills unlearned.");

			} else if (templatePath == "cleanse_character") {

				if (!player->isInCombat()) {
					player->sendSystemMessage("You have been cleansed from the signs of previous battles.");

					for (int i = 0; i < 9; ++i) {
						player->setWounds(i, 0);
					}

					player->setShockWounds(0);
				} else {
					player->sendSystemMessage("Not within combat.");
				}

			} else if (templatePath == "reset_buffs") {

				if (!player->isInCombat()) {
					player->sendSystemMessage("Your buffs have been reset.");

					player->clearBuffs(true);

					ghost->setFoodFilling(0);
					ghost->setDrinkFilling(0);
				} else {
					player->sendSystemMessage("Not within combat.");
				}

			} else if (templatePath.beginsWith("crafting_apron_")) {

				//"object/tangible/wearables/apron/apron_chef_s01.iff"
				//"object/tangible/wearables/ithorian/apron_chef_jacket_s01_ith.iff"

				uint32 itemCrc = ( player->getSpecies() != CreatureObject::ITHORIAN ) ? 0x5DDC4E5D : 0x6C191FBB;

				ManagedReference<WearableObject*> apron = zserv->createObject(itemCrc, 2).castTo<WearableObject*>();

				if (apron == NULL) {
					player->sendSystemMessage("There was an error creating the requested item. Please contact customer support with this issue.");
					ghost->addSuiBox(cbSui);
					player->sendMessage(cbSui->generateMessage());

					error("could not create frog crafting apron");
					return;
				}

				apron->createChildObjects();

				if (apron->isWearableObject()) {
					uint32 bitmask = apron->getOptionsBitmask() | OptionBitmask::YELLOW;
					apron->setOptionsBitmask(bitmask, false);

					UnicodeString modName = "(General)";
					apron->addSkillMod(SkillModManager::WEARABLE, "general_assembly", 25);
					apron->addSkillMod(SkillModManager::WEARABLE, "general_experimentation", 25);

					if(templatePath == "crafting_apron_armorsmith") {
						modName = "(Armorsmith)";
						apron->addSkillMod(SkillModManager::WEARABLE, "armor_assembly", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "armor_experimentation", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "armor_repair", 25);
					} else if(templatePath == "crafting_apron_weaponsmith") {
						modName = "(Weaponsmith)";
						apron->addSkillMod(SkillModManager::WEARABLE, "weapon_assembly", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "weapon_experimentation", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "weapon_repair", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "grenade_assembly", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "grenade_experimentation", 25);
					} else if(templatePath == "crafting_apron_tailor") {
						modName = "(Tailor)";
						apron->addSkillMod(SkillModManager::WEARABLE, "clothing_assembly", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "clothing_experimentation", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "clothing_repair", 25);
					} else if(templatePath == "crafting_apron_chef") {
						modName = "(Chef)";
						apron->addSkillMod(SkillModManager::WEARABLE, "food_assembly", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "food_experimentation", 25);
					} else if(templatePath == "crafting_apron_architect") {
						modName = "(Architect)";
						apron->addSkillMod(SkillModManager::WEARABLE, "structure_assembly", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "structure_experimentation", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "structure_complexity", 25);
					} else if(templatePath == "crafting_apron_droid_engineer") {
						modName = "(Droid Engineer)";
						apron->addSkillMod(SkillModManager::WEARABLE, "droid_assembly", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "droid_experimentation", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "droid_complexity", 25);
					} else if(templatePath == "crafting_apron_doctor") {
						modName = "(Doctor)";
						apron->addSkillMod(SkillModManager::WEARABLE, "medicine_assembly", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "medicine_experimentation", 25);
					} else if(templatePath == "crafting_apron_combat_medic") {
						modName = "(Combat Medic)";
						apron->addSkillMod(SkillModManager::WEARABLE, "combat_medicine_assembly", 25);
						apron->addSkillMod(SkillModManager::WEARABLE, "combat_medicine_experimentation", 25);
					}

					UnicodeString apronName = "Crafting Apron " + modName;
					apron->setCustomObjectName(apronName, false);
				}

				ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");
				apron->sendTo(player, true);
				inventory->transferObject(apron, -1, true);

				StringIdChatParameter stringId;
				stringId.setStringId("@faction_perk:bonus_base_name"); //You received a: %TO.
				stringId.setTO(apron);
				player->sendSystemMessage(stringId);

			} else if (templatePath == "enhance_character") {

				ManagedReference<SceneObject*> scob = cbSui->getUsingObject();
				if (scob != NULL) {

					if (scob->getGameObjectType() == SceneObjectType::CHARACTERBUILDERTERMINAL) {
						CharacterBuilderTerminal* bluefrog = cast<CharacterBuilderTerminal*>( scob.get());
						bluefrog->enhanceCharacter(player);
					}
				}

			} else if (templatePath == "credits") {

				player->addCashCredits(50000, true);
				player->sendSystemMessage("You have received 50.000 Credits");

			} else if (templatePath == "faction_rebel") {

				ghost->increaseFactionStanding("rebel", 100000);

			} else if (templatePath == "faction_imperial") {

				ghost->increaseFactionStanding("imperial", 100000);

			} else if (templatePath == "language") {

				ManagedReference<SceneObject*> scob = cbSui->getUsingObject();
				if (scob != NULL) {

					if (scob->getGameObjectType() == SceneObjectType::CHARACTERBUILDERTERMINAL) {
						CharacterBuilderTerminal* bluefrog = cast<CharacterBuilderTerminal*>( scob.get());
						bluefrog->giveLanguages(player);
					}
				}

			} else if (templatePath == "apply_dots") {
				ManagedReference<SceneObject*> scob = cbSui->getUsingObject();
				player->addDotState(CreatureState::POISONED, scob->getObjectID(), 100, CreatureAttribute::HEALTH, 60, 80, 0);
				player->addDotState(CreatureState::BLEEDING, scob->getObjectID(), 100, CreatureAttribute::ACTION, 60, 80, 0);
				player->addDotState(CreatureState::DISEASED, scob->getObjectID(), 100, CreatureAttribute::ACTION, 60, 80, 0);
				player->addDotState(CreatureState::ONFIRE, scob->getObjectID(), 100, CreatureAttribute::HEALTH, 60, 80, 0);
			} else if (templatePath == "clear_dots") {
				player->clearDots();
			} else if (templatePath == "max_xp") {
				ghost->maximizeExperience();
				player->sendSystemMessage("You have maximized all xp types.");
			} else {

				if (templatePath.length() > 0) {

					SkillManager::instance()->awardSkill(templatePath, player, true, true, true);
					if (player->hasSkill(templatePath))
						player->sendSystemMessage("You have learned a skill.");

				} else {

					player->sendSystemMessage("Unknown selection.");

				}
			}

			ghost->addSuiBox(cbSui);
			player->sendMessage(cbSui->generateMessage());
		} else { // Items

			if (templatePath.contains("event_perk")) {
				if (ghost->getEventPerkCount() >= 5) {
					player->sendSystemMessage("@event_perk:pro_too_many_perks"); // You cannot rent any more items right now.
					ghost->addSuiBox(cbSui);
					player->sendMessage(cbSui->generateMessage());
					return;
				}
			}

			ManagedReference<SceneObject*> item = zserv->createObject(node->getTemplateCRC(), 1);

			if (item == NULL) {
				player->sendSystemMessage("There was an error creating the requested item. Please contact customer support with this issue.");
				ghost->addSuiBox(cbSui);
				player->sendMessage(cbSui->generateMessage());

				error("could not create frog item: " + node->getDisplayName());
				return;
			}

			item->createChildObjects();

			if (item->isEventPerkDeed()) {
				EventPerkDeed* deed = cast<EventPerkDeed*>(item.get());
				deed->setOwner(player);
				ghost->addEventPerk(deed);
			}

			ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");
			item->sendTo(player, true);
			inventory->transferObject(item, -1, true);

			StringIdChatParameter stringId;
			stringId.setStringId("@faction_perk:bonus_base_name"); //You received a: %TO.
			stringId.setTO(item);
			player->sendSystemMessage(stringId);

			ghost->addSuiBox(cbSui);
			player->sendMessage(cbSui->generateMessage());
		}
	}
}
bool PlayerCreationManager::createCharacter(MessageCallback* data) {
	TemplateManager* templateManager = TemplateManager::instance();

	ClientCreateCharacterCallback* callback = cast<
			ClientCreateCharacterCallback*>(data);
	ZoneClientSession* client = data->getClient();

	if (client->getCharacterCount(zoneServer.get()->getGalaxyID()) >= 10) {
		ErrorMessage* errMsg = new ErrorMessage("Create Error", "You are limited to 10 characters per galaxy.", 0x0);
		client->sendMessage(errMsg);

		return false;
	}

	PlayerManager* playerManager = zoneServer.get()->getPlayerManager();

	SkillManager* skillManager = SkillManager::instance();

	//Get all the data and validate it.
	UnicodeString characterName;
	callback->getCharacterName(characterName);

	//TODO: Replace this at some point?
	if (!playerManager->checkPlayerName(callback))
		return false;

	String raceFile;
	callback->getRaceFile(raceFile);

	uint32 serverObjectCRC = raceFile.hashCode();

	PlayerCreatureTemplate* playerTemplate =
			dynamic_cast<PlayerCreatureTemplate*>(templateManager->getTemplate(
					serverObjectCRC));

	if (playerTemplate == NULL) {
		error("Unknown player template selected: " + raceFile);
		return false;
	}

	int raceID = playerTemplate->getRace();


	String fileName = playerTemplate->getTemplateFileName();
	String clientTemplate = templateManager->getTemplateFile(
			playerTemplate->getClientObjectCRC());

	RacialCreationData* raceData = racialCreationData.get(fileName);

	if (raceData == NULL)
		raceData = racialCreationData.get(0); //Just get the first race, since they tried to create a race that doesn't exist.

	String profession, customization, hairTemplate, hairCustomization;
	callback->getSkill(profession);

	if (profession.contains("jedi"))
		profession = "crafting_artisan";

	callback->getCustomizationString(customization);
	callback->getHairObject(hairTemplate);
	callback->getHairCustomization(hairCustomization);

	float height = callback->getHeight();
	height = MAX(MIN(height, playerTemplate->getMaxScale()),
			playerTemplate->getMinScale());

	//validate biography
	UnicodeString bio;
	callback->getBiography(bio);

	bool doTutorial = callback->getTutorialFlag();
	//bool doTutorial = false;

	ManagedReference<CreatureObject*> playerCreature =
			zoneServer.get()->createObject(
					serverObjectCRC, 2).castTo<CreatureObject*>();

	if (playerCreature == NULL) {
		error("Could not create player with template: " + raceFile);
		return false;
	}

	Locker playerLocker(playerCreature);

	playerCreature->createChildObjects();
	playerCreature->setHeight(height);
	playerCreature->setCustomObjectName(characterName, false); //TODO: Validate with Name Manager.

	client->setPlayer(playerCreature);
	playerCreature->setClient(client);

	// Set starting cash and starting bank
	playerCreature->setCashCredits(startingCash, false);
	playerCreature->setBankCredits(startingBank, false);

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

	if (ghost != NULL) {
		//Set skillpoints before adding any skills.
		ghost->setSkillPoints(skillPoints);
		ghost->setStarterProfession(profession);
	}

	addCustomization(playerCreature, customization,
			playerTemplate->getAppearanceFilename());
	addHair(playerCreature, hairTemplate, hairCustomization);
	if (!doTutorial) {
		addProfessionStartingItems(playerCreature, profession, clientTemplate,
				false);
		addStartingItems(playerCreature, clientTemplate, false);
		addRacialMods(playerCreature, fileName,
				playerTemplate->getStartingSkills(),
				playerTemplate->getStartingItems(), false);
	} else {
		addProfessionStartingItems(playerCreature, profession, clientTemplate,
				true);
		addStartingItems(playerCreature, clientTemplate, true);
		addRacialMods(playerCreature, fileName,
				playerTemplate->getStartingSkills(),
				playerTemplate->getStartingItems(), true);
	}

	// Set starting cash and starting bank
	playerCreature->setCashCredits(startingCash, false);
	playerCreature->setBankCredits(startingBank, false);

	if (ghost != NULL) {

		ghost->setAccountID(client->getAccountID());

		if (!freeGodMode) {
			try {
				uint32 accID = client->getAccountID();

				ManagedReference<Account*> playerAccount = playerManager->getAccount(accID);

				if (playerAccount == NULL) {
					playerCreature->destroyPlayerCreatureFromDatabase(true);
					return false;
				}

				int accountPermissionLevel = playerAccount->getAdminLevel();
				String accountName = playerAccount->getUsername();

				if(accountPermissionLevel > 0 && (accountPermissionLevel == 9 || accountPermissionLevel == 10 || accountPermissionLevel == 12 || accountPermissionLevel == 15)) {
					playerManager->updatePermissionLevel(playerCreature, accountPermissionLevel);

					/*
					Reference<ShipControlDevice*> shipControlDevice = zoneServer->createObject(STRING_HASHCODE("object/intangible/ship/sorosuub_space_yacht_pcd.iff"), 1).castTo<ShipControlDevice*>();
					//ShipObject* ship = (ShipObject*) server->createObject(STRING_HASHCODE("object/ship/player/player_sorosuub_space_yacht.iff"), 1);
					Reference<ShipObject*> ship = zoneServer->createObject(STRING_HASHCODE("object/ship/player/player_basic_tiefighter.iff"), 1).castTo<ShipObject*>();

					shipControlDevice->setControlledObject(ship);

					if (!shipControlDevice->transferObject(ship, 4))
						info("Adding of ship to device failed");

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

					if (datapad != NULL) {
						if (!datapad->transferObject(shipControlDevice, -1)) {
							shipControlDevice->destroyObjectFromDatabase(true);
						}
					} else {
						shipControlDevice->destroyObjectFromDatabase(true);
						error("could not get datapad from player");
					}
					*/
				}

				if (accountPermissionLevel < 9) {
					try {
						StringBuffer query;
						//query << "SELECT UNIX_TIMESTAMP(creation_date) FROM characters c WHERE galaxy_id = " << zoneServer.get()->getGalaxyID() << " AND account_id = " << client->getAccountID() << " ORDER BY creation_date desc;";
						uint32 galaxyId = zoneServer.get()->getGalaxyID();
						uint32 accountId = client->getAccountID();
						query << "(SELECT UNIX_TIMESTAMP(c.creation_date) as t FROM characters as c WHERE c.account_id = " << accountId << " AND c.galaxy_id = " << galaxyId << " ORDER BY c.creation_date DESC) UNION (SELECT UNIX_TIMESTAMP(d.creation_date) FROM deleted_characters as d WHERE d.account_id = " << accountId << " AND d.galaxy_id = " << galaxyId << " ORDER BY d.creation_date DESC) ORDER BY t DESC LIMIT 1";

						Reference<ResultSet*> res = ServerDatabase::instance()->executeQuery(query);

						if (res != NULL && res->next()) {
							uint32 sec = res->getUnsignedInt(0);

							Time timeVal(sec);

							if (timeVal.miliDifference() < 86400000) {
								ErrorMessage* errMsg = new ErrorMessage("Create Error", "You are only permitted to create one character every 24 hours. Repeat attempts prior to 24 hours elapsing will reset the timer.", 0x0);
								client->sendMessage(errMsg);

								playerCreature->destroyPlayerCreatureFromDatabase(true);
								return false;
							}
							//timeVal.se
						}
					} catch (DatabaseException& e) {
						error(e.getMessage());
					}

					Locker locker(&charCountMutex);

					if (lastCreatedCharacter.containsKey(accID)) {
						Time lastCreatedTime = lastCreatedCharacter.get(accID);

						if (lastCreatedTime.miliDifference() < 86400000) {
							ErrorMessage* errMsg = new ErrorMessage("Create Error", "You are only permitted to create one character every 24 hours. Repeat attempts prior to 24 hours elapsing will reset the timer.", 0x0);
							client->sendMessage(errMsg);

							playerCreature->destroyPlayerCreatureFromDatabase(true);
							return false;
						} else {
							lastCreatedTime.updateToCurrentTime();

							lastCreatedCharacter.put(accID, lastCreatedTime);
						}
					} else {
						lastCreatedCharacter.put(accID, Time());
					}
				}

			} catch (Exception& e) {
				error(e.getMessage());
			}
		} else {
			playerManager->updatePermissionLevel(playerCreature, PermissionLevelList::instance()->getLevelNumber("admin"));
		}

		if (doTutorial)
			playerManager->createTutorialBuilding(playerCreature);
		else
			playerManager->createSkippedTutorialBuilding(playerCreature);

		ValidatedPosition* lastValidatedPosition =
				ghost->getLastValidatedPosition();
		lastValidatedPosition->update(playerCreature);

		ghost->setBiography(bio);
		ghost->setRaceID(raceID);

		ghost->setLanguageID(playerTemplate->getDefaultLanguage());
	}

	playerCreature->setLevel(1);

	ClientCreateCharacterSuccess* msg = new ClientCreateCharacterSuccess(
			playerCreature->getObjectID());
	playerCreature->sendMessage(msg);

	ChatManager* chatManager = zoneServer.get()->getChatManager();
	chatManager->addPlayer(playerCreature);

	String firstName = playerCreature->getFirstName();
	String lastName = playerCreature->getLastName();

	try {
		StringBuffer query;
		query
				<< "INSERT INTO `characters_dirty` (`character_oid`, `account_id`, `galaxy_id`, `firstname`, `surname`, `race`, `gender`, `template`)"
				<< " VALUES (" << playerCreature->getObjectID() << ","
				<< client->getAccountID() << "," << zoneServer.get()->getGalaxyID()
				<< "," << "'" << firstName.escapeString() << "','"
				<< lastName.escapeString() << "'," << raceID << "," << 0 << ",'"
				<< raceFile.escapeString() << "')";

		ServerDatabase::instance()->executeStatement(query);
	} catch (DatabaseException& e) {
		error(e.getMessage());
	}

	playerManager->addPlayer(playerCreature);

	// Copy claimed veteran rewards from player's alt character
	uint32 accID = client->getAccountID();
	ManagedReference<Account*> playerAccount = playerManager->getAccount(accID);
	if (playerAccount != NULL && ghost != NULL) {

		// Find the first alt character
		ManagedReference<CreatureObject*> altPlayer = NULL;
		CharacterList* characters = playerAccount->getCharacterList();
		for(int i = 0; i < characters->size(); ++i) {
			CharacterListEntry* entry = &characters->get(i);
			if(entry->getGalaxyID() == zoneServer.get()->getGalaxyID() &&
		       entry->getFirstName() != playerCreature->getFirstName() ) {

				altPlayer = playerManager->getPlayer(entry->getFirstName());
				if( altPlayer != NULL ){
					break;
				}
			}
		}

		// Record the rewards if alt player was found
		if( altPlayer != NULL && altPlayer->getPlayerObject() != NULL){

			Locker alocker( altPlayer );
			for( int i = 0; i < playerManager->getNumVeteranRewardMilestones(); i++ ){
				int milestone = playerManager->getVeteranRewardMilestone(i);
				String claimedReward = altPlayer->getPlayerObject()->getChosenVeteranReward(milestone);
				if( !claimedReward.isEmpty() ){
					ghost->addChosenVeteranReward(milestone,claimedReward);
				}
			}
		}
	}

	client->addCharacter(playerCreature->getObjectID(), zoneServer.get()->getGalaxyID());

	JediManager::instance()->onPlayerCreated(playerCreature);

	ManagedReference<SuiMessageBox*> box = new SuiMessageBox(playerCreature, SuiWindowType::NONE);
	box->setPromptTitle("PLEASE NOTE");
	box->setPromptText("You are limited to creating one character every 24 hours. Attempting to create another character or deleting your character before the 24 hour timer expires will reset the timer.");

	ghost->addSuiBox(box);
	playerCreature->sendMessage(box->generateMessage());
	ghost->recalculateCombatLevel(playerCreature);

	return true;
}
void CreateVendorSessionImplementation::createVendor(String& name) {
	ManagedReference<CreatureObject*> player = this->player.get();

	Locker locker(player);

	if (!VendorManager::instance()->isValidVendorName(name)) {
		player->sendSystemMessage("@player_structure:obscene");
		SuiInputBox* input = new SuiInputBox(player, SuiWindowType::STRUCTURE_NAME_VENDOR);
		input->setCallback(new NameVendorSuiCallback(player->getZoneServer()));
		input->setCancelButton(true, "@cancel");
		input->setPromptTitle("@player_structure:name_t");
		input->setPromptText("@player_structure:name_d");

		player->sendMessage(input->generateMessage());
		player->getPlayerObject()->addSuiBox(input);
		return;
	}

	ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");
	if (inventory == NULL) {
		cancelSession();
		return;
	}

	ManagedReference<TangibleObject*> vendor;

	try {
		vendor = (player->getZoneServer()->createObject(templatePath.hashCode())).castTo<TangibleObject*>();
	} catch (Exception& e) {
		error(e.getMessage());
	}

	if (vendor == NULL) {
		error("could not create vendor " + templatePath);
		cancelSession();
		return;
	}

	Locker clocker(vendor, player);

	if (!vendor->isVendor()) {
		error("could not create vendor " + templatePath);
		vendor->destroyObjectFromDatabase(true);
		cancelSession();
		return;
	}

	vendor->createChildObjects();

	if (inventory->isContainerFullRecursive()) {
		player->sendSystemMessage("@player_structure:create_failed");
		vendor->destroyObjectFromDatabase(true);
		cancelSession();
		return;
	}

	DataObjectComponentReference* data = vendor->getDataObjectComponent();
	if(data == NULL || data->get() == NULL || !data->get()->isVendorData()) {
		error("Invalid vendor, no data component: " + templatePath);
		player->sendSystemMessage("@player_structure:create_failed");
		vendor->destroyObjectFromDatabase(true);
		cancelSession();
		return;
	}

	VendorDataComponent* vendorData = cast<VendorDataComponent*>(data->get());
	if(vendorData == NULL) {
		error("Invalid vendor, no data component: " + templatePath);
		player->sendSystemMessage("@player_structure:create_failed");
		vendor->destroyObjectFromDatabase(true);
		cancelSession();
		return ;
	}

	vendorData->setOwnerId(player->getObjectID());

	vendor->setCustomObjectName("Vendor: " + name, false);
	vendor->setContainerOwnerID(player->getObjectID());

	vendor->setMaxCondition(1000, false);
	vendor->setConditionDamage(0, false);

	if(vendor->isCreatureObject()) {
		randomizeVendorLooks(cast<CreatureObject*>(vendor.get()));
	}

	if(!inventory->transferObject(vendor, -1, false)) {
		player->sendSystemMessage("@player_structure:create_failed");
		vendor->destroyObjectFromDatabase(true);
		cancelSession();
		return;
	}

	inventory->broadcastObject(vendor, true);
	player->getPlayerObject()->addVendor(vendor);

	player->sendSystemMessage("@player_structure:create_success");
	cancelSession();
}
TangibleObject* LootManagerImplementation::createLootObject(LootItemTemplate* templateObject, int level, bool maxCondition) {

	if(level < 1)
		level = 1;

	if(level > 300)
		level = 300;

	String directTemplateObject = templateObject->getDirectObjectTemplate();

	ManagedReference<TangibleObject*> prototype = zoneServer->createObject(directTemplateObject.hashCode(), 2).castTo<TangibleObject*>();

	if (prototype == NULL) {
		error("could not create loot object: " + directTemplateObject);
		return NULL;
	}

	prototype->createChildObjects();

	String serial = craftingManager->generateSerial();
	prototype->setSerialNumber(serial);
	prototype->setJunkDealerNeeded(templateObject->getJunkDealerTypeNeeded());
	float junkMinValue = templateObject->getJunkMinValue() * junkValueModifier;
	float junkMaxValue = templateObject->getJunkMaxValue() * junkValueModifier;
	float fJunkValue = junkMinValue+System::random(junkMaxValue-junkMinValue);

	if (level>0 && templateObject->getJunkDealerTypeNeeded()>1){
		fJunkValue=fJunkValue + (fJunkValue * ((float)level / 100)); // This is the loot value calculation if the item has a level
	}
	CraftingValues craftingValues = templateObject->getCraftingValuesCopy();

	setInitialObjectStats(templateObject, &craftingValues, prototype);

	setCustomObjectName(prototype, templateObject);

	float excMod = 1.0;

	if (System::random(legendaryChance) == legendaryChance) {
			uint32 bitmask = prototype->getOptionsBitmask() | OptionBitmask::YELLOW;

			UnicodeString newName = prototype->getDisplayedName() + " (Legendary)";
			prototype->setCustomObjectName(newName, false);

			excMod = legendaryModifier;

			prototype->setOptionsBitmask(bitmask, false);
	} else if (System::random(exceptionalChance) == exceptionalChance) {
		uint32 bitmask = prototype->getOptionsBitmask() | OptionBitmask::YELLOW;

		UnicodeString newName = prototype->getDisplayedName() + " (Exceptional)";
		prototype->setCustomObjectName(newName, false);

		excMod = exceptionalModifier;

		prototype->setOptionsBitmask(bitmask, false);
	}
	String subtitle;
	bool yellow = false;

	for (int i = 0; i < craftingValues.getExperimentalPropertySubtitleSize(); ++i) {
		subtitle = craftingValues.getExperimentalPropertySubtitle(i);

		if (subtitle == "hitpoints" || subtitle == "maxrange") {
			if(!(prototype->isComponent())) {
				continue;
			}
		}

		float min = craftingValues.getMinValue(subtitle);
		float max = craftingValues.getMaxValue(subtitle);

		if (min == max)
			continue;

		if (subtitle != "useCount" &&
				subtitle != "quantity" &&
				subtitle != "charges" &&
				subtitle != "uses" &&
				subtitle != "charge") {

			float minMod = (max > min) ? 2000.f : -2000.f;
			float maxMod = (max > min) ? 500.f : -500.f;

			if (max > min && min >= 0) { // Both max and min non-negative, max is higher
				min = ((min * level / minMod) + min) * excMod;
				max = ((max * level / maxMod) + max) * excMod;

			} else if (max > min && max <= 0) { // Both max and min are non-positive, max is higher
				minMod *= -1;
				maxMod *= -1;
				min = ((min * level / minMod) + min) / excMod;
				max = ((max * level / maxMod) + max) / excMod;

			} else if (max > min) { // max is positive, min is negative
				minMod *= -1;
				min = ((min * level / minMod) + min) / excMod;
				max = ((max * level / maxMod) + max) * excMod;

			} else if (max < min && max >= 0) { // Both max and min are non-negative, min is higher
				min = ((min * level / minMod) + min) / excMod;
				max = ((max * level / maxMod) + max) / excMod;

			} else if (max < min && min <= 0) { // Both max and min are non-positive, min is higher
				minMod *= -1;
				maxMod *= -1;
				min = ((min * level / minMod) + min) * excMod;
				max = ((max * level / maxMod) + max) * excMod;

			} else { // max is negative, min is positive
				maxMod *= -1;
				min = ((min * level / minMod) + min) / excMod;
				max = ((max * level / maxMod) + max) * excMod;
			}
		} else {
			if (excMod != 1.0) {
				min *= yellowModifier;
				max *= yellowModifier;
			}
		}

		if (excMod == 1.0 && (yellowChance == 0 || System::random(yellowChance) == 0)) {
			if (max > min && min >= 0) {
				min *= yellowModifier;
				max *= yellowModifier;
			} else if (max > min && max <= 0) {
				min /= yellowModifier;
				max /= yellowModifier;
			} else if (max > min) {
				min /= yellowModifier;
				max *= yellowModifier;
			} else if (max < min && max >= 0) {
				min /= yellowModifier;
				max /= yellowModifier;
			} else if (max < min && min <= 0) {
				min *= yellowModifier;
				max *= yellowModifier;
			} else {
				min /= yellowModifier;
				max *= yellowModifier;
			}

			yellow = true;
		}

		craftingValues.setMinValue(subtitle, min);
		craftingValues.setMaxValue(subtitle, max);

		float percentage = System::random(10000) / 10000.f;

		craftingValues.setCurrentPercentage(subtitle, percentage);
	}

	if (yellow) {
		uint32 bitmask = prototype->getOptionsBitmask() | OptionBitmask::YELLOW;
		prototype->setOptionsBitmask(bitmask, false);
		prototype->setJunkValue((int)(fJunkValue * 1.25));
	}else{
		if (excMod==1){
			prototype->setJunkValue((int)(fJunkValue));
		}else{
			prototype->setJunkValue((int)(fJunkValue * (excMod/2)));
		}
	}

	// Use percentages to recalculate the values
	craftingValues.recalculateValues(false);

	craftingValues.addExperimentalProperty("creatureLevel", "creatureLevel", level, level, 0, false, CraftingManager::LINEARCOMBINE);
	craftingValues.setHidden("creatureLevel");

	//check weapons and weapon components for min damage > max damage
	if (prototype->isComponent() || prototype->isWeaponObject()) {
		if (craftingValues.hasProperty("mindamage") && craftingValues.hasProperty("maxdamage")) {
			float oldMin = craftingValues.getCurrentValue("mindamage");
			float oldMax = craftingValues.getCurrentValue("maxdamage");

			if (oldMin > oldMax) {
				craftingValues.setCurrentValue("mindamage", oldMax);
				craftingValues.setCurrentValue("maxdamage", oldMin);
			}
		}
	}

	// Add Dots to weapon objects.
	addStaticDots(prototype, templateObject, level);
	addRandomDots(prototype, templateObject, level, excMod);

	setSkillMods(prototype, templateObject, level, excMod);

	setSockets(prototype, &craftingValues);

	// Update the Tano with new values
	prototype->updateCraftingValues(&craftingValues, true);

	//add some condition damage where appropriate
	if (!maxCondition)
		addConditionDamage(prototype, &craftingValues);

	return prototype;
}