TradeSession.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. package me.lethunderhawk.tradeplugin.trade;
  2. import me.lethunderhawk.economy.EconomyModule;
  3. import me.lethunderhawk.main.Main;
  4. import me.lethunderhawk.main.util.ItalicDeco;
  5. import me.lethunderhawk.tradeplugin.TradeModule;
  6. import net.kyori.adventure.audience.Audience;
  7. import net.kyori.adventure.text.Component;
  8. import net.kyori.adventure.text.format.NamedTextColor;
  9. import org.bukkit.NamespacedKey;
  10. import org.bukkit.entity.Player;
  11. import org.bukkit.inventory.Inventory;
  12. import org.bukkit.inventory.ItemStack;
  13. import org.bukkit.inventory.meta.ItemMeta;
  14. import org.bukkit.inventory.meta.SkullMeta;
  15. import org.bukkit.persistence.PersistentDataContainer;
  16. import org.bukkit.persistence.PersistentDataType;
  17. import java.util.ArrayList;
  18. import java.util.List;
  19. import java.util.UUID;
  20. public class TradeSession {
  21. private final Player p1;
  22. private final Player p2;
  23. private final List<ItemStack> p1Items = new ArrayList<>();
  24. private final List<ItemStack> p2Items = new ArrayList<>();
  25. private static final NamespacedKey FLUX_KEY =
  26. new NamespacedKey(Main.getInstance(), "flux_item");
  27. private static final NamespacedKey OWNER_KEY =
  28. new NamespacedKey(Main.getInstance(), "flux_owner");
  29. private static final NamespacedKey VALUE_KEY =
  30. new NamespacedKey(Main.getInstance(), "flux_value");
  31. private TradeState state = TradeState.WAITING;
  32. private int p1Flux = 0, p2Flux = 0;
  33. private final TradeInventory inventory;
  34. public TradeSession(Player p1, Player p2) {
  35. this.p1 = p1;
  36. this.p2 = p2;
  37. this.inventory = new TradeInventory(this);
  38. p1.openInventory(inventory.getInventoryFor(p1));
  39. p2.openInventory(inventory.getInventoryFor(p2));
  40. }
  41. /**
  42. * @return if the player has already accepted
  43. */
  44. public boolean accept(Player p) {
  45. if (p.equals(p1)) {
  46. if(state == TradeState.ACCEPTED_P1){
  47. return true;
  48. }
  49. state = state == TradeState.ACCEPTED_P2 ? TradeState.COMPLETED : TradeState.ACCEPTED_P1;
  50. updateInventories();
  51. } else if(p.equals(p2)){
  52. if(state == TradeState.ACCEPTED_P2){
  53. return true;
  54. }
  55. state = state == TradeState.ACCEPTED_P1 ? TradeState.COMPLETED : TradeState.ACCEPTED_P2;
  56. updateInventories();
  57. }
  58. return false;
  59. }
  60. public void undoAccept(Player p){
  61. if (p.equals(p1)) {
  62. state = state == TradeState.ACCEPTED_P1 ? TradeState.WAITING : TradeState.ACCEPTED_P1;
  63. updateInventories();
  64. } else if(p.equals(p2)){
  65. state = state == TradeState.ACCEPTED_P2 ? TradeState.WAITING : TradeState.ACCEPTED_P2;
  66. updateInventories();
  67. }
  68. }
  69. private void updateInventories() {
  70. inventory.updateInventory(state);
  71. }
  72. public boolean addItem(Player p, ItemStack item) {
  73. if(item == null) return false;
  74. if (p.equals(p1)) {
  75. if(inventory.addItem(p1, item, true)
  76. && inventory.addItem(p2, item, false)){
  77. p1Items.add(item);
  78. return true;
  79. }
  80. } else if(p.equals(p2)){
  81. if(inventory.addItem(p2, item, true)
  82. && inventory.addItem(p1, item, false)){
  83. p2Items.add(item);
  84. return true;
  85. }
  86. }
  87. return false;
  88. }
  89. public boolean addCosmeticItem(Player p, ItemStack item) {
  90. if(item == null) return false;
  91. if (p.equals(p1)) {
  92. return inventory.addItem(p1, item, true)
  93. && inventory.addItem(p2, item, false);
  94. } else if(p.equals(p2)){
  95. return inventory.addItem(p2, item, true)
  96. && inventory.addItem(p1, item, false);
  97. }
  98. return false;
  99. }
  100. public void complete() {
  101. sendTradeCompletedMsg();
  102. for (ItemStack item : p1Items) {
  103. if(item != null){
  104. p2.getInventory().addItem(item);
  105. }
  106. }
  107. for (ItemStack item : p2Items) {
  108. if(item != null) {
  109. p1.getInventory().addItem(item);
  110. }
  111. }
  112. transferFlux();
  113. p1Items.clear();
  114. p2Items.clear();
  115. }
  116. private void sendReceivingMsg(Audience receiver, Component itemName, int amount){
  117. TradeModule.sendText(receiver, Component.text("+ ", NamedTextColor.GREEN )
  118. .append(itemName.color(NamedTextColor.GRAY))
  119. .append(Component.text((amount> 1 ? " x" + amount : ""), NamedTextColor.GRAY)));
  120. }
  121. private void sendGivingMsg(Audience receiver, Component itemName, int amount){
  122. TradeModule.sendText(receiver, Component.text("- ", NamedTextColor.RED )
  123. .append(itemName.color(NamedTextColor.GRAY))
  124. .append(Component.text((amount> 1 ? " x" + amount : ""), NamedTextColor.GRAY)));
  125. }
  126. private void sendTradeCompletedMsg() {
  127. sendTradeCompletedLine(p1, p2);
  128. sendTradeCompletedLine(p2, p1);
  129. sendItemTransfers(p1Items, p1, p2);
  130. sendItemTransfers(p2Items, p2, p1);
  131. sendFluxTransfer(p1Flux, p1, p2);
  132. sendFluxTransfer(p2Flux, p2, p1);
  133. }
  134. private void sendTradeCompletedLine(Player receiver, Player other) {
  135. TradeModule.sendText(receiver,
  136. Component.text("Handel mit ", NamedTextColor.GOLD)
  137. .append(other.displayName().color(NamedTextColor.GRAY))
  138. .append(Component.text(" abgeschlossen!", NamedTextColor.GOLD))
  139. );
  140. }
  141. private void sendItemTransfers(List<ItemStack> items, Audience giver, Audience receiver) {
  142. for (ItemStack item : items) {
  143. if (item == null) continue;
  144. sendGivingMsg(giver, item.displayName(), item.getAmount());
  145. sendReceivingMsg(receiver, item.displayName(), item.getAmount());
  146. }
  147. }
  148. private void sendFluxTransfer(int flux, Audience giver, Audience receiver) {
  149. if (flux <= 0) return;
  150. Component fluxComp = Component.text(flux)
  151. .append(Component.text(" Flux"));
  152. sendGivingMsg(giver, fluxComp, 1);
  153. sendReceivingMsg(receiver, fluxComp, 1);
  154. }
  155. private void transferFlux() {
  156. if(p2Flux > 0){
  157. EconomyModule.getInstance().getEconomyAPI().pay(p2.getUniqueId(), p1.getUniqueId(), p2Flux);
  158. }
  159. if(p1Flux > 0){
  160. EconomyModule.getInstance().getEconomyAPI().pay(p1.getUniqueId(), p2.getUniqueId(), p1Flux);
  161. }
  162. }
  163. public void decline() {
  164. for (ItemStack item : p1Items) {
  165. if(item != null){
  166. p1.getInventory().addItem(item);
  167. }
  168. }
  169. for (ItemStack item : p2Items) {
  170. if(item != null) {
  171. p2.getInventory().addItem(item);
  172. }
  173. }
  174. p1Items.clear();
  175. p2Items.clear();
  176. }
  177. public Player getP1() { return p1; }
  178. public Player getP2() { return p2; }
  179. public TradeInventory getTradeInventory() { return inventory; }
  180. public TradeState getTradeState() {
  181. return state;
  182. }
  183. public void removeItem(Player p, ItemStack item, int mySlot) {
  184. if(item == null) return;
  185. if (p.equals(p1)) {
  186. if(inventory.removeItem(p1, item, mySlot)){
  187. p1Items.remove(item);
  188. }
  189. } else if(p.equals(p2)){
  190. if(inventory.removeItem(p2, item, mySlot)){
  191. p2Items.remove(item);
  192. }
  193. }
  194. }
  195. public void setTradeState(TradeState state) {
  196. this.state = state;
  197. }
  198. public int getMoneyFor(Player p) {
  199. if(p1.getUniqueId().equals(p.getUniqueId())){
  200. return p1Flux;
  201. }
  202. if(p2.getUniqueId().equals(p.getUniqueId())){
  203. return p2Flux;
  204. }
  205. return 0;
  206. }
  207. public boolean addFluxValue(Player player, int value) {
  208. if(p1.getUniqueId().equals(player.getUniqueId())){
  209. if(addCosmeticItem(p1, getCosmeticFlux(p1, value))){
  210. p1Flux += value;
  211. refreshAllFlux();
  212. return true;
  213. }
  214. }else if(p2.getUniqueId().equals(player.getUniqueId())){
  215. if(addCosmeticItem(p2, getCosmeticFlux(p2, value))){
  216. p2Flux += value;
  217. refreshAllFlux();
  218. return true;
  219. }
  220. }
  221. return false;
  222. }
  223. public ItemStack getCosmeticFlux(Player owner, int value) {
  224. ItemStack item = TradeInventory.getFluxItemStack();
  225. SkullMeta meta = (SkullMeta) item.getItemMeta();
  226. meta.displayName(ItalicDeco.remove(Component.text(value + " Flux", NamedTextColor.GOLD)));
  227. meta.getPersistentDataContainer().set(FLUX_KEY, PersistentDataType.INTEGER, 1);
  228. meta.getPersistentDataContainer().set(OWNER_KEY, PersistentDataType.STRING, owner.getUniqueId().toString());
  229. meta.getPersistentDataContainer().set(VALUE_KEY, PersistentDataType.INTEGER, value);
  230. int total = TradeModule.getTradeManager()
  231. .getSession(owner)
  232. .getMoneyFor(owner);
  233. meta.lore(List.of(
  234. ItalicDeco.remove(Component.text("Lup-sum amount", NamedTextColor.GRAY)),
  235. ItalicDeco.remove(Component.text("", NamedTextColor.GRAY)),
  236. ItalicDeco.remove(Component.text("Total Flux Offered: ", NamedTextColor.GOLD)),
  237. ItalicDeco.remove(Component.text(String.valueOf(total), NamedTextColor.GRAY))
  238. ));
  239. item.setItemMeta(meta);
  240. return item;
  241. }
  242. public void refreshFluxItems(Inventory inv) {
  243. for (int i = 0; i < inv.getSize(); i++) {
  244. ItemStack item = inv.getItem(i);
  245. if (item == null) continue;
  246. ItemMeta meta = item.getItemMeta();
  247. if (meta == null) continue;
  248. PersistentDataContainer pdc = meta.getPersistentDataContainer();
  249. if (!pdc.has(FLUX_KEY, PersistentDataType.INTEGER)) continue;
  250. UUID ownerId = UUID.fromString(pdc.get(OWNER_KEY, PersistentDataType.STRING));
  251. int value = pdc.get(VALUE_KEY, PersistentDataType.INTEGER);
  252. Player owner = ownerId.equals(getP1().getUniqueId())
  253. ? getP1()
  254. : getP2();
  255. inv.setItem(i, getCosmeticFlux(owner, value));
  256. }
  257. }
  258. /**
  259. *
  260. * @param p The Player who is not the viewer
  261. * @return The Player who is the viewer
  262. */
  263. public Player getViewer(Player p){
  264. if(p.equals(p1)) {
  265. return p2;
  266. }else if(p.equals(p2)) {
  267. return p1;
  268. }
  269. return null;
  270. }
  271. public static NamespacedKey getFluxKey(){
  272. return FLUX_KEY;
  273. }
  274. public static NamespacedKey getOwnerKey(){
  275. return OWNER_KEY;
  276. }
  277. public static NamespacedKey getValueKey(){
  278. return VALUE_KEY;
  279. }
  280. public void removeFlux(Player p, int value) {
  281. if (p.equals(p1)) {
  282. p1Flux -= value;
  283. if (p1Flux < 0) p1Flux = 0;
  284. } else if (p.equals(p2)) {
  285. p2Flux -= value;
  286. if (p2Flux < 0) p2Flux = 0;
  287. }
  288. }
  289. public void refreshAllFlux() {
  290. refreshFluxItems(inventory.getInventoryFor(p1));
  291. refreshFluxItems(inventory.getInventoryFor(p2));
  292. }
  293. public boolean isP1(Player p) {
  294. return p1.equals(p);
  295. }
  296. }