Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2015
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.81 KB | None | 0 0
  1. /**
  2. * The Forgotten Server - a free and open-source MMORPG server emulator
  3. * Copyright (C) 2014 Mark Samman <mark.samman@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. */
  19.  
  20. #include "otpch.h"
  21.  
  22. #include "party.h"
  23. #include "player.h"
  24. #include "game.h"
  25. #include "configmanager.h"
  26. #include "events.h"
  27.  
  28. extern Game g_game;
  29. extern ConfigManager g_config;
  30. extern Events* g_events;
  31.  
  32. Party::Party(Player* _leader)
  33. {
  34. sharedExpActive = false;
  35. sharedExpEnabled = false;
  36.  
  37. if (_leader) {
  38. setLeader(_leader);
  39. _leader->setParty(this);
  40. }
  41. }
  42.  
  43. Party::~Party()
  44. {
  45. //
  46. }
  47.  
  48. void Party::disband()
  49. {
  50. if (!g_events->eventPartyOnDisband(this)) {
  51. return;
  52. }
  53.  
  54. Player* currentLeader = leader;
  55. setLeader(nullptr);
  56.  
  57. currentLeader->setParty(nullptr);
  58. currentLeader->sendClosePrivate(CHANNEL_PARTY);
  59. g_game.updatePlayerShield(currentLeader);
  60. g_game.updatePlayerHelpers(*currentLeader);
  61. currentLeader->sendCreatureSkull(currentLeader);
  62. currentLeader->sendTextMessage(MESSAGE_INFO_DESCR, "Your party has been disbanded.");
  63.  
  64. for (Player* invitee : inviteList) {
  65. invitee->removePartyInvitation(this);
  66. currentLeader->sendCreatureShield(invitee);
  67. }
  68. inviteList.clear();
  69.  
  70. for (Player* member : memberList) {
  71. member->setParty(nullptr);
  72. member->sendClosePrivate(CHANNEL_PARTY);
  73. member->sendTextMessage(MESSAGE_INFO_DESCR, "Your party has been disbanded.");
  74. }
  75.  
  76. for (Player* member : memberList) {
  77. g_game.updatePlayerShield(member);
  78.  
  79. for (Player* otherMember : memberList) {
  80. otherMember->sendCreatureSkull(member);
  81. }
  82.  
  83. member->sendCreatureSkull(currentLeader);
  84. currentLeader->sendCreatureSkull(member);
  85. g_game.updatePlayerHelpers(*member);
  86. }
  87. memberList.clear();
  88. delete this;
  89. }
  90.  
  91. bool Party::leaveParty(Player* player)
  92. {
  93. if (!player) {
  94. return false;
  95. }
  96.  
  97. if (player->getParty() != this && leader != player) {
  98. return false;
  99. }
  100.  
  101. if (!g_events->eventPartyOnLeave(this, player)) {
  102. return false;
  103. }
  104.  
  105. bool missingLeader = false;
  106. if (leader == player) {
  107. if (!memberList.empty()) {
  108. if (memberList.size() == 1 && inviteList.empty()) {
  109. missingLeader = true;
  110. } else {
  111. passPartyLeadership(memberList.front());
  112. }
  113. } else {
  114. missingLeader = true;
  115. }
  116. }
  117.  
  118. //since we already passed the leadership, we remove the player from the list
  119. auto it = std::find(memberList.begin(), memberList.end(), player);
  120. if (it != memberList.end()) {
  121. memberList.erase(it);
  122. }
  123.  
  124. player->setParty(nullptr);
  125. player->sendClosePrivate(CHANNEL_PARTY);
  126. g_game.updatePlayerShield(player);
  127. g_game.updatePlayerHelpers(*player);
  128.  
  129. for (Player* member : memberList) {
  130. member->sendCreatureSkull(player);
  131. player->sendPlayerPartyIcons(member);
  132. g_game.updatePlayerHelpers(*member);
  133. }
  134.  
  135. leader->sendCreatureSkull(player);
  136. player->sendCreatureSkull(player);
  137. player->sendPlayerPartyIcons(leader);
  138.  
  139. player->sendTextMessage(MESSAGE_INFO_DESCR, "You have left the party.");
  140.  
  141. updateSharedExperience();
  142. clearPlayerPoints(player);
  143.  
  144. std::ostringstream ss;
  145. ss << player->getName() << " has left the party.";
  146. broadcastPartyMessage(MESSAGE_INFO_DESCR, ss.str());
  147.  
  148. if (missingLeader || empty()) {
  149. disband();
  150. }
  151.  
  152. return true;
  153. }
  154.  
  155. bool Party::passPartyLeadership(Player* player)
  156. {
  157. if (!player || leader == player || player->getParty() != this) {
  158. return false;
  159. }
  160.  
  161. //Remove it before to broadcast the message correctly
  162. auto it = std::find(memberList.begin(), memberList.end(), player);
  163. if (it != memberList.end()) {
  164. memberList.erase(it);
  165. }
  166.  
  167. std::ostringstream ss;
  168. ss << player->getName() << " is now the leader of the party.";
  169. broadcastPartyMessage(MESSAGE_INFO_DESCR, ss.str(), true);
  170.  
  171. Player* oldLeader = leader;
  172. setLeader(player);
  173.  
  174. memberList.insert(memberList.begin(), oldLeader);
  175.  
  176. updateSharedExperience();
  177.  
  178. for (Player* member : memberList) {
  179. member->sendCreatureShield(oldLeader);
  180. member->sendCreatureShield(leader);
  181. }
  182.  
  183. for (Player* invitee : inviteList) {
  184. invitee->sendCreatureShield(oldLeader);
  185. invitee->sendCreatureShield(leader);
  186. }
  187.  
  188. leader->sendCreatureShield(oldLeader);
  189. leader->sendCreatureShield(leader);
  190.  
  191. player->sendTextMessage(MESSAGE_INFO_DESCR, "You are now the leader of the party.");
  192. return true;
  193. }
  194.  
  195. bool Party::joinParty(Player& player)
  196. {
  197. if (!g_events->eventPartyOnJoin(this, &player)) {
  198. return false;
  199. }
  200.  
  201. auto it = std::find(inviteList.begin(), inviteList.end(), &player);
  202. if (it == inviteList.end()) {
  203. return false;
  204. }
  205.  
  206. inviteList.erase(it);
  207.  
  208. std::ostringstream ss;
  209. ss << player.getName() << " has joined the party.";
  210. broadcastPartyMessage(MESSAGE_INFO_DESCR, ss.str());
  211.  
  212. player.setParty(this);
  213.  
  214. g_game.updatePlayerShield(&player);
  215.  
  216. for (Player* member : memberList) {
  217. member->sendCreatureSkull(&player);
  218. player.sendPlayerPartyIcons(member);
  219. }
  220.  
  221. player.sendCreatureSkull(&player);
  222. leader->sendCreatureSkull(&player);
  223. player.sendPlayerPartyIcons(leader);
  224.  
  225. memberList.push_back(&player);
  226.  
  227. g_game.updatePlayerHelpers(player);
  228.  
  229. player.removePartyInvitation(this);
  230. updateSharedExperience();
  231.  
  232. const std::string& leaderName = leader->getName();
  233. ss.str("");
  234. ss << "You have joined " << leaderName << "'" << (leaderName.back() == 's' ? "" : "s") <<
  235. " party. Open the party channel to communicate with your companions.";
  236. player.sendTextMessage(MESSAGE_INFO_DESCR, ss.str());
  237. return true;
  238. }
  239.  
  240. bool Party::removeInvite(Player& player, bool removeFromPlayer/* = true*/)
  241. {
  242. auto it = std::find(inviteList.begin(), inviteList.end(), &player);
  243. if (it == inviteList.end()) {
  244. return false;
  245. }
  246.  
  247. inviteList.erase(it);
  248.  
  249. leader->sendCreatureShield(&player);
  250. player.sendCreatureShield(leader);
  251.  
  252. if (removeFromPlayer) {
  253. player.removePartyInvitation(this);
  254. }
  255.  
  256. if (empty()) {
  257. disband();
  258. } else {
  259. for (Player* member : memberList) {
  260. g_game.updatePlayerHelpers(*member);
  261. }
  262.  
  263. g_game.updatePlayerHelpers(*leader);
  264. }
  265.  
  266. return true;
  267. }
  268.  
  269. void Party::revokeInvitation(Player& player)
  270. {
  271. std::ostringstream ss;
  272. ss << leader->getName() << " has revoked " << (leader->getSex() == PLAYERSEX_FEMALE ? "her" : "his") << " invitation.";
  273. player.sendTextMessage(MESSAGE_INFO_DESCR, ss.str());
  274.  
  275. ss.str("");
  276. ss << "Invitation for " << player.getName() << " has been revoked.";
  277. leader->sendTextMessage(MESSAGE_INFO_DESCR, ss.str());
  278.  
  279. removeInvite(player);
  280. }
  281.  
  282. bool Party::invitePlayer(Player& player)
  283. {
  284. if (isPlayerInvited(&player)) {
  285. return false;
  286. }
  287.  
  288. std::ostringstream ss;
  289. ss << player.getName() << " has been invited.";
  290.  
  291. if (memberList.empty() && inviteList.empty()) {
  292. ss << " Open the party channel to communicate with your members.";
  293. g_game.updatePlayerShield(leader);
  294. leader->sendCreatureSkull(leader);
  295. }
  296.  
  297. leader->sendTextMessage(MESSAGE_INFO_DESCR, ss.str());
  298.  
  299. inviteList.push_back(&player);
  300.  
  301. for (Player* member : memberList) {
  302. g_game.updatePlayerHelpers(*member);
  303. }
  304. g_game.updatePlayerHelpers(*leader);
  305.  
  306. leader->sendCreatureShield(&player);
  307. player.sendCreatureShield(leader);
  308.  
  309. player.addPartyInvitation(this);
  310.  
  311. ss.str("");
  312. ss << leader->getName() << " has invited you to " << (leader->getSex() == PLAYERSEX_FEMALE ? "her" : "his") << " party.";
  313. player.sendTextMessage(MESSAGE_INFO_DESCR, ss.str());
  314. return true;
  315. }
  316.  
  317. bool Party::isPlayerInvited(const Player* player) const
  318. {
  319. return std::find(inviteList.begin(), inviteList.end(), player) != inviteList.end();
  320. }
  321.  
  322. void Party::updateAllPartyIcons()
  323. {
  324. for (Player* member : memberList) {
  325. for (Player* otherMember : memberList) {
  326. member->sendCreatureShield(otherMember);
  327. }
  328.  
  329. member->sendCreatureShield(leader);
  330. leader->sendCreatureShield(member);
  331. }
  332. leader->sendCreatureShield(leader);
  333. }
  334.  
  335. void Party::broadcastPartyMessage(MessageClasses msgClass, const std::string& msg, bool sendToInvitations /*= false*/)
  336. {
  337. for (Player* member : memberList) {
  338. member->sendTextMessage(msgClass, msg);
  339. }
  340.  
  341. leader->sendTextMessage(msgClass, msg);
  342.  
  343. if (sendToInvitations) {
  344. for (Player* invitee : inviteList) {
  345. invitee->sendTextMessage(msgClass, msg);
  346. }
  347. }
  348. }
  349.  
  350. void Party::broadcastPartyLoot(const std::string& loot)
  351. {
  352. leader->sendTextMessage(MESSAGE_INFO_DESCR, loot);
  353.  
  354. for (Player* member : memberList) {
  355. member->sendTextMessage(MESSAGE_INFO_DESCR, loot);
  356. }
  357. }
  358.  
  359. void Party::updateSharedExperience()
  360. {
  361. if (sharedExpActive) {
  362. bool result = canEnableSharedExperience();
  363.  
  364. if (result != sharedExpEnabled) {
  365. sharedExpEnabled = result;
  366. updateAllPartyIcons();
  367. }
  368. }
  369. }
  370.  
  371. bool Party::setSharedExperience(Player* player, bool _sharedExpActive)
  372. {
  373. if (!player || leader != player) {
  374. return false;
  375. }
  376.  
  377. if (sharedExpActive == _sharedExpActive) {
  378. return true;
  379. }
  380.  
  381. sharedExpActive = _sharedExpActive;
  382.  
  383. if (sharedExpActive) {
  384. sharedExpEnabled = canEnableSharedExperience();
  385.  
  386. if (sharedExpEnabled) {
  387. leader->sendTextMessage(MESSAGE_INFO_DESCR, "Shared Experience is now active.");
  388. } else {
  389. leader->sendTextMessage(MESSAGE_INFO_DESCR, "Shared Experience has been activated, but some members of your party are inactive.");
  390. }
  391. } else {
  392. leader->sendTextMessage(MESSAGE_INFO_DESCR, "Shared Experience has been deactivated.");
  393. }
  394.  
  395. updateAllPartyIcons();
  396. return true;
  397. }
  398.  
  399. void Party::shareExperience(uint64_t experience)
  400. {
  401. uint32_t shareExperience = (uint64_t)std::ceil((((double)experience / (memberList.size() + 1)) + ((double)experience * 0.05)));
  402. for (Player* member : memberList) {
  403. member->onGainSharedExperience(shareExperience);
  404. }
  405. leader->onGainSharedExperience(shareExperience);
  406. }
  407.  
  408. bool Party::canUseSharedExperience(const Player* player) const
  409. {
  410. if (memberList.empty()) {
  411. return false;
  412. }
  413.  
  414. uint32_t highestLevel = leader->getLevel();
  415. for (Player* member : memberList) {
  416. if (member->getLevel() > highestLevel) {
  417. highestLevel = member->getLevel();
  418. }
  419. }
  420.  
  421. uint32_t minLevel = (int32_t)std::ceil(((float)(highestLevel) * 2) / 3);
  422. if (player->getLevel() < minLevel) {
  423. return false;
  424. }
  425.  
  426. const Position& leaderPos = leader->getPosition();
  427. const Position& memberPos = player->getPosition();
  428. if (!Position::areInRange<30, 30, 1>(leaderPos, memberPos)) {
  429. return false;
  430. }
  431.  
  432. if (!player->hasFlag(PlayerFlag_NotGainInFight)) {
  433. //check if the player has healed/attacked anything recently
  434. auto it = pointMap.find(player->getID());
  435. if (it == pointMap.end()) {
  436. return false;
  437. }
  438.  
  439. uint64_t timeDiff = OTSYS_TIME() - it->second.ticks;
  440. if (timeDiff > (uint64_t)g_config.getNumber(ConfigManager::PZ_LOCKED)) {
  441. return false;
  442. }
  443. }
  444. return true;
  445. }
  446.  
  447. bool Party::canEnableSharedExperience()
  448. {
  449. if (!canUseSharedExperience(leader)) {
  450. return false;
  451. }
  452.  
  453. for (Player* member : memberList) {
  454. if (!canUseSharedExperience(member)) {
  455. return false;
  456. }
  457. }
  458. return true;
  459. }
  460.  
  461. void Party::addPlayerHealedMember(Player* player, uint32_t points)
  462. {
  463. if (!player->hasFlag(PlayerFlag_NotGainInFight)) {
  464. if (points > 0) {
  465. auto it = pointMap.find(player->getID());
  466. if (it == pointMap.end()) {
  467. CountBlock_t cb;
  468. cb.ticks = OTSYS_TIME();
  469. cb.totalHeal = points;
  470. cb.totalDamage = 0;
  471. pointMap[player->getID()] = cb;
  472. } else {
  473. it->second.totalHeal += points;
  474. it->second.ticks = OTSYS_TIME();
  475. }
  476. updateSharedExperience();
  477. }
  478. }
  479. }
  480.  
  481. void Party::addPlayerDamageMonster(Player* player, uint32_t points)
  482. {
  483. if (!player->hasFlag(PlayerFlag_NotGainInFight)) {
  484. if (points > 0) {
  485. CountMap::iterator it = pointMap.find(player->getID());
  486. if (it == pointMap.end()) {
  487. CountBlock_t cb;
  488. cb.ticks = OTSYS_TIME();
  489. cb.totalDamage = points;
  490. cb.totalHeal = 0;
  491. pointMap[player->getID()] = cb;
  492. } else {
  493. it->second.totalDamage += points;
  494. it->second.ticks = OTSYS_TIME();
  495. }
  496. updateSharedExperience();
  497. }
  498. }
  499. }
  500.  
  501. void Party::clearPlayerPoints(Player* player)
  502. {
  503. auto it = pointMap.find(player->getID());
  504. if (it != pointMap.end()) {
  505. pointMap.erase(it);
  506. updateSharedExperience();
  507. }
  508. }
  509.  
  510. bool Party::canOpenCorpse(uint32_t ownerId) const
  511. {
  512. if (Player* player = g_game.getPlayerByID(ownerId)) {
  513. return leader->getID() == ownerId || player->getParty() == this;
  514. }
  515. return false;
  516. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement