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 ForageManagerImplementation::startForaging(CreatureObject* player, int forageType) { if (player == NULL) return; Locker playerLocker(player); int actionCostForage = 50; int mindCostShellfish = 100; int actionCostShellfish = 100; //Check if already foraging. Reference<Task*> pendingForage = player->getPendingTask("foraging"); if (pendingForage != NULL) { if (forageType == ForageManager::SHELLFISH) player->sendSystemMessage("@harvesting:busy"); else player->sendSystemMessage("@skl_use:sys_forage_already"); //"You are already foraging." return; } // Check if mounted if (player->isRidingMount()) { player->sendSystemMessage("@error_message:survey_on_mount"); // You cannot perform that action while mounted on a creature or driving a vehicle. return; } //Check if player is inside a structure. if (player->getParentID() != 0) { if (forageType == ForageManager::SHELLFISH) player->sendSystemMessage("@harvesting:inside"); else player->sendSystemMessage("@skl_use:sys_forage_inside"); //"You can't forage inside a structure." return; } //Check if a player is swimming for shellfish harvesting if (forageType == ForageManager::SHELLFISH && player->isSwimming()){ player->sendSystemMessage("@harvesting:swimming"); return; } //Check if player is in water for shellfish harvesting if (forageType == ForageManager::SHELLFISH && !player->isInWater()){ player->sendSystemMessage("@harvesting:in_water"); return; } //Check for action and deduct cost. if (forageType == ForageManager::SHELLFISH){ //Adjust costs based upon player's Focus and Quickness int mindCost = player->calculateCostAdjustment(CreatureAttribute::FOCUS, mindCostShellfish); int actionCost = player->calculateCostAdjustment(CreatureAttribute::QUICKNESS, actionCostShellfish); if (player->getHAM(CreatureAttribute::MIND) < mindCost + 1 || player->getHAM(CreatureAttribute::ACTION) < actionCost + 1) return; else { player->inflictDamage(player, CreatureAttribute::MIND, mindCost, false, true); player->inflictDamage(player, CreatureAttribute::ACTION, actionCost, false, true); } } else { //Adjust action cost based upon a player's Quickness int actionCost = player->calculateCostAdjustment(CreatureAttribute::QUICKNESS, actionCostForage); if (player->getHAM(CreatureAttribute::ACTION) >= actionCost + 1) player->inflictDamage(player, CreatureAttribute::ACTION, actionCost, false, true); else { player->sendSystemMessage("@skl_use:sys_forage_attrib"); //"You need to rest before you can forage again." return; } } //Collect player's current position. float playerX = player->getPositionX(); float playerY = player->getPositionY(); ManagedReference<ZoneServer*> zoneServer = player->getZoneServer(); //Queue the foraging task. Zone* zone = player->getZone(); if (zone == NULL) return; Reference<Task*> foragingEvent = new ForagingEvent(player, forageType, playerX, playerY, zone->getZoneName()); player->addPendingTask("foraging", foragingEvent, 8500); if(forageType == ForageManager::LAIR){ player->sendSystemMessage("You begin to search the lair for creatures"); //"You begin to search the lair for creatures." } else{ player->sendSystemMessage("@skl_use:sys_forage_start"); //"You begin to search the area for goods." } player->doAnimation("forage"); }
bool ForageManagerImplementation::forageGiveItems(CreatureObject* player, int forageType, float forageX, float forageY, const String& planet) { if (player == NULL) return false; Locker playerLocker(player); ManagedReference<LootManager*> lootManager = player->getZoneServer()->getLootManager(); ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory"); if (lootManager == NULL || inventory == NULL) { player->sendSystemMessage("@skl_use:sys_forage_fail"); return false; } //Check if inventory is full. if (inventory->hasFullContainerObjects()) { player->sendSystemMessage("@skl_use:sys_forage_noroom"); //"Some foraged items were discarded, because your inventory is full." return false; } int itemCount = 1; //Determine how many items the player finds. if (forageType == ForageManager::SCOUT) { if (player->hasSkill("outdoors_scout_camp_03") && System::random(5) == 1) itemCount += 1; if (player->hasSkill("outdoors_scout_master") && System::random(5) == 1) itemCount += 1; } //Discard items if player's inventory does not have enough space. int inventorySpace = inventory->getContainerVolumeLimit() - inventory->getContainerObjectsSize(); if (itemCount > inventorySpace) { itemCount = inventorySpace; player->sendSystemMessage("@skl_use:sys_forage_noroom"); //"Some foraged items were discarded, because your inventory is full." } //Determine what the player finds. int dice; int level = 1; String lootGroup = ""; String resName = ""; if (forageType == ForageManager::SHELLFISH){ bool mullosks = false; if (System::random(100) > 50) { resName = "seafood_mollusk"; mullosks = true; } else resName = "seafood_crustacean"; if(forageGiveResource(player, forageX, forageY, planet, resName)) { if (mullosks) player->sendSystemMessage("@harvesting:found_mollusks"); else player->sendSystemMessage("@harvesting:found_crustaceans"); return true; } else { player->sendSystemMessage("@harvesting:found_nothing"); return false; } } if (forageType == ForageManager::SCOUT) { for (int i = 0; i < itemCount; i++) { dice = System::random(200); level = 1; if (dice >= 0 && dice < 160) { lootGroup = "forage_food"; } else if (dice > 159 && dice < 200) { lootGroup = "forage_bait"; } else { lootGroup = "forage_rare"; } lootManager->createLoot(inventory, lootGroup, level); } } else if (forageType == ForageManager::MEDICAL) { //Medical Forage dice = System::random(200); level = 1; if (dice >= 0 && dice < 40) { //Forage food. lootGroup = "forage_food"; } else if (dice > 39 && dice < 110) { //Resources. if(forageGiveResource(player, forageX, forageY, planet, resName)) { player->sendSystemMessage("@skl_use:sys_forage_success"); return true; } else { player->sendSystemMessage("@skl_use:sys_forage_fail"); return false; } } else if (dice > 109 && dice < 170) { //Average components. lootGroup = "forage_medical_component"; level = 1; } else if (dice > 169 && dice < 200) { //Good components. lootGroup = "forage_medical_component"; level = 60; } else { //Exceptional Components lootGroup = "forage_medical_component"; level = 200; } lootManager->createLoot(inventory, lootGroup, level); } else if (forageType == ForageManager::LAIR) { //Lair Search dice = System::random(109); level = 1; if (dice >= 0 && dice < 40) { // Live Creatures lootGroup = "forage_live_creatures"; } else if (dice > 39 && dice < 110) { // Eggs resName = "meat_egg"; if(forageGiveResource(player, forageX, forageY, planet, resName)) { player->sendSystemMessage("@lair_n:found_eggs"); return true; } else { player->sendSystemMessage("@lair_n:found_nothing"); return false; } } if(!lootManager->createLoot(inventory, lootGroup, level)) { player->sendSystemMessage("Unable to create loot for lootgroup " + lootGroup); return false; } player->sendSystemMessage("@lair_n:found_bugs"); return true; } player->sendSystemMessage("@skl_use:sys_forage_success"); return true; }
void ForageManagerImplementation::finishForaging(CreatureObject* player, int forageType, float forageX, float forageY, const String& zoneName) { if (player == NULL) return; Locker playerLocker(player); Locker forageAreasLocker(_this.get()); player->removePendingTask("foraging"); if (player->getZone() == NULL) return; //Check if player moved. float playerX = player->getPositionX(); float playerY = player->getPositionY(); if ((fabs(playerX - forageX) > 2.0) || (fabs(playerY - forageY) > 2.0) || player->getZone()->getZoneName() != zoneName) { player->sendSystemMessage("@skl_use:sys_forage_movefail"); //"You fail to forage because you moved." return; } //Check if player is in combat. if (player->isInCombat()) { player->sendSystemMessage("@skl_use:sys_forage_combatfail"); //"Combat distracts you from your foraging attempt." return; } //Check if player is allowed to forage in this area. if (forageType != ForageManager::SHELLFISH) { Reference<ForageAreaCollection*> forageAreaCollection = forageAreas.get(player->getFirstName()); if (forageAreaCollection != NULL) { //Player has foraged before. if (!forageAreaCollection->checkForageAreas(forageX, forageY, zoneName, forageType)) { if( forageType == LAIR ){ player->sendSystemMessage("There is nothing of interest remaining in the lair."); } else{ player->sendSystemMessage("@skl_use:sys_forage_empty"); //"There is nothing in this area to forage." } return; } } else { //Player has not foraged before. forageAreaCollection = new ForageAreaCollection(player, forageX, forageY, zoneName, forageType); forageAreas.put(player->getFirstName(), forageAreaCollection); } } //Calculate the player's chance to find an item. int chance; int skillMod; switch(forageType) { case ForageManager::SCOUT: case ForageManager::LAIR: skillMod = player->getSkillMod("foraging"); chance = (int)(15 + (skillMod * 0.8)); break; case ForageManager::MEDICAL: skillMod = player->getSkillMod("medical_foraging"); chance = (int)(15 + (skillMod * 0.6)); break; default: skillMod = 20; chance = (int)(15 + (skillMod * 0.6)); break; } //Determine if player finds an item. if (chance > 100) //There could possibly be +foraging skill tapes. chance = 100; if (System::random(80) > chance) { if (forageType == ForageManager::SHELLFISH) player->sendSystemMessage("@harvesting:found_nothing"); else if (forageType == ForageManager::LAIR) player->sendSystemMessage("@lair_n:found_nothing"); else player->sendSystemMessage("@skl_use:sys_forage_fail"); //"You failed to find anything worth foraging." } else { forageGiveItems(player, forageType, forageX, forageY, zoneName); } return; }