Advertisement
kissofdarknes

Untitled

May 27th, 2017
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 174.45 KB | None | 0 0
  1. /*
  2. * PlayerManagerImplementation.cpp
  3. *
  4. * Created on: 18/07/2009
  5. * Author: TheAnswer
  6. */
  7.  
  8. #include "server/zone/managers/player/PlayerManager.h"
  9.  
  10. #include "server/login/account/AccountManager.h"
  11. #include "server/zone/packets/charcreation/ClientCreateCharacter.h"
  12. #include "server/zone/packets/charcreation/ClientCreateCharacterCallback.h"
  13. #include "server/zone/packets/charcreation/ClientCreateCharacterSuccess.h"
  14. #include "server/zone/packets/charcreation/ClientCreateCharacterFailed.h"
  15. #include "server/zone/objects/player/Races.h"
  16. #include "server/zone/ZoneServer.h"
  17. #include "server/zone/ZoneProcessServer.h"
  18. #include "server/zone/managers/name/NameManager.h"
  19. #include "templates/manager/TemplateManager.h"
  20. #include "server/zone/managers/object/ObjectManager.h"
  21. #include "server/zone/managers/faction/FactionManager.h"
  22. #include "server/db/ServerDatabase.h"
  23. #include "server/db/MantisDatabase.h"
  24. #include "server/chat/ChatManager.h"
  25. #include "conf/ConfigManager.h"
  26. #include "server/zone/managers/objectcontroller/ObjectController.h"
  27. #include "server/zone/managers/player/VeteranRewardList.h"
  28. #include "server/zone/managers/combat/CombatManager.h"
  29. #include "server/zone/managers/skill/Performance.h"
  30. #include "server/zone/managers/collision/CollisionManager.h"
  31. #include "server/zone/objects/intangible/VehicleControlDevice.h"
  32. #include "server/zone/objects/tangible/threat/ThreatMap.h"
  33. #include "server/zone/objects/creature/VehicleObject.h"
  34. #include "server/zone/objects/area/ActiveArea.h"
  35. #include "server/login/packets/ErrorMessage.h"
  36. #include "server/zone/packets/player/LogoutMessage.h"
  37. #include "server/zone/objects/player/sessions/TradeSession.h"
  38. #include "server/zone/objects/player/sessions/ProposeUnitySession.h"
  39. #include "server/zone/objects/player/sessions/VeteranRewardSession.h"
  40. #include "templates/params/OptionBitmask.h"
  41. #include "server/zone/managers/player/JukeboxSong.h"
  42. #include "server/zone/managers/player/QuestInfo.h"
  43.  
  44. #include "server/zone/objects/intangible/ShipControlDevice.h"
  45. #include "server/zone/objects/ship/ShipObject.h"
  46.  
  47. #include "server/zone/objects/group/GroupObject.h"
  48.  
  49. #include "server/zone/objects/building/BuildingObject.h"
  50. #include "templates/building/CloningBuildingObjectTemplate.h"
  51. #include "server/zone/objects/player/PlayerObject.h"
  52. #include "server/zone/objects/tangible/wearables/ArmorObject.h"
  53. #include "server/zone/objects/tangible/weapon/WeaponObject.h"
  54. #include "server/zone/objects/tangible/wearables/WearableObject.h"
  55.  
  56. #include "server/zone/objects/player/events/PlayerIncapacitationRecoverTask.h"
  57. #include "server/zone/objects/creature/events/ProposeUnityExpiredTask.h"
  58. #include "server/zone/objects/player/events/ForceMeditateTask.h"
  59. #include "server/zone/objects/player/events/MeditateTask.h"
  60. #include "server/zone/objects/player/events/LogoutTask.h"
  61. #include "server/zone/objects/player/sessions/EntertainingSession.h"
  62.  
  63. #include "templates/building/CloneSpawnPoint.h"
  64.  
  65. #include "server/zone/objects/player/sui/messagebox/SuiMessageBox.h"
  66. #include "server/zone/objects/player/sui/listbox/SuiListBox.h"
  67. #include "server/zone/objects/cell/CellObject.h"
  68. #include "server/zone/managers/skill/SkillManager.h"
  69.  
  70. #include "server/zone/objects/player/FactionStatus.h"
  71. #include "server/zone/managers/planet/PlanetManager.h"
  72.  
  73. #include "server/zone/packets/trade/AbortTradeMessage.h"
  74. #include "server/zone/packets/trade/AcceptTransactionMessage.h"
  75. #include "server/zone/packets/trade/UnAcceptTransactionMessage.h"
  76. #include "server/zone/packets/trade/AddItemMessage.h"
  77. #include "server/zone/packets/trade/BeginTradeMessage.h"
  78. #include "server/zone/packets/trade/DenyTradeMessage.h"
  79. #include "server/zone/packets/trade/TradeCompleteMessage.h"
  80. #include "server/zone/packets/trade/GiveMoneyMessage.h"
  81. #include "server/zone/packets/chat/ChatSystemMessage.h"
  82. #include "server/zone/packets/tangible/UpdatePVPStatusMessage.h"
  83.  
  84. #include "server/zone/packets/tangible/TangibleObjectDeltaMessage3.h"
  85. #include "server/zone/packets/player/PlayMusicMessage.h"
  86. #include "server/zone/packets/player/PlayerObjectDeltaMessage6.h"
  87. #include "server/zone/packets/object/StartingLocationListMessage.h"
  88.  
  89. #include "server/zone/objects/region/CityRegion.h"
  90. #include "server/zone/managers/director/DirectorManager.h"
  91.  
  92. #include "server/zone/objects/player/sui/callbacks/CloningRequestSuiCallback.h"
  93.  
  94. #include "server/zone/objects/tangible/tool/CraftingStation.h"
  95. #include "server/zone/objects/tangible/tool/CraftingTool.h"
  96.  
  97. #include "server/zone/Zone.h"
  98. #include "server/zone/managers/player/creation/PlayerCreationManager.h"
  99. #include "server/ServerCore.h"
  100.  
  101. #include "server/login/account/Account.h"
  102.  
  103. #include "server/zone/objects/player/sui/callbacks/PlayerTeachSuiCallback.h"
  104. #include "server/zone/objects/player/sui/callbacks/PlayerTeachConfirmSuiCallback.h"
  105. #include "server/zone/objects/player/sui/callbacks/ProposeUnitySuiCallback.h"
  106. #include "server/zone/objects/player/sui/callbacks/SelectUnityRingSuiCallback.h"
  107. #include "server/zone/objects/player/sui/callbacks/ConfirmDivorceSuiCallback.h"
  108. #include "server/zone/objects/player/sui/callbacks/SelectVeteranRewardSuiCallback.h"
  109. #include "server/zone/objects/player/sui/callbacks/ConfirmVeteranRewardSuiCallback.h"
  110.  
  111. #include "server/zone/managers/stringid/StringIdManager.h"
  112.  
  113. #include "server/zone/objects/creature/buffs/PowerBoostBuff.h"
  114.  
  115. #include "server/zone/objects/creature/ai/Creature.h"
  116. #include "server/zone/objects/creature/events/DespawnCreatureTask.h"
  117. #include "server/zone/objects/creature/ai/AiAgent.h"
  118. #include "server/zone/managers/gcw/GCWManager.h"
  119.  
  120. #include "server/zone/managers/creature/LairObserver.h"
  121. #include "server/zone/objects/intangible/PetControlDevice.h"
  122. #include "server/zone/managers/creature/PetManager.h"
  123.  
  124. #include "server/zone/objects/creature/events/BurstRunNotifyAvailableEvent.h"
  125. #include "server/zone/objects/creature/ai/DroidObject.h"
  126. #include "server/zone/objects/player/Races.h"
  127. #include "server/zone/objects/tangible/components/droid/DroidPlaybackModuleDataComponent.h"
  128.  
  129. #include "server/zone/objects/player/badges/Badge.h"
  130. #include "server/zone/managers/creature/SpawnSmugglerJunk.h"
  131. #include "server/zone/objects/creature/events/DespawnSmugglerOffTheBooksTask.h"
  132. #include "server/zone/objects/creature/CreatureObject.h"
  133. #include "server/zone/managers/player/PlayerManager.h"
  134. #include "server/zone/packets/group/GroupObjectDeltaMessage6.h"
  135.  
  136. // GOTO line 688 for next portion: NGE Player BH system
  137. /*
  138. #include "server/zone/managers/visibility/VisibilityManager.h"
  139. #include "server/zone/objects/player/sui/callbacks/BountyHuntSuiCallback.h"
  140. #include "server/zone/objects/player/sui/inputbox/SuiInputBox.h" */
  141.  
  142. #include <iostream>
  143.  
  144. int PlayerManagerImplementation::MAX_CHAR_ONLINE_COUNT = 2;
  145.  
  146. PlayerManagerImplementation::PlayerManagerImplementation(ZoneServer* zoneServer, ZoneProcessServer* impl) :
  147. Logger("PlayerManager") {
  148. server = zoneServer;
  149. processor = impl;
  150. playerMap = new PlayerMap(3000);
  151. nameMap = new CharacterNameMap();
  152.  
  153. DirectorManager::instance()->getLuaInstance()->runFile("scripts/screenplays/checklnum.lua");
  154.  
  155. loadLuaConfig();
  156. loadStartingLocations();
  157. loadQuestInfo();
  158. loadPermissionLevels();
  159.  
  160. setGlobalLogging(true);
  161. setLogging(false);
  162.  
  163. if (ServerCore::truncateDatabases()) {
  164. try {
  165. String query = "TRUNCATE TABLE characters";
  166.  
  167. Reference<ResultSet*> res = ServerDatabase::instance()->executeQuery(query);
  168.  
  169. info("characters table truncated", true);
  170. } catch (Exception& e) {
  171. error(e.getMessage());
  172. }
  173. }
  174.  
  175. loadNameMap();
  176. }
  177.  
  178. bool PlayerManagerImplementation::createPlayer(ClientCreateCharacterCallback* callback) {
  179. PlayerCreationManager* pcm = PlayerCreationManager::instance();
  180. return pcm->createCharacter(callback);
  181. }
  182.  
  183. void PlayerManagerImplementation::loadLuaConfig() {
  184. info("Loading configuration script.");
  185.  
  186. Lua* lua = new Lua();
  187. lua->init();
  188.  
  189. lua->runFile("scripts/managers/player_manager.lua");
  190.  
  191. performanceBuff = lua->getGlobalInt("performanceBuff");
  192. medicalBuff = lua->getGlobalInt("medicalBuff");
  193. performanceDuration = lua->getGlobalInt("performanceDuration");
  194. medicalDuration = lua->getGlobalInt("medicalDuration");
  195.  
  196. groupExpMultiplier = lua->getGlobalFloat("groupExpMultiplier");
  197.  
  198. globalExpMultiplier = lua->getGlobalFloat("globalExpMultiplier");
  199.  
  200. baseStoredCreaturePets = lua->getGlobalInt("baseStoredCreaturePets");
  201. baseStoredFactionPets = lua->getGlobalInt("baseStoredFactionPets");
  202. baseStoredDroids = lua->getGlobalInt("baseStoredDroids");
  203. baseStoredVehicles = lua->getGlobalInt("baseStoredVehicles");
  204. baseStoredShips = lua->getGlobalInt("baseStoredShips");
  205.  
  206. veteranRewardAdditionalMilestones = lua->getGlobalInt("veteranRewardAdditionalMilestones");
  207.  
  208. LuaObject rewardMilestonesLua = lua->getGlobalObject("veteranRewardMilestones");
  209. for (int i = 1; i <= rewardMilestonesLua.getTableSize(); ++i) {
  210. veteranRewardMilestones.add(rewardMilestonesLua.getIntAt(i));
  211. }
  212. rewardMilestonesLua.pop();
  213.  
  214. LuaObject rewardsListLua = lua->getGlobalObject("veteranRewards");
  215. int size = rewardsListLua.getTableSize();
  216.  
  217. lua_State* L = rewardsListLua.getLuaState();
  218.  
  219. for (int i = 0; i < size; ++i) {
  220. lua_rawgeti(L, -1, i + 1);
  221. LuaObject a(L);
  222.  
  223. VeteranReward reward;
  224. reward.parseFromLua(&a);
  225. veteranRewards.add(reward);
  226.  
  227. a.pop();
  228. }
  229.  
  230. rewardsListLua.pop();
  231.  
  232. info("Loaded " + String::valueOf(veteranRewards.size()) + " veteran rewards.", true);
  233.  
  234. LuaObject jboxSongs = lua->getGlobalObject("jukeboxSongs");
  235.  
  236. if (jboxSongs.isValidTable()) {
  237. for (int i = 1; i <= jboxSongs.getTableSize(); ++i) {
  238. LuaObject songData = jboxSongs.getObjectAt(i);
  239.  
  240. if (songData.isValidTable()) {
  241. String songStringID = songData.getStringAt(1);
  242. String songPath = songData.getStringAt(2);
  243.  
  244. Reference<JukeboxSong*> data = new JukeboxSong(songStringID, songPath);
  245.  
  246. jukeboxSongs.add(data);
  247. }
  248.  
  249. songData.pop();
  250. }
  251.  
  252. }
  253.  
  254. jboxSongs.pop();
  255.  
  256. delete lua;
  257. lua = NULL;
  258. }
  259.  
  260. void PlayerManagerImplementation::loadStartingLocations() {
  261. info("Loading starting locations.");
  262.  
  263. IffStream* iffStream = TemplateManager::instance()->openIffFile("datatables/creation/starting_locations.iff");
  264.  
  265. if (iffStream == NULL) {
  266. info("Couldn't load starting locations.", true);
  267. return;
  268. }
  269.  
  270. startingLocationList.parseFromIffStream(iffStream);
  271.  
  272. delete iffStream;
  273.  
  274. info("Loaded " + String::valueOf(startingLocationList.getTotalLocations()) + " starting locations.", true);
  275. }
  276.  
  277. void PlayerManagerImplementation::loadQuestInfo() {
  278. TemplateManager* templateManager = TemplateManager::instance();
  279.  
  280. IffStream* iffStream = templateManager->openIffFile("datatables/player/quests.iff");
  281.  
  282. if (iffStream == NULL) {
  283. info("quests.iff could not be found.", true);
  284. return;
  285. }
  286.  
  287. DataTableIff dtable;
  288. dtable.readObject(iffStream);
  289.  
  290. delete iffStream;
  291.  
  292. for (int i = 0; i < dtable.getTotalRows(); ++i) {
  293. DataTableRow* row = dtable.getRow(i);
  294.  
  295. QuestInfo* quest = new QuestInfo();
  296. quest->parseDataTableRow(row);
  297. questInfo.add(quest);
  298. }
  299.  
  300. info("Loaded " + String::valueOf(questInfo.size()) + " quests.", true);
  301. }
  302.  
  303. void PlayerManagerImplementation::loadPermissionLevels() {
  304. try {
  305. permissionLevelList = PermissionLevelList::instance();
  306. permissionLevelList->loadLevels();
  307. }
  308. catch(Exception& e) {
  309. error("Couldn't load permission levels.");
  310. error(e.getMessage());
  311. }
  312.  
  313.  
  314. }
  315.  
  316. void PlayerManagerImplementation::finalize() {
  317. delete playerMap;
  318. playerMap = NULL;
  319. delete nameMap;
  320. nameMap = NULL;
  321. }
  322.  
  323. void PlayerManagerImplementation::loadNameMap() {
  324. info("loading character names");
  325.  
  326. try {
  327. String query = "SELECT * FROM characters where character_oid > 16777216 and galaxy_id = " + String::valueOf(server->getGalaxyID()) + " order by character_oid asc";
  328.  
  329. Reference<ResultSet*> res = ServerDatabase::instance()->executeQuery(query);
  330.  
  331. while (res->next()) {
  332. uint64 oid = res->getUnsignedLong(0);
  333. String firstName = res->getString(3);
  334.  
  335. if (!nameMap->put(firstName.toLowerCase(), oid)) {
  336. error("error coliding name:" + firstName.toLowerCase());
  337. }
  338. }
  339.  
  340. } catch (Exception& e) {
  341. error(e.getMessage());
  342. }
  343.  
  344. StringBuffer msg;
  345. msg << "loaded " << nameMap->size() << " character names in memory";
  346. info(msg.toString(), true);
  347. }
  348.  
  349. int PlayerManagerImplementation::getPlayerQuestID(const String& name) {
  350. for (int i = 0; i < questInfo.size(); ++i) {
  351. QuestInfo* quest = questInfo.get(i);
  352.  
  353. if (quest != NULL && quest->getQuestName().hashCode() == name.hashCode())
  354. return i;
  355. }
  356.  
  357. return -1;
  358. }
  359.  
  360. String PlayerManagerImplementation::getPlayerQuestParent(int questID) {
  361. QuestInfo* quest = questInfo.get(questID);
  362.  
  363. if (quest != NULL)
  364. return quest->getQuestParent();
  365. else
  366. return "";
  367. }
  368.  
  369. bool PlayerManagerImplementation::existsName(const String& name) {
  370. bool res = false;
  371.  
  372. try {
  373. res = nameMap->containsKey(name.toLowerCase());
  374. } catch (DatabaseException& e) {
  375. error(e.getMessage());
  376. }
  377.  
  378. return res;
  379. }
  380.  
  381.  
  382. bool PlayerManagerImplementation::kickUser(const String& name, const String& admin, String& reason, bool doBan) {
  383. ManagedReference<ChatManager*> chatManager = server->getChatManager();
  384.  
  385. if (chatManager == NULL)
  386. return false;
  387.  
  388. ManagedReference<CreatureObject*> player = chatManager->getPlayer(name);
  389.  
  390. if (player == NULL)
  391. return false;
  392.  
  393. ManagedReference<CreatureObject*> adminplayer = chatManager->getPlayer(admin);
  394.  
  395. if (adminplayer == NULL)
  396. return false;
  397.  
  398. Reference<PlayerObject*> ghost = player->getSlottedObject("ghost").castTo<PlayerObject*>();
  399.  
  400.  
  401. Reference<PlayerObject*> adminghost = adminplayer->getSlottedObject("ghost").castTo<PlayerObject*>();
  402.  
  403. if(adminghost == NULL)
  404. return false;
  405.  
  406. StringBuffer kickMessage;
  407. kickMessage << "You have been kicked by " << admin << " for '" << reason << "'";
  408. player->sendSystemMessage(kickMessage.toString());
  409.  
  410. if(ghost != NULL)
  411. ghost->setLoggingOut();
  412.  
  413. ErrorMessage* errmsg = new ErrorMessage(admin, "You have been kicked", 0);
  414. player->sendMessage(errmsg);
  415.  
  416. player->sendMessage(new LogoutMessage());
  417.  
  418. ManagedReference<ZoneClientSession*> session = player->getClient();
  419.  
  420. if(session != NULL)
  421. session->disconnect(true);
  422.  
  423. /// 10 min ban
  424. if(doBan) {
  425. String banMessage = banAccount(adminghost, ghost->getAccount(), 60 * 10, reason);
  426. adminplayer->sendSystemMessage(banMessage);
  427. }
  428.  
  429. return true;
  430. }
  431.  
  432. Reference<CreatureObject*> PlayerManagerImplementation::getPlayer(const String& name) {
  433. uint64 oid = 0;
  434.  
  435. try {
  436. oid = nameMap->get(name.toLowerCase());
  437. } catch (ArrayIndexOutOfBoundsException& ex) {
  438. // `oid` is initialized with zero so the method will return NULL after unlocking.
  439. error("Didn't find player " + name);
  440. }
  441.  
  442. if (oid == 0)
  443. return NULL;
  444.  
  445. Reference<SceneObject*> obj = server->getObject(oid);
  446.  
  447. if (obj == NULL || !obj->isPlayerCreature())
  448. return NULL;
  449.  
  450. return obj.castTo<CreatureObject*>();
  451. }
  452.  
  453. uint64 PlayerManagerImplementation::getObjectID(const String& name) {
  454. uint64 oid = 0;
  455.  
  456. oid = nameMap->get(name.toLowerCase());
  457.  
  458. return oid;
  459. }
  460.  
  461. bool PlayerManagerImplementation::checkExistentNameInDatabase(const String& name) {
  462. if (name.isEmpty())
  463. return false;
  464.  
  465. try {
  466. String fname = name.toLowerCase();
  467. Database::escapeString(fname);
  468. String query = "SELECT * FROM characters WHERE lower(firstname) = \""
  469. + fname + "\"";
  470.  
  471. Reference<ResultSet*> res = ServerDatabase::instance()->executeQuery(query);
  472. bool nameExists = res->next();
  473.  
  474. return !nameExists;
  475. } catch (DatabaseException& e) {
  476. return false;
  477. }
  478.  
  479. return false;
  480. }
  481.  
  482. bool PlayerManagerImplementation::checkPlayerName(ClientCreateCharacterCallback* callback) {
  483. ZoneClientSession* client = callback->getClient();
  484.  
  485. NameManager* nm = processor->getNameManager();
  486. BaseMessage* msg = NULL;
  487.  
  488. String firstName;
  489.  
  490. UnicodeString unicodeName;
  491. callback->getCharacterName(unicodeName);
  492.  
  493. String name = unicodeName.toString();
  494.  
  495. //Get the firstname
  496. int idx = name.indexOf(" ");
  497. if (idx != -1)
  498. firstName = name.subString(0, idx);
  499. else
  500. firstName = name;
  501.  
  502. //Does this name already exist?
  503. if (nameMap->containsKey(firstName.toLowerCase())) {
  504. msg = new ClientCreateCharacterFailed("name_declined_in_use");
  505. client->sendMessage(msg);
  506.  
  507. return false;
  508. }
  509.  
  510. //Check to see if name is valid
  511. int res = nm->validateName(name, callback->getSpecies());
  512.  
  513. if (res != NameManagerResult::ACCEPTED) {
  514. switch (res) {
  515. case NameManagerResult::DECLINED_EMPTY:
  516. msg = new ClientCreateCharacterFailed("name_declined_empty");
  517. break;
  518. case NameManagerResult::DECLINED_DEVELOPER:
  519. msg = new ClientCreateCharacterFailed("name_declined_developer");
  520. break;
  521. case NameManagerResult::DECLINED_FICT_RESERVED:
  522. msg = new ClientCreateCharacterFailed("name_declined_fictionally_reserved");
  523. break;
  524. case NameManagerResult::DECLINED_PROFANE:
  525. msg = new ClientCreateCharacterFailed("name_declined_profane");
  526. break;
  527. case NameManagerResult::DECLINED_RACE_INAPP:
  528. msg = new ClientCreateCharacterFailed("name_declined_racially_inappropriate");
  529. break;
  530. case NameManagerResult::DECLINED_SYNTAX:
  531. msg = new ClientCreateCharacterFailed("name_declined_syntax");
  532. break;
  533. case NameManagerResult::DECLINED_RESERVED:
  534. msg = new ClientCreateCharacterFailed("name_declined_reserved");
  535. break;
  536. default:
  537. msg = new ClientCreateCharacterFailed("name_declined_retry");
  538. break;
  539. }
  540.  
  541. client->sendMessage(msg); //Name failed filters
  542. return false;
  543. }
  544.  
  545. return true;
  546. }
  547.  
  548. void PlayerManagerImplementation::createTutorialBuilding(CreatureObject* player) {
  549. Zone* zone = server->getZone("tatooine");
  550.  
  551. player->initializePosition(3528, 5, -4802);
  552. zone->transferObject(player, -1, true);
  553.  
  554. PlayerObject* ghost = player->getPlayerObject();
  555. ghost->setSavedTerrainName(zone->getZoneName());
  556. ghost->setJediState(2);
  557.  
  558. /* Zone* zone = server->getZone("tutorial");
  559.  
  560. // const static String cell = "object/cell/cell.iff";
  561.  
  562. Reference<BuildingObject*> tutorial = server->createObject(STRING_HASHCODE("object/building/general/newbie_hall.iff"), 1).castTo<BuildingObject*>();
  563.  
  564. Locker locker(tutorial);
  565.  
  566. tutorial->createCellObjects();
  567. tutorial->setPublicStructure(true);
  568.  
  569. tutorial->initializePosition(System::random(5000), 0, System::random(5000));
  570. zone->transferObject(tutorial, -1, true);
  571.  
  572. locker.release();
  573.  
  574. SceneObject* cellTut = tutorial->getCell(11);
  575.  
  576. SceneObject* cellTutPlayer = tutorial->getCell(1);
  577.  
  578. player->initializePosition(0, 0, -3);
  579.  
  580. cellTutPlayer->transferObject(player, -1);
  581. PlayerObject* ghost = player->getPlayerObject();
  582. ghost->setSavedTerrainName(zone->getZoneName());
  583. ghost->setSavedParentID(cellTutPlayer->getObjectID());
  584.  
  585. tutorial->updateToDatabase();*/
  586. }
  587.  
  588. void PlayerManagerImplementation::createSkippedTutorialBuilding(CreatureObject* player) {
  589. Zone* zone = server->getZone("tatooine");
  590.  
  591. player->initializePosition(3528, 5, -4802);
  592. zone->transferObject(player, -1, true);
  593.  
  594. PlayerObject* ghost = player->getPlayerObject();
  595. ghost->setSavedTerrainName(zone->getZoneName());
  596. ghost->setJediState(2);
  597.  
  598. /* Zone* zone = server->getZone("tutorial");
  599.  
  600. Reference<BuildingObject*> tutorial = server->createObject(STRING_HASHCODE("object/building/general/newbie_hall_skipped.iff"), 1).castTo<BuildingObject*>();
  601.  
  602. Locker locker(tutorial);
  603.  
  604. tutorial->createCellObjects();
  605. tutorial->initializePosition(System::random(5000), 0, System::random(5000));
  606. zone->transferObject(tutorial, -1, true);
  607.  
  608. locker.release();
  609.  
  610. Reference<SceneObject*> travelTutorialTerminal = server->createObject(STRING_HASHCODE("object/tangible/terminal/terminal_travel_tutorial.iff"), 1);
  611.  
  612. SceneObject* cellTut = tutorial->getCell(1);
  613.  
  614. Locker locker2(travelTutorialTerminal);
  615.  
  616. cellTut->transferObject(travelTutorialTerminal, -1);
  617.  
  618. travelTutorialTerminal->initializePosition(27.0f, -3.5f, -168.0f);
  619.  
  620. player->initializePosition(27.0f, -3.5f, -165.0f);
  621. cellTut->transferObject(player, -1);
  622. PlayerObject* ghost = player->getPlayerObject();
  623. ghost->setSavedTerrainName(zone->getZoneName());
  624. ghost->setSavedParentID(cellTut->getObjectID());
  625.  
  626. tutorial->updateToDatabase();*/
  627. }
  628.  
  629. uint8 PlayerManagerImplementation::calculateIncapacitationTimer(CreatureObject* playerCreature, int condition) {
  630. //Switch the sign of the value
  631. int32 value = -condition;
  632.  
  633. if (value < 0)
  634. return 0;
  635.  
  636. uint32 recoveryTime = (value / 5); //In seconds - 3 seconds is recoveryEvent timer
  637.  
  638. //Recovery time is gated between 10 and 60 seconds.
  639. recoveryTime = MIN(MAX(recoveryTime, 10), 60);
  640.  
  641. //Check for incap recovery food buff - overrides recovery time gate.
  642. /*if (hasBuff(BuffCRC::FOOD_INCAP_RECOVERY)) {
  643. Buff* buff = getBuff(BuffCRC::FOOD_INCAP_RECOVERY);
  644.  
  645. if (buff != NULL) {
  646. float percent = buff->getSkillModifierValue("incap_recovery");
  647.  
  648. recoveryTime = round(recoveryTime * ((100.0f - percent) / 100.0f));
  649.  
  650. StfParameter* params = new StfParameter();
  651. params->addDI(percent);
  652.  
  653. sendSystemMessage("combat_effects", "incap_recovery", params); //Incapacitation recovery time reduced by %DI%.
  654. delete params;
  655.  
  656. removeBuff(buff);
  657. }
  658. }*/
  659.  
  660. return recoveryTime;
  661. }
  662.  
  663. int PlayerManagerImplementation::notifyDestruction(TangibleObject* destructor, TangibleObject* destructedObject, int condition, bool isCombatAction) {
  664. if (destructor == NULL) {
  665. assert(0 && "destructor should always be != NULL.");
  666. }
  667.  
  668. if (!destructedObject->isPlayerCreature())
  669. return 1;
  670.  
  671. CreatureObject* playerCreature = cast<CreatureObject*>( destructedObject);
  672.  
  673. if ((playerCreature->isIncapacitated() && !(playerCreature->isFeigningDeath())) || playerCreature->isDead())
  674. return 1;
  675.  
  676. if (playerCreature->isRidingMount()) {
  677. playerCreature->updateCooldownTimer("mount_dismount", 0);
  678. playerCreature->executeObjectControllerAction(STRING_HASHCODE("dismount"));
  679. }
  680.  
  681. PlayerObject* ghost = playerCreature->getPlayerObject();
  682.  
  683. ghost->addIncapacitationTime();
  684.  
  685. DeltaVector<ManagedReference<SceneObject*> >* defenderList = destructor->getDefenderList();
  686.  
  687. bool isDefender = false;
  688.  
  689. if (defenderList->contains(destructedObject)) {
  690. isDefender = true;
  691. destructor->removeDefender(destructedObject);
  692. }
  693.  
  694. if ((destructor->isKiller() && isDefender) || ghost->getIncapacitationCounter() >= 3) {
  695. killPlayer(destructor, playerCreature, 0, isCombatAction);
  696. } else {
  697.  
  698. playerCreature->setPosture(CreaturePosture::INCAPACITATED, !isCombatAction, !isCombatAction);
  699. playerCreature->clearState(CreatureState::FEIGNDEATH); // We got incapped for real - Remove the state so we can be DB'd
  700.  
  701.  
  702. uint32 incapTime = calculateIncapacitationTimer(playerCreature, condition);
  703. playerCreature->setCountdownTimer(incapTime, true);
  704.  
  705. Reference<Task*> oldTask = playerCreature->getPendingTask("incapacitationRecovery");
  706.  
  707. if (oldTask != NULL && oldTask->isScheduled()) {
  708. oldTask->cancel();
  709. playerCreature->removePendingTask("incapacitationRecovery");
  710. }
  711.  
  712. Reference<Task*> task = new PlayerIncapacitationRecoverTask(playerCreature, false);
  713. playerCreature->addPendingTask("incapacitationRecovery", task, incapTime * 1000);
  714.  
  715. StringIdChatParameter toVictim;
  716.  
  717. toVictim.setStringId("base_player", "prose_victim_incap");
  718. toVictim.setTT(destructor->getDisplayedName());
  719.  
  720. playerCreature->sendSystemMessage(toVictim);
  721.  
  722.  
  723. if(destructor->isPlayerCreature()) {
  724. StringIdChatParameter toKiller;
  725.  
  726. toKiller.setStringId("base_player", "prose_target_incap");
  727. toKiller.setTT(playerCreature->getDisplayedName());
  728.  
  729. destructor->asCreatureObject()->sendSystemMessage(toKiller);
  730. }
  731. }
  732.  
  733. return 0;
  734. }
  735.  
  736. void PlayerManagerImplementation::killPlayer(TangibleObject* attacker, CreatureObject* player, int typeofdeath, bool isCombatAction) {
  737. StringIdChatParameter stringId;
  738.  
  739. ThreatMap* threatMap = player->getThreatMap();
  740.  
  741. if (attacker->isPlayerCreature()) {
  742. ManagedReference<CreatureObject*> playerRef = player->asCreatureObject();
  743.  
  744. stringId.setStringId("base_player", "prose_target_dead");
  745. stringId.setTT(player->getDisplayedName());
  746. playerRef->sendSystemMessage(stringId);
  747.  
  748. Reference<ThreatMap*> copyThreatMap = new ThreatMap(*threatMap);
  749. PlayerManager* pManager = _this.getReferenceUnsafeStaticCast();
  750.  
  751. EXECUTE_TASK_3(pManager, playerRef, copyThreatMap, {
  752. if (playerRef_p != NULL) {
  753. Locker locker(playerRef_p);
  754. pManager_p->doPvpDeathRatingUpdate(playerRef_p, copyThreatMap_p);
  755. }
  756. });
  757. }
  758.  
  759. if (player->isRidingMount()) {
  760. player->updateCooldownTimer("mount_dismount", 0);
  761. player->executeObjectControllerAction(STRING_HASHCODE("dismount"));
  762. }
  763.  
  764. player->clearDots();
  765.  
  766. player->setPosture(CreaturePosture::DEAD, !isCombatAction, !isCombatAction);
  767.  
  768. sendActivateCloneRequest(player, typeofdeath);
  769.  
  770. stringId.setStringId("base_player", "prose_victim_dead");
  771. stringId.setTT(attacker->getDisplayedName());
  772. player->sendSystemMessage(stringId);
  773.  
  774. player->updateTimeOfDeath();
  775. player->clearBuffs(true);
  776. // NGE BH SYSTEM, COMMENTED OUT UNTIL READY
  777. /*
  778. if(attacker->isPlayerCreature())
  779. {
  780. ManagedReference<SuiInputBox*> input = new SuiInputBox(player, SuiWindowType::STRUCTURE_VENDOR_WITHDRAW);
  781. input->setPromptTitle("Bounty Hunter Request");
  782. input->setPromptText("Please specify an amount to place. It must be greater than 100,000 credits. There is no limit.");
  783. input->setUsingObject(attacker);
  784. input->setCallback(new BountyHuntSuiCallback(player->getZoneServer()));
  785. player->getPlayerObject()->addSuiBox(input);
  786. player->sendMessage(input->generateMessage());
  787. } */
  788.  
  789. PlayerObject* ghost = player->getPlayerObject();
  790.  
  791. if (ghost != NULL)
  792. ghost->resetIncapacitationTimes();
  793.  
  794. if (attacker->getFaction() != 0) {
  795. if (attacker->isPlayerCreature() || attacker->isPet()) {
  796. CreatureObject* attackerCreature = attacker->asCreatureObject();
  797.  
  798. if (attackerCreature->isPet()) {
  799. CreatureObject* owner = attackerCreature->getLinkedCreature().get();
  800.  
  801. if (owner != NULL && owner->isPlayerCreature()) {
  802. attackerCreature = owner;
  803. }
  804. }
  805.  
  806. if (attackerCreature->isPlayerCreature()) {
  807. if (!CombatManager::instance()->areInDuel(attackerCreature, player)) {
  808. FactionManager::instance()->awardPvpFactionPoints(attackerCreature, player);
  809. }
  810. }
  811. }
  812. }
  813.  
  814. CombatManager::instance()->freeDuelList(player, false);
  815.  
  816. threatMap->removeAll(true);
  817.  
  818. player->dropFromDefenderLists();
  819. player->setTargetID(0, true);
  820.  
  821. player->notifyObjectKillObservers(attacker);
  822. }
  823.  
  824. void PlayerManagerImplementation::sendActivateCloneRequest(CreatureObject* player, int typeofdeath) {
  825. Zone* zone = player->getZone();
  826.  
  827. if (zone == NULL)
  828. return;
  829.  
  830. PlayerObject* ghost = player->getPlayerObject();
  831.  
  832. if (ghost == NULL)
  833. return;
  834.  
  835. ghost->removeSuiBoxType(SuiWindowType::CLONE_REQUEST);
  836. ghost->removeSuiBoxType(SuiWindowType::CLONE_REQUEST_DECAY);
  837.  
  838. ManagedReference<SuiListBox*> cloneMenu = new SuiListBox(player, SuiWindowType::CLONE_REQUEST);
  839. cloneMenu->setCallback(new CloningRequestSuiCallback(player->getZoneServer(), typeofdeath));
  840. cloneMenu->setPromptTitle("@base_player:revive_title");
  841. /*
  842. if (typeofdeath == 1) {
  843. cloneMenu = new SuiListBox(player, SuiWindowType::CLONE_REQUEST);//no decay - GM command, deathblow or factional death
  844. } else if (typeofdeath == 0) {
  845. cloneMenu = new SuiListBox(player, SuiWindowType::CLONE_REQUEST_DECAY);
  846. } else if (ghost->getFactionStatus() == FactionStatus::OVERT) {//TODO: Do proper check if faction death
  847. cloneMenu = new SuiListBox(player, SuiWindowType::CLONE_REQUEST_FACTIONAL);
  848. }*/
  849.  
  850. uint64 preDesignatedFacilityOid = ghost->getCloningFacility();
  851. ManagedReference<SceneObject*> preDesignatedFacility = server->getObject(preDesignatedFacilityOid);
  852. String predesignatedName = "None";
  853.  
  854. //Get the name of the pre-designated facility
  855. if (preDesignatedFacility != NULL) {
  856. ManagedReference<CityRegion*> cr = preDesignatedFacility->getCityRegion();
  857.  
  858. if (preDesignatedFacility->getZone() != zone) {
  859. predesignatedName = "off-planet (unavailable)";
  860. } else if (cr != NULL) {
  861. predesignatedName = cr->getRegionDisplayedName();
  862. } else {
  863. predesignatedName = preDesignatedFacility->getDisplayedName();
  864. }
  865. }
  866.  
  867. SortedVector<ManagedReference<SceneObject*> > locations = zone->getPlanetaryObjectList("cloningfacility");
  868. ManagedReference<SceneObject*> closestCloning = zone->getNearestPlanetaryObject(player, "cloningfacility");
  869. if(closestCloning == NULL){
  870. warning("nearest cloning facility for player is NULL");
  871. return;
  872. }
  873. String closestName = "None";
  874. ManagedReference<CityRegion*> cr = closestCloning->getCityRegion();
  875. unsigned long long playerID = player->getObjectID();
  876. CloningBuildingObjectTemplate* cbot = cast<CloningBuildingObjectTemplate*>(closestCloning->getObjectTemplate());
  877.  
  878. //Check if player is city banned where the closest facility is or if it's not a valid cloner
  879. if ((cr != NULL && cr->isBanned(playerID)) || cbot == NULL || (cbot->getFaction() != 0 && cbot->getFaction() != player->getFaction())) {
  880. int distance = 50000;
  881. for (int j = 0; j < locations.size(); j++) {
  882. ManagedReference<SceneObject*> location = locations.get(j);
  883.  
  884. if (location == NULL)
  885. continue;
  886.  
  887. cbot = cast<CloningBuildingObjectTemplate*>(location->getObjectTemplate());
  888.  
  889. if (cbot == NULL || (cbot->getFaction() != 0 && cbot->getFaction() != player->getFaction()))
  890. continue;
  891.  
  892. cr = location->getCityRegion();
  893. String name;
  894.  
  895. if (cr != NULL) {
  896. if (cr->isBanned(playerID))
  897. continue;
  898.  
  899. name = cr->getRegionDisplayedName();
  900. } else {
  901. name = location->getDisplayedName();
  902. }
  903.  
  904. if (location->getDistanceTo(player) < distance) {
  905. distance = location->getDistanceTo(player);
  906. closestName = name;
  907. closestCloning = location;
  908. }
  909. }
  910.  
  911. } else {
  912. if (cr != NULL)
  913. closestName = cr->getRegionDisplayedName();
  914. else
  915. closestName = closestCloning->getDisplayedName();
  916. }
  917.  
  918. StringBuffer promptText;
  919. promptText << "Closest:\t\t " << closestName << "\n"
  920. << "Pre-Designated: " << predesignatedName << "\n"
  921. << "Cash Balance:\t " << player->getCashCredits() << "\n\n"
  922. << "Select the desired option and click OK.";
  923.  
  924. cloneMenu->setPromptText(promptText.toString());
  925.  
  926. if (closestCloning != NULL)
  927. cloneMenu->addMenuItem("@base_player:revive_closest", closestCloning->getObjectID());
  928.  
  929. if (preDesignatedFacility != NULL && preDesignatedFacility->getZone() == zone)
  930. cloneMenu->addMenuItem("@base_player:revive_bind", preDesignatedFacility->getObjectID());
  931.  
  932. ghost->addSuiBox(cloneMenu);
  933. player->sendMessage(cloneMenu->generateMessage());
  934. }
  935.  
  936. void PlayerManagerImplementation::sendPlayerToCloner(CreatureObject* player, uint64 clonerID, int typeofdeath) {
  937. ManagedReference<SceneObject*> cloner = server->getObject(clonerID);
  938.  
  939. if (cloner == NULL) {
  940. error("Cloning structure is null");
  941. return;
  942. }
  943.  
  944. PlayerObject* ghost = player->getPlayerObject();
  945.  
  946. if (ghost == NULL) {
  947. error("The player to be cloned is null");
  948. return;
  949. }
  950.  
  951.  
  952. CloningBuildingObjectTemplate* cbot = cast<CloningBuildingObjectTemplate*>(cloner->getObjectTemplate());
  953.  
  954. if (cbot == NULL) {
  955. error("Not a cloning building template.");
  956. return;
  957. }
  958.  
  959. BuildingObject* cloningBuilding = cloner.castTo<BuildingObject*>();
  960.  
  961. if (cloningBuilding == NULL) {
  962. error("Cloning building is null");
  963. return;
  964. }
  965.  
  966. CloneSpawnPoint* clonePoint = cbot->getRandomSpawnPoint();
  967.  
  968. if (clonePoint == NULL) {
  969. error("clone point null");
  970. return;
  971. }
  972.  
  973. Coordinate* coordinate = clonePoint->getCoordinate();
  974. Quaternion* direction = clonePoint->getDirection();
  975.  
  976. int cellID = clonePoint->getCellID();
  977.  
  978. SceneObject* cell = cloningBuilding->getCell(cellID);
  979.  
  980. if (cell == NULL) {
  981. StringBuffer msg;
  982. msg << "null cell for cellID " << cellID << " in building: " << cbot->getFullTemplateString();
  983. error(msg.toString());
  984. return;
  985. }
  986.  
  987. Zone* zone = player->getZone();
  988.  
  989. player->switchZone(zone->getZoneName(), coordinate->getPositionX(), coordinate->getPositionZ(), coordinate->getPositionY(), cell->getObjectID());
  990.  
  991. uint64 preDesignatedFacilityOid = ghost->getCloningFacility();
  992. ManagedReference<SceneObject*> preDesignatedFacility = server->getObject(preDesignatedFacilityOid);
  993.  
  994. if (preDesignatedFacility == NULL || preDesignatedFacility != cloningBuilding) {
  995. player->addWounds(CreatureAttribute::HEALTH, 100, true, false);
  996. player->addWounds(CreatureAttribute::ACTION, 100, true, false);
  997. player->addWounds(CreatureAttribute::MIND, 100, true, false);
  998. player->addShockWounds(100, true);
  999. }
  1000.  
  1001. if (ghost->getFactionStatus() != FactionStatus::ONLEAVE && cbot->getFaction() == 0)
  1002. ghost->setFactionStatus(FactionStatus::ONLEAVE);
  1003.  
  1004. if (ghost->hasPvpTef())
  1005. ghost->schedulePvpTefRemovalTask(true);
  1006.  
  1007.  
  1008. SortedVector<ManagedReference<SceneObject*> > insurableItems = getInsurableItems(player, false);
  1009.  
  1010. // Decay
  1011. if (typeofdeath == 0 && insurableItems.size() > 0) {
  1012.  
  1013. ManagedReference<SuiListBox*> suiCloneDecayReport = new SuiListBox(player, SuiWindowType::CLONE_REQUEST_DECAY, SuiListBox::HANDLESINGLEBUTTON);
  1014. suiCloneDecayReport->setPromptTitle("DECAY REPORT");
  1015. suiCloneDecayReport->setPromptText("The following report summarizes the status of your items after the decay event.");
  1016. suiCloneDecayReport->addMenuItem("\\#00FF00DECAYED ITEMS");
  1017.  
  1018. for (int i = 0; i < insurableItems.size(); i++) {
  1019. SceneObject* item = insurableItems.get(i);
  1020.  
  1021. if (item != NULL && item->isTangibleObject()) {
  1022. ManagedReference<TangibleObject*> obj = cast<TangibleObject*>(item);
  1023.  
  1024. Locker clocker(obj, player);
  1025.  
  1026. if (obj->getOptionsBitmask() & OptionBitmask::INSURED) {
  1027. //1% Decay for insured items
  1028. obj->inflictDamage(obj, 0, 0.01 * obj->getMaxCondition(), true, true);
  1029. //Set uninsured
  1030. uint32 bitmask = obj->getOptionsBitmask() - OptionBitmask::INSURED;
  1031. obj->setOptionsBitmask(bitmask);
  1032. } else {
  1033. //5% Decay for uninsured items
  1034. obj->inflictDamage(obj, 0, 0.05 * obj->getMaxCondition(), true, true);
  1035. }
  1036.  
  1037. // Calculate condition percentage for decay report
  1038. int max = obj->getMaxCondition();
  1039. int min = max - obj->getConditionDamage();
  1040. int condPercentage = ( min / (float)max ) * 100.0f;
  1041. String line = " - " + obj->getDisplayedName() + " (@"+String::valueOf(condPercentage)+"%)";
  1042.  
  1043. suiCloneDecayReport->addMenuItem(line, item->getObjectID());
  1044. }
  1045. }
  1046.  
  1047. ghost->addSuiBox(suiCloneDecayReport);
  1048. player->sendMessage(suiCloneDecayReport->generateMessage());
  1049.  
  1050. }
  1051.  
  1052.  
  1053.  
  1054. Reference<Task*> task = new PlayerIncapacitationRecoverTask(player, true);
  1055. task->schedule(3 * 1000);
  1056.  
  1057. player->notifyObservers(ObserverEventType::PLAYERCLONED, player, 0);
  1058.  
  1059.  
  1060. // Jedi experience loss.
  1061. /*if(ghost->getJediState() >= 2) {
  1062. int jediXpCap = ghost->getXpCap("jedi_general");
  1063. int xpLoss = (int)(jediXpCap * -0.05);
  1064. int curExp = ghost->getExperience("jedi_general");
  1065.  
  1066. int negXpCap = -10000000; // Cap on negative jedi experience
  1067.  
  1068. if ((curExp + xpLoss) < negXpCap)
  1069. xpLoss = negXpCap - curExp;
  1070.  
  1071. awardExperience(player, "jedi_general", xpLoss, true);
  1072. StringIdChatParameter message("base_player","prose_revoke_xp");
  1073. message.setDI(xpLoss * -1);
  1074. message.setTO("exp_n", "jedi_general");
  1075. player->sendSystemMessage(message);
  1076. }*/
  1077. }
  1078.  
  1079. void PlayerManagerImplementation::ejectPlayerFromBuilding(CreatureObject* player) {
  1080. Zone* zone = player->getZone();
  1081.  
  1082. if (zone == NULL)
  1083. return;
  1084.  
  1085. ManagedReference<SceneObject*> parent = player->getParent();
  1086.  
  1087. if (parent == NULL || !parent->isCellObject())
  1088. return;
  1089.  
  1090. ManagedReference<CellObject*> cell = cast<CellObject*>(parent.get());
  1091.  
  1092. if (cell == NULL)
  1093. return;
  1094.  
  1095. ManagedReference<BuildingObject*> building = cell->getParent().castTo<BuildingObject*>();
  1096.  
  1097. if (building == NULL)
  1098. return;
  1099.  
  1100. if (building->hasTemplateEjectionPoint()) {
  1101. Vector3 ejectionPoint = building->getEjectionPoint();
  1102. player->switchZone(zone->getZoneName(), ejectionPoint.getX(), ejectionPoint.getZ(), ejectionPoint.getY(), 0);
  1103. }
  1104. }
  1105.  
  1106.  
  1107.  
  1108. void PlayerManagerImplementation::disseminateExperience(TangibleObject* destructedObject, ThreatMap* threatMap,
  1109. SynchronizedVector<ManagedReference<CreatureObject*> >* spawnedCreatures) {
  1110. uint32 totalDamage = threatMap->getTotalDamage();
  1111.  
  1112. VectorMap<ManagedReference<CreatureObject*>, int> slExperience;
  1113. slExperience.setAllowOverwriteInsertPlan();
  1114. slExperience.setNullValue(0);
  1115.  
  1116.  
  1117. float gcwBonus = 1.0f;
  1118. uint32 winningFaction = -1;
  1119. int baseXp = 0;
  1120.  
  1121. Zone* zone = destructedObject->getZone();
  1122.  
  1123. if (zone != NULL) {
  1124. GCWManager* gcwMan = zone->getGCWManager();
  1125.  
  1126. if (gcwMan != NULL) {
  1127. gcwBonus += (gcwMan->getGCWXPBonus() / 100.0f);
  1128. winningFaction = gcwMan->getWinningFaction();
  1129. }
  1130. }
  1131.  
  1132. if (!destructedObject->isCreatureObject() && spawnedCreatures != NULL) {
  1133. ManagedReference<AiAgent*> ai = NULL;
  1134.  
  1135. for (int i = 0; i < spawnedCreatures->size(); i++) {
  1136. ai = cast<AiAgent*>(spawnedCreatures->get(i).get());
  1137.  
  1138. if (ai != NULL) {
  1139. Creature* creature = cast<Creature*>(ai.get());
  1140.  
  1141. if (creature != NULL && creature->isBaby())
  1142. continue;
  1143. else
  1144. break;
  1145. }
  1146. }
  1147.  
  1148. if (ai != NULL)
  1149. baseXp = ai->getBaseXp();
  1150.  
  1151. } else {
  1152. ManagedReference<AiAgent*> ai = cast<AiAgent*>(destructedObject);
  1153.  
  1154. if (ai != NULL)
  1155. baseXp = ai->getBaseXp();
  1156. }
  1157.  
  1158. for (int i = 0; i < threatMap->size(); ++i) {
  1159. ThreatMapEntry* entry = &threatMap->elementAt(i).getValue();
  1160. CreatureObject* attacker = threatMap->elementAt(i).getKey();
  1161.  
  1162. if (entry == NULL || attacker == NULL) {
  1163. continue;
  1164. }
  1165.  
  1166. if (attacker->isPet()) {
  1167. PetControlDevice* pcd = attacker->getControlDevice().get().castTo<PetControlDevice*>();
  1168.  
  1169. // only creature pets will award exp, so discard anything else
  1170. if (pcd == NULL || pcd->getPetType() != PetManager::CREATUREPET) {
  1171. continue;
  1172. }
  1173.  
  1174. CreatureObject* owner = attacker->getLinkedCreature().get();
  1175. if (owner == NULL || !owner->isPlayerCreature()) {
  1176. continue;
  1177. }
  1178.  
  1179. Locker crossLocker(owner, destructedObject);
  1180.  
  1181. PlayerObject* ownerGhost = owner->getPlayerObject();
  1182. if (ownerGhost == NULL || !owner->hasSkill("outdoors_creaturehandler_novice") || !destructedObject->isInRange(owner, 80)) {
  1183. continue;
  1184. }
  1185.  
  1186. int totalPets = 1;
  1187.  
  1188. for (int i = 0; i < ownerGhost->getActivePetsSize(); i++) {
  1189. ManagedReference<AiAgent*> object = ownerGhost->getActivePet(i);
  1190.  
  1191. if (object != NULL && object->isCreature()) {
  1192. if (object == attacker)
  1193. continue;
  1194.  
  1195. PetControlDevice* petControlDevice = object->getControlDevice().get().castTo<PetControlDevice*>();
  1196. if (petControlDevice != NULL && petControlDevice->getPetType() == PetManager::CREATUREPET)
  1197. totalPets++;
  1198. }
  1199. }
  1200.  
  1201. // TODO: Find a more correct CH xp formula
  1202. float levelRatio = (float)destructedObject->getLevel() / (float)attacker->getLevel();
  1203.  
  1204. float xpAmount = levelRatio * 500.f;
  1205.  
  1206. if (levelRatio <= 0.5) {
  1207. xpAmount = 1;
  1208. } else {
  1209. xpAmount = MIN(xpAmount, (float)attacker->getLevel() * 50.f);
  1210. xpAmount /= totalPets;
  1211.  
  1212. if (winningFaction == attacker->getFaction())
  1213. xpAmount *= gcwBonus;
  1214. }
  1215.  
  1216. awardExperience(owner, "creaturehandler", xpAmount);
  1217.  
  1218. } else if (attacker->isPlayerCreature()) {
  1219. if (!destructedObject->isInRange(attacker, 80))
  1220. continue;
  1221.  
  1222. ManagedReference<GroupObject*> group = attacker->getGroup();
  1223.  
  1224. uint32 combatXp = 0;
  1225.  
  1226. Locker crossLocker(attacker, destructedObject);
  1227.  
  1228. for (int j = 0; j < entry->size(); ++j) {
  1229. uint32 damage = entry->elementAt(j).getValue();
  1230. String xpType = entry->elementAt(j).getKey();
  1231. float xpAmount = baseXp;
  1232.  
  1233. //xpAmount *= (float) damage / totalDamage;
  1234.  
  1235. //Cap xp based on level
  1236. xpAmount = MIN(xpAmount, calculatePlayerLevel(attacker, xpType) * 300.f);
  1237.  
  1238. //Apply group bonus if in group
  1239. if (group != NULL)
  1240. xpAmount *= groupExpMultiplier;
  1241.  
  1242. if (winningFaction == attacker->getFaction())
  1243. xpAmount *= gcwBonus;
  1244.  
  1245. //Jedi experience doesn't count towards combat experience supposedly.
  1246. if (xpType != "jedi_general")
  1247. combatXp += xpAmount;
  1248.  
  1249. //Award individual expType
  1250. awardExperience(attacker, xpType, xpAmount);
  1251. }
  1252.  
  1253. combatXp /= 10.f;
  1254.  
  1255. awardExperience(attacker, "combat_general", combatXp);
  1256.  
  1257. //Check if the group leader is a squad leader
  1258. if (group == NULL)
  1259. continue;
  1260.  
  1261. Vector3 pos(attacker->getWorldPositionX(), attacker->getWorldPositionY(), 0);
  1262.  
  1263. crossLocker.release();
  1264.  
  1265. ManagedReference<CreatureObject*> groupLeader = group->getLeader();
  1266.  
  1267. if (groupLeader == NULL || !groupLeader->isPlayerCreature())
  1268. continue;
  1269.  
  1270. Locker squadLock(groupLeader, destructedObject);
  1271.  
  1272. //If he is a squad leader, and is in range of this player, then add the combat exp for him to use.
  1273. if (groupLeader->hasSkill("outdoors_squadleader_novice") && pos.distanceTo(attacker->getWorldPosition()) <= ZoneServer::CLOSEOBJECTRANGE) {
  1274. int v = slExperience.get(groupLeader) + combatXp;
  1275. slExperience.put(groupLeader, v);
  1276. }
  1277. }
  1278. }
  1279.  
  1280. //Send out squad leader experience.
  1281. for (int i = 0; i < slExperience.size(); ++i) {
  1282. VectorMapEntry<ManagedReference<CreatureObject*>, int>* entry = &slExperience.elementAt(i);
  1283. CreatureObject* leader = entry->getKey();
  1284.  
  1285. if (leader == NULL)
  1286. continue;
  1287.  
  1288. Locker clock(leader, destructedObject);
  1289.  
  1290. awardExperience(leader, "squadleader", entry->getValue() * 2.f);
  1291. }
  1292.  
  1293. threatMap->removeAll();
  1294. }
  1295.  
  1296.  
  1297.  
  1298. bool PlayerManagerImplementation::checkEncumbrancies(CreatureObject* player, ArmorObject* armor) {
  1299. int strength = player->getHAM(CreatureAttribute::STRENGTH);
  1300. int constitution = player->getHAM(CreatureAttribute::CONSTITUTION);
  1301. int quickness = player->getHAM(CreatureAttribute::QUICKNESS);
  1302. int stamina = player->getHAM(CreatureAttribute::STAMINA);
  1303. int focus = player->getHAM(CreatureAttribute::FOCUS);
  1304. int willpower = player->getHAM(CreatureAttribute::WILLPOWER);
  1305.  
  1306. int healthEncumb = armor->getHealthEncumbrance();
  1307. int actionEncumb = armor->getActionEncumbrance();
  1308. int mindEncumb = armor->getMindEncumbrance();
  1309.  
  1310. if (healthEncumb <= 0 && actionEncumb <= 0 && mindEncumb <= 0)
  1311. return true;
  1312.  
  1313. if (healthEncumb >= strength || healthEncumb >= constitution ||
  1314. actionEncumb >= quickness || actionEncumb >= stamina ||
  1315. mindEncumb >= focus || mindEncumb >= willpower) {
  1316. player->sendSystemMessage("@system_msg:equip_armor_fail"); // You are not healthy enough to wear this armor!
  1317.  
  1318. if (healthEncumb >= strength) {
  1319. int statStr = (healthEncumb - strength) + 1;
  1320. StringIdChatParameter params("@system_msg:equip_armor_fail_prose"); // You need %DI more %TT to wear this armor.
  1321. params.setDI(statStr);
  1322. params.setTT("@att_n:strength");
  1323. player->sendSystemMessage(params);
  1324. }
  1325.  
  1326. if (healthEncumb >= constitution) {
  1327. int statCon = (healthEncumb - constitution) + 1;
  1328. StringIdChatParameter params("@system_msg:equip_armor_fail_prose");
  1329. params.setDI(statCon);
  1330. params.setTT("@att_n:constitution");
  1331. player->sendSystemMessage(params);
  1332. }
  1333.  
  1334. if (actionEncumb >= quickness) {
  1335. int statQuick = (actionEncumb - quickness) + 1;
  1336. StringIdChatParameter params("@system_msg:equip_armor_fail_prose");
  1337. params.setDI(statQuick);
  1338. params.setTT("@att_n:quickness");
  1339. player->sendSystemMessage(params);
  1340. }
  1341.  
  1342. if (actionEncumb >= stamina) {
  1343. int statStam = (actionEncumb - stamina) + 1;
  1344. StringIdChatParameter params("@system_msg:equip_armor_fail_prose");
  1345. params.setDI(statStam);
  1346. params.setTT("@att_n:stamina");
  1347. player->sendSystemMessage(params);
  1348. }
  1349.  
  1350. if (mindEncumb >= focus) {
  1351. int statFoc = (mindEncumb - focus) + 1;
  1352. StringIdChatParameter params("@system_msg:equip_armor_fail_prose");
  1353. params.setDI(statFoc);
  1354. params.setTT("@att_n:focus");
  1355. player->sendSystemMessage(params);
  1356. }
  1357.  
  1358. if (mindEncumb >= willpower) {
  1359. int statWill = (mindEncumb - willpower) + 1;
  1360. StringIdChatParameter params("@system_msg:equip_armor_fail_prose");
  1361. params.setDI(statWill);
  1362. params.setTT("@att_n:willpower");
  1363. player->sendSystemMessage(params);
  1364. }
  1365.  
  1366. return false;
  1367. }
  1368. else
  1369. return true;
  1370. }
  1371.  
  1372.  
  1373. void PlayerManagerImplementation::applyEncumbrancies(CreatureObject* player, ArmorObject* armor) {
  1374. int healthEncumb = MAX(0, armor->getHealthEncumbrance());
  1375. int actionEncumb = MAX(0, armor->getActionEncumbrance());
  1376. int mindEncumb = MAX(0, armor->getMindEncumbrance());
  1377.  
  1378. player->addEncumbrance(CreatureEncumbrance::HEALTH, healthEncumb, true);
  1379. player->addEncumbrance(CreatureEncumbrance::ACTION, actionEncumb, true);
  1380. player->addEncumbrance(CreatureEncumbrance::MIND, mindEncumb, true);
  1381.  
  1382. player->inflictDamage(player, CreatureAttribute::STRENGTH, healthEncumb, true);
  1383. player->addMaxHAM(CreatureAttribute::STRENGTH, -healthEncumb, true);
  1384.  
  1385. player->inflictDamage(player, CreatureAttribute::CONSTITUTION, healthEncumb, true);
  1386. player->addMaxHAM(CreatureAttribute::CONSTITUTION, -healthEncumb, true);
  1387.  
  1388. player->inflictDamage(player, CreatureAttribute::QUICKNESS, actionEncumb, true);
  1389. player->addMaxHAM(CreatureAttribute::QUICKNESS, -actionEncumb, true);
  1390.  
  1391. player->inflictDamage(player, CreatureAttribute::STAMINA, actionEncumb, true);
  1392. player->addMaxHAM(CreatureAttribute::STAMINA, -actionEncumb, true);
  1393.  
  1394. player->inflictDamage(player, CreatureAttribute::FOCUS, mindEncumb, true);
  1395. player->addMaxHAM(CreatureAttribute::FOCUS, -mindEncumb, true);
  1396.  
  1397. player->inflictDamage(player, CreatureAttribute::WILLPOWER, mindEncumb, true);
  1398. player->addMaxHAM(CreatureAttribute::WILLPOWER, -mindEncumb, true);
  1399. }
  1400.  
  1401. void PlayerManagerImplementation::removeEncumbrancies(CreatureObject* player, ArmorObject* armor) {
  1402. int healthEncumb = MAX(0, armor->getHealthEncumbrance());
  1403. int actionEncumb = MAX(0, armor->getActionEncumbrance());
  1404. int mindEncumb = MAX(0, armor->getMindEncumbrance());
  1405.  
  1406. player->addEncumbrance(CreatureEncumbrance::HEALTH, -healthEncumb, true);
  1407. player->addEncumbrance(CreatureEncumbrance::ACTION, -actionEncumb, true);
  1408. player->addEncumbrance(CreatureEncumbrance::MIND, -mindEncumb, true);
  1409.  
  1410. player->addMaxHAM(CreatureAttribute::STRENGTH, healthEncumb, true);
  1411. player->healDamage(player, CreatureAttribute::STRENGTH, healthEncumb, true);
  1412.  
  1413. player->addMaxHAM(CreatureAttribute::CONSTITUTION, healthEncumb, true);
  1414. player->healDamage(player, CreatureAttribute::CONSTITUTION, healthEncumb, true);
  1415.  
  1416. player->addMaxHAM(CreatureAttribute::QUICKNESS, actionEncumb, true);
  1417. player->healDamage(player, CreatureAttribute::QUICKNESS, actionEncumb, true);
  1418.  
  1419. player->addMaxHAM(CreatureAttribute::STAMINA, actionEncumb, true);
  1420. player->healDamage(player, CreatureAttribute::STAMINA, actionEncumb, true);
  1421.  
  1422. player->addMaxHAM(CreatureAttribute::FOCUS, mindEncumb, true);
  1423. player->healDamage(player, CreatureAttribute::FOCUS, mindEncumb, true);
  1424.  
  1425. player->addMaxHAM(CreatureAttribute::WILLPOWER, mindEncumb, true);
  1426. player->healDamage(player, CreatureAttribute::WILLPOWER, mindEncumb, true);
  1427. }
  1428.  
  1429. void PlayerManagerImplementation::awardBadge(PlayerObject* ghost, uint32 badgeId) {
  1430. const Badge* badge = BadgeList::instance()->get(badgeId);
  1431. if (badge != NULL)
  1432. awardBadge(ghost, badge);
  1433. }
  1434.  
  1435. void PlayerManagerImplementation::awardBadge(PlayerObject* ghost, const Badge* badge) {
  1436. if (badge == NULL) {
  1437. ghost->error("Failed to award null badge.");
  1438. return;
  1439. }
  1440.  
  1441. StringIdChatParameter stringId("badge_n", "");
  1442. stringId.setTO("badge_n", badge->getKey());
  1443.  
  1444. ManagedReference<CreatureObject*> player = dynamic_cast<CreatureObject*>(ghost->getParent().get().get());
  1445. const unsigned int badgeId = badge->getIndex();
  1446. if (ghost->hasBadge(badgeId)) {
  1447. stringId.setStringId("badge_n", "prose_hasbadge");
  1448. player->sendSystemMessage(stringId);
  1449. return;
  1450. }
  1451.  
  1452. ghost->setBadge(badgeId);
  1453. stringId.setStringId("badge_n", "prose_grant");
  1454. player->sendSystemMessage(stringId);
  1455.  
  1456. if (badge->getHasMusic()) {
  1457. String music = badge->getMusic();
  1458. PlayMusicMessage* musicMessage = new PlayMusicMessage(music);
  1459. player->sendMessage(musicMessage);
  1460. }
  1461.  
  1462. player->notifyObservers(ObserverEventType::BADGEAWARDED, player, badgeId);
  1463. BadgeList* badgeList = BadgeList::instance();
  1464. switch (ghost->getNumBadges()) {
  1465. case 5:
  1466. awardBadge(ghost, badgeList->get("count_5"));
  1467. break;
  1468. case 10:
  1469. awardBadge(ghost, badgeList->get("count_10"));
  1470. break;
  1471. case 25:
  1472. awardBadge(ghost, badgeList->get("count_25"));
  1473. break;
  1474. case 50:
  1475. awardBadge(ghost, badgeList->get("count_50"));
  1476. break;
  1477. case 75:
  1478. awardBadge(ghost, badgeList->get("count_75"));
  1479. break;
  1480. case 100:
  1481. awardBadge(ghost, badgeList->get("count_100"));
  1482. break;
  1483. case 125:
  1484. awardBadge(ghost, badgeList->get("count_125"));
  1485. break;
  1486. default:
  1487. break;
  1488. }
  1489.  
  1490. if (badge->getType() == Badge::EXPLORATION) {
  1491. switch (ghost->getBadgeTypeCount(static_cast<uint8>(Badge::EXPLORATION))) {
  1492. case 10:
  1493. awardBadge(ghost, badgeList->get("bdg_exp_10_badges"));
  1494. break;
  1495. case 20:
  1496. awardBadge(ghost, badgeList->get("bdg_exp_20_badges"));
  1497. break;
  1498. case 30:
  1499. awardBadge(ghost, badgeList->get("bdg_exp_30_badges"));
  1500. break;
  1501. case 40:
  1502. awardBadge(ghost, badgeList->get("bdg_exp_40_badges"));
  1503. break;
  1504. case 45:
  1505. awardBadge(ghost, badgeList->get("bdg_exp_45_badges"));
  1506. break;
  1507. default:
  1508. break;
  1509. }
  1510. }
  1511. }
  1512.  
  1513. void PlayerManagerImplementation::setExperienceMultiplier(float globalMultiplier) {
  1514. globalExpMultiplier = globalMultiplier;
  1515. }
  1516.  
  1517. /*
  1518. * Award experience to a player.
  1519. * Ex.
  1520. PlayerManager* playerManager = server->getPlayerManager();
  1521. playerManager->awardExperience(playerCreature, "resource_harvesting_inorganic", 500);
  1522. *
  1523. */
  1524. void PlayerManagerImplementation::awardExperience(CreatureObject* player, const String& xpType,
  1525. int amount, bool sendSystemMessage, float localMultiplier) {
  1526.  
  1527. PlayerObject* playerObject = player->getPlayerObject();
  1528.  
  1529. if (playerObject == NULL)
  1530. return;
  1531.  
  1532. int xp = playerObject->addExperience(xpType, (int) (amount * localMultiplier * globalExpMultiplier));
  1533.  
  1534. player->notifyObservers(ObserverEventType::XPAWARDED, player, xp);
  1535.  
  1536. if (sendSystemMessage) {
  1537. if (xp > 0) {
  1538. StringIdChatParameter message("base_player","prose_grant_xp");
  1539. message.setDI(xp);
  1540. message.setTO("exp_n", xpType);
  1541. player->sendSystemMessage(message);
  1542. }
  1543. if (xp > 0 && playerObject->hasCappedExperience(xpType)) {
  1544. StringIdChatParameter message("base_player", "prose_hit_xp_cap"); //You have achieved your current limit for %TO experience.
  1545. message.setTO("exp_n", xpType);
  1546. player->sendSystemMessage(message);
  1547. }
  1548. }
  1549.  
  1550.  
  1551. }
  1552.  
  1553. void PlayerManagerImplementation::sendLoginMessage(CreatureObject* creature) {
  1554. String motd = server->getLoginMessage();
  1555.  
  1556. ChatSystemMessage* csm = new ChatSystemMessage(UnicodeString(motd), ChatSystemMessage::DISPLAY_CHATONLY);
  1557. creature->sendMessage(csm);
  1558. }
  1559.  
  1560. void PlayerManagerImplementation::resendLoginMessageToAll() {
  1561. ChatManager* chatManager = server->getChatManager();
  1562.  
  1563. if (chatManager != NULL) {
  1564. String motd = server->getLoginMessage();
  1565.  
  1566. ChatSystemMessage* csm = new ChatSystemMessage(UnicodeString(motd), ChatSystemMessage::DISPLAY_CHATONLY);
  1567. chatManager->broadcastMessage(csm);
  1568. }
  1569. }
  1570.  
  1571. void PlayerManagerImplementation::handleAbortTradeMessage(CreatureObject* player) {
  1572. Locker _locker(player);
  1573.  
  1574. ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1575.  
  1576. if (tradeContainer == NULL) {
  1577. AbortTradeMessage* msg = new AbortTradeMessage();
  1578. player->sendMessage(msg);
  1579.  
  1580. return;
  1581. }
  1582.  
  1583. uint64 targID = tradeContainer->getTradeTargetPlayer();
  1584. ManagedReference<SceneObject*> obj = server->getObject(targID);
  1585.  
  1586. AbortTradeMessage* msg = new AbortTradeMessage();
  1587.  
  1588. if (obj != NULL && obj->isPlayerCreature()) {
  1589. CreatureObject* receiver = cast<CreatureObject*>( obj.get());
  1590.  
  1591. Locker locker(receiver, player);
  1592.  
  1593. ManagedReference<TradeSession*> receiverContainer = receiver->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1594.  
  1595. if (receiverContainer != NULL && receiverContainer->getTradeTargetPlayer() == player->getObjectID()) {
  1596. receiver->dropActiveSession(SessionFacadeType::TRADE);
  1597. receiver->sendMessage(msg->clone());
  1598. }
  1599.  
  1600. locker.release();
  1601. }
  1602.  
  1603. player->sendMessage(msg->clone());
  1604.  
  1605. delete msg;
  1606.  
  1607. player->dropActiveSession(SessionFacadeType::TRADE);
  1608. }
  1609.  
  1610. void PlayerManagerImplementation::handleAddItemToTradeWindow(CreatureObject* player, uint64 itemID) {
  1611. Locker _locker(player);
  1612.  
  1613. ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1614.  
  1615. if (tradeContainer == NULL)
  1616. return;
  1617.  
  1618. // First Verify Target is Player
  1619. uint64 targID = tradeContainer->getTradeTargetPlayer();
  1620. ManagedReference<SceneObject*> obj = server->getObject(targID);
  1621.  
  1622. if (obj == NULL || !obj->isPlayerCreature())
  1623. return;
  1624.  
  1625. CreatureObject* receiver = cast<CreatureObject*>( obj.get());
  1626.  
  1627. ManagedReference<SceneObject*> objectToTrade = server->getObject(itemID);
  1628.  
  1629. if (objectToTrade == NULL || !objectToTrade->isASubChildOf(player) ||
  1630. !objectToTrade->checkContainerPermission(player, ContainerPermissions::MOVECONTAINER)) {
  1631. player->sendSystemMessage("@container_error_message:container26");
  1632. handleAbortTradeMessage(player);
  1633. return;
  1634. }
  1635.  
  1636. if (objectToTrade->isNoTrade()) {
  1637. player->sendSystemMessage("@container_error_message:container26");
  1638. handleAbortTradeMessage(player);
  1639. return;
  1640. }
  1641.  
  1642. // Containers containing notrade items...
  1643. if (objectToTrade->containsNoTradeObjectRecursive()) {
  1644. player->sendSystemMessage("@container_error_message:container26");
  1645. handleAbortTradeMessage(player);
  1646. return;
  1647. }
  1648.  
  1649. if(objectToTrade->isControlDevice()) {
  1650. Reference<ControlDevice*> controlDevice = cast<ControlDevice*>(objectToTrade.get());
  1651. Reference<TangibleObject*> controlledObject = controlDevice->getControlledObject();
  1652.  
  1653. if (controlledObject != NULL) {
  1654. Locker crossLocker(controlledObject, player);
  1655.  
  1656. controlDevice->storeObject(player, true);
  1657. }
  1658. }
  1659.  
  1660. tradeContainer->addTradeItem(objectToTrade);
  1661.  
  1662. SceneObject* inventory = player->getSlottedObject("inventory");
  1663. inventory->sendWithoutContainerObjectsTo(receiver);
  1664. objectToTrade->sendTo(receiver, true);
  1665.  
  1666. AddItemMessage* msg = new AddItemMessage(itemID);
  1667. receiver->sendMessage(msg);
  1668. }
  1669.  
  1670. void PlayerManagerImplementation::handleGiveMoneyMessage(CreatureObject* player, uint32 value) {
  1671. Locker _locker(player);
  1672.  
  1673. int currentMoney = player->getCashCredits();
  1674.  
  1675. if (value > currentMoney)
  1676. value = currentMoney;
  1677.  
  1678. ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1679.  
  1680. if (tradeContainer == NULL)
  1681. return;
  1682.  
  1683. tradeContainer->setMoneyToTrade(value);
  1684.  
  1685. uint64 targID = tradeContainer->getTradeTargetPlayer();
  1686. ManagedReference<SceneObject*> obj = server->getObject(targID);
  1687.  
  1688. if (obj != NULL && obj->isPlayerCreature()) {
  1689. CreatureObject* receiver = cast<CreatureObject*>( obj.get());
  1690.  
  1691. GiveMoneyMessage* msg = new GiveMoneyMessage(value);
  1692. receiver->sendMessage(msg);
  1693. }
  1694. }
  1695.  
  1696. void PlayerManagerImplementation::handleAcceptTransactionMessage(CreatureObject* player) {
  1697. Locker _locker(player);
  1698.  
  1699. ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1700.  
  1701. if (tradeContainer == NULL)
  1702. return;
  1703.  
  1704. tradeContainer->setAcceptedTrade(true);
  1705.  
  1706. uint64 targID = tradeContainer->getTradeTargetPlayer();
  1707. ManagedReference<SceneObject*> obj = server->getObject(targID);
  1708.  
  1709. if (obj != NULL && obj->isPlayerCreature()) {
  1710. CreatureObject* receiver = cast<CreatureObject*>(obj.get());
  1711.  
  1712. AcceptTransactionMessage* msg = new AcceptTransactionMessage();
  1713. receiver->sendMessage(msg);
  1714. }
  1715. }
  1716.  
  1717. void PlayerManagerImplementation::handleUnAcceptTransactionMessage(CreatureObject* player) {
  1718. Locker _locker(player);
  1719.  
  1720. ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1721.  
  1722. if (tradeContainer == NULL)
  1723. return;
  1724.  
  1725. tradeContainer->setAcceptedTrade(false);
  1726.  
  1727. uint64 targID = tradeContainer->getTradeTargetPlayer();
  1728. ManagedReference<SceneObject*> obj = server->getObject(targID);
  1729.  
  1730. if (obj != NULL && obj->isPlayerCreature()) {
  1731. CreatureObject* receiver = cast<CreatureObject*>(obj.get());
  1732.  
  1733. UnAcceptTransactionMessage* msg = new UnAcceptTransactionMessage();
  1734. receiver->sendMessage(msg);
  1735. }
  1736.  
  1737. }
  1738.  
  1739. bool PlayerManagerImplementation::checkTradeItems(CreatureObject* player, CreatureObject* receiver) {
  1740. PlayerObject* ghost = player->getPlayerObject();
  1741. PlayerObject* targetGhost = receiver->getPlayerObject();
  1742.  
  1743. ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1744. ManagedReference<TradeSession*> receiverContainer = receiver->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1745.  
  1746. if (tradeContainer == NULL || receiverContainer == NULL)
  1747. return false;
  1748.  
  1749. if (tradeContainer->getTradeTargetPlayer() != receiver->getObjectID())
  1750. return false;
  1751.  
  1752. if (receiverContainer->getTradeTargetPlayer() != player->getObjectID())
  1753. return false;
  1754.  
  1755. SceneObject* playerInventory = player->getSlottedObject("inventory");
  1756. SceneObject* receiverInventory = receiver->getSlottedObject("inventory");
  1757.  
  1758. SceneObject* playerDatapad = player->getSlottedObject("datapad");
  1759. SceneObject* receiverDatapad = receiver->getSlottedObject("datapad");
  1760.  
  1761. int playerTanos = 0;
  1762. int playerItnos = 0;
  1763. int recieverTanos = 0;
  1764. int recieverItnos = 0;
  1765. int playerCreaturePetsTraded = 0;
  1766. int receiverCreaturePetsTraded = 0;
  1767. int playerFactionPetsTraded = 0;
  1768. int receiverFactionPetsTraded = 0;
  1769. int playerDroidsTraded = 0;
  1770. int receiverDroidsTraded = 0;
  1771. int playerVehiclesTraded = 0;
  1772. int receiverVehiclesTraded = 0;
  1773. int playerShipsTraded = 0;
  1774. int receiverShipsTraded = 0;
  1775.  
  1776. for (int i = 0; i < tradeContainer->getTradeSize(); ++i) {
  1777. ManagedReference<SceneObject*> scene = tradeContainer->getTradeItem(i);
  1778.  
  1779. if(scene->isNoTrade())
  1780. return false;
  1781.  
  1782. if(scene->isTangibleObject()) {
  1783.  
  1784. String err;
  1785. if (receiverInventory->canAddObject(scene, -1, err) != 0)
  1786. return false;
  1787.  
  1788. if (!playerInventory->hasObjectInContainer(scene->getObjectID()))
  1789. return false;
  1790.  
  1791. recieverTanos++;
  1792.  
  1793. } else if(scene->isIntangibleObject()) {
  1794.  
  1795. String err;
  1796. if (receiverDatapad->canAddObject(scene, -1, err) != 0)
  1797. return false;
  1798.  
  1799. if (!playerDatapad->hasObjectInContainer(scene->getObjectID()))
  1800. return false;
  1801.  
  1802. if (scene->isPetControlDevice()) {
  1803. PetControlDevice* petControlDevice = cast<PetControlDevice*>(scene.get());
  1804.  
  1805. if (petControlDevice->getPetType() == PetManager::CREATUREPET) {
  1806. if (!petControlDevice->canBeTradedTo(player, receiver, receiverCreaturePetsTraded))
  1807. return false;
  1808.  
  1809. receiverCreaturePetsTraded++;
  1810. } else if (petControlDevice->getPetType() == PetManager::FACTIONPET) {
  1811. if (!petControlDevice->canBeTradedTo(player, receiver, receiverFactionPetsTraded))
  1812. return false;
  1813.  
  1814. receiverFactionPetsTraded++;
  1815. } else if (petControlDevice->getPetType() == PetManager::DROIDPET) {
  1816. if (!petControlDevice->canBeTradedTo(player, receiver, receiverDroidsTraded))
  1817. return false;
  1818.  
  1819. receiverDroidsTraded++;
  1820. }
  1821. } else if (scene->isVehicleControlDevice()) {
  1822. VehicleControlDevice* vehicleControlDevice = cast<VehicleControlDevice*>(scene.get());
  1823.  
  1824. if (!vehicleControlDevice->canBeTradedTo(player, receiver, receiverVehiclesTraded))
  1825. return false;
  1826.  
  1827. receiverVehiclesTraded++;
  1828. } else if (scene->isShipControlDevice()) {
  1829. ShipControlDevice* shipControlDevice = cast<ShipControlDevice*>(scene.get());
  1830.  
  1831. if (!shipControlDevice->canBeTradedTo(player, receiver, receiverShipsTraded))
  1832. return false;
  1833.  
  1834. receiverShipsTraded++;
  1835. }
  1836.  
  1837. recieverItnos++;
  1838.  
  1839. } else {
  1840. return false;
  1841. }
  1842. }
  1843.  
  1844. for (int i = 0; i < receiverContainer->getTradeSize(); ++i) {
  1845. ManagedReference<SceneObject*> scene = receiverContainer->getTradeItem(i);
  1846.  
  1847. if(scene->isNoTrade())
  1848. return false;
  1849.  
  1850. if(scene->isTangibleObject()) {
  1851.  
  1852. String err;
  1853. if (playerInventory->canAddObject(scene, -1, err) != 0)
  1854. return false;
  1855.  
  1856. if (!receiverInventory->hasObjectInContainer(scene->getObjectID()))
  1857. return false;
  1858.  
  1859. playerTanos++;
  1860.  
  1861. } else if(scene->isIntangibleObject()) {
  1862.  
  1863. String err;
  1864. if (playerDatapad->canAddObject(scene, -1, err) != 0)
  1865. return false;
  1866.  
  1867. if (!receiverDatapad->hasObjectInContainer(scene->getObjectID()))
  1868. return false;
  1869.  
  1870. if (scene->isPetControlDevice()) {
  1871. PetControlDevice* petControlDevice = cast<PetControlDevice*>(scene.get());
  1872.  
  1873. if (petControlDevice->getPetType() == PetManager::CREATUREPET) {
  1874. if (!petControlDevice->canBeTradedTo(receiver, player, playerCreaturePetsTraded))
  1875. return false;
  1876.  
  1877. playerCreaturePetsTraded++;
  1878. } else if (petControlDevice->getPetType() == PetManager::FACTIONPET) {
  1879. if (!petControlDevice->canBeTradedTo(receiver, player, playerFactionPetsTraded))
  1880. return false;
  1881.  
  1882. playerFactionPetsTraded++;
  1883. } else if (petControlDevice->getPetType() == PetManager::DROIDPET) {
  1884. if (!petControlDevice->canBeTradedTo(receiver, player, playerDroidsTraded))
  1885. return false;
  1886.  
  1887. playerDroidsTraded++;
  1888. }
  1889. } else if (scene->isVehicleControlDevice()) {
  1890. VehicleControlDevice* vehicleControlDevice = cast<VehicleControlDevice*>(scene.get());
  1891.  
  1892. if (!vehicleControlDevice->canBeTradedTo(receiver, player, playerVehiclesTraded))
  1893. return false;
  1894.  
  1895. playerVehiclesTraded++;
  1896. } else if (scene->isShipControlDevice()) {
  1897. ShipControlDevice* shipControlDevice = cast<ShipControlDevice*>(scene.get());
  1898.  
  1899. if (!shipControlDevice->canBeTradedTo(receiver, player, playerShipsTraded))
  1900. return false;
  1901.  
  1902. playerShipsTraded++;
  1903. }
  1904.  
  1905. playerItnos++;
  1906.  
  1907. } else {
  1908. return false;
  1909. }
  1910. }
  1911.  
  1912. if (recieverTanos != 0 && (receiverInventory->getContainerObjectsSize() + recieverTanos >= receiverInventory->getContainerVolumeLimit())) {
  1913. player->sendSystemMessage("@container_error_message:container19");
  1914. receiver->sendSystemMessage("@container_error_message:container19");
  1915. return false;
  1916. }
  1917.  
  1918. if (playerTanos != 0 && (playerInventory->getContainerObjectsSize() + playerTanos >= playerInventory->getContainerVolumeLimit())) {
  1919. player->sendSystemMessage("@container_error_message:container19");
  1920. receiver->sendSystemMessage("@container_error_message:container19");
  1921. return false;
  1922. }
  1923.  
  1924. if (receiverDatapad->getContainerObjectsSize() + recieverItnos >= receiverDatapad->getContainerVolumeLimit()) {
  1925. player->sendSystemMessage("@container_error_message:container19");
  1926. receiver->sendSystemMessage("@container_error_message:container19");
  1927. return false;
  1928. }
  1929.  
  1930. if (playerDatapad->getContainerObjectsSize() + playerItnos >= playerDatapad->getContainerVolumeLimit()) {
  1931. player->sendSystemMessage("@container_error_message:container19");
  1932. receiver->sendSystemMessage("@container_error_message:container19");
  1933. return false;
  1934. }
  1935.  
  1936. int playerMoneyToTrade = tradeContainer->getMoneyToTrade();
  1937.  
  1938. if (playerMoneyToTrade < 0)
  1939. return false;
  1940.  
  1941. if (playerMoneyToTrade > player->getCashCredits())
  1942. return false;
  1943.  
  1944. int receiverMoneyToTrade = receiverContainer->getMoneyToTrade();
  1945.  
  1946. if (receiverMoneyToTrade < 0)
  1947. return false;
  1948.  
  1949. if (receiverMoneyToTrade > receiver->getCashCredits())
  1950. return false;
  1951.  
  1952. if (player->getDistanceTo(receiver) >= 15.f) {
  1953. player->sendSystemMessage("You are too far to trade");
  1954. receiver->sendSystemMessage("You are too far to trade");
  1955. return false;
  1956. }
  1957.  
  1958.  
  1959. return true;
  1960. }
  1961.  
  1962. void PlayerManagerImplementation::handleVerifyTradeMessage(CreatureObject* player) {
  1963. ManagedReference<ObjectController*> objectController = server->getObjectController();
  1964.  
  1965. Locker locker(player);
  1966.  
  1967. ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1968.  
  1969. if (tradeContainer == NULL) {
  1970. return;
  1971. }
  1972.  
  1973. tradeContainer->setVerifiedTrade(true);
  1974.  
  1975. uint64 targID = tradeContainer->getTradeTargetPlayer();
  1976. ManagedReference<SceneObject*> obj = server->getObject(targID);
  1977.  
  1978. if (obj != NULL && obj->isPlayerCreature()) {
  1979. CreatureObject* receiver = cast<CreatureObject*>(obj.get());
  1980.  
  1981. Locker clocker(receiver, player);
  1982.  
  1983. ManagedReference<TradeSession*> receiverTradeContainer = receiver->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();
  1984.  
  1985. if (receiverTradeContainer == NULL) {
  1986. tradeContainer->setVerifiedTrade(false);
  1987. return;
  1988. }
  1989.  
  1990. if (!checkTradeItems(player, receiver)) {
  1991. clocker.release();
  1992. handleAbortTradeMessage(player);
  1993.  
  1994. locker.release();
  1995. return;
  1996. }
  1997.  
  1998. if (receiverTradeContainer->hasVerifiedTrade()) {
  1999. SceneObject* receiverInventory = receiver->getSlottedObject("inventory");
  2000. SceneObject* receiverDatapad = receiver->getSlottedObject("datapad");
  2001.  
  2002. for (int i = 0; i < tradeContainer->getTradeSize(); ++i) {
  2003. ManagedReference<SceneObject*> item = tradeContainer->getTradeItem(i);
  2004.  
  2005. if(item->isTangibleObject()) {
  2006. if (objectController->transferObject(item, receiverInventory, -1, true))
  2007. item->sendDestroyTo(player);
  2008. } else {
  2009. if (objectController->transferObject(item, receiverDatapad, -1, true))
  2010. item->sendDestroyTo(player);
  2011. }
  2012. }
  2013.  
  2014. SceneObject* playerInventory = player->getSlottedObject("inventory");
  2015. SceneObject* playerDatapad = player->getSlottedObject("datapad");
  2016.  
  2017. for (int i = 0; i < receiverTradeContainer->getTradeSize(); ++i) {
  2018. ManagedReference<SceneObject*> item = receiverTradeContainer->getTradeItem(i);
  2019.  
  2020. if(item->isTangibleObject()) {
  2021. if (objectController->transferObject(item, playerInventory, -1, true))
  2022. item->sendDestroyTo(receiver);
  2023. } else {
  2024. if (objectController->transferObject(item, playerDatapad, -1, true))
  2025. item->sendDestroyTo(receiver);
  2026. }
  2027. }
  2028.  
  2029. uint32 giveMoney = tradeContainer->getMoneyToTrade();
  2030.  
  2031. if (giveMoney > 0) {
  2032. player->subtractCashCredits(giveMoney);
  2033. receiver->addCashCredits(giveMoney);
  2034. }
  2035.  
  2036. giveMoney = receiverTradeContainer->getMoneyToTrade();
  2037.  
  2038. if (giveMoney > 0) {
  2039. receiver->subtractCashCredits(giveMoney);
  2040. player->addCashCredits(giveMoney);
  2041. }
  2042.  
  2043. receiver->dropActiveSession(SessionFacadeType::TRADE);
  2044. player->dropActiveSession(SessionFacadeType::TRADE);
  2045.  
  2046. TradeCompleteMessage* msg = new TradeCompleteMessage();
  2047. receiver->sendMessage(msg->clone());
  2048. player->sendMessage(msg->clone());
  2049.  
  2050. delete msg;
  2051. }
  2052. }
  2053. }
  2054.  
  2055. int PlayerManagerImplementation::notifyObserverEvent(uint32 eventType, Observable* observable, ManagedObject* arg1, int64 arg2) {
  2056.  
  2057. if (eventType == ObserverEventType::POSTURECHANGED) {
  2058. CreatureObject* creature = cast<CreatureObject*>(observable);
  2059.  
  2060. if (creature == NULL)
  2061. return 1;
  2062.  
  2063. if (creature->hasState(CreatureState::ALERT)) { // This can apply to TKA AND Jedi meditate since they share the same sysmsgs / moods.
  2064. creature->sendSystemMessage("@teraskasi:med_end");
  2065. creature->setMood(creature->getMoodID(), true);
  2066. creature->clearState(CreatureState::ALERT, true);
  2067.  
  2068. // Check POSTERCHANGE on Meditate...
  2069. Reference<MeditateTask*> meditateTask = creature->getPendingTask("meditate").castTo<MeditateTask*>();
  2070. if (meditateTask != NULL) {
  2071. creature->removePendingTask("meditate");
  2072.  
  2073. if (meditateTask->isScheduled())
  2074. meditateTask->cancel();
  2075. }
  2076.  
  2077. // Check POSTERCHANGE on Force Meditate...
  2078. Reference<ForceMeditateTask*> fmeditateTask = creature->getPendingTask("forcemeditate").castTo<ForceMeditateTask*>( );
  2079.  
  2080. if (fmeditateTask != NULL) {
  2081. creature->removePendingTask("forcemeditate");
  2082.  
  2083. if (fmeditateTask->isScheduled())
  2084. fmeditateTask->cancel();
  2085. }
  2086. }
  2087.  
  2088. // Check POSTURECHANGED disrupting Logout...
  2089. Reference<LogoutTask*> logoutTask = creature->getPendingTask("logout").castTo<LogoutTask*>();
  2090. if(logoutTask != NULL) {
  2091. logoutTask->cancelLogout();
  2092. }
  2093.  
  2094. return 1;
  2095. }
  2096.  
  2097. return 0;
  2098. }
  2099.  
  2100. void PlayerManagerImplementation::sendBattleFatigueMessage(CreatureObject* player, CreatureObject* target) {
  2101. if (target->isPlayerCreature()) {
  2102. uint32 targetBattleFatigue = target->getShockWounds();
  2103.  
  2104. if (targetBattleFatigue >= 250 && targetBattleFatigue < 500) {
  2105. target->sendSystemMessage("@healing:shock_effect_low_target");
  2106. } else if (targetBattleFatigue >= 500 && targetBattleFatigue < 750) {
  2107. target->sendSystemMessage("@healing:shock_effect_medium_target");
  2108. } else if (targetBattleFatigue >= 750) {
  2109. target->sendSystemMessage("@healing:shock_effec_high_target");
  2110. }
  2111. }
  2112.  
  2113. uint32 playerBattleFatigue = player->getShockWounds();
  2114.  
  2115. if (playerBattleFatigue >= 250 && playerBattleFatigue < 500) {
  2116. player->sendSystemMessage("@healing:shock_effect_low");
  2117. } else if (playerBattleFatigue >= 500 && playerBattleFatigue < 750) {
  2118. player->sendSystemMessage("@healing:shock_effect_medium");
  2119. } else if (playerBattleFatigue >= 750) {
  2120. player->sendSystemMessage("@healing:shock_effect_high");
  2121. }
  2122. }
  2123.  
  2124. int PlayerManagerImplementation::healEnhance(CreatureObject* enhancer, CreatureObject* patient, byte attribute, int buffvalue, float duration) {
  2125. String buffname = "medical_enhance_" + BuffAttribute::getName(attribute);
  2126. uint32 buffcrc = buffname.hashCode();
  2127. uint32 buffdiff = buffvalue;
  2128.  
  2129. //If a stronger buff already exists, then we don't buff the patient.
  2130. if (patient->hasBuff(buffcrc)) {
  2131. Buff* buff = patient->getBuff(buffcrc);
  2132.  
  2133. if (buff != NULL) {
  2134. int value = buff->getAttributeModifierValue(attribute);
  2135.  
  2136. if(BuffAttribute::isProtection(attribute))
  2137. value = buff->getSkillModifierValue(BuffAttribute::getProtectionString(attribute));
  2138.  
  2139. if (value > buffvalue)
  2140. return 0;
  2141.  
  2142. buffdiff -= value;
  2143. }
  2144. }
  2145.  
  2146. Reference<Buff*> buff = new Buff(patient, buffcrc, duration, BuffType::MEDICAL);
  2147.  
  2148. Locker locker(buff);
  2149.  
  2150. if(BuffAttribute::isProtection(attribute)) {
  2151. buff->setSkillModifier(BuffAttribute::getProtectionString(attribute), buffvalue);
  2152. } else {
  2153. buff->setAttributeModifier(attribute, buffvalue);
  2154. buff->setFillAttributesOnBuff(true);
  2155. }
  2156.  
  2157. patient->addBuff(buff);
  2158.  
  2159. enhancer->notifyObservers(ObserverEventType::ENHANCINGPERFORMED, patient, buffdiff);
  2160.  
  2161. return buffdiff;
  2162. }
  2163.  
  2164. void PlayerManagerImplementation::stopListen(CreatureObject* creature, uint64 entid, bool doSendPackets, bool forced, bool doLock, bool outOfRange) {
  2165. Locker locker(creature);
  2166.  
  2167. ManagedReference<SceneObject*> object = server->getObject(entid);
  2168. uint64 listenID = creature->getListenID();
  2169.  
  2170. if (object == NULL)
  2171. return;
  2172.  
  2173. // If the player selected "Stop listening" by using a radial menu created on a
  2174. // musician other than the one that they are currently listening to then change
  2175. // entid to their listenID so that the player can still stop listening.
  2176. if (entid != listenID && listenID != 0 && creature->isListening()) {
  2177. entid = listenID;
  2178. }
  2179.  
  2180. if(object->isDroidObject()) {
  2181. creature->setMood(creature->getMoodID());
  2182. if(doSendPackets) {
  2183. creature->setListenToID(0, true);
  2184. creature->setMoodString(creature->getMoodString(), true);
  2185. }
  2186. if (creature->isPlayerCreature()) {
  2187. CreatureObject* player = cast<CreatureObject*>( creature);
  2188. StringIdChatParameter stringID;
  2189. if (forced) {
  2190. stringID.setTU(entid);
  2191. stringID.setStringId("performance", "music_stop_other"); // "%TU stops playing."
  2192. player->sendSystemMessage(stringID);
  2193. return;
  2194. } else if (outOfRange) {
  2195. // The correct string id is @performance:music_listen_out_of_range ("You stop listening to %TT because %OT is too far away.")
  2196. // but %OT will get replaced by him/her which gives an incorrect message.
  2197. StringBuffer msg;
  2198. msg << "You stop listening to " << object->getDisplayedName() << " because they are too far away.";
  2199. player->sendSystemMessage(msg.toString());
  2200. return;
  2201. } else {
  2202. player->sendSystemMessage("@performance:music_listen_stop_self"); // "You stop listening."
  2203. return;
  2204. }
  2205. }
  2206. return;
  2207. }
  2208.  
  2209. if (!object->isPlayerCreature()) {
  2210. creature->sendSystemMessage("@performance:music_listen_npc"); // "You cannot /listen to NPCs."
  2211. return;
  2212. }
  2213.  
  2214. CreatureObject* entertainer = cast<CreatureObject*>( object.get());
  2215.  
  2216. if (entertainer == creature)
  2217. return;
  2218.  
  2219. String entName;
  2220. ManagedReference<EntertainingSession*> esession;
  2221.  
  2222. if (entertainer != NULL) {
  2223. Locker clocker(entertainer, creature);
  2224.  
  2225. entName = entertainer->getFirstName();
  2226.  
  2227. ManagedReference<Facade*> session = entertainer->getActiveSession(SessionFacadeType::ENTERTAINING);
  2228.  
  2229. if (session != NULL) {
  2230. esession = dynamic_cast<EntertainingSession*>(session.get());
  2231.  
  2232. if (esession != NULL) {
  2233. esession->activateEntertainerBuff(creature, PerformanceType::MUSIC);
  2234.  
  2235. esession->removeListener(creature);
  2236. }
  2237. }
  2238.  
  2239. clocker.release();
  2240. }
  2241.  
  2242. creature->setMood(creature->getMoodID());
  2243.  
  2244. if (doSendPackets && esession != NULL)
  2245. esession->sendEntertainmentUpdate(creature, 0, creature->getMoodString());
  2246.  
  2247. if (creature->isPlayerCreature() && entertainer != NULL) {
  2248. CreatureObject* player = cast<CreatureObject*>( creature);
  2249.  
  2250. StringIdChatParameter stringID;
  2251.  
  2252. if (forced) {
  2253. stringID.setTU(entid);
  2254. stringID.setStringId("performance", "music_stop_other"); // "%TU stops playing."
  2255.  
  2256. player->sendSystemMessage(stringID);
  2257. } else if (outOfRange) {
  2258. // The correct string id is @performance:music_listen_out_of_range ("You stop listening to %TT because %OT is too far away.")
  2259. // but %OT will get replaced by him/her which gives an incorrect message.
  2260. StringBuffer msg;
  2261. msg << "You stop listening to " << entertainer->getFirstName() << " because they are too far away.";
  2262. player->sendSystemMessage(msg.toString());
  2263. } else {
  2264. player->sendSystemMessage("@performance:music_listen_stop_self"); // "You stop listening."
  2265. }
  2266.  
  2267. ManagedReference<PlayerObject*> entPlayer = entertainer->getPlayerObject();
  2268. if (entPlayer != NULL && entPlayer->getPerformanceBuffTarget() == player->getObjectID())
  2269. entPlayer->setPerformanceBuffTarget(0);
  2270. }
  2271. //esession->setEntertainerBuffDuration(creature, PerformanceType::MUSIC, 0.0f); // reset
  2272. //esession->setEntertainerBuffStrength(creature, PerformanceType::MUSIC, 0.0f);
  2273. creature->info("stopped listening [" + entName + "]");
  2274.  
  2275. creature->setListenToID(0, true);
  2276. }
  2277.  
  2278.  
  2279. void PlayerManagerImplementation::stopWatch(CreatureObject* creature, uint64 entid, bool doSendPackets, bool forced, bool doLock, bool outOfRange) {
  2280. Locker locker(creature);
  2281.  
  2282. uint64 watchID = creature->getWatchToID();
  2283.  
  2284. // If the player selected "Stop watching" by using a radial menu created on a
  2285. // dancer other than the one that they are currently watching then change
  2286. // entid to their watchID so that the player can still stop watching.
  2287. if (entid != watchID && watchID != 0 && creature->isWatching()) {
  2288. entid = watchID;
  2289. }
  2290.  
  2291. ManagedReference<SceneObject*> object = server->getObject(entid);
  2292.  
  2293. if (object == NULL)
  2294. return;
  2295.  
  2296. if (!object->isPlayerCreature()) {
  2297. creature->sendSystemMessage("@performance:dance_watch_npc"); // "You cannot /watch NPCs."
  2298. return;
  2299. }
  2300.  
  2301. CreatureObject* entertainer = cast<CreatureObject*>( object.get());
  2302.  
  2303. if (entertainer == creature)
  2304. return;
  2305.  
  2306. ManagedReference<EntertainingSession*> esession = NULL;
  2307.  
  2308. String entName;
  2309. if (entertainer != NULL) {
  2310. Locker clocker(entertainer, creature);
  2311.  
  2312. entName = entertainer->getFirstName();
  2313.  
  2314. ManagedReference<Facade*> session = entertainer->getActiveSession(SessionFacadeType::ENTERTAINING);
  2315.  
  2316. if (session != NULL) {
  2317. esession = dynamic_cast<EntertainingSession*>(session.get());
  2318.  
  2319. if (esession != NULL) {
  2320. esession->activateEntertainerBuff(creature, PerformanceType::DANCE);
  2321.  
  2322. esession->removeWatcher(creature);
  2323. }
  2324. }
  2325.  
  2326. clocker.release();
  2327. }
  2328.  
  2329. creature->setMood(creature->getMoodID());
  2330.  
  2331. if (doSendPackets && esession != NULL)
  2332. esession->sendEntertainmentUpdate(creature, 0, creature->getMoodString());
  2333.  
  2334. //System Message.
  2335. if (creature->isPlayerCreature() && entertainer != NULL) {
  2336. CreatureObject* player = cast<CreatureObject*>( creature);
  2337.  
  2338. StringIdChatParameter stringID;
  2339.  
  2340. if (forced) {
  2341. stringID.setTU(entid);
  2342. stringID.setStringId("performance", "dance_stop_other"); // %TU stops dancing.
  2343.  
  2344. player->sendSystemMessage(stringID);
  2345. } else if (outOfRange) {
  2346. // The correct string id is @performance:dance_watch_out_of_range ("You stop watching %TT because %OT is too far away.")
  2347. // but %OT will get replaced by him/her which gives an incorrect message.
  2348. StringBuffer msg;
  2349. msg << "You stop watching " << entertainer->getFirstName() << " because they are too far away.";
  2350. player->sendSystemMessage(msg.toString());
  2351. } else {
  2352. player->sendSystemMessage("@performance:dance_watch_stop_self"); //"You stop watching."
  2353. }
  2354.  
  2355. ManagedReference<PlayerObject*> entPlayer = entertainer->getPlayerObject();
  2356. if (entPlayer != NULL && entPlayer->getPerformanceBuffTarget() == player->getObjectID())
  2357. entPlayer->setPerformanceBuffTarget(0);
  2358. }
  2359.  
  2360.  
  2361. //esession->setEntertainerBuffDuration(creature, PerformanceType::DANCE, 0.0f); // reset
  2362. //esession->setEntertainerBuffStrength(creature, PerformanceType::DANCE, 0.0f);
  2363. creature->info("stopped watching [" + entName + "]");
  2364.  
  2365. creature->setWatchToID(0);
  2366. /*doWatching = false;
  2367. watchID = 0;*/
  2368. }
  2369.  
  2370. void PlayerManagerImplementation::startWatch(CreatureObject* creature, uint64 entid) {
  2371. Locker locker(creature);
  2372.  
  2373. ManagedReference<SceneObject*> object = server->getObject(entid);
  2374. uint64 watchID = creature->getWatchToID();
  2375.  
  2376. if (watchID == entid)
  2377. return;
  2378.  
  2379. if (object == NULL)
  2380. return;
  2381.  
  2382. /*if (object->isNonPlayerCreature()) {
  2383. creature->sendSystemMessage("@performance:dance_watch_npc");
  2384. return;
  2385. }*/
  2386.  
  2387. if (!object->isPlayerCreature()) {
  2388. creature->sendSystemMessage("@performance:dance_watch_npc"); // "You can not /watch NPCs."
  2389. return;
  2390. }
  2391.  
  2392. CreatureObject* entertainer = cast<CreatureObject*>( object.get());
  2393.  
  2394. if (creature == entertainer)
  2395. return;
  2396.  
  2397. Locker clocker(entertainer, creature);
  2398.  
  2399. if (creature->isDancing() || creature->isPlayingMusic()) {
  2400. StringIdChatParameter stringID;
  2401. stringID.setStringId("cmd_err", "locomotion_prose"); // "You cannot %TO while %TU."
  2402. stringID.setTO("/watch");
  2403. stringID.setTU("@locomotion_n:skillanimating"); // "Skill Animating"
  2404. creature->sendSystemMessage(stringID);
  2405.  
  2406. return;
  2407. } else if (!entertainer->isDancing()) {
  2408. StringIdChatParameter stringID;
  2409. stringID.setStringId("performance", "dance_watch_not_dancing"); // "%TT is not dancing."
  2410. stringID.setTT(entid);
  2411. creature->sendSystemMessage(stringID);
  2412. return;
  2413. }
  2414.  
  2415. ManagedReference<Facade*> facade = entertainer->getActiveSession(SessionFacadeType::ENTERTAINING);
  2416.  
  2417. if (facade == NULL)
  2418. return;
  2419.  
  2420. EntertainingSession* entertainingSession = dynamic_cast<EntertainingSession*>(facade.get());
  2421.  
  2422. if (entertainingSession == NULL)
  2423. return;
  2424.  
  2425. if (creature->isWatching()) {
  2426. stopWatch(creature, watchID, false);
  2427. }
  2428.  
  2429. //sendEntertainmentUpdate(entid, "entertained");
  2430.  
  2431. entertainingSession->sendEntertainmentUpdate(creature, entid, "entertained");
  2432. entertainingSession->addWatcher(creature);
  2433.  
  2434. entertainer->notifyObservers(ObserverEventType::WASWATCHED, creature);
  2435.  
  2436. //creature->addWatcher(_this);
  2437.  
  2438. StringIdChatParameter stringID;
  2439. stringID.setStringId("performance", "dance_watch_self"); // You start watching %TT.
  2440. stringID.setTT(entid);
  2441. creature->sendSystemMessage(stringID);
  2442.  
  2443. //setEntertainerBuffDuration(PerformanceType::DANCE, 0.0f);
  2444. //setEntertainerBuffStrength(PerformanceType::DANCE, 0.0f);
  2445.  
  2446. creature->info("started watching [" + entertainer->getCustomObjectName().toString() + "]");
  2447.  
  2448. creature->setWatchToID(entertainer->getObjectID());
  2449. //watchID = entid;
  2450. }
  2451.  
  2452. void PlayerManagerImplementation::startListen(CreatureObject* creature, uint64 entid) {
  2453. Locker locker(creature);
  2454.  
  2455. ManagedReference<SceneObject*> object = server->getObject(entid);
  2456. uint64 listenID = creature->getListenID();
  2457.  
  2458. if (listenID == entid)
  2459. return;
  2460.  
  2461. if (object == NULL)
  2462. return;
  2463.  
  2464. /*if (object->isNonPlayerCreature()) {
  2465. creature->sendSystemMessage("@performance:dance_watch_npc");
  2466. return;
  2467. }*/
  2468.  
  2469. // Droid playback handling
  2470. if(object->isDroidObject()) {
  2471. DroidObject* droid = cast<DroidObject*>( object.get());
  2472. if (droid == NULL) {
  2473. creature->sendSystemMessage("@performance:music_listen_npc"); // "You cannot /listen to NPCs."
  2474. return;
  2475. }
  2476. BaseDroidModuleComponent* bmodule = droid->getModule("playback_module");
  2477. if(bmodule != NULL) {
  2478. DroidPlaybackModuleDataComponent* module = cast<DroidPlaybackModuleDataComponent*>(bmodule);
  2479. if(module != NULL) {
  2480. if (creature->isDancing() || creature->isPlayingMusic()) {
  2481. StringIdChatParameter stringID;
  2482. stringID.setStringId("cmd_err", "locomotion_prose"); // "You cannot %TO while %TU."
  2483. stringID.setTO("/listen");
  2484. stringID.setTU("@locomotion_n:skillanimating"); // "Skill Animating"
  2485. creature->sendSystemMessage(stringID);
  2486. return;
  2487. }
  2488.  
  2489. if(module->isActive()) {
  2490. // the droid is playing so we can do something
  2491. if (creature->isListening()) {
  2492. stopListen(creature, listenID, false);
  2493. }
  2494.  
  2495. StringIdChatParameter stringID;
  2496. stringID.setTT(entid);
  2497. stringID.setStringId("performance", "music_listen_self"); // "You start listening to %TT."
  2498. creature->sendSystemMessage(stringID);
  2499.  
  2500. creature->setListenToID(entid, true);
  2501. String str = Races::getMoodStr("entertained");
  2502. creature->setMoodString(str, true);
  2503. creature->setListenToID(droid->getObjectID());
  2504. module->addListener(creature->getObjectID());
  2505. return;
  2506. } else {
  2507. StringIdChatParameter stringID;
  2508. stringID.setTT(entid);
  2509. stringID.setStringId("performance", "music_listen_not_playing"); // %TT is not playing a song.
  2510. creature->sendSystemMessage(stringID);
  2511. return;
  2512. }
  2513. } else {
  2514. creature->sendSystemMessage("@performance:music_listen_npc"); // "You cannot /listen to NPCs."
  2515. }
  2516. } else {
  2517. creature->sendSystemMessage("@performance:music_listen_npc"); // "You cannot /listen to NPCs."
  2518. }
  2519. return;
  2520. }
  2521.  
  2522. if (!object->isPlayerCreature()) {
  2523. creature->sendSystemMessage("@performance:music_listen_npc"); // "You cannot /listen to NPCs."
  2524. return;
  2525. }
  2526.  
  2527. CreatureObject* entertainer = cast<CreatureObject*>( object.get());
  2528.  
  2529. if (creature == entertainer)
  2530. return;
  2531.  
  2532. Locker clocker(entertainer, creature);
  2533.  
  2534. if (creature->isDancing() || creature->isPlayingMusic()) {
  2535. StringIdChatParameter stringID;
  2536. stringID.setStringId("cmd_err", "locomotion_prose"); // "You cannot %TO while %TU."
  2537. stringID.setTO("/listen");
  2538. stringID.setTU("@locomotion_n:skillanimating"); // "Skill Animating"
  2539. creature->sendSystemMessage(stringID);
  2540. return;
  2541. } else if (!entertainer->isPlayingMusic()) {
  2542. StringIdChatParameter stringID;
  2543. stringID.setTT(entid);
  2544. stringID.setStringId("performance", "music_listen_not_playing"); // %TT is not playing a song.
  2545. creature->sendSystemMessage(stringID);
  2546.  
  2547. return;
  2548. }
  2549.  
  2550. ManagedReference<Facade*> facade = entertainer->getActiveSession(SessionFacadeType::ENTERTAINING);
  2551.  
  2552. if (facade == NULL)
  2553. return;
  2554.  
  2555. EntertainingSession* entertainingSession = dynamic_cast<EntertainingSession*>(facade.get());
  2556.  
  2557. if (entertainingSession == NULL)
  2558. return;
  2559.  
  2560. if (creature->isListening()) {
  2561. stopListen(creature, listenID, false);
  2562. }
  2563.  
  2564. //sendEntertainmentUpdate(entid, "entertained");
  2565.  
  2566. entertainingSession->sendEntertainmentUpdate(creature, entid, "entertained");
  2567. entertainingSession->addListener(creature);
  2568.  
  2569. entertainer->notifyObservers(ObserverEventType::WASLISTENEDTO, creature);
  2570.  
  2571. //creature->addWatcher(_this);
  2572.  
  2573. StringIdChatParameter stringID;
  2574. stringID.setTT(entid);
  2575. stringID.setStringId("performance", "music_listen_self"); // "You start listening to %TT."
  2576. creature->sendSystemMessage(stringID);
  2577.  
  2578. //setEntertainerBuffDuration(PerformanceType::DANCE, 0.0f);
  2579. //setEntertainerBuffStrength(PerformanceType::DANCE, 0.0f);
  2580.  
  2581. creature->info("started listening to [" + entertainer->getCustomObjectName().toString() + "]");
  2582.  
  2583. creature->setListenToID(entertainer->getObjectID());
  2584. //watchID = entid;
  2585. }
  2586.  
  2587.  
  2588. SceneObject* PlayerManagerImplementation::getInRangeStructureWithAdminRights(CreatureObject* creature, uint64 targetID) {
  2589. ZoneServer* zoneServer = server;
  2590.  
  2591. //First we need to check if the target. if it's not right...
  2592. //Check the building they are standing in, if it's not right...
  2593. //Find the nearest installation.
  2594.  
  2595. ManagedReference<SceneObject*> obj = NULL;
  2596.  
  2597. if (targetID != 0) {
  2598. obj = zoneServer->getObject(targetID);
  2599.  
  2600. if (obj != NULL && obj->isStructureObject() && (cast<StructureObject*>(obj.get()))->isOnAdminList(creature))
  2601. return obj.get();
  2602. }
  2603.  
  2604.  
  2605. ManagedReference<SceneObject*> rootParent = creature->getRootParent();
  2606.  
  2607. if (rootParent != NULL && rootParent->isStructureObject() && (cast<StructureObject*>(rootParent.get()))->isOnAdminList(creature)) {
  2608. return rootParent;
  2609. }
  2610.  
  2611. StructureObject* structure = NULL;
  2612. float distance = 16000;
  2613.  
  2614. Zone* zone = creature->getZone();
  2615.  
  2616. if (zone == NULL) {
  2617. return NULL;
  2618. }
  2619.  
  2620. //We need to search nearby for an installation that belongs to the player.
  2621. Locker _locker(zone);
  2622.  
  2623. CloseObjectsVector* closeObjs = (CloseObjectsVector*)creature->getCloseObjects();
  2624. SortedVector<QuadTreeEntry*> closeObjects;
  2625. closeObjs->safeCopyTo(closeObjects);
  2626.  
  2627. for (int i = 0; i < closeObjects.size(); ++i) {
  2628. ManagedReference<SceneObject*> tObj = cast<SceneObject*>( closeObjects.get(i));
  2629.  
  2630. if (tObj != NULL) {
  2631. if (tObj->isStructureObject()) {
  2632. float dist = tObj->getDistanceTo(creature);
  2633.  
  2634. StructureObject* structureObject = cast<StructureObject*>( tObj.get());
  2635.  
  2636. if (structureObject->isOnAdminList(creature) && dist < distance) {
  2637. structure = structureObject;
  2638. distance = dist;
  2639. }
  2640. }
  2641. }
  2642. }
  2643.  
  2644. if (distance < 25)
  2645. return structure;
  2646.  
  2647. return NULL;
  2648. }
  2649.  
  2650. StructureObject* PlayerManagerImplementation::getInRangeOwnedStructure(CreatureObject* creature, float range) {
  2651. Locker _lock(creature);
  2652.  
  2653. ManagedReference<PlayerObject*> ghost = creature->getPlayerObject();
  2654.  
  2655. if (ghost == NULL)
  2656. return NULL;
  2657.  
  2658. ManagedReference<StructureObject*> closestStructure = NULL;
  2659. float closestDistance = 16000.f;
  2660.  
  2661. for (int i = 0; i < ghost->getTotalOwnedStructureCount(); ++i) {
  2662. uint64 oid = ghost->getOwnedStructure(i);
  2663.  
  2664. ManagedReference<StructureObject*> structure = (ghost->getZoneServer()->getObject(oid)).castTo<StructureObject*>();
  2665.  
  2666. Locker _slock(structure, creature);
  2667.  
  2668. if (creature->getZone() != structure->getZone())
  2669. continue;
  2670.  
  2671. float distance = structure->getDistanceTo(creature);
  2672.  
  2673. if (distance <= range && distance < closestDistance) {
  2674. closestStructure = structure;
  2675. closestDistance = distance;
  2676. }
  2677. }
  2678.  
  2679. return closestStructure;
  2680. }
  2681.  
  2682. void PlayerManagerImplementation::updatePermissionLevel(CreatureObject* targetPlayer, int permissionLevel) {
  2683.  
  2684. if (targetPlayer == NULL) {
  2685. return;
  2686. }
  2687.  
  2688. //Locker clocker(targetPlayer, player);
  2689. Locker locker(targetPlayer);
  2690. ManagedReference<PlayerObject*> ghost = targetPlayer->getPlayerObject();
  2691.  
  2692. if (ghost == NULL) {
  2693. return;
  2694. }
  2695.  
  2696. SkillManager* skillManager = server->getSkillManager();
  2697.  
  2698. int currentPermissionLevel = ghost->getAdminLevel();
  2699.  
  2700. /*Temporarily removed so that we can update admin levels immediately
  2701. if(currentPermissionLevel == permissionLevel)
  2702. return;*/
  2703.  
  2704. if (currentPermissionLevel != 0) {
  2705. Vector<String>* skillsToBeRemoved = permissionLevelList->getPermissionSkills(currentPermissionLevel);
  2706. if(skillsToBeRemoved != NULL) {
  2707. for(int i = 0; i < skillsToBeRemoved->size(); i++) {
  2708. String skill = skillsToBeRemoved->get(i);
  2709. targetPlayer->sendSystemMessage("Staff skill revoked: " + skill);
  2710. skillManager->surrenderSkill(skill, targetPlayer, true);
  2711. }
  2712. }
  2713. }
  2714.  
  2715. if(permissionLevel != 0) {
  2716. Vector<String>* skillsToBeAdded = permissionLevelList->getPermissionSkills(permissionLevel);
  2717. if(skillsToBeAdded != NULL) {
  2718. for(int i = 0; i < skillsToBeAdded->size(); ++i) {
  2719. String skill = skillsToBeAdded->get(i);
  2720. targetPlayer->sendSystemMessage("Staff skill granted: " + skill);
  2721. skillManager->awardSkill(skill, targetPlayer, false, true, true);
  2722. }
  2723. }
  2724. }
  2725.  
  2726. ghost->setAdminLevel(permissionLevel);
  2727. updatePermissionName(targetPlayer, permissionLevel);
  2728. }
  2729.  
  2730. void PlayerManagerImplementation::updatePermissionName(CreatureObject* player, int permissionLevel) {
  2731. ManagedReference<PlayerObject*> ghost = player->getPlayerObject();
  2732. //Send deltas
  2733. if (player->isOnline()) {
  2734. UnicodeString tag = permissionLevelList->getPermissionTag(permissionLevel);
  2735.  
  2736. TangibleObjectDeltaMessage3* tanod3 = new TangibleObjectDeltaMessage3(player);
  2737. tanod3->updateCustomName(player->getDisplayedName(), tag);
  2738. tanod3->close();
  2739. player->broadcastMessage(tanod3, true);
  2740.  
  2741. /*PlayerObjectDeltaMessage6* playd6 = new PlayerObjectDeltaMessage6(ghost);
  2742. playd6->setAdminLevel(adminLevel);
  2743. playd6->close();
  2744. player->broadcastMessage(playd6, true);*/
  2745. }
  2746. }
  2747.  
  2748. void PlayerManagerImplementation::updateSwimmingState(CreatureObject* player, float newZ, IntersectionResults* intersections, CloseObjectsVector* closeObjectsVector) {
  2749. player->notifySelfPositionUpdate();
  2750. if (player->getParent() != NULL) {
  2751. return;
  2752. }
  2753.  
  2754. ManagedReference<Zone*> zone = player->getZone();
  2755.  
  2756. if (zone == NULL) {
  2757. player->info("No zone.", true);
  2758. return;
  2759. }
  2760.  
  2761. ManagedReference<PlanetManager*> planetManager = zone->getPlanetManager();
  2762.  
  2763. if (planetManager == NULL) {
  2764. player->info("No planet manager.", true);
  2765. return;
  2766. }
  2767.  
  2768. ManagedReference<TerrainManager*> terrainManager = planetManager->getTerrainManager();
  2769.  
  2770. if (terrainManager == NULL) {
  2771. player->info("No terrain manager.", true);
  2772. return;
  2773. }
  2774.  
  2775. float landHeight = zone->getHeight(player->getPositionX(), player->getPositionY());
  2776. float waterHeight = landHeight;
  2777. bool waterIsDefined = terrainManager->getWaterHeight(player->getPositionX(), player->getPositionY(), waterHeight);
  2778.  
  2779. if (waterIsDefined && (waterHeight > landHeight) && (landHeight + player->getSwimHeight() - waterHeight < 0.2)) {
  2780. //Water level is higher than the terrain level and is deep enough for the player to be swimming.
  2781. //Check if the player is on a bridge or other terrain above the water level.
  2782. //SortedVector<IntersectionResult> intersections;
  2783. Reference<IntersectionResults*> ref;
  2784.  
  2785. if (intersections == NULL) {
  2786. ref = intersections = new IntersectionResults();
  2787.  
  2788. CollisionManager::getWorldFloorCollisions(player->getPositionX(), player->getPositionY(), zone, intersections, closeObjectsVector);
  2789. }
  2790.  
  2791. for (int i = 0; i < intersections->size(); i++) {
  2792. if (fabs(16384 - intersections->get(i).getIntersectionDistance() - newZ) < 0.2) {
  2793. //Player is on terrain above the water.
  2794. player->clearState(CreatureState::SWIMMING, true);
  2795. return;
  2796. }
  2797. }
  2798.  
  2799. //Player is in the water.
  2800. player->setState(CreatureState::SWIMMING, true);
  2801. return;
  2802. }
  2803.  
  2804. //Terrain is above water level.
  2805. player->clearState(CreatureState::SWIMMING, true);
  2806. }
  2807.  
  2808. int PlayerManagerImplementation::checkSpeedHackFirstTest(CreatureObject* player, float parsedSpeed, ValidatedPosition& teleportPosition, float errorMultiplier) {
  2809. float allowedSpeedMod = player->getSpeedMultiplierMod();
  2810. float allowedSpeedBase = player->getRunSpeed();
  2811. ManagedReference<SceneObject*> parent = player->getParent();
  2812. SpeedMultiplierModChanges* changeBuffer = player->getSpeedMultiplierModChanges();
  2813. Vector3 teleportPoint = teleportPosition.getPosition();
  2814. uint64 teleportParentID = teleportPosition.getParent();
  2815.  
  2816. if (parent != NULL && parent->isVehicleObject()) {
  2817. VehicleObject* vehicle = cast<VehicleObject*>( parent.get());
  2818.  
  2819. allowedSpeedMod = vehicle->getSpeedMultiplierMod();
  2820. allowedSpeedBase = vehicle->getRunSpeed();
  2821. } else if (parent != NULL && parent->isMount()){
  2822. Creature* mount = cast<Creature*>( parent.get());
  2823.  
  2824. allowedSpeedMod = mount->getSpeedMultiplierMod();
  2825.  
  2826. PetManager* petManager = server->getPetManager();
  2827.  
  2828. if (petManager != NULL) {
  2829. allowedSpeedBase = petManager->getMountedRunSpeed(mount);
  2830. }
  2831.  
  2832. }
  2833.  
  2834. float maxAllowedSpeed = allowedSpeedMod * allowedSpeedBase;
  2835.  
  2836. if (parsedSpeed > maxAllowedSpeed * errorMultiplier) {
  2837. //float delta = abs(parsedSpeed - maxAllowedSpeed);
  2838.  
  2839. if (changeBuffer->size() == 0) { // no speed changes
  2840. StringBuffer msg;
  2841. msg << "max allowed speed should be " << maxAllowedSpeed * errorMultiplier;
  2842. msg << " parsed " << parsedSpeed;
  2843. player->info(msg.toString());
  2844.  
  2845. player->teleport(teleportPoint.getX(), teleportPoint.getZ(), teleportPoint.getY(), teleportParentID);
  2846.  
  2847. return 1;
  2848. }
  2849.  
  2850. SpeedModChange* firstChange = &changeBuffer->get(changeBuffer->size() - 1);
  2851. Time* timeStamp = &firstChange->getTimeStamp();
  2852.  
  2853. if (timeStamp->miliDifference() > 2000) { // we already should have lowered the speed, 2 seconds lag
  2854. StringBuffer msg;
  2855. msg << "max allowed speed should be " << maxAllowedSpeed * errorMultiplier;
  2856. msg << " parsed " << parsedSpeed;
  2857. player->info(msg.toString());
  2858.  
  2859. player->teleport(teleportPoint.getX(), teleportPoint.getZ(), teleportPoint.getY(), teleportParentID);
  2860.  
  2861. return 1;
  2862. }
  2863.  
  2864. for (int i = 0; i < changeBuffer->size() - 1; ++i) {
  2865. SpeedModChange* change = &changeBuffer->get(i);
  2866. //Time timeStamp = change->getTimeStamp();
  2867.  
  2868. float oldSpeedMod = change->getNewSpeed();
  2869. float allowed = allowedSpeedBase * oldSpeedMod * errorMultiplier;
  2870.  
  2871. if (allowed >= parsedSpeed) {
  2872. return 0; // no hack detected
  2873. }
  2874.  
  2875. if (allowed > maxAllowedSpeed)
  2876. maxAllowedSpeed = allowed;
  2877. }
  2878.  
  2879. StringBuffer msg;
  2880. msg << "max allowed speed should be " << maxAllowedSpeed;
  2881. msg << " parsed " << parsedSpeed;
  2882. msg << " changeBufferSize: " << changeBuffer->size();
  2883.  
  2884. player->info(msg.toString());
  2885.  
  2886. player->teleport(teleportPoint.getX(), teleportPoint.getZ(), teleportPoint.getY(), teleportParentID);
  2887.  
  2888. return 1;
  2889. }
  2890.  
  2891. return 0;
  2892. }
  2893.  
  2894. int PlayerManagerImplementation::checkSpeedHackSecondTest(CreatureObject* player, float newX, float newZ, float newY, uint32 newStamp, SceneObject* newParent) {
  2895. PlayerObject* ghost = player->getPlayerObject();
  2896.  
  2897. uint32 deltaTime = ghost->getServerMovementTimeDelta();//newStamp - stamp;
  2898.  
  2899. if (deltaTime < 1000) {
  2900. //info("time hasnt passed yet", true);
  2901. return 0;
  2902. }
  2903.  
  2904. uint32 stamp = ghost->getClientLastMovementStamp();
  2905.  
  2906. if (stamp > newStamp) {
  2907. //info("older stamp received", true);
  2908. return 1;
  2909. }
  2910.  
  2911. Vector3 newWorldPosition(newX, newY, newZ);
  2912.  
  2913. /*StringBuffer newWorldPosMsg;
  2914. newWorldPosMsg << "x:" << newWorldPosition.getX() << " z:" << newWorldPosition.getZ() << " y:" << newWorldPosition.getY();
  2915. player->info(newWorldPosMsg.toString(), true);*/
  2916.  
  2917. if (newParent != NULL) {
  2918. ManagedReference<SceneObject*> root = newParent->getRootParent();
  2919.  
  2920. if (!root->isBuildingObject())
  2921. return 1;
  2922.  
  2923. float length = Math::sqrt(newX * newX + newY * newY);
  2924. float angle = root->getDirection()->getRadians() + atan2(newX, newY);
  2925.  
  2926. newWorldPosition.set(root->getPositionX() + (sin(angle) * length), root->getPositionZ() + newZ, root->getPositionY() + (cos(angle) * length));
  2927. }
  2928.  
  2929. /*newWorldPosMsg.deleteAll();
  2930. newWorldPosMsg << "x:" << newWorldPosition.getX() << " z:" << newWorldPosition.getZ() << " y:" << newWorldPosition.getY();
  2931. player->info(newWorldPosMsg.toString(), true);*/
  2932.  
  2933. ValidatedPosition* lastValidatedPosition = ghost->getLastValidatedPosition();
  2934.  
  2935. Vector3 lastValidatedWorldPosition = lastValidatedPosition->getWorldPosition(server);
  2936.  
  2937. //ignoring Z untill we have all heightmaps
  2938. float oldValidZ = lastValidatedWorldPosition.getZ();
  2939. float oldNewPosZ = newWorldPosition.getZ();
  2940.  
  2941. lastValidatedWorldPosition.setZ(0);
  2942. newWorldPosition.setZ(0);
  2943.  
  2944. float dist = newWorldPosition.distanceTo(lastValidatedWorldPosition);
  2945.  
  2946. if (dist < 1) {
  2947. //info("distance too small", true);
  2948. return 0;
  2949. }
  2950.  
  2951. float speed = dist / (float) deltaTime * 1000;
  2952.  
  2953. /*if (oldNewPosZ > oldValidZ) {
  2954. float heightDist = oldNewPosZ - oldValidZ;
  2955.  
  2956. //if (heightDist > speed) {
  2957. StringBuffer msg;
  2958. msg << " heightDist:" << heightDist << " speed:" << speed << " terrain neg:" << player->getSlopeModPercent();
  2959. player->info(msg.toString(), true);
  2960. //}
  2961. }*/
  2962.  
  2963. //lastValidatedPosition->set(newWorldPosition.getX(), oldNewPosZ, newWorldPosition.getY());
  2964.  
  2965. /*StringBuffer msg;
  2966. msg << "distancia recorreguda " << dist << " a una velocitat " << speed;
  2967. info(msg, true);*/
  2968.  
  2969. int ret = checkSpeedHackFirstTest(player, speed, *lastValidatedPosition, 1.5f);
  2970.  
  2971. if (ret == 0) {
  2972. lastValidatedPosition->setPosition(newX, newZ, newY);
  2973.  
  2974. if (newParent != NULL)
  2975. lastValidatedPosition->setParent(newParent->getObjectID());
  2976. else
  2977. lastValidatedPosition->setParent(0);
  2978.  
  2979. ghost->updateServerLastMovementStamp();
  2980.  
  2981. if (ghost->isOnLoadScreen())
  2982. ghost->setOnLoadScreen(false);
  2983. }
  2984.  
  2985. return ret;
  2986.  
  2987. //return 0;
  2988. }
  2989.  
  2990. void PlayerManagerImplementation::lootAll(CreatureObject* player, CreatureObject* ai) {
  2991. Locker locker(ai, player);
  2992.  
  2993. if (!ai->isDead() || player->isDead())
  2994. return;
  2995.  
  2996. SceneObject* creatureInventory = ai->getSlottedObject("inventory");
  2997.  
  2998. if (creatureInventory == NULL)
  2999. return;
  3000.  
  3001. int cashCredits = ai->getCashCredits();
  3002.  
  3003. if (cashCredits > 0) {
  3004. int luck = player->getSkillMod("force_luck");
  3005.  
  3006. if (luck > 0)
  3007. cashCredits += (cashCredits * luck) / 20;
  3008.  
  3009. player->addCashCredits(cashCredits, true);
  3010. ai->setCashCredits(0);
  3011.  
  3012. StringIdChatParameter param("base_player", "prose_coin_loot"); //You loot %DI credits from %TT.
  3013. param.setDI(cashCredits);
  3014. param.setTT(ai->getObjectID());
  3015.  
  3016. player->sendSystemMessage(param);
  3017. }
  3018.  
  3019. ai->notifyObservers(ObserverEventType::LOOTCREATURE, player, 0);
  3020.  
  3021. SceneObject* playerInventory = player->getSlottedObject("inventory");
  3022.  
  3023. if (playerInventory == NULL)
  3024. return;
  3025.  
  3026. int totalItems = creatureInventory->getContainerObjectsSize();
  3027.  
  3028. if (totalItems < 1) {
  3029. rescheduleCorpseDestruction(player, ai);
  3030. return;
  3031. }
  3032.  
  3033. StringBuffer args;
  3034. args << playerInventory->getObjectID() << " -1 0 0 0";
  3035.  
  3036. String stringArgs = args.toString();
  3037.  
  3038. for (int i = totalItems - 1; i >= 0; --i) {
  3039. SceneObject* object = creatureInventory->getContainerObject(i);
  3040.  
  3041. player->executeObjectControllerAction(STRING_HASHCODE("transferitemmisc"), object->getObjectID(), stringArgs);
  3042. }
  3043.  
  3044. if (creatureInventory->getContainerObjectsSize() <= 0) {
  3045. player->sendSystemMessage("@base_player:corpse_looted"); //You have completely looted the corpse of all items.
  3046.  
  3047. rescheduleCorpseDestruction(player, ai);
  3048. }
  3049. }
  3050.  
  3051. void PlayerManagerImplementation::sendStartingLocationsTo(CreatureObject* player) {
  3052. StartingLocationListMessage* slm = new StartingLocationListMessage(player);
  3053. startingLocationList.insertToMessage(slm);
  3054.  
  3055. player->sendMessage(slm);
  3056. }
  3057.  
  3058. StartingLocation* PlayerManagerImplementation::getStartingLocation(const String& city) {
  3059. for (int i = 0; i < startingLocationList.size(); ++i) {
  3060. StartingLocation* loc = &startingLocationList.get(i);
  3061.  
  3062. if (loc == NULL)
  3063. continue;
  3064.  
  3065. if (loc->getLocation() == city)
  3066. return loc;
  3067. }
  3068.  
  3069. return NULL;
  3070. }
  3071.  
  3072. void PlayerManagerImplementation::addInsurableItemsRecursive(SceneObject* obj, SortedVector<ManagedReference<SceneObject*> >* items, bool onlyInsurable) {
  3073. for (int j = 0; j < obj->getContainerObjectsSize(); j++) {
  3074. SceneObject* object = obj->getContainerObject(j);
  3075.  
  3076. if (!object->isTangibleObject())
  3077. continue;
  3078.  
  3079. TangibleObject* item = cast<TangibleObject*>( object);
  3080.  
  3081. if(item == NULL || item->hasAntiDecayKit())
  3082. continue;
  3083.  
  3084. if (!(item->getOptionsBitmask() & OptionBitmask::INSURED) && (item->isArmorObject() || item->isWearableObject())) {
  3085. items->put(item);
  3086. } else if ((item->getOptionsBitmask() & OptionBitmask::INSURED) && (item->isArmorObject() || item->isWearableObject()) && !onlyInsurable) {
  3087. items->put(item);
  3088. }
  3089.  
  3090. if (object->isContainerObject())
  3091. addInsurableItemsRecursive(object, items, onlyInsurable);
  3092. }
  3093. }
  3094.  
  3095. SortedVector<ManagedReference<SceneObject*> > PlayerManagerImplementation::getInsurableItems(CreatureObject* player, bool onlyInsurable) {
  3096. SortedVector<ManagedReference<SceneObject*> > insurableItems;
  3097. insurableItems.setNoDuplicateInsertPlan();
  3098.  
  3099. if (player == NULL)
  3100. return insurableItems;
  3101.  
  3102. SceneObject* datapad = player->getSlottedObject("datapad");
  3103. SceneObject* defweapon = player->getSlottedObject("default_weapon");
  3104. SceneObject* bank = player->getSlottedObject("bank");
  3105.  
  3106. for (int i = 0; i < player->getSlottedObjectsSize(); ++i) {
  3107. SceneObject* container = player->getSlottedObject(i);
  3108.  
  3109. if (container == datapad || container == NULL || container == bank || container == defweapon)
  3110. continue;
  3111.  
  3112. if (container->isTangibleObject()) {
  3113. TangibleObject* item = cast<TangibleObject*>( container);
  3114.  
  3115. if(item == NULL || item->hasAntiDecayKit())
  3116. continue;
  3117.  
  3118. if (!(item->getOptionsBitmask() & OptionBitmask::INSURED) && (item->isArmorObject() || item->isWearableObject())) {
  3119. insurableItems.put(item);
  3120. } else if ((item->getOptionsBitmask() & OptionBitmask::INSURED) && (item->isArmorObject() || item->isWearableObject()) && !onlyInsurable) {
  3121. insurableItems.put(item);
  3122. }
  3123. }
  3124.  
  3125. addInsurableItemsRecursive(container, &insurableItems, onlyInsurable);
  3126. }
  3127.  
  3128. return insurableItems;
  3129. }
  3130.  
  3131. int PlayerManagerImplementation::calculatePlayerLevel(CreatureObject* player) {
  3132.  
  3133. ManagedReference<WeaponObject*> weapon = player->getWeapon();
  3134.  
  3135. if (weapon == NULL) {
  3136. player->error("player with NULL weapon");
  3137.  
  3138. return 0;
  3139. }
  3140.  
  3141. String weaponType = weapon->getWeaponType();
  3142. int skillMod = player->getSkillMod("private_" + weaponType + "_combat_difficulty");
  3143.  
  3144. if (player->getPlayerObject() != NULL && player->getPlayerObject()->isJedi() && weapon->isJediWeapon())
  3145. skillMod += player->getSkillMod("private_jedi_difficulty");
  3146.  
  3147. int level = MIN(25, skillMod / 100 + 1);
  3148.  
  3149. return level;
  3150. }
  3151.  
  3152. int PlayerManagerImplementation::calculatePlayerLevel(CreatureObject* player, String& xpType) {
  3153. if (xpType.isEmpty() || xpType == "jedi_general")
  3154. return calculatePlayerLevel(player);
  3155.  
  3156. String weaponType;
  3157. if (xpType.contains("onehand"))
  3158. weaponType = "onehandmelee";
  3159. else if (xpType.contains("polearm"))
  3160. weaponType = "polearm";
  3161. else if (xpType.contains("twohand"))
  3162. weaponType = "twohandmelee";
  3163. else if (xpType.contains("unarmed"))
  3164. weaponType = "unarmed";
  3165. else if (xpType.contains("carbine"))
  3166. weaponType = "carbine";
  3167. else if (xpType.contains("pistol"))
  3168. weaponType = "pistol";
  3169. else if (xpType.contains("rifle"))
  3170. weaponType = "rifle";
  3171. else
  3172. weaponType = "heavyweapon";
  3173.  
  3174. int level = MIN(25, player->getSkillMod("private_" + weaponType + "_combat_difficulty") / 100 + 1);
  3175.  
  3176. return level;
  3177. }
  3178.  
  3179. CraftingStation* PlayerManagerImplementation::getNearbyCraftingStation(CreatureObject* player, int type) {
  3180.  
  3181. ManagedReference<Zone*> zone = player->getZone();
  3182.  
  3183. if (zone == NULL)
  3184. return NULL;
  3185.  
  3186. ManagedReference<ZoneServer*> server = zone->getZoneServer();
  3187.  
  3188. if (server == NULL)
  3189. return NULL;
  3190.  
  3191. ManagedReference<CraftingStation*> station = NULL;
  3192.  
  3193. //Locker locker(zone);
  3194.  
  3195. SortedVector < QuadTreeEntry* > *closeObjects = new SortedVector<QuadTreeEntry*>(100, 50);
  3196. CloseObjectsVector* vec = (CloseObjectsVector*) player->getCloseObjects();
  3197. vec->safeCopyTo(*closeObjects);
  3198.  
  3199. for (int i = 0; i < closeObjects->size(); ++i) {
  3200. SceneObject* scno = static_cast<SceneObject*> (closeObjects->get(i));
  3201. if (scno->isCraftingStation() && (fabs(scno->getPositionZ() - player->getPositionZ()) < 7.0f) && player->isInRange(scno, 7.0f)) {
  3202.  
  3203. station = server->getObject(scno->getObjectID()).castTo<CraftingStation*>();
  3204.  
  3205. if (station == NULL)
  3206. continue;
  3207.  
  3208. ManagedReference<SceneObject*> parent = station->getParent().get();
  3209.  
  3210. if (parent != NULL && !parent->isCellObject())
  3211. continue;
  3212.  
  3213. if (type == station->getStationType() || (type
  3214. == CraftingTool::JEDI && station->getStationType()
  3215. == CraftingTool::WEAPON)) {
  3216.  
  3217. return station;
  3218. }
  3219. }
  3220. // dont check Z axis here just check in range call. z axis check for some reason returns a huge number when checking a mob standing on you.
  3221. // in range should be sufficient
  3222. if( scno->isDroidObject() && player->isInRange(scno, 7.0f)){
  3223. // check the droids around
  3224. DroidObject* droid = cast<DroidObject*>(scno);
  3225. if (droid == NULL) {
  3226. continue;
  3227. }
  3228. // only the player can benefit from their own droid
  3229. if( droid->getLinkedCreature() != player ) {
  3230. continue;
  3231. }
  3232. // check the droid
  3233. station = droid->getCraftingStation(type);
  3234. if (station != NULL && droid->hasPower()){
  3235. return station;
  3236. }
  3237. }
  3238. }
  3239.  
  3240. return NULL;
  3241. }
  3242.  
  3243. void PlayerManagerImplementation::finishHologrind(CreatureObject* player) {
  3244.  
  3245. ManagedReference<PlayerObject*> ghost = player->getPlayerObject();
  3246.  
  3247. if (ghost->hasSuiBoxWindowType(SuiWindowType::HOLOGRIND_UNLOCK))
  3248. return;
  3249.  
  3250. ManagedReference<SuiMessageBox*> box = new SuiMessageBox(player, SuiWindowType::NONE);
  3251. box->setPromptTitle("@quest/force_sensitive/intro:force_sensitive"); // You feel a tingle in the Force.
  3252. box->setPromptText("Perhaps you should meditate somewhere alone...");
  3253.  
  3254. ghost->addSuiBox(box);
  3255. player->sendMessage(box->generateMessage());
  3256.  
  3257. SkillManager::instance()->awardSkill("force_title_jedi_novice", player, true, false, true);
  3258.  
  3259. ghost->setJediState(1);
  3260.  
  3261. }
  3262.  
  3263. String PlayerManagerImplementation::banAccount(PlayerObject* admin, Account* account, uint32 seconds, const String& reason) {
  3264.  
  3265. if(admin == NULL || !admin->isPrivileged())
  3266. return "";
  3267.  
  3268. if(account == NULL)
  3269. return "Account Not Found";
  3270.  
  3271. String escapedReason = reason;
  3272. Database::escapeString(escapedReason);
  3273.  
  3274. try {
  3275. StringBuffer query;
  3276. query << "INSERT INTO account_bans values (NULL, " << account->getAccountID() << ", " << admin->getAccountID() << ", now(), " << (uint64)time(0) + seconds << ", '" << escapedReason << "');";
  3277.  
  3278. ServerDatabase::instance()->executeStatement(query);
  3279. } catch(Exception& e) {
  3280. return "Exception banning account: " + e.getMessage();
  3281. }
  3282.  
  3283. Locker locker(account);
  3284.  
  3285. account->setBanReason(reason);
  3286. account->setBanExpires(System::getMiliTime() + seconds*1000);
  3287. account->setBanAdmin(admin->getAccountID());
  3288.  
  3289. try {
  3290.  
  3291. Reference<CharacterList*> characters = account->getCharacterList();
  3292. for(int i = 0; i < characters->size(); ++i) {
  3293. CharacterListEntry* entry = &characters->get(i);
  3294. if(entry->getGalaxyID() == server->getGalaxyID()) {
  3295.  
  3296. ManagedReference<CreatureObject*> player = getPlayer(entry->getFirstName());
  3297. if(player != NULL) {
  3298. clearOwnedStructuresPermissions(player);
  3299.  
  3300. if (player->isOnline()) {
  3301. player->sendMessage(new LogoutMessage());
  3302.  
  3303. Reference<ZoneClientSession*> session = player->getClient();
  3304.  
  3305. if(session != NULL)
  3306. session->disconnect(true);
  3307. }
  3308. }
  3309. }
  3310. }
  3311. } catch(Exception& e) {
  3312. return "Account Successfully Banned, but error kicking characters. " + e.getMessage();
  3313. }
  3314.  
  3315. return "Account Successfully Banned";
  3316. }
  3317.  
  3318. String PlayerManagerImplementation::unbanAccount(PlayerObject* admin, Account* account, const String& reason) {
  3319.  
  3320. if(admin == NULL || !admin->isPrivileged())
  3321. return "";
  3322.  
  3323. if(account == NULL)
  3324. return "Account Not Found";
  3325.  
  3326. String escapedReason = reason;
  3327. Database::escapeString(escapedReason);
  3328.  
  3329. try {
  3330. StringBuffer query;
  3331. query << "UPDATE account_bans SET expires = UNIX_TIMESTAMP(), reason = '" << escapedReason << "' WHERE account_id = " << account->getAccountID() << " and expires > UNIX_TIMESTAMP();";
  3332.  
  3333. ServerDatabase::instance()->executeStatement(query);
  3334. } catch(Exception& e) {
  3335. return "Exception unbanning account: " + e.getMessage();
  3336. }
  3337.  
  3338. Locker locker(account);
  3339. account->setBanExpires(System::getMiliTime());
  3340. account->setBanReason(reason);
  3341.  
  3342. return "Account Successfully Unbanned";
  3343. }
  3344.  
  3345. String PlayerManagerImplementation::banFromGalaxy(PlayerObject* admin, Account* account, const uint32 galaxy, uint32 seconds, const String& reason) {
  3346.  
  3347. if(admin == NULL || !admin->isPrivileged())
  3348. return "";
  3349.  
  3350. if(account == NULL)
  3351. return "Account Not Found";
  3352.  
  3353. String escapedReason = reason;
  3354. Database::escapeString(escapedReason);
  3355.  
  3356. try {
  3357. StringBuffer query;
  3358. query << "INSERT INTO galaxy_bans values (NULL, " << account->getAccountID() << ", " << admin->getAccountID() << "," << galaxy << ", now()," << (uint64)time(0) + seconds << ", '" << escapedReason << "');";
  3359.  
  3360. ServerDatabase::instance()->executeStatement(query);
  3361. } catch(Exception& e) {
  3362. return "Exception banning from galaxy: " + e.getMessage();
  3363. }
  3364.  
  3365. Locker locker(account);
  3366.  
  3367. Time current;
  3368. Time expires;
  3369.  
  3370. expires.addMiliTime(seconds*10000);
  3371.  
  3372. Reference<GalaxyBanEntry*> ban = new GalaxyBanEntry();
  3373.  
  3374. ban->setAccountID(account->getAccountID());
  3375. ban->setBanAdmin(admin->getAccountID());
  3376. ban->setGalaxyID(galaxy);
  3377.  
  3378. ban->setCreationDate(current);
  3379.  
  3380. ban->setBanExpiration(expires);
  3381.  
  3382. ban->setBanReason(reason);
  3383.  
  3384. account->addGalaxyBan(ban, galaxy);
  3385.  
  3386. try {
  3387.  
  3388. if (server->getGalaxyID() == galaxy) {
  3389. Reference<CharacterList*> characters = account->getCharacterList();
  3390. for(int i = 0; i < characters->size(); ++i) {
  3391. CharacterListEntry* entry = &characters->get(i);
  3392. if(entry->getGalaxyID() == galaxy) {
  3393.  
  3394. ManagedReference<CreatureObject*> player = getPlayer(entry->getFirstName());
  3395. if(player != NULL) {
  3396. clearOwnedStructuresPermissions(player);
  3397.  
  3398. if (player->isOnline()) {
  3399. player->sendMessage(new LogoutMessage());
  3400.  
  3401. ManagedReference<ZoneClientSession*> session = player->getClient();
  3402.  
  3403. if(session != NULL)
  3404. session->disconnect(true);
  3405. }
  3406. }
  3407. }
  3408. }
  3409. } else {
  3410. return "Successfully Banned from Galaxy, but cannot kick characters because Galaxy is not your current galaxy.";
  3411. }
  3412. } catch(Exception& e) {
  3413. return "Successfully Banned from Galaxy, but error kicking characters. " + e.getMessage();
  3414. }
  3415.  
  3416. return "Successfully Banned from Galaxy";
  3417. }
  3418.  
  3419. String PlayerManagerImplementation::unbanFromGalaxy(PlayerObject* admin, Account* account, const uint32 galaxy, const String& reason) {
  3420.  
  3421. if(admin == NULL || !admin->isPrivileged())
  3422. return "";
  3423.  
  3424. if(account == NULL)
  3425. return "Account Not Found";
  3426.  
  3427. String escapedReason = reason;
  3428. Database::escapeString(escapedReason);
  3429.  
  3430. try {
  3431. StringBuffer query;
  3432.  
  3433. query << "UPDATE galaxy_bans SET expires = UNIX_TIMESTAMP(), reason = '" << escapedReason << "' WHERE account_id = " << account->getAccountID() << " and galaxy_id = " << galaxy << " and expires > UNIX_TIMESTAMP();";
  3434.  
  3435. ServerDatabase::instance()->executeStatement(query);
  3436. } catch(Exception& e) {
  3437. return "Exception unbanning from galaxy: " + e.getMessage();
  3438. }
  3439.  
  3440. Locker locker(account);
  3441. account->removeGalaxyBan(galaxy);
  3442.  
  3443. return "Successfully Unbanned from Galaxy";
  3444. }
  3445.  
  3446. String PlayerManagerImplementation::banCharacter(PlayerObject* admin, Account* account, const String& name, const uint32 galaxyID, uint32 seconds, const String& reason) {
  3447.  
  3448. if(admin == NULL || !admin->isPrivileged())
  3449. return "";
  3450.  
  3451. if(account == NULL)
  3452. return "Account Not Found";
  3453.  
  3454. String escapedReason = reason;
  3455. Database::escapeString(escapedReason);
  3456.  
  3457. String escapedName = name;
  3458. Database::escapeString(escapedName);
  3459.  
  3460.  
  3461. try {
  3462. StringBuffer query;
  3463. query << "INSERT INTO character_bans values (NULL, " << account->getAccountID() << ", " << admin->getAccountID() << ", " << galaxyID << ", '" << escapedName << "', " << "now(), UNIX_TIMESTAMP() + " << seconds << ", '" << escapedReason << "');";
  3464.  
  3465. ServerDatabase::instance()->executeStatement(query);
  3466. } catch(Exception& e) {
  3467. return "Exception banning character: " + e.getMessage();
  3468. }
  3469.  
  3470. Locker locker(account);
  3471.  
  3472. Reference<CharacterList*> characters = account->getCharacterList();
  3473.  
  3474. for (int i=0; i<characters->size(); i++) {
  3475. CharacterListEntry& entry = characters->get(i);
  3476.  
  3477. if (entry.getFirstName() == name && entry.getGalaxyID() == galaxyID) {
  3478. Time expires;
  3479. expires.addMiliTime(seconds*1000);
  3480.  
  3481. entry.setBanReason(reason);
  3482. entry.setBanAdmin(admin->getAccountID());
  3483. entry.setBanExpiration(expires);
  3484. }
  3485. }
  3486.  
  3487. locker.release();
  3488.  
  3489. try {
  3490. if (server->getGalaxyID() == galaxyID) {
  3491. ManagedReference<CreatureObject*> player = getPlayer(name);
  3492. if(player != NULL) {
  3493. clearOwnedStructuresPermissions(player);
  3494.  
  3495. if (player->isOnline()) {
  3496. player->sendMessage(new LogoutMessage());
  3497.  
  3498. ManagedReference<ZoneClientSession*> session = player->getClient();
  3499.  
  3500. if(session != NULL)
  3501. session->disconnect(true);
  3502. }
  3503. }
  3504. } else {
  3505. return "Character Successfully Banned, but cannot kick character because it's on a different galaxy.";
  3506. }
  3507. } catch(Exception& e) {
  3508. return "Character Successfully Banned, but error kicking Character. " + e.getMessage();
  3509. }
  3510.  
  3511. return "Character Successfully Banned";
  3512. }
  3513.  
  3514. String PlayerManagerImplementation::unbanCharacter(PlayerObject* admin, Account* account, const String& name, const uint32 galaxyID, const String& reason) {
  3515.  
  3516. if(admin == NULL || !admin->isPrivileged())
  3517. return "";
  3518.  
  3519. if(account == NULL)
  3520. return "Account Not Found";
  3521.  
  3522. String escapedReason = reason;
  3523. Database::escapeString(escapedReason);
  3524.  
  3525. String escapedName = name;
  3526. Database::escapeString(escapedName);
  3527.  
  3528. try {
  3529. StringBuffer query;
  3530. query << "UPDATE character_bans SET expires = UNIX_TIMESTAMP(), reason = '" << escapedReason << "' WHERE account_id = " << account->getAccountID() << " AND galaxy_id = " << galaxyID << " and name = '" << escapedName << "' and expires > UNIX_TIMESTAMP();";
  3531.  
  3532. ServerDatabase::instance()->executeStatement(query);
  3533. } catch(Exception& e) {
  3534. return "Exception banning character: " + e.getMessage();
  3535. }
  3536.  
  3537. Locker locker(account);
  3538. CharacterListEntry *entry = account->getCharacterBan(galaxyID, name);
  3539.  
  3540. if (entry != NULL) {
  3541. Time now;
  3542. entry->setBanExpiration(now);
  3543. entry->setBanReason(reason);
  3544. }
  3545.  
  3546. return "Character Successfully Unbanned";
  3547. }
  3548.  
  3549. void PlayerManagerImplementation::clearOwnedStructuresPermissions(CreatureObject* player) {
  3550. PlayerObject* ghost = player->getPlayerObject();
  3551.  
  3552. if (ghost == NULL) {
  3553. return;
  3554. }
  3555.  
  3556. for (int i = 0; i < ghost->getTotalOwnedStructureCount(); i++) {
  3557. uint64 structureID = ghost->getOwnedStructure(i);
  3558.  
  3559. ManagedReference<StructureObject*> structure = server->getObject(structureID).castTo<StructureObject*>();
  3560.  
  3561. if (structure == NULL) {
  3562. continue;
  3563. }
  3564.  
  3565. structure->revokeAllPermissions();
  3566. }
  3567. }
  3568.  
  3569. void PlayerManagerImplementation::fixHAM(CreatureObject* player) {
  3570. Locker locker(player);
  3571.  
  3572. try {
  3573. BuffList* buffs = player->getBuffList();
  3574.  
  3575. VectorMap<byte, int> attributeValues;
  3576. attributeValues.setNullValue(0);
  3577. attributeValues.setAllowOverwriteInsertPlan();
  3578.  
  3579. ManagedReference<Buff*> powerBoost;
  3580.  
  3581. //check buffs
  3582. for (int i = 0; i < buffs->getBuffListSize(); ++i) {
  3583. ManagedReference<Buff*> buff = buffs->getBuffByIndex(i);
  3584.  
  3585. PowerBoostBuff* power = dynamic_cast<PowerBoostBuff*>(buff.get());
  3586.  
  3587. if (power != NULL) {
  3588. powerBoost = power;
  3589. continue;
  3590. }
  3591.  
  3592. VectorMap<byte, int>* attributeModifiers = buff->getAttributeModifiers();
  3593.  
  3594. for (int j = 0; j < attributeModifiers->size(); ++j) {
  3595. byte modifier = attributeModifiers->elementAt(j).getKey();
  3596. int val = attributeModifiers->elementAt(j).getValue();
  3597.  
  3598. attributeValues.put(modifier, attributeValues.get(modifier) + val);
  3599. }
  3600. }
  3601.  
  3602. if (powerBoost != NULL) {
  3603. Locker buffLocker(powerBoost);
  3604.  
  3605. player->removeBuff(powerBoost);
  3606. }
  3607.  
  3608. int encumbranceType = -1;
  3609.  
  3610. for (int i = 0; i < 9; ++i) {
  3611. int maxModifier = attributeValues.get((byte)i);
  3612. int baseHam = player->getBaseHAM(i);
  3613. int max = player->getMaxHAM(i);
  3614.  
  3615. int calculated = baseHam + maxModifier;
  3616.  
  3617. if (i % 3 == 0) {
  3618. ++encumbranceType;
  3619. } else {
  3620. calculated -= player->getEncumbrance(encumbranceType);
  3621. }
  3622.  
  3623. //info("attribute: " + CreatureAttribute::getName(i, true) + " max = " + String::valueOf(max) + " calculatedMax = " + String::valueOf(calculated), true);
  3624.  
  3625. if (calculated != max && calculated > 1) {
  3626. if (player->getHAM(i) > calculated)
  3627. player->setHAM(i, calculated, false);
  3628.  
  3629. player->setMaxHAM(i, calculated, false);
  3630. }
  3631. }
  3632. PlayerObject* ghost = player->getPlayerObject();
  3633. ghost->addMasterLevelAttributes(player);
  3634. player->setRunSpeed(CreatureObjectImplementation::DEFAULTRUNSPEED);
  3635.  
  3636.  
  3637. } catch (Exception& e) {
  3638. error(e.getMessage());
  3639. }
  3640. }
  3641.  
  3642. void PlayerManagerImplementation::fixBuffSkillMods(CreatureObject* player) {
  3643. Locker locker(player);
  3644.  
  3645. try {
  3646. GroupObject* grp = player->getGroup();
  3647. if (grp != NULL)
  3648. GroupManager::instance()->leaveGroup(grp, player);
  3649.  
  3650. Reference<Buff*> buff = player->getBuff(STRING_HASHCODE("squadleader"));
  3651. if (buff != NULL) {
  3652. Locker locker(buff);
  3653. player->removeBuff(buff);
  3654. }
  3655.  
  3656. if (player->getSkillModList() == NULL)
  3657. return;
  3658.  
  3659. Locker smodsGuard(player->getSkillModMutex());
  3660.  
  3661. SkillModGroup* smodGroup = player->getSkillModList()->getSkillModGroup(SkillModManager::BUFF);
  3662. smodGroup->removeAll();
  3663.  
  3664. smodsGuard.release();
  3665.  
  3666. BuffList* buffs = player->getBuffList();
  3667.  
  3668. for (int i = 0; i < buffs->getBuffListSize(); i++) {
  3669. ManagedReference<Buff*> buff = buffs->getBuffByIndex(i);
  3670.  
  3671. Locker clocker(buff, player);
  3672.  
  3673. buff->setModsApplied(true);
  3674.  
  3675. buff->applySkillModifiers();
  3676. }
  3677.  
  3678. if (grp != NULL && grp->getLeader() != NULL) {
  3679. player->updateGroupInviterID(grp->getLeader()->getObjectID());
  3680. GroupManager::instance()->joinGroup(player);
  3681. }
  3682. } catch (Exception& e) {
  3683. error(e.getMessage());
  3684. }
  3685. }
  3686.  
  3687. bool PlayerManagerImplementation::promptTeachableSkills(CreatureObject* teacher, SceneObject* target) {
  3688. if (target == NULL || !target->isPlayerCreature()) {
  3689. teacher->sendSystemMessage("@teaching:no_target"); //Whom do you want to teach?
  3690. return false;
  3691. }
  3692.  
  3693. if (target == teacher) {
  3694. teacher->sendSystemMessage("@teaching:no_teach_self"); //You cannot teach yourself.
  3695. return false;
  3696. }
  3697.  
  3698. Locker _lock(target, teacher);
  3699.  
  3700. //We checked if they had the player object in slot with isPlayerCreature
  3701. CreatureObject* student = cast<CreatureObject*>(target);
  3702.  
  3703. if (teacher->getGroup() == NULL || student->getGroup() != teacher->getGroup()) {
  3704. StringIdChatParameter params("teaching", "not_in_same_group"); //You must be within the same group as %TT in order to teach.
  3705. params.setTT(student->getDisplayedName());
  3706. teacher->sendSystemMessage(params);
  3707. return false;
  3708. }
  3709.  
  3710. if (student->isDead()) {
  3711. StringIdChatParameter params("teaching", "student_dead"); //%TT does not feel like being taught right now.
  3712. params.setTT(student->getDisplayedName());
  3713. teacher->sendSystemMessage(params);
  3714. return false;
  3715. }
  3716.  
  3717. if (!student->isInRange(teacher, 32.f)) {
  3718. teacher->sendSystemMessage("@teaching:student_too_far"); // Your student must be nearby in order to teach.
  3719. return false;
  3720. }
  3721.  
  3722. ManagedReference<PlayerObject*> studentGhost = student->getPlayerObject();
  3723.  
  3724. //Do they have an outstanding teaching offer?
  3725. if (studentGhost->hasSuiBoxWindowType(SuiWindowType::TEACH_OFFER)) {
  3726. StringIdChatParameter params("teaching", "student_has_offer_to_learn"); //%TT already has an offer to learn.
  3727. params.setTT(student->getDisplayedName());
  3728. teacher->sendSystemMessage(params);
  3729. return false;
  3730. }
  3731.  
  3732. SortedVector<String> skills = getTeachableSkills(teacher, student);
  3733.  
  3734. if (skills.size() <= 0) {
  3735. StringIdChatParameter params("teaching", "no_skills_for_student"); //You have no skills that %TT can currently learn."
  3736. params.setTT(student->getDisplayedName());
  3737. teacher->sendSystemMessage(params);
  3738. return false;
  3739. }
  3740.  
  3741. ManagedReference<SuiListBox*> listbox = new SuiListBox(teacher, SuiWindowType::TEACH_SKILL);
  3742. listbox->setUsingObject(student);
  3743. listbox->setForceCloseDistance(32.f);
  3744. listbox->setPromptTitle("SELECT SKILL");
  3745. listbox->setPromptText("Select a skill to teach.");
  3746. listbox->setCancelButton(true, "@cancel");
  3747.  
  3748. for (int i = 0; i < skills.size(); ++i) {
  3749. String skill = skills.get(i);
  3750. listbox->addMenuItem("@skl_n:" + skill, skill.hashCode());
  3751. }
  3752.  
  3753. listbox->setCallback(new PlayerTeachSuiCallback(server));
  3754.  
  3755. if (teacher->isPlayerCreature()) {
  3756. ManagedReference<PlayerObject*> teacherGhost = teacher->getPlayerObject();
  3757.  
  3758. teacherGhost->addSuiBox(listbox);
  3759. }
  3760.  
  3761. teacher->sendMessage(listbox->generateMessage());
  3762.  
  3763. return true;
  3764. }
  3765.  
  3766. bool PlayerManagerImplementation::offerTeaching(CreatureObject* teacher, CreatureObject* student, Skill* skill) {
  3767. ManagedReference<PlayerObject*> studentGhost = student->getPlayerObject();
  3768.  
  3769. //Do they have an outstanding teaching offer?
  3770. if (studentGhost->hasSuiBoxWindowType(SuiWindowType::TEACH_OFFER)) {
  3771. StringIdChatParameter params("teaching", "student_has_offer_to_learn"); //%TT already has an offer to learn.
  3772. params.setTT(student->getDisplayedName());
  3773. teacher->sendSystemMessage(params);
  3774. return false;
  3775. }
  3776.  
  3777. ManagedReference<SuiMessageBox*> suibox = new SuiMessageBox(teacher, SuiWindowType::TEACH_OFFER);
  3778. suibox->setUsingObject(teacher);
  3779. suibox->setForceCloseDistance(32.f);
  3780. suibox->setPromptTitle("@sui:swg"); //Star Wars Galaxies
  3781.  
  3782. StringIdManager* sidman = StringIdManager::instance();
  3783.  
  3784. String sklname = sidman->getStringId(String("@skl_n:" + skill->getSkillName()).hashCode()).toString();
  3785. String expname = sidman->getStringId(String("@exp_n:" + skill->getXpType()).hashCode()).toString();
  3786.  
  3787. StringBuffer prompt;
  3788. prompt << teacher->getDisplayedName()
  3789. << " has offered to teach you " << sklname << " (" << skill->getXpCost()
  3790. << " " << expname << " experience cost).";
  3791.  
  3792. suibox->setPromptText(prompt.toString());
  3793. suibox->setCallback(new PlayerTeachConfirmSuiCallback(server, skill));
  3794.  
  3795. suibox->setOkButton(true, "@yes");
  3796. suibox->setCancelButton(true, "@no");
  3797.  
  3798. studentGhost->addSuiBox(suibox);
  3799. student->sendMessage(suibox->generateMessage());
  3800.  
  3801. StringIdChatParameter params("teaching", "offer_given"); //You offer to teach %TT %TO.
  3802. params.setTT(student->getDisplayedName());
  3803. params.setTO("@skl_n:" + skill->getSkillName());
  3804. teacher->sendSystemMessage(params);
  3805.  
  3806. return true;
  3807. }
  3808.  
  3809. bool PlayerManagerImplementation::acceptTeachingOffer(CreatureObject* teacher, CreatureObject* student, Skill* skill) {
  3810. if (teacher->getGroup() == NULL || student->getGroup() != teacher->getGroup()) {
  3811. StringIdChatParameter params("teaching", "not_in_same_group"); //You must be within the same group as %TT in order to teach.
  3812. params.setTT(student->getDisplayedName());
  3813. teacher->sendSystemMessage(params);
  3814. return false;
  3815. }
  3816.  
  3817. //Check to see if the teacher still has the skill and the student can still learn the skill.
  3818. SkillManager* skillManager = SkillManager::instance();
  3819.  
  3820. if (!student->isInRange(teacher, 32.f)) {
  3821. StringIdChatParameter params("teaching", "teacher_too_far_target"); //You are too far away from %TT to learn.
  3822. params.setTT(teacher->getDisplayedName());
  3823. student->sendSystemMessage(params);
  3824.  
  3825. params.setStringId("teaching", "student_too_far_target");
  3826. params.setTT(student->getDisplayedName()); //You are too far away from %TT to teach.
  3827. teacher->sendSystemMessage(params);
  3828. return false;
  3829. }
  3830.  
  3831. if (teacher->hasSkill(skill->getSkillName()) && skillManager->awardSkill(skill->getSkillName(), student, true, false, false)) {
  3832. StringIdChatParameter params("teaching", "student_skill_learned"); //You learn %TO from %TT.
  3833. params.setTO("@skl_n:" + skill->getSkillName());
  3834. params.setTT(teacher->getDisplayedName());
  3835. student->sendSystemMessage(params);
  3836.  
  3837. params.setStringId("teaching", "teacher_skill_learned"); //%TT learns %TO from you.
  3838. params.setTT(student->getDisplayedName());
  3839. teacher->sendSystemMessage(params);
  3840.  
  3841. if (skillManager->isApprenticeshipEnabled() && !skill->getSkillName().endsWith("novice")) {
  3842. int exp = 10 + (skill->getTotalChildren() * 10);
  3843.  
  3844. StringIdChatParameter params("teaching", "experience_received"); //You have received %DI Apprenticeship experience.
  3845. params.setDI(exp);
  3846. teacher->sendSystemMessage(params);
  3847.  
  3848. awardExperience(teacher, "apprenticeship", exp, false);
  3849. }
  3850. } else {
  3851. student->sendSystemMessage("@teaching:learning_failed"); //Learning failed.
  3852. teacher->sendSystemMessage("@teaching:teaching_failed"); //Teaching failed.
  3853. return false;
  3854. }
  3855.  
  3856. return true;
  3857. }
  3858.  
  3859. SortedVector<String> PlayerManagerImplementation::getTeachableSkills(CreatureObject* teacher, CreatureObject* student) {
  3860. SortedVector<String> skills;
  3861. skills.setNoDuplicateInsertPlan();
  3862.  
  3863. SkillList* skillList = teacher->getSkillList();
  3864.  
  3865. SkillManager* skillManager = SkillManager::instance();
  3866.  
  3867. for (int i = 0; i < skillList->size(); ++i) {
  3868. Skill* skill = skillList->get(i);
  3869.  
  3870. String skillName = skill->getSkillName();
  3871.  
  3872. if (!(skillName.contains("novice") || skillName.contains("force_sensitive") || skillName.contains("force_rank") || skillName.contains("force_title")) && skillManager->canLearnSkill(skillName, student, false))
  3873. skills.put(skillName);
  3874. }
  3875.  
  3876. return skills;
  3877. }
  3878.  
  3879. void PlayerManagerImplementation::decreaseOnlineCharCount(ZoneClientSession* client) {
  3880. Locker locker(&onlineMapMutex);
  3881.  
  3882. uint32 accountId = client->getAccountID();
  3883.  
  3884. if (!onlineZoneClientMap.containsKey(accountId))
  3885. return;
  3886.  
  3887. BaseClientProxy* session = client->getSession();
  3888.  
  3889.  
  3890.  
  3891. Vector<Reference<ZoneClientSession*> > clients = onlineZoneClientMap.get(accountId);
  3892.  
  3893. for (int i = 0; i < clients.size(); ++i)
  3894. if (clients.get(i) == client) {
  3895. clients.remove(i);
  3896.  
  3897. break;
  3898. }
  3899.  
  3900. if (clients.size() == 0)
  3901. onlineZoneClientMap.remove(accountId);
  3902. else
  3903. onlineZoneClientMap.put(accountId, clients);
  3904.  
  3905. locker.release();
  3906.  
  3907. if (session != NULL) {
  3908. onlineZoneClientMap.accountLoggedOut(session->getIPAddress(), accountId);
  3909. }
  3910. }
  3911.  
  3912. void PlayerManagerImplementation::proposeUnity( CreatureObject* askingPlayer, CreatureObject* respondingPlayer, SceneObject* askingPlayerRing ){
  3913.  
  3914. if( !askingPlayer->isPlayerCreature() ){
  3915. return;
  3916. }
  3917.  
  3918. // Check if target is self
  3919. if( askingPlayer == respondingPlayer ){
  3920. askingPlayer->sendSystemMessage("@unity:bad_target"); // "You must have a valid player target to Propose Unity."
  3921. return;
  3922. }
  3923.  
  3924. // Check if target is a player
  3925. if( !respondingPlayer->isPlayerCreature() ){
  3926. askingPlayer->sendSystemMessage("@unity:bad_target"); // "You must have a valid player target to Propose Unity."
  3927. return;
  3928. }
  3929.  
  3930. Reference<PlayerObject*> askingGhost = askingPlayer->getPlayerObject();
  3931. Reference<PlayerObject*> respondingGhost = respondingPlayer->getPlayerObject();
  3932. if( askingGhost == NULL || respondingGhost == NULL ){
  3933. return;
  3934. }
  3935.  
  3936. // Check if askingPlayer is married
  3937. if( askingGhost->isMarried() ){
  3938. StringIdChatParameter errAskerMarried;
  3939. errAskerMarried.setStringId("unity", "prose_already_married"); // "You cannot propose unity. You are already united with %TO."
  3940. errAskerMarried.setTO( askingGhost->getSpouseName() );
  3941. askingPlayer->sendSystemMessage( errAskerMarried );
  3942. return;
  3943. }
  3944.  
  3945. // Check if respondingPlayer is married
  3946. if( respondingGhost->isMarried() ){
  3947. askingPlayer->sendSystemMessage("@unity:target_married"); // "You cannot propose unity to someone who is already united."
  3948. return;
  3949. }
  3950.  
  3951. // Check distance
  3952. if( !respondingPlayer->isInRange( askingPlayer, 15.0 ) ){
  3953. askingPlayer->sendSystemMessage("@unity:out_of_range"); // "Your target is too far away to properly propose!"
  3954. return;
  3955. }
  3956.  
  3957. // TODO: Check facing
  3958. // askingPlayer->sendSystemMessage("@unity:bad_facing");// "You must be facing your target to properly propose!"
  3959.  
  3960. // Check if asking player has a proposal outstanding
  3961. if( askingPlayer->getActiveSession(SessionFacadeType::PROPOSEUNITY) != NULL ){
  3962. askingPlayer->sendSystemMessage("But you already have an outstanding unity proposal");
  3963. return;
  3964. }
  3965.  
  3966. // Check if responding player has a proposal outstanding
  3967. if( respondingPlayer->getActiveSession(SessionFacadeType::PROPOSEUNITY) != NULL ){
  3968. askingPlayer->sendSystemMessage("@unity:target_proposed"); // "Your proposal target is already engaged in a unity proposal."
  3969. return;
  3970. }
  3971.  
  3972. //
  3973. // All checks passed
  3974. //
  3975.  
  3976. Locker rlocker( askingPlayer, respondingPlayer );
  3977.  
  3978. // Initialize session
  3979. ManagedReference<ProposeUnitySession*> askerUnitySession =
  3980. new ProposeUnitySession( askingPlayer->getObjectID(), respondingPlayer->getObjectID(), askingPlayerRing->getObjectID() );
  3981. askingPlayer->addActiveSession(SessionFacadeType::PROPOSEUNITY, askerUnitySession);
  3982.  
  3983. ManagedReference<ProposeUnitySession*> responderUnitySession =
  3984. new ProposeUnitySession( askingPlayer->getObjectID(), respondingPlayer->getObjectID(), askingPlayerRing->getObjectID() );
  3985. respondingPlayer->addActiveSession(SessionFacadeType::PROPOSEUNITY, responderUnitySession);
  3986.  
  3987. // Submit timeout task
  3988. Reference<Task*> askerExpiredTask = new ProposeUnityExpiredTask( askingPlayer );
  3989. askingPlayer->addPendingTask("propose_unity", askerExpiredTask, 60000); // 1 min
  3990.  
  3991. Reference<Task*> responderExpiredTask = new ProposeUnityExpiredTask( respondingPlayer );
  3992. respondingPlayer->addPendingTask("propose_unity", responderExpiredTask, 60000); // 1 min
  3993.  
  3994. // Build and send proposal window
  3995. ManagedReference<SuiMessageBox*> suiBox = new SuiMessageBox(respondingPlayer, SuiWindowType::PROPOSE_UNITY);
  3996. suiBox->setCallback(new ProposeUnitySuiCallback(server));
  3997. suiBox->setPromptTitle("@unity:accept_title"); // "Accept Unity Proposal?"
  3998. suiBox->setPromptText( askingPlayer->getCreatureName().toString() + " is proposing unity to you. Do you wish to accept?" );
  3999. suiBox->setUsingObject( askingPlayer );
  4000. suiBox->setCancelButton(true, "@no");
  4001. suiBox->setOkButton(true, "@yes");
  4002.  
  4003. respondingGhost->addSuiBox(suiBox);
  4004. respondingPlayer->sendMessage(suiBox->generateMessage());
  4005.  
  4006. // Send message to asking player
  4007. StringIdChatParameter proposalSent;
  4008. proposalSent.setStringId("unity", "prose_propose"); // "You propose unity to %TO."
  4009. proposalSent.setTO( respondingPlayer->getFirstName() );
  4010. askingPlayer->sendSystemMessage( proposalSent );
  4011.  
  4012. }
  4013.  
  4014. void PlayerManagerImplementation::denyUnity( CreatureObject* respondingPlayer ){
  4015.  
  4016. if( respondingPlayer == NULL )
  4017. return;
  4018.  
  4019. // Check session
  4020. ManagedReference<ProposeUnitySession*> proposeUnitySession = respondingPlayer->getActiveSession(SessionFacadeType::PROPOSEUNITY).castTo<ProposeUnitySession*>();
  4021. if( proposeUnitySession == NULL ){
  4022. respondingPlayer->sendSystemMessage("@unity:expire_target"); // "The unity proposal extended to you has expired."
  4023. return;
  4024. }
  4025.  
  4026. // Pull asking player
  4027. uint64 targID = proposeUnitySession->getAskingPlayer();
  4028. ManagedReference<SceneObject*> obj = server->getObject(targID);
  4029. if( obj == NULL || !obj->isPlayerCreature() ){
  4030. respondingPlayer->sendSystemMessage("@unity:wed_error"); // "An error has occurred during the unity process."
  4031. return;
  4032. }
  4033.  
  4034. CreatureObject* askingPlayer = cast<CreatureObject*>( obj.get());
  4035. Locker alocker( askingPlayer, respondingPlayer );
  4036. askingPlayer->sendSystemMessage("@unity:declined"); // "Your unity proposal has been declined.")
  4037. respondingPlayer->sendSystemMessage("@unity:decline"); // "You decline the unity proposal.")
  4038.  
  4039. // Remove session
  4040. cancelProposeUnitySession(respondingPlayer, askingPlayer);
  4041.  
  4042. }
  4043.  
  4044. void PlayerManagerImplementation::acceptUnity( CreatureObject* respondingPlayer ){
  4045.  
  4046. if( respondingPlayer == NULL )
  4047. return;
  4048.  
  4049. // Check session
  4050. ManagedReference<ProposeUnitySession*> proposeUnitySession = respondingPlayer->getActiveSession(SessionFacadeType::PROPOSEUNITY).castTo<ProposeUnitySession*>();
  4051. if( proposeUnitySession == NULL ){
  4052. respondingPlayer->sendSystemMessage("@unity:expire_target"); // "The unity proposal extended to you has expired."
  4053. return;
  4054. }
  4055.  
  4056. // Pull asking player
  4057. uint64 targID = proposeUnitySession->getAskingPlayer();
  4058. ManagedReference<SceneObject*> obj = server->getObject(targID);
  4059. if( obj == NULL || !obj->isPlayerCreature() ){
  4060. respondingPlayer->sendSystemMessage("@unity:wed_error"); // "An error has occurred during the unity process."
  4061. return;
  4062. }
  4063.  
  4064. CreatureObject* askingPlayer = cast<CreatureObject*>( obj.get());
  4065. Locker alocker( askingPlayer, respondingPlayer );
  4066.  
  4067. // Check distance
  4068. if( !respondingPlayer->isInRange( askingPlayer, 15.0 ) ){
  4069. askingPlayer->sendSystemMessage("@unity:wed_oor"); // "You must remain within 15 meters during the unity process for it to complete."
  4070. respondingPlayer->sendSystemMessage("@unity:wed_oor"); // "You must remain within 15 meters during the unity process for it to complete."
  4071. cancelProposeUnitySession(respondingPlayer, askingPlayer);
  4072. return;
  4073. }
  4074.  
  4075. // Check for a ring in player's inventory
  4076. ManagedReference<SceneObject*> inventory = respondingPlayer->getSlottedObject("inventory");
  4077. if( inventory == NULL ){
  4078. respondingPlayer->sendSystemMessage("@unity:wed_error"); // "An error has occurred during the unity process."
  4079. askingPlayer->sendSystemMessage("@unity:wed_error"); // "An error has occurred during the unity process."
  4080. cancelProposeUnitySession(respondingPlayer, askingPlayer);
  4081. return;
  4082. }
  4083.  
  4084. bool hasRing = false;
  4085. for (int i = 0; i < inventory->getContainerObjectsSize(); i++) {
  4086. ManagedReference<WearableObject*> wearable = cast<WearableObject*>(inventory->getContainerObject(i).get());
  4087. if( wearable != NULL && wearable->getGameObjectType() == SceneObjectType::RING && !wearable->isEquipped() ){
  4088. hasRing = true;
  4089. }
  4090. }
  4091.  
  4092. // No ring found
  4093. if( !hasRing ){
  4094. askingPlayer->sendSystemMessage("@unity:accept_fail"); // "Your proposal target has no ring to offer in return."
  4095. respondingPlayer->sendSystemMessage("@unity:no_ring"); // "You cannot accept a unity proposal without a ring to offer."
  4096. cancelProposeUnitySession(respondingPlayer, askingPlayer);
  4097. return;
  4098. }
  4099.  
  4100. // Build and send list box for ring selection
  4101. ManagedReference<SuiListBox*> box = new SuiListBox(respondingPlayer, SuiWindowType::SELECT_UNITY_RING, SuiListBox::HANDLETWOBUTTON);
  4102. box->setCallback(new SelectUnityRingSuiCallback(server));
  4103. box->setPromptText("@unity:ring_prompt"); // "Select the ring you would like to offer, in return, for your unity."
  4104. box->setPromptTitle("Select Unity Ring");
  4105. box->setOkButton(true, "@ok");
  4106. box->setCancelButton(true, "@cancel");
  4107.  
  4108. for (int i = 0; i < inventory->getContainerObjectsSize(); i++) {
  4109. ManagedReference<WearableObject*> wearable = cast<WearableObject*>(inventory->getContainerObject(i).get());
  4110. if( wearable != NULL && wearable->getGameObjectType() == SceneObjectType::RING && !wearable->isEquipped() && !wearable->isNoTrade() ){
  4111. String itemName = wearable->getDisplayedName();
  4112. box->addMenuItem(itemName, wearable->getObjectID());
  4113. }
  4114. }
  4115.  
  4116. box->setUsingObject(respondingPlayer);
  4117. respondingPlayer->getPlayerObject()->addSuiBox(box);
  4118. respondingPlayer->sendMessage(box->generateMessage());
  4119.  
  4120. }
  4121.  
  4122. void PlayerManagerImplementation::completeUnity( CreatureObject* respondingPlayer, unsigned long long respondingPlayerRingId ){
  4123.  
  4124. if( respondingPlayer == NULL )
  4125. return;
  4126.  
  4127. // Check session
  4128. ManagedReference<ProposeUnitySession*> proposeUnitySession = respondingPlayer->getActiveSession(SessionFacadeType::PROPOSEUNITY).castTo<ProposeUnitySession*>();
  4129. if( proposeUnitySession == NULL ){
  4130. respondingPlayer->sendSystemMessage("@unity:expire_target"); // "The unity proposal extended to you has expired."
  4131. return;
  4132. }
  4133.  
  4134. // Pull asking player
  4135. uint64 targID = proposeUnitySession->getAskingPlayer();
  4136. ManagedReference<SceneObject*> obj = server->getObject(targID);
  4137. if( obj == NULL || !obj->isPlayerCreature() ){
  4138. respondingPlayer->sendSystemMessage("@unity:wed_error"); // "An error has occurred during the unity process."
  4139. return;
  4140. }
  4141.  
  4142. CreatureObject* askingPlayer = cast<CreatureObject*>( obj.get());
  4143. Locker alocker( askingPlayer, respondingPlayer );
  4144.  
  4145. // Check distance
  4146. if( !respondingPlayer->isInRange( askingPlayer, 15.0 ) ){
  4147. askingPlayer->sendSystemMessage("@unity:wed_oor"); // "You must remain within 15 meters during the unity process for it to complete."
  4148. respondingPlayer->sendSystemMessage("@unity:wed_oor"); // "You must remain within 15 meters during the unity process for it to complete."
  4149. cancelProposeUnitySession(respondingPlayer, askingPlayer);
  4150. return;
  4151. }
  4152.  
  4153. // Find selected ring
  4154. ManagedReference<SceneObject*> respondingPlayerInventory = respondingPlayer->getSlottedObject("inventory");
  4155. ManagedReference<SceneObject*> askingPlayerInventory = askingPlayer->getSlottedObject("inventory");
  4156. if( respondingPlayerInventory == NULL || askingPlayerInventory == NULL ){
  4157. respondingPlayer->sendSystemMessage("@unity:wed_error"); // "An error has occurred during the unity process."
  4158. askingPlayer->sendSystemMessage("@unity:wed_error"); // "An error has occurred during the unity process."
  4159. cancelProposeUnitySession(respondingPlayer, askingPlayer);
  4160. return;
  4161. }
  4162.  
  4163. // Find responder's ring
  4164. ManagedReference<WearableObject*> wearable = NULL;
  4165. ManagedReference<WearableObject*> respondingRing = NULL;
  4166. for (int i = 0; i < respondingPlayerInventory->getContainerObjectsSize(); i++) {
  4167. wearable = cast<WearableObject*>(respondingPlayerInventory->getContainerObject(i).get());
  4168. if( wearable != NULL && wearable->getObjectID() == respondingPlayerRingId && !wearable->isEquipped() ){
  4169. respondingRing = wearable;
  4170. break;
  4171. }
  4172. }
  4173.  
  4174. // Find asker's ring
  4175. wearable = NULL;
  4176. ManagedReference<WearableObject*> askingRing = NULL;
  4177. for (int i = 0; i < askingPlayerInventory->getContainerObjectsSize(); i++) {
  4178. wearable = cast<WearableObject*>(askingPlayerInventory->getContainerObject(i).get());
  4179. if( wearable != NULL && wearable->getObjectID() == proposeUnitySession->getAskingPlayerRing() && !wearable->isEquipped() ){
  4180. askingRing = wearable;
  4181. break;
  4182. }
  4183. }
  4184.  
  4185.  
  4186. // Rings not found
  4187. if( respondingRing == NULL || askingRing == NULL ){
  4188. askingPlayer->sendSystemMessage("@unity:accept_fail"); // "Your proposal target has no ring to offer in return."
  4189. respondingPlayer->sendSystemMessage("@unity:no_ring"); // "You cannot accept a unity proposal without a ring to offer."
  4190. cancelProposeUnitySession(respondingPlayer, askingPlayer);
  4191. return;
  4192. }
  4193.  
  4194. // Exchange rings
  4195. ManagedReference<ObjectController*> objectController = server->getObjectController();
  4196. if (objectController->transferObject(askingRing, respondingPlayerInventory, -1, true, true)){ // Allow overflow
  4197. askingRing->sendDestroyTo(askingPlayer);
  4198. respondingPlayerInventory->broadcastObject(askingRing, true);
  4199. }
  4200.  
  4201. if (objectController->transferObject(respondingRing, askingPlayerInventory, -1, true, true)){ // Allow overflow
  4202. respondingRing->sendDestroyTo(respondingPlayer);
  4203. askingPlayerInventory->broadcastObject(respondingRing, true);
  4204. }
  4205.  
  4206. // Set married
  4207. String respondingPlayerName = respondingPlayer->getFirstName();
  4208. String askingPlayerName = askingPlayer->getFirstName();
  4209. askingPlayer->getPlayerObject()->setSpouseName( respondingPlayerName );
  4210. respondingPlayer->getPlayerObject()->setSpouseName( askingPlayerName );
  4211.  
  4212. // Send obligatory congratulations
  4213. StringIdChatParameter congratsAsker;
  4214. congratsAsker.setStringId("unity", "prose_wed_complete"); // "Your union with %TT is complete."
  4215. congratsAsker.setTT( respondingPlayer->getFirstName() );
  4216. askingPlayer->sendSystemMessage( congratsAsker );
  4217.  
  4218. StringIdChatParameter congratsResponder;
  4219. congratsResponder.setStringId("unity", "prose_wed_complete"); // "Your union with %TT is complete."
  4220. congratsResponder.setTT( askingPlayer->getFirstName() );
  4221. respondingPlayer->sendSystemMessage( congratsResponder );
  4222.  
  4223. // Remove session
  4224. cancelProposeUnitySession(respondingPlayer, askingPlayer);
  4225.  
  4226. }
  4227.  
  4228. void PlayerManagerImplementation::cancelProposeUnitySession(CreatureObject* respondingPlayer, CreatureObject* askingPlayer){
  4229. askingPlayer->dropActiveSession(SessionFacadeType::PROPOSEUNITY);
  4230. respondingPlayer->dropActiveSession(SessionFacadeType::PROPOSEUNITY);
  4231. askingPlayer->removePendingTask( "propose_unity" );
  4232. respondingPlayer->removePendingTask( "propose_unity" );
  4233. }
  4234.  
  4235. void PlayerManagerImplementation::promptDivorce(CreatureObject* player) {
  4236. if (player == NULL || !player->isPlayerCreature())
  4237. return;
  4238.  
  4239. // Check if player is married
  4240. PlayerObject* playerGhost = player->getPlayerObject();
  4241.  
  4242. if (playerGhost == NULL)
  4243. return;
  4244.  
  4245. if (!playerGhost->isMarried()) {
  4246. player->sendSystemMessage("You are not united with anyone!");
  4247. return;
  4248. }
  4249.  
  4250. // Build and confirmation window
  4251. ManagedReference<SuiMessageBox*> suiBox = new SuiMessageBox(player, SuiWindowType::CONFIRM_DIVORCE);
  4252. suiBox->setCallback(new ConfirmDivorceSuiCallback(server));
  4253. suiBox->setPromptTitle("Confirm Divorce?");
  4254. suiBox->setPromptText("Do you wish to nullify your unity with " + playerGhost->getSpouseName() + "?");
  4255. suiBox->setCancelButton(true, "@no");
  4256. suiBox->setOkButton(true, "@yes");
  4257.  
  4258. playerGhost->addSuiBox(suiBox);
  4259. player->sendMessage(suiBox->generateMessage());
  4260. }
  4261.  
  4262. void PlayerManagerImplementation::grantDivorce(CreatureObject* player) {
  4263. if (player == NULL || !player->isPlayerCreature())
  4264. return;
  4265.  
  4266. // Check if player is married
  4267. PlayerObject* playerGhost = player->getPlayerObject();
  4268.  
  4269. if (playerGhost == NULL || !playerGhost->isMarried())
  4270. return;
  4271.  
  4272. // Find spouse
  4273. CreatureObject* spouse = getPlayer(playerGhost->getSpouseName());
  4274.  
  4275. StringIdChatParameter msg;
  4276. msg.setStringId("unity", "prose_end_unity"); // "Your union with %TO has ended."
  4277.  
  4278. // Remove spouse name from both players
  4279. if (spouse != NULL && spouse->isPlayerCreature()) {
  4280. Locker slocker(spouse, player);
  4281.  
  4282. PlayerObject* spouseGhost = spouse->getPlayerObject();
  4283.  
  4284. if (spouseGhost != NULL)
  4285. spouseGhost->removeSpouse();
  4286.  
  4287. playerGhost->removeSpouse();
  4288.  
  4289. msg.setTO(player->getFirstName());
  4290. spouse->sendSystemMessage(msg);
  4291.  
  4292. msg.setTO(spouse->getFirstName());
  4293. player->sendSystemMessage(msg);
  4294.  
  4295. } else {
  4296. // If spouse player is null (perhaps it's been deleted), we can still remove the spouse from the current player
  4297. msg.setTO(playerGhost->getSpouseName());
  4298. player->sendSystemMessage(msg);
  4299.  
  4300. playerGhost->removeSpouse();
  4301. }
  4302. }
  4303.  
  4304. void PlayerManagerImplementation::claimVeteranRewards(CreatureObject* player){
  4305.  
  4306. if( player == NULL || !player->isPlayerCreature() )
  4307. return;
  4308.  
  4309. PlayerObject* playerGhost = player->getPlayerObject();
  4310.  
  4311. // Get account
  4312. ManagedReference<Account*> account = playerGhost->getAccount();
  4313. if( account == NULL )
  4314. return;
  4315.  
  4316. // Send message with current account age
  4317. StringIdChatParameter timeActiveMsg;
  4318. timeActiveMsg.setStringId("veteran", "self_time_active"); // You have %DI days logged for veteran rewards.
  4319. timeActiveMsg.setDI( account->getAgeInDays() );
  4320. player->sendSystemMessage( timeActiveMsg );
  4321.  
  4322. // Verify player is eligible for a reward
  4323. int milestone = getEligibleMilestone( playerGhost, account );
  4324. if( milestone < 0){
  4325. player->sendSystemMessage( "@veteran:not_eligible"); // You are not currently eligible for a veteran reward.
  4326. return;
  4327. }
  4328.  
  4329. // Verify player is not already choosing a reward
  4330. if( player->getActiveSession(SessionFacadeType::VETERANREWARD) != NULL ){
  4331. player->sendSystemMessage( "You are already attempting to claim a veteran reward." );
  4332. return;
  4333. }
  4334.  
  4335. // Create session
  4336. ManagedReference<VeteranRewardSession*> rewardSession = new VeteranRewardSession( milestone );
  4337. player->addActiveSession(SessionFacadeType::VETERANREWARD, rewardSession);
  4338.  
  4339. // Build and SUI list box of rewards
  4340. ManagedReference<SuiListBox*> box = new SuiListBox(player, SuiWindowType::SELECT_VETERAN_REWARD, SuiListBox::HANDLETWOBUTTON);
  4341. box->setCallback(new SelectVeteranRewardSuiCallback(server));
  4342. box->setPromptText("@veteran_new:choice_description" ); // You may choose one of the items listed below. This item will be placed in your inventory.
  4343. box->setPromptTitle("@veteran_new:item_grant_box_title"); // Reward
  4344. box->setOkButton(true, "@ok");
  4345. box->setCancelButton(true, "@cancel");
  4346.  
  4347. for( int i = 0; i < veteranRewards.size(); i++ ){
  4348.  
  4349. // Any rewards at or below current milestone are eligible
  4350. VeteranReward reward = veteranRewards.get(i);
  4351. if( reward.getMilestone() <= milestone ){
  4352.  
  4353. // Filter out one-time rewards already claimed
  4354. if( reward.isOneTime() && playerGhost->hasChosenVeteranReward( reward.getTemplateFile() ) ){
  4355. continue;
  4356. }
  4357.  
  4358. SharedObjectTemplate* rewardTemplate = TemplateManager::instance()->getTemplate( reward.getTemplateFile().hashCode() );
  4359. if( rewardTemplate != NULL ){
  4360. if( reward.getDescription().isEmpty() ){
  4361. box->addMenuItem( rewardTemplate->getDetailedDescription(), i);
  4362. }
  4363. else{
  4364. box->addMenuItem( reward.getDescription(), i);
  4365. }
  4366. }
  4367. }
  4368. }
  4369.  
  4370. box->setUsingObject(NULL);
  4371. playerGhost->addSuiBox(box);
  4372. player->sendMessage(box->generateMessage());
  4373.  
  4374. }
  4375.  
  4376. void PlayerManagerImplementation::cancelVeteranRewardSession(CreatureObject* player){
  4377. player->dropActiveSession(SessionFacadeType::VETERANREWARD);
  4378. }
  4379.  
  4380. void PlayerManagerImplementation::confirmVeteranReward(CreatureObject* player, int itemIndex ){
  4381.  
  4382. if( player == NULL || !player->isPlayerCreature() ){
  4383. return;
  4384. }
  4385.  
  4386. if( itemIndex < 0 || itemIndex >= veteranRewards.size() ){
  4387. player->sendSystemMessage( "@veteran:reward_error"); // The reward could not be granted.
  4388. cancelVeteranRewardSession( player );
  4389. return;
  4390. }
  4391.  
  4392. // Get account
  4393. PlayerObject* playerGhost = player->getPlayerObject();
  4394. ManagedReference<Account*> account = playerGhost->getAccount();
  4395. if( account == NULL ){
  4396. player->sendSystemMessage( "@veteran:reward_error"); // The reward could not be granted.
  4397. cancelVeteranRewardSession( player );
  4398. return;
  4399. }
  4400.  
  4401. // Check session
  4402. ManagedReference<VeteranRewardSession*> rewardSession = player->getActiveSession(SessionFacadeType::VETERANREWARD).castTo<VeteranRewardSession*>();
  4403. if( rewardSession == NULL ){
  4404. player->sendSystemMessage( "@veteran:reward_error"); // The reward could not be granted.
  4405. return;
  4406. }
  4407.  
  4408. VeteranReward reward = veteranRewards.get(itemIndex);
  4409. rewardSession->setSelectedRewardIndex(itemIndex);
  4410.  
  4411. // Generate confirmation dialog if item is one-time. Otherwise, just generate it.
  4412. if( reward.isOneTime() ){
  4413.  
  4414. ManagedReference<SuiMessageBox*> suibox = new SuiMessageBox(player, SuiWindowType::CONFIRM_VETERAN_REWARD);
  4415. suibox->setPromptTitle("@veteran_new:unique_are_you_sure_box_title"); // Reward
  4416. suibox->setPromptText( "@veteran_new:item_unique_are_you_sure"); // The item you are selecting can only be selected as a reward item once for the the lifetime of your account. Are you sure you wish to continue selecting this item?
  4417. suibox->setCallback(new ConfirmVeteranRewardSuiCallback(server));
  4418. suibox->setOkButton(true, "@yes");
  4419. suibox->setCancelButton(true, "@no");
  4420.  
  4421. playerGhost->addSuiBox(suibox);
  4422. player->sendMessage(suibox->generateMessage());
  4423.  
  4424. }
  4425. else{
  4426. generateVeteranReward( player );
  4427. }
  4428.  
  4429. }
  4430.  
  4431. void PlayerManagerImplementation::generateVeteranReward(CreatureObject* player ){
  4432.  
  4433. if( player == NULL || !player->isPlayerCreature() ){
  4434. return;
  4435. }
  4436.  
  4437. // Get account
  4438. PlayerObject* playerGhost = player->getPlayerObject();
  4439. ManagedReference<Account*> account = playerGhost->getAccount();
  4440. if( account == NULL ){
  4441. player->sendSystemMessage( "@veteran:reward_error"); // The reward could not be granted.
  4442. cancelVeteranRewardSession( player );
  4443. return;
  4444. }
  4445.  
  4446. // Check session
  4447. ManagedReference<VeteranRewardSession*> rewardSession = player->getActiveSession(SessionFacadeType::VETERANREWARD).castTo<VeteranRewardSession*>();
  4448. if( rewardSession == NULL ){
  4449. player->sendSystemMessage( "@veteran:reward_error"); // The reward could not be granted.
  4450. return;
  4451. }
  4452.  
  4453. // Final check to see if milestone has already been claimed on any of the player's characters
  4454. // (prevent claiming while multi-logged)
  4455.  
  4456.  
  4457. bool milestoneClaimed = false;
  4458. if(!playerGhost->getChosenVeteranReward( rewardSession->getMilestone() ).isEmpty() )
  4459. milestoneClaimed = true;
  4460.  
  4461. if( milestoneClaimed ){
  4462. player->sendSystemMessage( "@veteran:reward_error"); // The reward could not be granted.
  4463. cancelVeteranRewardSession( player );
  4464. return;
  4465. }
  4466.  
  4467. // Generate item
  4468. SceneObject* inventory = player->getSlottedObject("inventory");
  4469. if( inventory == NULL ){
  4470. player->sendSystemMessage( "@veteran:reward_error"); // The reward could not be granted.
  4471. cancelVeteranRewardSession( player );
  4472. return;
  4473. }
  4474.  
  4475. VeteranReward reward = veteranRewards.get(rewardSession->getSelectedRewardIndex());
  4476. Reference<SceneObject*> rewardSceno = server->createObject(reward.getTemplateFile().hashCode(), 1);
  4477. if( rewardSceno == NULL ){
  4478. player->sendSystemMessage( "@veteran:reward_error"); // The reward could not be granted.
  4479. cancelVeteranRewardSession( player );
  4480. return;
  4481. }
  4482.  
  4483. // Transfer to player
  4484. if( !inventory->transferObject(rewardSceno, -1, false, true) ){ // Allow overflow
  4485. player->sendSystemMessage( "@veteran:reward_error"); // The reward could not be granted.
  4486. rewardSceno->destroyObjectFromDatabase(true);
  4487. cancelVeteranRewardSession( player );
  4488. return;
  4489. }
  4490.  
  4491. inventory->broadcastObject(rewardSceno, true);
  4492. player->sendSystemMessage( "@veteran:reward_given"); // Your reward has been placed in your inventory.
  4493.  
  4494. // Record reward in all characters registered to the account
  4495. playerGhost->addChosenVeteranReward(rewardSession->getMilestone(), reward.getTemplateFile());
  4496.  
  4497.  
  4498. cancelVeteranRewardSession( player );
  4499.  
  4500. // If player is eligible for another reward, kick off selection
  4501. if( getEligibleMilestone( playerGhost, account ) >= 0 ){
  4502. player->enqueueCommand(STRING_HASHCODE("claimveteranreward"), 0, 0, "");
  4503. }
  4504. }
  4505.  
  4506. int PlayerManagerImplementation::getEligibleMilestone( PlayerObject *playerGhost, Account* account ) {
  4507.  
  4508. if( account == NULL || playerGhost == NULL )
  4509. return -1;
  4510.  
  4511. int accountAge = account->getAgeInDays();
  4512. int milestone = -1;
  4513.  
  4514. // Return -1 if account age is less than the first milestone
  4515. if (accountAge < veteranRewardMilestones.get(0)) {
  4516. return -1;
  4517. }
  4518.  
  4519. // Return the first milestone for which the player is eligible and has not already claimed
  4520. for( int i=0; i < veteranRewardMilestones.size(); i++) {
  4521. milestone = veteranRewardMilestones.get(i);
  4522. if( accountAge >= milestone && playerGhost->getChosenVeteranReward(milestone).isEmpty() ) {
  4523. return milestone;
  4524. }
  4525. }
  4526.  
  4527. // They've claimed all of the established milestones, see if they're eligible for an additional one
  4528. milestone += veteranRewardAdditionalMilestones;
  4529.  
  4530. while (accountAge >= milestone) {
  4531. if (playerGhost->getChosenVeteranReward(milestone).isEmpty()) {
  4532. return milestone;
  4533. }
  4534.  
  4535. milestone += veteranRewardAdditionalMilestones;
  4536. }
  4537.  
  4538. // Not eligible for any milestones
  4539. return -1;
  4540. }
  4541.  
  4542. int PlayerManagerImplementation::getFirstIneligibleMilestone( PlayerObject *playerGhost, Account* account ){
  4543.  
  4544. if( account == NULL || playerGhost == NULL )
  4545. return -1;
  4546.  
  4547. int accountAge = account->getAgeInDays();
  4548. int milestone = -1;
  4549.  
  4550. // Return the first milestone the player has not already claimed
  4551. for( int i=0; i < veteranRewardMilestones.size(); i++){
  4552. milestone = veteranRewardMilestones.get(i);
  4553. if( accountAge < milestone ) {
  4554. return milestone;
  4555. }
  4556. }
  4557.  
  4558. // Check additional milestones if all established ones have been claimed
  4559. while (accountAge >= milestone) {
  4560. milestone += veteranRewardAdditionalMilestones;
  4561. }
  4562.  
  4563. return milestone;
  4564. }
  4565.  
  4566. bool PlayerManagerImplementation::increaseOnlineCharCountIfPossible(ZoneClientSession* client) {
  4567. Locker locker(&onlineMapMutex);
  4568.  
  4569. uint32 accountId = client->getAccountID();
  4570.  
  4571. BaseClientProxy* session = client->getSession();
  4572.  
  4573. if (!onlineZoneClientMap.containsKey(accountId)) {
  4574. Vector<Reference<ZoneClientSession*> > clients;
  4575. clients.add(client);
  4576.  
  4577. onlineZoneClientMap.put(accountId, clients);
  4578.  
  4579. locker.release();
  4580.  
  4581. if (session != NULL) {
  4582. String ip = session->getIPAddress();
  4583.  
  4584. onlineZoneClientMap.addAccount(ip, accountId);
  4585. }
  4586.  
  4587. return true;
  4588. }
  4589.  
  4590. Vector<Reference<ZoneClientSession*> > clients = onlineZoneClientMap.get(accountId);
  4591.  
  4592. int onlineCount = 0;
  4593.  
  4594. for (int i = 0; i < clients.size(); ++i) {
  4595. ZoneClientSession* session = clients.get(i);
  4596.  
  4597. ManagedReference<CreatureObject*> player = session->getPlayer();
  4598.  
  4599. if (player != NULL) {
  4600. Reference<PlayerObject*> ghost = player->getPlayerObject();
  4601.  
  4602. if (ghost != NULL && ghost->getAdminLevel() > 0)
  4603. continue;
  4604. else if (player->getClient() == session)
  4605. ++onlineCount;
  4606. }
  4607. }
  4608.  
  4609. if (onlineCount >= MAX_CHAR_ONLINE_COUNT)
  4610. return false;
  4611.  
  4612. clients.add(client);
  4613.  
  4614. onlineZoneClientMap.put(accountId, clients);
  4615.  
  4616. locker.release();
  4617.  
  4618. if (session != NULL) {
  4619. String ip = session->getIPAddress();
  4620.  
  4621. onlineZoneClientMap.addAccount(ip, accountId);
  4622. }
  4623.  
  4624. return true;
  4625. }
  4626.  
  4627. /*
  4628. int PlayerManagerImplementation::getOnlineCharCount(unsigned int accountId) {
  4629. //onlineMapMutex.rlock()
  4630. return 0;
  4631. }
  4632. */
  4633.  
  4634. bool PlayerManagerImplementation::shouldRescheduleCorpseDestruction(CreatureObject* player, CreatureObject* ai) {
  4635.  
  4636. if(player == NULL || ai == NULL)
  4637. return false;
  4638.  
  4639. if (!player->isPlayerCreature()) {
  4640. return true;
  4641. }
  4642.  
  4643. if (ai->isNonPlayerCreatureObject()) {
  4644. NonPlayerCreatureObject *npc = dynamic_cast<NonPlayerCreatureObject*>(ai);
  4645.  
  4646. if (!npc->hasLoot() && npc->getCashCredits() < 1 && npc->getBankCredits() < 1) {
  4647. return true;
  4648. }
  4649. } else if (ai->isCreature()) {
  4650. Creature * creature = dynamic_cast<Creature*>(ai);
  4651.  
  4652. if(creature->hasLoot() || creature->getCashCredits() > 0 || creature->getBankCredits() > 0)
  4653. return false;
  4654.  
  4655. return !(creature->hasSkillToHarvestMe(player) || canGroupMemberHarvestCorpse(player, creature));
  4656.  
  4657. }
  4658.  
  4659. return false;
  4660. }
  4661.  
  4662. bool PlayerManagerImplementation::canGroupMemberHarvestCorpse(CreatureObject* player, Creature* creature) {
  4663.  
  4664. if (!player->isGrouped())
  4665. return false;
  4666.  
  4667. ManagedReference<GroupObject*> group = player->getGroup();
  4668. int groupSize = group->getGroupSize();
  4669.  
  4670. for (int i = 0; i < groupSize; i++) {
  4671. ManagedReference<CreatureObject*> groupMember = group->getGroupMember(i);
  4672.  
  4673. if (player->getObjectID() == groupMember->getObjectID())
  4674. continue;
  4675.  
  4676. if (creature->isInRange(groupMember, 256.0f) && creature->hasSkillToHarvestMe(groupMember)) {
  4677. return true;
  4678. }
  4679. }
  4680.  
  4681. return false;
  4682. }
  4683.  
  4684. void PlayerManagerImplementation::rescheduleCorpseDestruction(CreatureObject* player, CreatureObject* ai) {
  4685.  
  4686. //If the looting player or no group members in the area can harvest then despawn immediately
  4687. if (shouldRescheduleCorpseDestruction(player, ai)) {
  4688. Reference<DespawnCreatureTask*> despawn = ai->getPendingTask("despawn").castTo<DespawnCreatureTask*>();
  4689. if (despawn != NULL) {
  4690. despawn->cancel();
  4691. despawn->reschedule(1000);
  4692. }
  4693.  
  4694. }
  4695. }
  4696.  
  4697.  
  4698. void PlayerManagerImplementation::getCleanupCharacterCount(){
  4699. info("**** GETTING CHARACTER CLEANUP INFORMATION ***",true);
  4700.  
  4701. ObjectDatabase* thisDatabase = ObjectDatabaseManager::instance()->loadObjectDatabase("sceneobjects", true, 0xFFFF, false);
  4702.  
  4703. if(thisDatabase == NULL)
  4704. return;
  4705.  
  4706. ObjectInputStream objectData(2000);
  4707. ObjectDatabaseIterator iterator(thisDatabase);
  4708.  
  4709. uint64 objectID;
  4710.  
  4711. String className;
  4712. uint64 deletedCount = 0;
  4713. uint64 playerCount = 0;
  4714.  
  4715. ZoneServer* server = ServerCore::getZoneServer();
  4716.  
  4717. if(server == NULL){
  4718. error("NULL ZoneServer in character cleanup");
  4719. return;
  4720. }
  4721.  
  4722. int galaxyID = server->getGalaxyID();
  4723.  
  4724. while(iterator.getNextKeyAndValue(objectID, &objectData)){
  4725. if(Serializable::getVariable<String>(STRING_HASHCODE("_className"), &className, &objectData)){
  4726. if(className == "CreatureObject"){
  4727. playerCount++;
  4728.  
  4729. if(shouldDeleteCharacter(objectID, galaxyID)){
  4730. deletedCount++;
  4731. info("DELETE CHARACTER " + String::valueOf(objectID),true);
  4732. }
  4733.  
  4734. }
  4735. }
  4736. objectData.reset();
  4737. }
  4738.  
  4739. StringBuffer deletedMessage;
  4740. deletedMessage << "TOTAL CHARACTERS " << " TO BE DELETED " << String::valueOf(deletedCount);
  4741. info("TOTAL CHARACTERS IN OBJECT DB: " + String::valueOf(playerCount),true);
  4742. info(deletedMessage.toString(),true);
  4743. }
  4744.  
  4745. void PlayerManagerImplementation::cleanupCharacters(){
  4746.  
  4747. info("**** PERFORMING CHARACTER CLEANUP ***",true);
  4748.  
  4749. ObjectDatabase* thisDatabase = ObjectDatabaseManager::instance()->loadObjectDatabase("sceneobjects", true, 0xFFFF, false);
  4750.  
  4751. if(thisDatabase == NULL)
  4752. return;
  4753.  
  4754. ObjectInputStream objectData(2000);
  4755. ObjectDatabaseIterator iterator(thisDatabase);
  4756.  
  4757. uint64 objectID;
  4758.  
  4759. String className;
  4760. uint64 deletedCount = 0;
  4761. uint64 playerCount = 0;
  4762.  
  4763. ZoneServer* server = ServerCore::getZoneServer();
  4764.  
  4765. if(server == NULL){
  4766. error("NULL ZoneServer in character cleanup");
  4767. return;
  4768. }
  4769.  
  4770. int galaxyID = server->getGalaxyID();
  4771.  
  4772. while(iterator.getNextKeyAndValue(objectID, &objectData) && deletedCount < 400 ){
  4773. if(Serializable::getVariable<String>(STRING_HASHCODE("_className"), &className, &objectData)){
  4774. if(className == "CreatureObject"){
  4775. playerCount++;
  4776.  
  4777. if(shouldDeleteCharacter(objectID, galaxyID)){
  4778.  
  4779. ManagedReference<CreatureObject*> object = Core::getObjectBroker()->lookUp(objectID).castTo<CreatureObject*>();
  4780.  
  4781. if(object == NULL){
  4782. info("OBJECT NULL when getting object " + String::valueOf(objectID),true);
  4783. }else if (object->isPlayerCreature()){
  4784.  
  4785. deletedCount++;
  4786. info("DELETING CHARACTER: " + String::valueOf(objectID)+ " NAME: " + object->getFirstName() + " " + object->getLastName() ,true);
  4787. Locker _lock(object);
  4788.  
  4789. ManagedReference<ZoneClientSession*> client = object->getClient();
  4790.  
  4791. if (client != NULL)
  4792. client->disconnect();
  4793.  
  4794. object->destroyObjectFromWorld(false); //Don't need to send destroy to the player - they are being disconnected.
  4795. object->destroyPlayerCreatureFromDatabase(true);
  4796.  
  4797. }
  4798.  
  4799. }
  4800.  
  4801. }
  4802.  
  4803. }
  4804.  
  4805. objectData.reset();
  4806. }
  4807.  
  4808. StringBuffer deletedMessage;
  4809. deletedMessage << "TOTAL CHARACTERS";
  4810. deletedMessage << " DELETED FROM OBJECTDB: " << String::valueOf(deletedCount);
  4811. info(deletedMessage.toString(),true);
  4812.  
  4813. }
  4814.  
  4815. bool PlayerManagerImplementation::shouldDeleteCharacter(uint64 characterID, int galaxyID){
  4816. String query = "SELECT * FROM characters WHERE character_oid = " + String::valueOf(characterID) + " AND galaxy_id = " + String::valueOf(galaxyID);
  4817.  
  4818. try {
  4819. Reference<ResultSet*> result = ServerDatabase::instance()->executeQuery(query);
  4820.  
  4821. if(result == NULL) {
  4822. error("ERROR WHILE LOOKING UP CHARACTER IN SQL TABLE");
  4823. } else if (result.get()->getRowsAffected() > 1) {
  4824.  
  4825. error("More than one character with oid = " + String::valueOf(characterID) + " in galaxy " + String::valueOf(galaxyID));
  4826. return false;
  4827.  
  4828. } else if ( result.get()->getRowsAffected() == 0) {
  4829. return true;
  4830. }
  4831.  
  4832. return false;
  4833.  
  4834. } catch ( DatabaseException &err){
  4835. info("database error " + err.getMessage(),true);
  4836. return false;
  4837. }
  4838.  
  4839. }
  4840.  
  4841. bool PlayerManagerImplementation::doBurstRun(CreatureObject* player, float hamModifier, float cooldownModifier) {
  4842. if (player == NULL)
  4843. return false;
  4844.  
  4845. if (player->isRidingMount()) {
  4846. player->sendSystemMessage("@cbt_spam:no_burst"); // You cannot burst-run while mounted on a creature or vehicle.
  4847. return false;
  4848. }
  4849.  
  4850. if (player->hasBuff(STRING_HASHCODE("gallop")) || player->hasBuff(STRING_HASHCODE("burstrun")) || player->hasBuff(STRING_HASHCODE("retreat"))) {
  4851. player->sendSystemMessage("@combat_effects:burst_run_no"); // You cannot burst run right now.
  4852. return false;
  4853. }
  4854.  
  4855. uint32 forceRun1CRC = BuffCRC::JEDI_FORCE_RUN_1;
  4856. uint32 forceRun2CRC = BuffCRC::JEDI_FORCE_RUN_2;
  4857. uint32 forceRun3CRC = BuffCRC::JEDI_FORCE_RUN_3;
  4858.  
  4859. if(player->hasBuff(forceRun1CRC) || player->hasBuff(forceRun2CRC) || player->hasBuff(forceRun3CRC)) {
  4860. player->sendSystemMessage("@combat_effects:burst_run_no"); // You cannot burst run right now.
  4861. return false;
  4862. }
  4863.  
  4864. Zone* zone = player->getZone();
  4865.  
  4866. if (zone == NULL) {
  4867. return false;
  4868. }
  4869.  
  4870. if (zone->getZoneName() == "dungeon1") {
  4871. player->sendSystemMessage("@combat_effects:burst_run_space_dungeon"); // The artificial gravity makes burst running impossible here.
  4872. return false;
  4873. }
  4874.  
  4875. if (!player->checkCooldownRecovery("burstrun")) {
  4876. player->sendSystemMessage("@combat_effects:burst_run_wait"); //You are too tired to Burst Run.
  4877. return false;
  4878. }
  4879.  
  4880. uint32 crc = STRING_HASHCODE("burstrun");
  4881. float hamCost = 100.0f;
  4882. float duration = 30;
  4883. float cooldown = 300;
  4884.  
  4885. float burstRunMod = (float) player->getSkillMod("burst_run");
  4886. hamModifier += (burstRunMod / 100.f);
  4887.  
  4888. if (hamModifier > 1.0f) {
  4889. hamModifier = 1.0f;
  4890. }
  4891.  
  4892. float hamReduction = 1.f - hamModifier;
  4893. hamCost *= hamReduction;
  4894. int newHamCost = (int) hamCost;
  4895.  
  4896. if (cooldownModifier > 1.0f) {
  4897. cooldownModifier = 1.0f;
  4898. }
  4899.  
  4900. float coodownReduction = 1.f - cooldownModifier;
  4901. cooldown *= coodownReduction;
  4902. int newCooldown = (int) cooldown;
  4903.  
  4904. if (player->getHAM(CreatureAttribute::HEALTH) <= newHamCost || player->getHAM(CreatureAttribute::ACTION) <= newHamCost || player->getHAM(CreatureAttribute::MIND) <= newHamCost) {
  4905. player->sendSystemMessage("@combat_effects:burst_run_wait"); // You are too tired to Burst Run.
  4906. return false;
  4907. }
  4908.  
  4909. player->inflictDamage(player, CreatureAttribute::HEALTH, newHamCost, true);
  4910. player->inflictDamage(player, CreatureAttribute::ACTION, newHamCost, true);
  4911. //player->inflictDamage(player, CreatureAttribute::MIND, newHamCost, true);
  4912.  
  4913. StringIdChatParameter startStringId("cbt_spam", "burstrun_start_single");
  4914. StringIdChatParameter modifiedStartStringId("combat_effects", "instant_burst_run");
  4915. StringIdChatParameter endStringId("cbt_spam", "burstrun_stop_single");
  4916.  
  4917. ManagedReference<Buff*> buff = new Buff(player, crc, duration, BuffType::SKILL);
  4918.  
  4919. Locker locker(buff);
  4920.  
  4921. buff->setSpeedMultiplierMod(1.822f);
  4922. buff->setAccelerationMultiplierMod(1.822f);
  4923.  
  4924. if (cooldownModifier == 0.f)
  4925. buff->setStartMessage(startStringId);
  4926. else
  4927. buff->setStartMessage(modifiedStartStringId);
  4928.  
  4929. buff->setEndMessage(endStringId);
  4930.  
  4931. StringIdChatParameter startSpam("cbt_spam", "burstrun_start");
  4932. StringIdChatParameter endSpam("cbt_spam", "burstrun_stop");
  4933. buff->setStartSpam(startSpam);
  4934. buff->setEndSpam(endSpam);
  4935. buff->setBroadcastSpam(true);
  4936.  
  4937. player->addBuff(buff);
  4938.  
  4939. player->updateCooldownTimer("burstrun", (newCooldown + duration) * 1000);
  4940.  
  4941. Reference<BurstRunNotifyAvailableEvent*> task = new BurstRunNotifyAvailableEvent(player);
  4942. player->addPendingTask("burst_run_notify", task, (newCooldown + duration) * 1000);
  4943.  
  4944. return true;
  4945. }
  4946. bool PlayerManagerImplementation::doOffTheBooks(CreatureObject* player, float cooldownModifier) {
  4947. if (player == NULL)
  4948. return false;
  4949.  
  4950. Zone* zone = player->getZone();
  4951.  
  4952. if (zone == NULL) {
  4953. return false;
  4954. }
  4955.  
  4956. if (!player->checkCooldownRecovery("offthebooks")) {
  4957. player->sendSystemMessage("@smuggler_contacts:failure"); //You are too tired to use Off The Books again.
  4958. return false;
  4959. }
  4960.  
  4961. uint32 crc = String("offthebooks").hashCode();
  4962. float cooldown = 300;
  4963.  
  4964. if (cooldownModifier > 1.0f) {
  4965. cooldownModifier = 1.0f;
  4966. }
  4967.  
  4968. float coodownReduction = 1.f - cooldownModifier;
  4969. cooldown *= coodownReduction;
  4970. int newCooldown = (int) cooldown;
  4971.  
  4972. player->sendSystemMessage("@smuggler_contacts:success"); //You are able to call a Junk Dealer
  4973.  
  4974. SpawnSmugglerJunk junkDealer;
  4975. junkDealer.SpawnJunkDealer(player, zone);
  4976.  
  4977. player->updateCooldownTimer("offthebooks", newCooldown * 1000);
  4978.  
  4979. return true;
  4980. }
  4981. bool PlayerManagerImplementation::doEnhanceCharacter(uint32 crc, CreatureObject* player, int amount, int duration, int buffType, uint8 attribute) {
  4982. if (player == NULL)
  4983. return false;
  4984.  
  4985. if (player->hasBuff(crc))
  4986. return false;
  4987.  
  4988. ManagedReference<Buff*> buff = new Buff(player, crc, duration, buffType);
  4989.  
  4990. Locker locker(buff);
  4991.  
  4992. buff->setAttributeModifier(attribute, amount);
  4993. player->addBuff(buff);
  4994.  
  4995. return true;
  4996. }
  4997.  
  4998. void PlayerManagerImplementation::enhanceCharacter(CreatureObject* player) {
  4999. if (player == NULL)
  5000. return;
  5001.  
  5002. bool message = true;
  5003.  
  5004. message = message && doEnhanceCharacter(0x98321369, player, medicalBuff, medicalDuration, BuffType::MEDICAL, 0); // medical_enhance_health
  5005. message = message && doEnhanceCharacter(0x815D85C5, player, medicalBuff, medicalDuration, BuffType::MEDICAL, 1); // medical_enhance_strength
  5006. message = message && doEnhanceCharacter(0x7F86D2C6, player, medicalBuff, medicalDuration, BuffType::MEDICAL, 2); // medical_enhance_constitution
  5007. message = message && doEnhanceCharacter(0x4BF616E2, player, medicalBuff, medicalDuration, BuffType::MEDICAL, 3); // medical_enhance_action
  5008. message = message && doEnhanceCharacter(0x71B5C842, player, medicalBuff, medicalDuration, BuffType::MEDICAL, 4); // medical_enhance_quickness
  5009. message = message && doEnhanceCharacter(0xED0040D9, player, medicalBuff, medicalDuration, BuffType::MEDICAL, 5); // medical_enhance_stamina
  5010.  
  5011. message = message && doEnhanceCharacter(0x506039D8, player, performanceBuff, performanceDuration, BuffType::PERFORMANCE, 6); // performance_enhance_dance_health
  5012. message = message && doEnhanceCharacter(0x937BE22A, player, performanceBuff, performanceDuration, BuffType::PERFORMANCE, 6); // performance_enhance_dance_strength
  5013. message = message && doEnhanceCharacter(0xA082139A, player, performanceBuff, performanceDuration, BuffType::PERFORMANCE, 6); // performance_enhance_dance_constitution
  5014. message = message && doEnhanceCharacter(0xF2C724A5, player, performanceBuff, performanceDuration, BuffType::PERFORMANCE, 7); // performance_enhance_music_action
  5015. message = message && doEnhanceCharacter(0xCC3A21FA, player, performanceBuff, performanceDuration, BuffType::PERFORMANCE, 8); // performance_enhance_music_quickness
  5016. message = message && doEnhanceCharacter(0x43C57AA8, player, performanceBuff, performanceDuration, BuffType::PERFORMANCE, 8); // performance_enhance_music_stamin
  5017.  
  5018. if (message && player->isPlayerCreature())
  5019. player->sendSystemMessage("An unknown force strengthens you for battles yet to come.");
  5020. }
  5021.  
  5022. void PlayerManagerImplementation::sendAdminJediList(CreatureObject* player) {
  5023. Reference<ObjectManager*> objectManager = player->getZoneServer()->getObjectManager();
  5024.  
  5025. HashTable<String, uint64> names = nameMap->getNames();
  5026. HashTableIterator<String, uint64> iter = names.iterator();
  5027.  
  5028. VectorMap<UnicodeString, int> players;
  5029. uint32 a = STRING_HASHCODE("SceneObject.slottedObjects");
  5030. uint32 b = STRING_HASHCODE("SceneObject.customName");
  5031. uint32 c = STRING_HASHCODE("PlayerObject.jediState");
  5032.  
  5033. while (iter.hasNext()) {
  5034. uint64 creoId = iter.next();
  5035. VectorMap<String, uint64> slottedObjects;
  5036. UnicodeString playerName;
  5037. int state = -1;
  5038.  
  5039. objectManager->getPersistentObjectsSerializedVariable<VectorMap<String, uint64> >(a, &slottedObjects, creoId);
  5040. objectManager->getPersistentObjectsSerializedVariable<UnicodeString>(b, &playerName, creoId);
  5041.  
  5042. uint64 ghostId = slottedObjects.get("ghost");
  5043.  
  5044. if (ghostId == 0) {
  5045. continue;
  5046. }
  5047.  
  5048. objectManager->getPersistentObjectsSerializedVariable<int>(c, &state, ghostId);
  5049.  
  5050. if (state > 1) {
  5051. players.put(playerName, state);
  5052. }
  5053. }
  5054.  
  5055. ManagedReference<SuiListBox*> listBox = new SuiListBox(player, SuiWindowType::ADMIN_JEDILIST);
  5056. listBox->setPromptTitle("Jedi List");
  5057. listBox->setPromptText("This is a list of all characters with a jedi state of 2 or greater (Name - State).");
  5058. listBox->setCancelButton(true, "@cancel");
  5059.  
  5060. for (int i = 0; i < players.size(); i++) {
  5061. listBox->addMenuItem(players.elementAt(i).getKey().toString() + " - " + String::valueOf(players.get(i)));
  5062. }
  5063.  
  5064. Locker locker(player);
  5065.  
  5066. player->getPlayerObject()->closeSuiWindowType(SuiWindowType::ADMIN_JEDILIST);
  5067.  
  5068. player->getPlayerObject()->addSuiBox(listBox);
  5069. player->sendMessage(listBox->generateMessage());
  5070. }
  5071.  
  5072. // FRS List
  5073. void PlayerManagerImplementation::sendAdminFRSList(CreatureObject* player) {
  5074. Reference<ObjectManager*> objectManager = player->getZoneServer()->getObjectManager();
  5075.  
  5076. HashTable<String, uint64> names = nameMap->getNames();
  5077. HashTableIterator<String, uint64> iter = names.iterator();
  5078.  
  5079. VectorMap<UnicodeString, int> players;
  5080. uint32 a = STRING_HASHCODE("SceneObject.slottedObjects");
  5081. uint32 b = STRING_HASHCODE("SceneObject.customName");
  5082. uint32 c = STRING_HASHCODE("PlayerObject.jediState");
  5083.  
  5084. while (iter.hasNext()) {
  5085. uint64 creoId = iter.next();
  5086. VectorMap<String, uint64> slottedObjects;
  5087. UnicodeString playerName;
  5088. int state = -1;
  5089.  
  5090. objectManager->getPersistentObjectsSerializedVariable<VectorMap<String, uint64> >(a, &slottedObjects, creoId);
  5091. objectManager->getPersistentObjectsSerializedVariable<UnicodeString>(b, &playerName, creoId);
  5092.  
  5093. uint64 ghostId = slottedObjects.get("ghost");
  5094.  
  5095. if (ghostId == 0) {
  5096. continue;
  5097. }
  5098.  
  5099. objectManager->getPersistentObjectsSerializedVariable<int>(c, &state, ghostId);
  5100.  
  5101. if (state >= 4) {
  5102. players.put(playerName, state);
  5103. }
  5104. }
  5105.  
  5106. ManagedReference<SuiListBox*> listBox = new SuiListBox(player, SuiWindowType::ADMIN_FRSLIST);
  5107. listBox->setPromptTitle("Force Ranking System List");
  5108. listBox->setPromptText("This is a list of all characters within the Force Ranking System (Name - State).");
  5109. listBox->setCancelButton(true, "@cancel");
  5110.  
  5111. for (int i = 0; i < players.size(); i++) {
  5112. listBox->addMenuItem(players.elementAt(i).getKey().toString() + " - " + String::valueOf(players.get(i)));
  5113. }
  5114.  
  5115. Locker locker(player);
  5116.  
  5117. player->getPlayerObject()->closeSuiWindowType(SuiWindowType::ADMIN_FRSLIST);
  5118.  
  5119. player->getPlayerObject()->addSuiBox(listBox);
  5120. player->sendMessage(listBox->generateMessage());
  5121. }
  5122.  
  5123. void PlayerManagerImplementation::sendAdminList(CreatureObject* player) {
  5124. Reference<ObjectManager*> objectManager = player->getZoneServer()->getObjectManager();
  5125.  
  5126. HashTable<String, uint64> names = nameMap->getNames();
  5127. HashTableIterator<String, uint64> iter = names.iterator();
  5128.  
  5129. VectorMap<UnicodeString, int> players;
  5130. uint32 a = STRING_HASHCODE("SceneObject.slottedObjects");
  5131. uint32 b = STRING_HASHCODE("SceneObject.customName");
  5132. uint32 c = STRING_HASHCODE("PlayerObject.adminLevel");
  5133.  
  5134. while (iter.hasNext()) {
  5135. uint64 creoId = iter.next();
  5136. VectorMap<String, uint64> slottedObjects;
  5137. UnicodeString playerName;
  5138. int state = -1;
  5139.  
  5140. objectManager->getPersistentObjectsSerializedVariable<VectorMap<String, uint64> >(a, &slottedObjects, creoId);
  5141. objectManager->getPersistentObjectsSerializedVariable<UnicodeString>(b, &playerName, creoId);
  5142.  
  5143. uint64 ghostId = slottedObjects.get("ghost");
  5144.  
  5145. if (ghostId == 0) {
  5146. continue;
  5147. }
  5148.  
  5149. objectManager->getPersistentObjectsSerializedVariable<int>(c, &state, ghostId);
  5150.  
  5151. if (state != 0) {
  5152. players.put(playerName, state);
  5153. }
  5154. }
  5155.  
  5156. ManagedReference<SuiListBox*> listBox = new SuiListBox(player, SuiWindowType::ADMIN_LIST);
  5157. listBox->setPromptTitle("Admin List");
  5158. listBox->setPromptText("This is a list of all characters with a admin level of 1 or greater (Name - State).");
  5159. listBox->setCancelButton(true, "@cancel");
  5160.  
  5161. for (int i = 0; i < players.size(); i++) {
  5162. listBox->addMenuItem(players.elementAt(i).getKey().toString() + " - " + String::valueOf(players.get(i)));
  5163. }
  5164.  
  5165. Locker locker(player);
  5166.  
  5167. player->getPlayerObject()->closeSuiWindowType(SuiWindowType::ADMIN_LIST);
  5168.  
  5169. player->getPlayerObject()->addSuiBox(listBox);
  5170. player->sendMessage(listBox->generateMessage());
  5171. }
  5172.  
  5173. void PlayerManagerImplementation::doPvpDeathRatingUpdate(CreatureObject* player, ThreatMap* threatMap) {
  5174. PlayerObject* ghost = player->getPlayerObject();
  5175.  
  5176. if (ghost == NULL)
  5177. return;
  5178.  
  5179. uint32 totalDamage = threatMap->getTotalDamage();
  5180. int defenderPvpRating = ghost->getPvpRating();
  5181. int victimRatingTotalDelta = 0;
  5182. ManagedReference<CreatureObject*> highDamageAttacker = NULL;
  5183. uint32 highDamageAmount = 0;
  5184.  
  5185. for (int i = 0; i < threatMap->size(); ++i) {
  5186. ThreatMapEntry* entry = &threatMap->elementAt(i).getValue();
  5187. CreatureObject* attacker = threatMap->elementAt(i).getKey();
  5188.  
  5189. if (entry == NULL || attacker == NULL || attacker == player || !attacker->isPlayerCreature())
  5190. continue;
  5191.  
  5192. if (player->getDistanceTo(attacker) > 80.f)
  5193. continue;
  5194.  
  5195. PlayerObject* attackerGhost = attacker->getPlayerObject();
  5196.  
  5197. if (attackerGhost == NULL)
  5198. continue;
  5199.  
  5200. int curAttackerRating = attackerGhost->getPvpRating();
  5201.  
  5202. if (highDamageAmount == 0 || entry->getTotalDamage() > highDamageAmount) {
  5203. highDamageAmount = entry->getTotalDamage();
  5204. highDamageAttacker = attacker;
  5205. }
  5206.  
  5207. if (ghost->hasOnKillerList(attacker->getObjectID())) {
  5208. String stringFile;
  5209.  
  5210. if (attacker->getSpecies() == CreatureObject::TRANDOSHAN)
  5211. stringFile = "rating_throttle_trandoshan_winner";
  5212. else
  5213. stringFile = "rating_throttle_winner";
  5214.  
  5215. StringIdChatParameter toAttacker;
  5216. toAttacker.setStringId("pvp_rating", stringFile);
  5217. toAttacker.setTT(player->getFirstName());
  5218. toAttacker.setTU(attacker->getObjectID());
  5219. toAttacker.setDI(curAttackerRating);
  5220.  
  5221. attacker->sendSystemMessage(toAttacker);
  5222. continue;
  5223. }
  5224.  
  5225. ghost->addToKillerList(attacker->getObjectID());
  5226.  
  5227. if (defenderPvpRating <= PlayerObject::PVP_RATING_FLOOR) {
  5228. String stringFile;
  5229. if (attacker->getSpecies() == CreatureObject::TRANDOSHAN)
  5230. stringFile = "rating_floor_trandoshan_winner";
  5231. else
  5232. stringFile = "rating_floor_winner";
  5233.  
  5234. StringIdChatParameter toAttacker;
  5235. toAttacker.setStringId("pvp_rating", stringFile);
  5236. toAttacker.setTT(player->getFirstName());
  5237. toAttacker.setDI(curAttackerRating);
  5238.  
  5239. attacker->sendSystemMessage(toAttacker);
  5240.  
  5241. continue;
  5242. }
  5243.  
  5244. float damageContribution = (float) entry->getTotalDamage() / totalDamage;
  5245.  
  5246. int attackerRatingDelta = 20 + ((curAttackerRating - defenderPvpRating) / 25);
  5247. int victimRatingDelta = -20 + ((defenderPvpRating - curAttackerRating) / 25);
  5248.  
  5249. if (attackerRatingDelta > 40)
  5250. attackerRatingDelta = 40;
  5251. else if (attackerRatingDelta < 0)
  5252. attackerRatingDelta = 0;
  5253.  
  5254. if (victimRatingDelta < -40)
  5255. victimRatingDelta = -40;
  5256. else if (victimRatingDelta > 0)
  5257. victimRatingDelta = 0;
  5258.  
  5259. attackerRatingDelta *= damageContribution;
  5260. victimRatingDelta *= damageContribution;
  5261.  
  5262. victimRatingTotalDelta += victimRatingDelta;
  5263. int newRating = curAttackerRating + attackerRatingDelta;
  5264.  
  5265. Locker crossLock(attacker, player);
  5266.  
  5267. attackerGhost->setPvpRating(newRating);
  5268.  
  5269. crossLock.release();
  5270.  
  5271. String stringFile;
  5272.  
  5273. int randNum = System::random(2) + 1;
  5274. if (attacker->getSpecies() == CreatureObject::TRANDOSHAN)
  5275. stringFile = "trandoshan_win" + String::valueOf(randNum);
  5276. else
  5277. stringFile = "win" + String::valueOf(randNum);
  5278.  
  5279. StringIdChatParameter toAttacker;
  5280. toAttacker.setStringId("pvp_rating", stringFile);
  5281. toAttacker.setTT(player->getFirstName());
  5282. toAttacker.setDI(newRating);
  5283.  
  5284. attacker->sendSystemMessage(toAttacker);
  5285. }
  5286.  
  5287. if (highDamageAttacker == NULL)
  5288. return;
  5289.  
  5290. if (defenderPvpRating <= PlayerObject::PVP_RATING_FLOOR) {
  5291. String stringFile;
  5292. if (player->getSpecies() == CreatureObject::TRANDOSHAN)
  5293. stringFile = "rating_floor_trandoshan_loser";
  5294. else
  5295. stringFile = "rating_floor_victim";
  5296.  
  5297. StringIdChatParameter toVictim;
  5298. toVictim.setStringId("pvp_rating", stringFile);
  5299. toVictim.setTT(highDamageAttacker->getFirstName());
  5300. toVictim.setDI(defenderPvpRating);
  5301.  
  5302. player->sendSystemMessage(toVictim);
  5303. } else if (victimRatingTotalDelta != 0) {
  5304. int newDefenderRating = defenderPvpRating + victimRatingTotalDelta;
  5305. ghost->setPvpRating(newDefenderRating);
  5306.  
  5307. String stringFile;
  5308.  
  5309. int randNum = System::random(2) + 1;
  5310. if (player->getSpecies() == CreatureObject::TRANDOSHAN)
  5311. stringFile = "trandoshan_killed" + String::valueOf(randNum);
  5312. else
  5313. stringFile = "killed" + String::valueOf(randNum);
  5314.  
  5315. StringIdChatParameter toVictim;
  5316. toVictim.setStringId("pvp_rating", stringFile);
  5317. toVictim.setTT(highDamageAttacker->getFirstName());
  5318. toVictim.setDI(newDefenderRating);
  5319.  
  5320. player->sendSystemMessage(toVictim);
  5321. } else {
  5322. String stringFile;
  5323.  
  5324. if (player->getSpecies() == CreatureObject::TRANDOSHAN)
  5325. stringFile = "rating_throttle_trandoshan_loser";
  5326. else
  5327. stringFile = "rating_throttle_loser";
  5328.  
  5329. StringIdChatParameter toVictim;
  5330. toVictim.setStringId("pvp_rating", stringFile);
  5331. toVictim.setTT(highDamageAttacker->getFirstName());
  5332. toVictim.setDI(defenderPvpRating);
  5333.  
  5334. player->sendSystemMessage(toVictim);
  5335. }
  5336. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement