Pixel PVP Plus

PVP plugin for IdlePixel

目前为 2024-09-21 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Pixel PVP Plus
  3. // @version 1.1.0
  4. // @description PVP plugin for IdlePixel
  5. // @author Dounford
  6. // @license MIT
  7. // @match *://idle-pixel.com/login/play*
  8. // @grant none
  9. // @require https://gf.qytechs.cn/scripts/441206-idlepixel/code/IdlePixel+.js
  10. // @require https://gf.qytechs.cn/scripts/506089-ip-dounford-scripts-styles/code/IP%20Dounford%20Scripts%20Styles.js
  11. // @require https://gf.qytechs.cn/scripts/488260-pixelshop/code/pixelshop.js
  12. // @namespace https://gf.qytechs.cn/users/1175326
  13. // ==/UserScript==
  14. const imagePath = "https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/";
  15. let pvpWebSocket;
  16. let userToken = "";
  17. let username = "";
  18. let boughtPets = [];
  19. let coins = 0;
  20. let titles = [];
  21. let wins = 0;
  22. let currentTitle = "novice";
  23. let currentPet = "calicoCat";
  24. let fightHistory = [];
  25. let enemyAvatar = "";
  26. let heroAvatar = "";
  27. let pets = {
  28. bamboo: {
  29. name: "Bamboo",
  30. level: 0,
  31. xp: 0
  32. },
  33. blackCat: {
  34. name: "Black Cat",
  35. level: 0,
  36. xp: 0
  37. },
  38. blackChicken: {
  39. name: "Black Chicken",
  40. level: 0,
  41. xp: 0
  42. },
  43. blueChicken: {
  44. name: "Blue Chicken",
  45. level: 0,
  46. xp: 0
  47. },
  48. blueMushroom: {
  49. name: "Blue Mushroom",
  50. level: 0,
  51. xp: 0
  52. },
  53. calicoCat: {
  54. name: "Calico Cat",
  55. level: 0,
  56. xp: 0
  57. },
  58. fireSpirit: {
  59. name: "Fire Spirit",
  60. level: 0,
  61. xp: 0
  62. },
  63. goldenChicken: {
  64. name: "Golden Chicken",
  65. level: 0,
  66. xp: 0
  67. },
  68. greenMushroom: {
  69. name: "Green Mushroom",
  70. level: 0,
  71. xp: 0
  72. },
  73. horse: {
  74. name: "Horse",
  75. level: 0,
  76. xp: 0
  77. },
  78. purpleJay: {
  79. name: "Purple Jay",
  80. level: 0,
  81. xp: 0
  82. },
  83. spirit: {
  84. name: "Spirit",
  85. level: 0,
  86. xp: 0
  87. },
  88. whiteBunny: {
  89. name: "White Bunny",
  90. level: 0,
  91. xp: 0
  92. },
  93. whiteCat: {
  94. name: "White Cat",
  95. level: 0,
  96. xp: 0
  97. },
  98. whiteChicken: {
  99. name: "White Chicken",
  100. level: 0,
  101. xp: 0
  102. },
  103. whyChicken: {
  104. name: "Why Chicken",
  105. level: 0,
  106. xp: 0
  107. }
  108. };
  109. const petsSize = {
  110. bamboo: 85,
  111. blackCat: 112,
  112. blackChicken: 85,
  113. blueChicken: 85,
  114. blueMushroom: 85,
  115. calicoCat: 112,
  116. fireSpirit: 85,
  117. goldenChicken: 85,
  118. greenMushroom: 85,
  119. horse: 121,
  120. purpleJay: 85,
  121. spirit: 85,
  122. whiteBunny: 65,
  123. whiteCat: 112,
  124. whiteChicken: 85,
  125. whyChicken: 85
  126. };
  127. const petsWithSpell = ["blackChicken","goldenChicken","spirit","whiteChicken"]
  128. const displayTitles = {
  129. "dounford" : "DOUNFORD",
  130. "contributor" : "Contributor",
  131. "completionist" : "Completionist",
  132. "wizard" : "Wizard",
  133. "aVerySpecialTitle" : "A VERY SPECIAL TITLE",
  134. "bossSlayer" : "BOSS SLAYER",
  135. "monster" : "MONSTER",
  136. "novice" : "Novice",
  137. "apprentice" : "Apprentice",
  138. "expert" : "Expert",
  139. "champion" : "Champion",
  140. "legend" : "LEGEND",
  141. "immortal" : "IMMORTAL",
  142. "" : ""
  143. }
  144. const manaCost = {
  145. heal: 2,
  146. fire: 3,
  147. reflect: 1,
  148. invisibility: 2,
  149. pet: 5
  150. };
  151. const intStats = ["damage", "arrowDamage","speed","defence", "accuracy","magicBonus","maxHp","maxMana","hp","mana"];
  152.  
  153. (function() {
  154. 'use strict';
  155. class pvpPlugin extends IdlePixelPlusPlugin {
  156. constructor() {
  157. super("pvp", {
  158. about: {
  159. name: GM_info.script.name,
  160. version: GM_info.script.version,
  161. author: GM_info.script.author,
  162. description: GM_info.script.description
  163. },
  164. config: [
  165. {
  166. id: "blockFights",
  167. label: "Reject all Fights and Friends requests",
  168. type: "boolean",
  169. default: false
  170. }
  171. ]
  172. });
  173. this.heroContext;
  174. this.enemyContext;
  175. this.fight = {};
  176. this.fighting = false;
  177. this.blockAll = false;
  178. this.blockedUsers = [];
  179. this.currentEnemy = "";
  180. this.fightHitplat = {};
  181. this.options = {
  182. petAlly: true,
  183. coldDay: false,
  184. defender: false,
  185. fireWeakness: false,
  186. iceWeakness: false,
  187. area: "fields",
  188. itRains: false,
  189. mudRain: false,
  190. noRanged: false,
  191. noSpells: false,
  192. darkness: false,
  193. }
  194. }
  195. async onLogin() {
  196. username = IdlePixelPlus.getVar("username");
  197. userToken = localStorage.getItem("dPVP-" + username + "Token") || "";
  198. const petStorage = localStorage.getItem("dPVP-" + username + "pets");
  199. if (petStorage) {
  200. pets = JSON.parse(petStorage);
  201. }
  202. this.addUI();
  203. await this.getData()
  204. this.shopInit();
  205.  
  206. const users = localStorage.getItem('PVP-BlockedUsers');
  207. if (users) {
  208. this.blockedUsers = JSON.parse(users)
  209. this.blockedUsers.forEach((user) => {this.blockPlayer(user)})
  210. }
  211.  
  212. for (let pet in pets) {
  213. document.getElementById("dpvpPetName" + pet).innerHTML = pets[pet].name;
  214. }
  215. const newTitle = localStorage.getItem("dPVP-" + username + "currentTitle");
  216. if (newTitle) {
  217. this.changeTitle(newTitle);
  218. }
  219. const newPet = localStorage.getItem("dPVP-" + username + "currentPet");
  220. if (newPet) {
  221. this.equipPet(newPet);
  222. }
  223. const historyString = localStorage.getItem("dPVP-" + username + "fightHistory");
  224. if (historyString) {
  225. fightHistory = JSON.parse(historyString);
  226. fightHistory.forEach((fight) => {
  227. IdlePixelPlus.plugins.pvp.addFightHistory(fight);
  228. });
  229. }
  230. IdlePixelPlus.plugins.pvp.changeaddFriendFunction()
  231. this.connectWebSocket();
  232. }
  233.  
  234. onConfigsChanged() {
  235. this.blockAll = this.getConfig("blockFights");
  236. }
  237. onCustomMessageReceived(player, content, callbackId) {
  238. if(content.startsWith("friendRequest")) {
  239. if (this.blockAll == false && !this.blockedUsers.includes(player)) {
  240. this.receiveFR(player);
  241. }
  242. };
  243. if(content.startsWith("pvpR:")) {
  244. if (this.fighting == false && this.blockAll == false && !this.blockedUsers.includes(player)) {
  245. this.receivePVPRequest(player,content.slice(5))
  246. }
  247. };
  248. if(content.startsWith("pvpAccept:")) {
  249. if (this.fighting == false && this.currentEnemy == player) {
  250. this.fighting = true;
  251. this.startFight()
  252. }
  253. }
  254. }
  255. onVariableSet(key, valueBefore, valueAfter) {
  256. if (!this.fighting) return;
  257. switch(key) {
  258. case "accuracy":
  259. case "speed":
  260. case "defence":
  261. this.sendNewStats(key, parseInt(valueAfter));
  262. break;
  263. case "head":
  264. case "body":
  265. case "legs":
  266. case "boots":
  267. case "gloves":
  268. case "amulet":
  269. case "shield":
  270. case "weapon":
  271. case "arrows":
  272. this.sendNewStats(key, valueAfter);
  273. break;
  274. case "melee_damage":
  275. this.sendNewStats("damage", parseInt(valueAfter));
  276. break;
  277. case "arrow_damage":
  278. this.sendNewStats("arrowDamage", parseInt(valueAfter));
  279. break;
  280. case "magic_bonus":
  281. this.sendNewStats("magicBonus", parseInt(valueAfter));
  282. break;
  283. }
  284. }
  285.  
  286. sendNewStats(stats, value) {
  287. pvpWebSocket.send("UpdateStats=" + stats + "~" + value);
  288. }
  289.  
  290. async getData() {
  291. try {
  292. const response = await fetch("https://idle-pixel-pvp.vercel.app/player?name=" + username);
  293. const Json = await response.json();
  294. boughtPets = JSON.parse(Json.pets)
  295. coins = Json.coins;
  296. titles = JSON.parse(Json.titles);
  297. wins = Json.wins;
  298.  
  299. if (window['var_chat_tag'] !== undefined && !titles.includes("contributor")) {
  300. fetch("https://idle-pixel-pvp.vercel.app/contributor", {
  301. method: "POST",
  302. headers: {
  303. "Content-Type": "application/json"
  304. },
  305. body: JSON.stringify({name: username})
  306. }).then((response) => {
  307. const Json = response.json();
  308. if (Json.message === "added") {
  309. titles.push("contributor");
  310. document.getElementById("dpvpcontributor").style.display = "";
  311. }
  312. })
  313. }
  314.  
  315. boughtPets.forEach((pet) => {
  316. document.getElementById("dpvp" + pet).style.display = "";
  317. })
  318. titles.forEach((title) => {
  319. document.getElementById("dpvp" + title).style.display = "";
  320. })
  321. } catch (error) {
  322. console.error(error.message);
  323. }
  324.  
  325. try {
  326. const response = await fetch("https://idle-pixel-pvp.vercel.app/petInfo?name=" + username);
  327. const Json = await response.json();
  328. if (Json == "none") return;
  329.  
  330. for (let pet in pets) {
  331. pets[pet].xp = Json[pet];
  332. pets[pet].level = Json[pet] > 24 ? 3 : Json[pet] > 9 ? 2 : 1;
  333. }
  334. } catch (error) {
  335. console.error(error.message);
  336. }
  337. }
  338.  
  339. async buyPet(petName) {
  340. if (userToken !== "") {
  341. const response = await fetch("https://idle-pixel-pvp.vercel.app/pets", {
  342. method: "POST",
  343. headers: {
  344. "Content-Type": "application/json"
  345. },
  346. body: JSON.stringify({name: username, pet: petName, token: userToken})
  347. })
  348. const responseJson = await response.json();
  349. return responseJson.bought
  350. }
  351. }
  352.  
  353. shopInit() {
  354. const moonCoins = {
  355. name: "Moon Coins",
  356. image: imagePath + "moonCoins.png",
  357. value: coins
  358. }
  359. PixelShopPlus.newCoin(moonCoins);
  360. PixelShopPlus.newShop('PVP','Moon Coins',this.buyPet);
  361.  
  362. let pets = [
  363. {
  364. name:"bamboo",
  365. imageUrl: imagePath + "bamboo.png",
  366. coin: "Moon Coins",
  367. price: 10,
  368. tooltipText: "Bamboo",
  369. buyText: "Buy Bamboo",
  370. boughtText: "Bamboo will be your friend forever",
  371. callback: (pet) => {
  372. boughtPets.push(pet);
  373. document.getElementById("dpvp" + pet).style.display = "";
  374. }
  375. },{
  376. name:"blackCat",
  377. imageUrl: imagePath + "blackCat.png",
  378. coin: "Moon Coins",
  379. price: 10,
  380. tooltipText: "Black Cat",
  381. buyText: "Buy Black Cat",
  382. boughtText: "Black Cat will be your friend forever",
  383. callback: (pet) => {
  384. boughtPets.push(pet);
  385. document.getElementById("dpvp" + pet).style.display = "";
  386. }
  387. },
  388. {
  389. name:"blackChicken",
  390. imageUrl: imagePath + "blackChicken.png",
  391. coin: "Moon Coins",
  392. price: 10,
  393. tooltipText: "Black Chicken",
  394. buyText: "Buy Black Chicken",
  395. boughtText: "Black Chicken will be your friend forever",
  396. callback: (pet) => {
  397. boughtPets.push(pet);
  398. document.getElementById("dpvp" + pet).style.display = "";
  399. }
  400. },
  401. {
  402. name: "blueChicken",
  403. imageUrl: imagePath + "blueChicken.png",
  404. coin: "Moon Coins",
  405. price: 10,
  406. tooltipText: "Blue Chicken",
  407. buyText: "Buy Blue Chicken",
  408. boughtText: "Blue Chicken will be your friend forever",
  409. callback: (pet) => {
  410. boughtPets.push(pet);
  411. document.getElementById("dpvp" + pet).style.display = "";
  412. }
  413. },
  414. {
  415. name: "blueMushroom",
  416. imageUrl: imagePath + "blueMushroom.png",
  417. coin: "Moon Coins",
  418. price: 10,
  419. tooltipText: "Blue Mushroom",
  420. buyText: "Buy Blue Mushroom",
  421. boughtText: "Blue Mushroom will be your friend forever",
  422. callback: (pet) => {
  423. boughtPets.push(pet);
  424. document.getElementById("dpvp" + pet).style.display = "";
  425. }
  426. },
  427. {
  428. name: "fireSpirit",
  429. imageUrl: imagePath + "fireSpirit.png",
  430. coin: "Moon Coins",
  431. price: 10,
  432. tooltipText: "Fire Spirit",
  433. buyText: "Buy Fire Spirit",
  434. boughtText: "Fire Spirit will be your friend forever",
  435. callback: (pet) => {
  436. boughtPets.push(pet);
  437. document.getElementById("dpvp" + pet).style.display = "";
  438. }
  439. },
  440. {
  441. name: "goldenChicken",
  442. imageUrl: imagePath + "goldenChicken.png",
  443. coin: "Moon Coins",
  444. price: 25,
  445. tooltipText: "Golden Chicken",
  446. buyText: "Buy Golden Chicken",
  447. boughtText: "Golden Chicken will be your friend forever",
  448. callback: (pet) => {
  449. boughtPets.push(pet);
  450. document.getElementById("dpvp" + pet).style.display = "";
  451. }
  452. },
  453. {
  454. name: "greenMushroom",
  455. imageUrl: imagePath + "greenMushroom.png",
  456. coin: "Moon Coins",
  457. price: 10,
  458. tooltipText: "Green Mushroom",
  459. buyText: "Buy Green Mushroom",
  460. boughtText: "Green Mushroom will be your friend forever",
  461. callback: (pet) => {
  462. boughtPets.push(pet);
  463. document.getElementById("dpvp" + pet).style.display = "";
  464. }
  465. },
  466. {
  467. name: "horse",
  468. imageUrl: imagePath + "horse.png",
  469. coin: "Moon Coins",
  470. price: 10,
  471. tooltipText: "Horse",
  472. buyText: "Buy Horse",
  473. boughtText: "Horse will be your friend forever",
  474. callback: (pet) => {
  475. boughtPets.push(pet);
  476. document.getElementById("dpvp" + pet).style.display = "";
  477. }
  478. },
  479. {
  480. name: "purpleJay",
  481. imageUrl: imagePath + "purpleJay.png",
  482. coin: "Moon Coins",
  483. price: 10,
  484. tooltipText: "Purple Jay",
  485. buyText: "Buy Purple Jay",
  486. boughtText: "Purple Jay will be your friend forever",
  487. callback: (pet) => {
  488. boughtPets.push(pet);
  489. document.getElementById("dpvp" + pet).style.display = "";
  490. }
  491. },
  492. {
  493. name: "spirit",
  494. imageUrl: imagePath + "spirit.png",
  495. coin: "Moon Coins",
  496. price: 10,
  497. tooltipText: "Spirit",
  498. buyText: "Buy Spirit",
  499. boughtText: "Spirit will be your friend forever",
  500. callback: (pet) => {
  501. boughtPets.push(pet);
  502. document.getElementById("dpvp" + pet).style.display = "";
  503. }
  504. },
  505. {
  506. name: "whiteBunny",
  507. imageUrl: imagePath + "whiteBunny.png",
  508. coin: "Moon Coins",
  509. price: 10,
  510. tooltipText: "White Bunny",
  511. buyText: "Buy White Bunny",
  512. boughtText: "White Bunny will be your friend forever",
  513. callback: (pet) => {
  514. boughtPets.push(pet);
  515. document.getElementById("dpvp" + pet).style.display = "";
  516. }
  517. },
  518. {
  519. name:"whiteCat",
  520. imageUrl: imagePath + "whiteCat.png",
  521. coin: "Moon Coins",
  522. price: 10,
  523. tooltipText: "White Cat",
  524. buyText: "Buy White Cat",
  525. boughtText: "White Cat will be your friend forever",
  526. callback: (pet) => {
  527. boughtPets.push(pet);
  528. document.getElementById("dpvp" + pet).style.display = "";
  529. }
  530. },
  531. {
  532. name:"whiteChicken",
  533. imageUrl: imagePath + "whiteChicken.png",
  534. coin: "Moon Coins",
  535. price: 10,
  536. tooltipText: "White Chicken",
  537. buyText: "Buy White Chicken",
  538. boughtText: "White Chicken will be your friend forever",
  539. callback: (pet) => {
  540. boughtPets.push(pet);
  541. document.getElementById("dpvp" + pet).style.display = "";
  542. }
  543. },
  544. {
  545. name:"whyChicken",
  546. imageUrl: imagePath + "whyChicken.png",
  547. coin: "Moon Coins",
  548. price: 10,
  549. tooltipText: "Why Chicken",
  550. buyText: "Buy Why Chicken",
  551. boughtText: "You will be doomed forever",
  552. callback: (pet) => {
  553. boughtPets.push(pet);
  554. document.getElementById("dpvp" + pet).style.display = "";
  555. }
  556. }
  557. ]
  558.  
  559. pets = pets.filter((pet)=>{
  560. if (!boughtPets.includes(pet.name)) {
  561. return pet
  562. }
  563. })
  564.  
  565. PixelShopPlus.newItems("PVP", pets)
  566. }
  567.  
  568. newModal(id, title, acceptFunction, acceptText, cancelText, body, hiddenInputs = []) {
  569. let modal = document.createElement('dialog');
  570. modal.classList.add('dounfordModal');
  571. modal.id = id;
  572. modal.setAttribute('onclick','event.target==this && this.close()');
  573. let modalHTML = `<div class="dounfordModalHeader">
  574. <h5 class="modal-title text-secondary">${title}</h5>
  575. <button type="button" class="btn-close" onclick="this.parentNode.parentNode.close()"></button>`
  576. hiddenInputs.forEach((input) => {
  577. modalHTML += `<input type="hidden" id="${input}">`
  578. })
  579. modalHTML += `</div>
  580. <div class="dounfordModalBody">`
  581. if(body !== "") {
  582. modalHTML += body
  583. }
  584. modalHTML += "</div>"
  585. if(acceptText !== "disabled") {
  586. modalHTML += `<div class="dounfordModalFooter">
  587. <button onclick="this.parentNode.parentNode.close()">
  588. <span class="font-pixel hover">${cancelText}</span>
  589. </button>
  590. <button class="background-primary float-end" onclick="${acceptFunction}">
  591. <span class="font-pixel hover">${acceptText}</span>
  592. </button>
  593. </div>`}
  594. modal.innerHTML = modalHTML
  595. document.getElementById('content').insertAdjacentElement('beforeend', modal);
  596. }
  597.  
  598. addUI() {
  599. //Friend Request Modal
  600. this.newModal(
  601. "friendRequest", "Friend Request", "IdlePixelPlus.plugins.pvp.acceptFR()", "Accept Friend Request", "Ignore", `<b><span id="friendRequestFriend">Player</span></b> wants to be your friend.`, ["friendRequestName"]
  602. )
  603.  
  604. //Block List Modal
  605. this.newModal(
  606. "blockListModal", "Block List", "", "disabled", "",
  607. `<div class="blockedUser">
  608. <input type="text" id="pvpBlockUser" placeholder="Block User">
  609. <button class="background-primary rounded" onclick="IdlePixelPlus.plugins.pvp.blockPlayer()">Block</button>
  610. </div>
  611. <br>`, []
  612. )
  613. //PVP Tab
  614. const pvpPanel = `<div style="text-align:center;">
  615. <button onclick="document.getElementById('sendPVPModal').showModal()" class="btn btn-success">
  616. <span class="font-pixel font-large hover">Fight</span>
  617. </button><button onclick="document.getElementById('pvpLobbyModal').showModal()" class="btn btn-info" style="margin-left: 10px;margin-right: 6px;">
  618. <span class="font-pixel font-large hover">LOBBY</span>
  619. </button>
  620. <button onclick="document.getElementById('blockListModal').showModal()" class="btn btn-danger">
  621. <span class="font-pixel font-large hover">Block List</span>
  622. </button>
  623. </div>
  624. <br>
  625. <div class="dounfordPVPGrid">
  626. <div style="background-color: darkturquoise;color: black;padding: 10px">
  627. <h3>PETS</h3>
  628. <div id="dounfordPVPPets" style="display: grid;grid-template-columns: 1fr 1fr 1fr;gap: 10px;">
  629. <div id="dpvpbamboo" onclick="IdlePixelPlus.plugins.pvp.openPetModal('bamboo')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Start with less hp, but gets more when reviving">
  630. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/Bamboo.png">
  631. <span id="dpvpPetNamebamboo">Bamboo</span>
  632. </div>
  633. <div id="dpvpblackCat" onclick="IdlePixelPlus.plugins.pvp.openPetModal('blackCat')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Spells may fail or be more powerful">
  634. <img src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/BlackCat.png" style="height: 50px;">
  635. <span id="dpvpPetNameblackCat">Black Cat</span>
  636. </div>
  637. <div id="dpvpblackChicken" onclick="IdlePixelPlus.plugins.pvp.openPetModal('blackChicken')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Can be eaten or befriended for a new spell">
  638. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/BlackChicken.png">
  639. <span id="dpvpPetNameblackChicken">Black Chicken</span>
  640. </div>
  641. <div id="dpvpblueChicken" onclick="IdlePixelPlus.plugins.pvp.openPetModal('blueChicken')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Shane would be pround of you, Egg Spell unlocked">
  642. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/BlueChicken.png">
  643. <span id="dpvpPetNameblueChicken">Blue Chicken</span>
  644. </div>
  645. <div id="dpvpblueMushroom" onclick="IdlePixelPlus.plugins.pvp.openPetModal('blueMushroom')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Attacks may fail or hit higher">
  646. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/BlueMushroom.png">
  647. <span id="dpvpPetNameblueMushroom">Blue Mushroom</span>
  648. </div>
  649. <div id="dpvpcalicoCat" onclick="IdlePixelPlus.plugins.pvp.openPetModal('calicoCat')" style="display: none;background-color: bisque" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Isn't it the cutest thing in the world?">
  650. <img src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/CalicoCat.png" style="height: 50px;">
  651. <span id="dpvpPetNamecalicoCat">Calico Cat</span>
  652. </div>
  653. <div id="dpvpfireSpirit" onclick="IdlePixelPlus.plugins.pvp.openPetModal('fireSpirit')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Empower all your attacks with fire">
  654. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/FireSpirit.png">
  655. <span id="dpvpPetNamefireSpirit">Fire Spirit</span>
  656. </div>
  657. <div id="dpvpgoldenChicken" onclick="IdlePixelPlus.plugins.pvp.openPetModal('goldenChicken')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Have you reached perfection? Anyways, Golden Egg Spell unlocked">
  658. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/GoldenChicken.png">
  659. <span id="dpvpPetNamegoldenChicken">Golden Chicken</span>
  660. </div>
  661. <div id="dpvpgreenMushroom" onclick="IdlePixelPlus.plugins.pvp.openPetModal('greenMushroom')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Do I have to explain?">
  662. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/GreenMushroom.png">
  663. <span id="dpvpPetNamegreenMushroom">Green Mushroom</span>
  664. </div>
  665. <div id="dpvphorse" onclick="IdlePixelPlus.plugins.pvp.openPetModal('horse')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Increase your speed">
  666. <img src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/horse.png" style="width:50px">
  667. <span id="dpvpPetNamehorse">Horse</span>
  668. </div>
  669. <div id="dpvppurpleJay" onclick="IdlePixelPlus.plugins.pvp.openPetModal('purpleJay')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="You may dodge some attacks">
  670. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/PurpleJay.png">
  671. <span id="dpvpPetNamepurpleJay">Purple Jay</span>
  672. </div>
  673. <div id="dpvpspirit" onclick="IdlePixelPlus.plugins.pvp.openPetModal('spirit')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Spirit Blast Spell unlocked">
  674. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/Spirit.png">
  675. <span id="dpvpPetNamespirit">Spirit</span>
  676. </div>
  677. <div id="dpvpwhiteBunny" onclick="IdlePixelPlus.plugins.pvp.openPetModal('whiteBunny')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Did you know that at first she would be the trainer in IP Pets script? Since it was scrapped your spells will be too">
  678. <img src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/WhiteBunny.png" style="height: 50px;">
  679. <span id="dpvpPetNamewhiteBunny">White Bunny</span>
  680. </div>
  681. <div id="dpvpwhiteCat" onclick="IdlePixelPlus.plugins.pvp.openPetModal('whiteCat')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Increase almost all of your stats">
  682. <img src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/WhiteCat.png" style="height: 50px;">
  683. <span id="dpvpPetNamewhiteCat">White Cat</span>
  684. </div>
  685. <div id="dpvpwhiteChicken" onclick="IdlePixelPlus.plugins.pvp.openPetModal('whiteChicken')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Egg Spell Unlocked">
  686. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/WhiteChicken.png">
  687. <span id="dpvpPetNamewhiteChicken">White Chicken</span>
  688. </div>
  689. <div id="dpvpwhyChicken" onclick="IdlePixelPlus.plugins.pvp.openPetModal('whyChicken')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="You may hit yourself">
  690. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/WhyChicken.png">
  691. <span id="dpvpPetNamewhyChicken">Why Chicken</span>
  692. </div>
  693. </div>
  694. </div>
  695. <div id="dounfordPVPLogs" style="background-color: aqua;grid-row: 1 / 3;grid-column: 2;padding: 10px;overflow-y: scroll;">
  696. <table style="font-size: 1.5rem;" class="market-history-table">
  697. <thead>
  698. <tr>
  699. <th>Opponent</th>
  700. <th>Outcome</th>
  701. <th>Date</th>
  702. </tr>
  703. </thead>
  704. <tbody id="dPVPLogsBody" style="text-transform: capitalize;"></tbody>
  705. </table>
  706. </div>
  707. <div style="background-color: teal;padding: 10px;">
  708. <h3>TITLES</h3>
  709. <div id="dounfordPVPTitles" style="display: grid;grid-template-columns: 1fr 1fr 1fr;gap: 10px;">
  710. <div id="dpvpdounford" onclick="IdlePixelPlus.plugins.pvp.changeTitle('dounford')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="What kind of person creates a title only for himself? Oh, that is right I did it">
  711. <img class="w50" src="https://cdn.idle-pixel.com/images/tree_sigil_chat.png">
  712. DOUNFORD
  713. </div>
  714. <div id="dpvpcontributor" onclick="IdlePixelPlus.plugins.pvp.changeTitle('contributor')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Thank you for helping the game, you deserve a title for it">
  715. <img class="w50" src="https://cdn.idle-pixel.com/images/donor_coins.png">
  716. Contributor
  717. </div>
  718. <div id="dpvpcompletionist" onclick="IdlePixelPlus.plugins.pvp.changeTitle('completionist')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="I hope you enjoyed the grind">
  719. <img class="w50" style="margin-top:-3px;" src="https://cdn.idle-pixel.com/images/trophy_icon.png">
  720. <span>Completionist</span>
  721. </div>
  722. <div id="dpvpwizard" onclick="IdlePixelPlus.plugins.pvp.changeTitle('wizard')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="Agro is that you?">
  723. <img class="w50" src="https://cdn.idle-pixel.com/images/magic.png">
  724. Wizard
  725. </div>
  726. <div id="dpvpaVerySpecialTitle" onclick="IdlePixelPlus.plugins.pvp.changeTitle('aVerySpecialTitle')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="This will be available in A VERY SPECIAL MOMENT">
  727. <img class="w50" src="https://cdn.idle-pixel.com/images/blood_diamond.png">
  728. A VERY SPECIAL TITLE
  729. </div>
  730. <div id="dpvpbossSlayer" onclick="IdlePixelPlus.plugins.pvp.changeTitle('bossSlayer')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="You defeated the boss">
  731. <img class="w50" src="https://cdn.idle-pixel.com/images/diamond.png">
  732. BOSS SLAYER
  733. </div>
  734. <div id="dpvpmonster" onclick="IdlePixelPlus.plugins.pvp.changeTitle('monster')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="You really ate your pet? Why!?">
  735. <img class="w50" src="https://cdn.idle-pixel.com/images/faradox_gaurdians_notes.png">
  736. MONSTER
  737. </div>
  738. <div id="dpvpnovice" onclick="IdlePixelPlus.plugins.pvp.changeTitle('novice')" style="display: none;background-color: bisque" class="dounfordPVPTitles dounfordHover" dounfordtooltip="You need to start somewhere">
  739. <img class="w50" src="https://cdn.idle-pixel.com/images/chicken_icon.png">
  740. Novice
  741. </div>
  742. <div id="dpvpapprentice" onclick="IdlePixelPlus.plugins.pvp.changeTitle('apprentice')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="You are getting better">
  743. <img class="w50" src="https://cdn.idle-pixel.com/images/skeleton_sword.png">
  744. Apprentice
  745. </div>
  746. <div id="dpvpexpert" onclick="IdlePixelPlus.plugins.pvp.changeTitle('expert')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="I'm sure you can defeat Smitty at this point">
  747. <img class="w50" src="https://cdn.idle-pixel.com/images/poison_stinger_dagger.png">
  748. Expert
  749. </div>
  750. <div id="dpvpchampion" onclick="IdlePixelPlus.plugins.pvp.changeTitle('champion')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="I can't believe someone spend so much time playing with my script, thank you">
  751. <img class="w50" src="https://cdn.idle-pixel.com/images/gold_rapier.png">
  752. Champion
  753. </div>
  754. <div id="dpvplegend" onclick="IdlePixelPlus.plugins.pvp.changeTitle('legend')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="You are one of the few who can be partner with the Lendary Golden Chicken">
  755. <img class="w50" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/goldenChicken.png">
  756. Legend
  757. </div>
  758. <div id="dpvpimmortal" onclick="IdlePixelPlus.plugins.pvp.changeTitle('immortal')" style="display: none" class="dounfordPVPTitles dounfordHover" dounfordtooltip="You is the GOAT, nothing can stop you">
  759. <img class="w50" src="https://cdn.idle-pixel.com/images/dark_sword.png">
  760. Immortal
  761. </div>
  762. </div>
  763. </div>
  764. </div>`
  765. IdlePixelPlus.addPanel("dounfordPVP", "PVP", pvpPanel);
  766.  
  767. const pvpMenuBtn = `
  768. <div onclick="switch_panels('panel-dounfordPVP')" class="hover hover-menu-bar-item left-menu-item">
  769. <table class="game-menu-bar-left-table-btn left-menu-item-other" style="width:100%">
  770. <tbody><tr>
  771. <td style="width:30px;">
  772. <img class="w30" src="https://cdn.idle-pixel.com/images/dark_sword.png">
  773. </td>
  774. <td>
  775. PVP
  776. </td>
  777. </tr>
  778. </tbody></table>
  779. </div>`
  780. document.getElementById('menu-bar-buttons').insertAdjacentHTML('beforeend', pvpMenuBtn);
  781.  
  782. //Pet Modal
  783. this.newModal("dounfordPet","PET","IdlePixelPlus.plugins.pvp.equipPet()","Equip","Close",
  784. `<h4 id="pvpPetDisplayName">PET NAME</h4>
  785. <img id="pvpPetImage" src="" style="height:100px">
  786. <br>
  787. <br>
  788. <input type="text" id="pvpPetNewName" style="margin-right: 0.5rem;border-radius: 0.4rem;" placeholder="New Name">
  789. <button onclick="IdlePixelPlus.plugins.pvp.renamePet()">Rename</button>
  790. <br>
  791. <b>Level </b><span id="dounfordPetLevel">3</span>
  792. <br>
  793. <div id="dounfordPetXP">
  794. <b>XP: </b><span id="dounfordPetXPRequired">0/100</span>
  795. </div>
  796. </div>`,
  797. ['pvpPetName'])
  798.  
  799. //Lobby Modal
  800. const pvpLobbyModal = `<dialog class="dounfordModal" id="pvpLobbyModal" onclick="event.target==this && this.close()" style="width: 900px;">
  801. <div class="dounfordModalHeader">
  802. <h5 class="modal-title text-secondary">Lobby</h5>
  803. <button type="button" class="btn-close" onclick="this.parentNode.parentNode.close()"></button>
  804. </div>
  805. <div id="pvpLobbyBody" class="dounfordModalBody" style="display: grid;grid-template-columns: 32% 32% 32%;height: 500px;overflow-y: auto;font-size: 1.5rem;grid-auto-rows: 100px;overflow-x: hidden;justify-content: space-between;row-gap: 15px;">
  806. </div>
  807. </dialog>`
  808. document.getElementById('content').insertAdjacentHTML('beforeend', pvpLobbyModal);
  809.  
  810.  
  811. //Send PVP Request Modal
  812. const sendPVPBody = `Enter Opponent's Username
  813. <br>
  814. <input type="text" id="sendFightName">
  815. <br>
  816. <br>
  817. <b>Fight Options</b>
  818. <div style="display: grid;grid-template-columns: auto auto auto;grid-gap: 5px;justify-items: start;">
  819. <div>
  820. <input type="checkbox" id="pvpCheck0" checked>
  821. <label for="pvpCheck0" dounfordTooltip="Enables Pets feature">PETS</label>
  822. </div>
  823. <div>
  824. <input type="checkbox" id="pvpCheck1">
  825. <label for="pvpCheck1" dounfordTooltip="Cold damage if you don't use bear/frozen crocodile armor">Cold Day</label>
  826. </div>
  827. <div>
  828. <input type="checkbox" id="pvpCheck2">
  829. <label for="pvpCheck2" dounfordTooltip="-1 hp each attack">Defender</label>
  830. </div>
  831. <div>
  832. <input type="radio" name="pvpWeakness" value="noWeakness" id="pvpNoWeakness" checked>
  833. <label for="pvpNoWeakness">No Weakness</label>
  834. </div>
  835. <div>
  836. <input type="radio" name="pvpWeakness" value="fireWeakness" id="pvpFireWeakness">
  837. <label for="pvpFireWeakness" dounfordTooltip="x2 fire damage">Fire Weakness</label>
  838. </div>
  839. <div>
  840. <input type="radio" name="pvpWeakness" value="iceWeakness" id="pvpIceWeakness">
  841. <label for="pvpIceWeakness" dounfordTooltip="x2 ice damage">Ice Weakness</label>
  842. </div>
  843. <div>
  844. <input type="radio" name="pvpArea" value="fields" id="pvpFields" checked>
  845. <label for="pvpFields">Fields</label>
  846. </div>
  847. <div>
  848. <input type="radio" name="pvpArea" value="mansion" id="pvpMansion">
  849. <label for="pvpMansion" dounfordTooltip="x2 Scythe damage">Haunted Mansion</label>
  850. </div>
  851. <div>
  852. <input type="radio" name="pvpArea" value="beach" id="pvpBeach">
  853. <label for="pvpBeach" dounfordTooltip="x2 Trident damage">Beach</label>
  854. </div>
  855. <div>
  856. <input type="radio" name="pvpRain" value="noRain" id="pvpNoRain" checked>
  857. <label for="pvpNoRain">No Rain</label>
  858. </div>
  859. <div>
  860. <input type="radio" name="pvpRain" value="rain" id="pvpRain">
  861. <label for="pvpRain" dounfordTooltip="Only Rain Amulet will cure">Rain</label>
  862. </div>
  863. <div>
  864. <input type="radio" name="pvpRain" value="mud" id="pvpMud">
  865. <label for="pvpMud" dounfordTooltip="Heavy damage if you don't use invisibility spell">Mud Rain</label>
  866. </div>
  867. <div>
  868. <input type="checkbox" id="pvpCheck3">
  869. <label for="pvpCheck3" dounfordTooltip="Arrows do nothing">No Ranged Weapons</label>
  870. </div>
  871. <div>
  872. <input type="checkbox" id="pvpCheck4">
  873. <label for="pvpCheck4" dounfordTooltip="Spells do nothing">No Spells</label>
  874. </div>
  875. <div>
  876. <input type="checkbox" id="pvpCheck5">
  877. <label for="pvpCheck5" dounfordTooltip="50% hit chance">Darkness</label>
  878. </div>
  879. </div>`
  880. this.newModal(
  881. "sendPVPModal", "Send PVP Request", "IdlePixelPlus.plugins.pvp.sendPVPRequest()", "Send PVP Request", "Cancel", sendPVPBody, []
  882. )
  883. //Receive PVP Request Modal
  884. const receivePVPBody = `<b><span id="receiveFightName">Opponent</span></b> wants to fight you.<br />
  885. <br />
  886. <div style="font-size: large; display: grid;">
  887. <span><b>Fight Options</b></span>
  888. <div id="receivePVPFlags" style="display: grid;grid-template-columns: auto auto;justify-content: space-around;">
  889. <span id="pvpFlag0" dounfordtooltip="Enables Pets feature">PETS</span>
  890. <span id="pvpFlag1" dounfordtooltip="Cold damage if you don't use bear/frozen crocodile armor">Cold Day</span>
  891. <span id="pvpFlag2" dounfordtooltip="-1 hp each attack">Defender</span>
  892. <span id="pvpFlag3" dounfordtooltip="Arrows do nothing">No Ranged Weapons</span>
  893. <span id="pvpFlag4" dounfordtooltip="Spells do nothing">No Spells</span>
  894. <span id="pvpFlag5" dounfordtooltip="50% hit chance">Darkness</span>
  895. <span id="pvpFlag6" dounfordtooltip="x2 fire damage">Fire Weakness</span>
  896. <span id="pvpFlag7" dounfordtooltip="x2 ice damage">Ice Weakness</span>
  897. <span id="pvpFlag8">Fields</span>
  898. <span id="pvpFlag9" dounfordtooltip="x2 Scythe damage">Haunted Mansion</span>
  899. <span id="pvpFlag10" dounfordtooltip="x2 Trident damage">Beach</span>
  900. <span id="pvpFlag11" dounfordtooltip="Only Rain Amulet will cure">Rain</span>
  901. <span id="pvpFlag12" dounfordtooltip="Heavy damage if you don't use invisibility spell">Mud Rain</span>
  902. </div>
  903. </div>`
  904. this.newModal(
  905. "receivePVPModal", "PVP Request", "IdlePixelPlus.plugins.pvp.acceptPVPRequest()", "Accept PVP Request", "Ignore", receivePVPBody, ["receiveFightEnemy"]
  906. )
  907.  
  908. //Result Modal
  909. this.newModal(
  910. "dpvpResult", "PVP Result", "", "disabled", "", "<h4 id='dpvpResultText'>You draw against <b>Player</b>!</h4>",[]
  911. )
  912.  
  913. //Combat Panel
  914. IdlePixelPlus.panels.dounfordPVPCombat = {id:'dounfordPVPCombat',title:'',content:''}
  915. const dpvpTab = `<div id="panel-dounfordPVPCombat" style="display: none;">
  916. <button onclick="switch_panels('panel-dounfordPVP')">BACK</button>
  917. <div style="margin: auto;width: fit-content;">
  918. <table>
  919. <tbody><tr>
  920. <td class="fight-right-border">
  921. </td>
  922. <td style="padding-top:20px;text-align: center;" class="canvas-fighting-td fight-top-border">
  923. <span class="hp-progress-bar">
  924. <span id="dpvp-hero-progress-bar-hp" class="hp-progress-bar-inner" style="width: 100%;"></span>
  925. <div class="progress-bar-label">
  926. <span id="dpvp_combat_hp">0/0</span>
  927. </div>
  928. </span>
  929. <br>
  930. <span class="mana-progress-bar">
  931. <span id="dpvp-hero-progress-bar-mana" class="mana-progress-bar-inner" style="width: 100%;"></span>
  932. <div class="progress-bar-label color-cyan">
  933. <span id="dpvp_combat_mana">0/0</span>
  934. </div>
  935. </span>
  936. </td>
  937. <td style="padding-top: 20px;" class="canvas-fighting-td fight-top-border">
  938. <center>
  939. <span class="hp-progress-bar">
  940. <span id="dpvp-enemy-progress-bar-hp" class="hp-progress-bar-inner" style="width: 100%;"></span>
  941. <div class="progress-bar-label">
  942. <span id="dpvp_combat_enemy_hp">0/0</span>
  943. </div>
  944. </span>
  945. <br><span class="mana-progress-bar">
  946. <span id="dpvp-enemy-progress-bar-mana" class="mana-progress-bar-inner" style="width: 100%;"></span>
  947. <div class="progress-bar-label color-cyan">
  948. <span id="dpvp_combat_enemy_mana">0/0</span>
  949. </div>
  950. </span>
  951. </center>
  952. </td>
  953. <td class="fight-left-border">
  954. </td>
  955. </tr>
  956. <tr>
  957. <td style="vertical-align:top;" class="fight-right-border">
  958. <div class="fighting-hero-stats-area hover shadow" style="border-right:none;text-align: center;display: flex;align-items: center;">
  959. <img id="dpvpHeroAvatar" class="w50" style="display: none;" src="">
  960. <div style="margin: auto;">
  961. <h3 id="dpvp-fighting-hero-label" style="text-transform: capitalize;">You</h3>
  962. <span id="dpvp-fighting-hero-title"></span>
  963. </div>
  964. </div>
  965. <div class="td-combat-bottom-panel shadow">
  966. <div class="td-combat-stat-entry">
  967. <img class="img-15" src="https://cdn.idle-pixel.com/images/accuracy_white.png">
  968. <span style="color:white">Accuracy:</span>
  969. <span id="dpvp_combat_hero_accuracy">0</span>
  970. </div>
  971. <div class="td-combat-stat-entry">
  972. <img class="img-15" src="https://cdn.idle-pixel.com/images/melee_damage_white.png">
  973. <span style="color:white">Damage:</span>
  974. <span id="dpvp_combat_hero_melee_damage">0</span>
  975. </div>
  976. <div class="td-combat-stat-entry">
  977. <img class="img-15" src="https://cdn.idle-pixel.com/images/arrow_damage_white.png">
  978. <span style="color:white">Damage:</span>
  979. <span id="dpvp_combat_hero_arrow_damage">0</span>
  980. </div>
  981. <div class="td-combat-stat-entry">
  982. <img class="img-15" src="https://cdn.idle-pixel.com/images/magic_damage_white.png">
  983. <span style="color:white">Magic:</span>
  984. <span id="dpvp_combat_hero_magic_bonus">0</span>
  985. </div>
  986. <div class="td-combat-stat-entry">
  987. <img class="img-15" src="https://cdn.idle-pixel.com/images/speed_white.png">
  988. <span style="color:white">Speed:</span>
  989. <span id="dpvp_combat_hero_speed">0</span>
  990. </div>
  991. <div class="td-combat-stat-entry">
  992. <img class="img-15" src="https://cdn.idle-pixel.com/images/defence_white.png">
  993. <span style="color:white">Defence:</span>
  994. <span id="dpvp_combat_hero_defence">0</span>
  995. </div>
  996. </div>
  997. <div id="dpvpSpells">
  998. <div id="dpvp-fighting-spell-heal" onclick="IdlePixelPlus.plugins.pvp.castSpell('heal')" class="fighting-spell-area-heal hover shadow">
  999. <img src="https://cdn.idle-pixel.com/images/upgraded_heal_spell_icon.png">
  1000. <span id="dpvp-fighting-spell-label-heal" style="color: white;">Heal <span class="color-grey">(Q)</span></span>
  1001. </div>
  1002. <div id="dpvp-fighting-spell-fire" onclick="IdlePixelPlus.plugins.pvp.castSpell('fire')" class="fighting-spell-area-fire hover shadow">
  1003. <img src="https://cdn.idle-pixel.com/images/fire_spell_icon.png">
  1004. <span id="dpvp-fighting-spell-label-fire" style="color: white;">Fire <span class="color-grey">(W)</span></span>
  1005. </div>
  1006. <div id="dpvp-fighting-spell-reflect" onclick="IdlePixelPlus.plugins.pvp.castSpell('reflect')" class="fighting-spell-area-fire hover shadow">
  1007. <img src="https://cdn.idle-pixel.com/images/reflect_spell_icon.png">
  1008. <span id="dpvp-fighting-spell-label-reflect" style="color: white;">Reflect <span class="color-grey">(E)</span></span>
  1009. </div>
  1010. <div id="dpvp-fighting-spell-invisibility" onclick="IdlePixelPlus.plugins.pvp.castSpell('invisibility')" class="fighting-spell-area-invisibility hover shadow">
  1011. <img src="https://cdn.idle-pixel.com/images/invisibility_spell_icon.png">
  1012. <span id="dpvp-fighting-spell-label-invisibility" style="color: white;">Invisibility <span class="color-grey">(R)</span></span>
  1013. </div>
  1014.  
  1015. <div id="dpvp-fighting-spell-pet" onclick="IdlePixelPlus.plugins.pvp.castSpell('pet')" class="fighting-spell-area-invisibility hover shadow">
  1016. <img id="dpvp-fighting-spell-image-pet" src="https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/whiteChicken.png" style="width: 30px;">
  1017. <span id="dpvp-fighting-spell-label-pet" style="color: white;">Pet Spell <span class="color-grey" style="color: rgb(128, 128, 128);">(T)</span></span>
  1018. </div>
  1019. </div>
  1020. </td>
  1021. <td class="canvas-fighting-td fight-bottom-border">
  1022. <div id="dpvp-fighting-countdown" style="display:none;" class="fighting-countdown">FIGHT IN 3</div>
  1023. <canvas class="canvas-fighting" style="margin-left:100px;margin-right:100px;" id="dpvp-combat-canvas-hero" width="300px" height="600px">
  1024. </canvas>
  1025. </td>
  1026. <td class="canvas-fighting-td fight-bottom-border">
  1027. <canvas class="canvas-fighting" id="dpvp-combat-canvas-enemy" width="300px" height="600px" style="margin-left: 100px;margin-right:100px;">
  1028. </canvas>
  1029. </td>
  1030. <td style="vertical-align:top;" class="fight-left-border">
  1031. <div class="fighting-monster-stats-area hover shadow" style="text-align: center;display: flex;align-items: center;">
  1032. <img id="dpvpEnemyAvatar" class="w50" style="display: none;" src="">
  1033. <div style="margin: auto;">
  1034. <h3 id="dpvp-fighting-enemy-label" style="text-transform: capitalize;">Enemy</h3>
  1035. <span id="dpvp-fighting-enemy-title"></span>
  1036. </div>
  1037. </div>
  1038. <div class="td-combat-bottom-panel shadow">
  1039. <div class="td-combat-stat-entry">
  1040. <img class="img-15" src="https://cdn.idle-pixel.com/images/accuracy_white.png">
  1041. <span style="color:white">Accuracy:</span>
  1042. <span id="dpvp_combat_enemy_accuracy">0</span>
  1043. </div>
  1044. <div class="td-combat-stat-entry">
  1045. <img class="img-15" src="https://cdn.idle-pixel.com/images/melee_damage_white.png">
  1046. <span style="color:white">Damage:</span>
  1047. <span id="dpvp_combat_enemy_melee_damage">0</span>
  1048. </div>
  1049. <div class="td-combat-stat-entry">
  1050. <img class="img-15" src="https://cdn.idle-pixel.com/images/arrow_damage_white.png">
  1051. <span style="color:white">Damage:</span>
  1052. <span id="dpvp_combat_enemy_arrow_damage">0</span>
  1053. </div>
  1054. <div class="td-combat-stat-entry">
  1055. <img class="img-15" src="https://cdn.idle-pixel.com/images/magic_damage_white.png">
  1056. <span style="color:white">Magic:</span>
  1057. <span id="dpvp_combat_enemy_magic_bonus">0</span>
  1058. </div>
  1059. <div class="td-combat-stat-entry">
  1060. <img class="img-15" src="https://cdn.idle-pixel.com/images/speed_white.png">
  1061. <span style="color:white">Speed:</span>
  1062. <span id="dpvp_combat_enemy_speed">0</span>
  1063. </div>
  1064. <div class="td-combat-stat-entry">
  1065. <img class="img-15" src="https://cdn.idle-pixel.com/images/defence_white.png">
  1066. <span style="color:white">Defence:</span>
  1067. <span id="dpvp_combat_enemy_defence">0</span>
  1068. </div>
  1069. </div>
  1070. </td>
  1071. </tr>
  1072. <tr>
  1073. <td></td>
  1074. <td style="text-align: center;">
  1075. <div id="dpvp-combat-presets-area" style="" class="combat-presets-area shadow center">
  1076. <img src="https://d1xsc8x7nc5q8t.cloudfront.net/images/combat_presets.png" class="w20" title="combat_presets"> <u class="color-silver">Presets</u><br><br>
  1077. <img id="dpvp-in-combat-presets-icon-1" onclick="websocket.send('PRESET_LOAD=1~1')" class="combat-presets-combat-icon hover w30" src="" style="background-color: rgb(219, 255, 220);">
  1078. <img id="dpvp-in-combat-presets-icon-2" onclick="websocket.send('PRESET_LOAD=2~1')" class="combat-presets-combat-icon hover w30" src="" style="background-color: rgb(117, 126, 255);">
  1079. <img id="dpvp-in-combat-presets-icon-3" onclick="websocket.send('PRESET_LOAD=3~1')" class="combat-presets-combat-icon hover w30" src="" style="background-color: rgb(219, 255, 220);">
  1080. <img id="dpvp-in-combat-presets-icon-4" onclick="websocket.send('PRESET_LOAD=4~1')" class="combat-presets-combat-icon hover w30" src="" style="background-color: rgb(255, 87, 87);">
  1081. <img id="dpvp-in-combat-presets-icon-5" onclick="websocket.send('PRESET_LOAD=5~1')" class="combat-presets-combat-icon hover w30" src="" style="background-color: rgb(219, 255, 220);">
  1082. </div>
  1083. </td>
  1084. <td></td>
  1085. <td></td>
  1086. </tr>
  1087. </tbody></table>
  1088. </div>
  1089. </div>`;
  1090. document.getElementById('panels').insertAdjacentHTML('beforeend', dpvpTab);
  1091. const dpvpNot = `<div id="notification-dpvp-combat" style="display: none;" onclick="switch_panels('panel-dounfordPVPCombat');document.getElementById('menu-bar').style.display = 'none'" class="notification-banner-red hover">
  1092. <img src="https://cdn.idle-pixel.com/images/fight.png" class="w20">
  1093. <span style="color:red">IN PVP!</span>
  1094. <span style="color:grey">(Click to resume)</span>
  1095. </div>`
  1096. document.getElementById('notification-raid').insertAdjacentHTML('afterend', dpvpNot);
  1097.  
  1098. this.heroContext = document.getElementById("dpvp-combat-canvas-hero").getContext("2d");
  1099. this.enemyContext = document.getElementById("dpvp-combat-canvas-enemy").getContext("2d");
  1100. document.addEventListener('keydown', function(e) {
  1101. const chatInput = document.getElementById('chat-area-input');
  1102. const dpvpCombatPanel = document.getElementById('panel-dounfordPVPCombat');
  1103. if (!chatInput.matches(':focus') && dpvpCombatPanel.style.display !== "none") {
  1104. switch (e.key) {
  1105. //Presets
  1106. case "1": websocket.send('PRESET_LOAD=1~1'); break;
  1107. case "2": websocket.send('PRESET_LOAD=2~1'); break;
  1108. case "3": websocket.send('PRESET_LOAD=3~1'); break;
  1109. case "4": websocket.send('PRESET_LOAD=4~1'); break;
  1110. case "5": websocket.send('PRESET_LOAD=5~1'); break;
  1111. //Spells
  1112. case "q": IdlePixelPlus.plugins.pvp.castSpell('heal'); break;
  1113. case "w": IdlePixelPlus.plugins.pvp.castSpell('fire'); break;
  1114. case "e": IdlePixelPlus.plugins.pvp.castSpell('reflect'); break;
  1115. case "r": IdlePixelPlus.plugins.pvp.castSpell('invisibility'); break;
  1116. case "t": IdlePixelPlus.plugins.pvp.castSpell('pet'); break;
  1117. }
  1118. }
  1119. });
  1120. }
  1121.  
  1122. addLobbyPlayer(player) {
  1123. if (document.getElementById("pvpLobbyPlayer-" + player)) {return;}
  1124. let playerBtn = document.createElement("button");
  1125. playerBtn.id = "pvpLobbyPlayer-" + player;
  1126. playerBtn.classList.add("background-primary", "rounded");
  1127. playerBtn.innerText = player;
  1128. playerBtn.addEventListener("click", () => {
  1129. IdlePixelPlus.plugins.pvp.openRequest(player);
  1130. });
  1131. document.getElementById("pvpLobbyBody").append(playerBtn);
  1132. }
  1133.  
  1134. openRequest(enemy) {
  1135. document.getElementById('pvpLobbyModal').close();
  1136. document.getElementById('sendFightName').value = enemy;
  1137. document.getElementById('sendPVPModal').showModal();
  1138. }
  1139.  
  1140. openPetModal(pet) {
  1141. document.getElementById('pvpPetName').value = pet
  1142. document.getElementById('pvpPetDisplayName').innerText = pets[pet].name
  1143. document.getElementById('pvpPetImage').src = imagePath + pet
  1144. document.getElementById('dounfordPetLevel').innerText = pets[pet].level
  1145. const levelRequirement = pets[pet].level == 1 ? "/10" : pets[pet].level == 2 ? "/25" : ""
  1146. document.getElementById('dounfordPetXPRequired').innerText = pets[pet].xp + levelRequirement
  1147. document.getElementById('dounfordPet').showModal()
  1148. }
  1149.  
  1150. renamePet() {
  1151. const pet = document.getElementById('pvpPetName').value
  1152. const newName = document.getElementById('pvpPetNewName').value
  1153. pets[pet].name = newName
  1154. document.getElementById("dpvpPetName" + pet).innerText = newName
  1155. document.getElementById('pvpPetDisplayName').innerText = newName
  1156. localStorage.setItem("dPVP-" + username + "pets", JSON.stringify(pets))
  1157. }
  1158.  
  1159. equipPet(pet) {
  1160. const newPet = document.getElementById('pvpPetName').value || pet;
  1161. if (boughtPets.includes(newPet) && newPet !== currentPet) {
  1162. document.getElementById("dpvp" + currentPet).style.backgroundColor = "";
  1163. document.getElementById("dpvp" + newPet).style.backgroundColor = "bisque";
  1164. currentPet = newPet;
  1165. document.getElementById("dounfordPet").close();
  1166. if(typeof mouseX !== "undefined"){Animations.scrollText("none", "white", "Pet Changed");}
  1167. localStorage.setItem("dPVP-" + username + "currentPet", currentPet)
  1168. }
  1169. }
  1170.  
  1171. addFightHistory(fight) {
  1172. let fightTr = document.createElement("tr");
  1173. fightTr.innerHTML = `<td style="text-transform: capitalize;">${fight[0]}</td>
  1174. <td>${fight[1]}</td>
  1175. <td>${fight[2]}</td>`;
  1176. document.getElementById("dPVPLogsBody").prepend(fightTr);
  1177. }
  1178.  
  1179. fightResult(result) {
  1180. let resultText = document.getElementById("dpvpResultText");
  1181. if (result == "Winner") {
  1182. PixelShopPlus.coinIncrease("Moon Coins",1)
  1183. resultText.innerHTML = `You won against <b style="text-transform: capitalize">${IdlePixelPlus.plugins.pvp.currentEnemy}</b>, you did great!`
  1184. if (currentPet !== "none") {
  1185. pets[currentPet].xp += 1
  1186. if (pets[currentPet].xp == 10 || pets[currentPet].xp == 25) {
  1187. pets[currentPet].level += 1
  1188. }
  1189. }
  1190. } else if (result == "Loser") {
  1191. resultText.innerHTML = `You lost against <b style="text-transform: capitalize">${IdlePixelPlus.plugins.pvp.currentEnemy}</b>, better luck next time!`
  1192. } else {
  1193. resultText.innerHTML = `The battle ended in a tie!`
  1194. }
  1195. switch_panels('panel-dounfordPVP')
  1196. document.getElementById("dpvpResult").showModal();
  1197. }
  1198.  
  1199. changeTitle(title) {
  1200. if (titles.includes(title) && title !== currentTitle) {
  1201. document.getElementById("dpvp" + currentTitle).style.backgroundColor = "";
  1202. document.getElementById("dpvp" + title).style.backgroundColor = "bisque";
  1203. currentTitle = title;
  1204. if(typeof mouseX !== 'undefined'){Animations.scrollText("none", "white", "Title Changed");}
  1205. localStorage.setItem("dPVP-" + username + "currentTitle", currentTitle)
  1206. }
  1207. }
  1208.  
  1209. changeaddFriendFunction() {
  1210. Chat.add_friend_modal_submit = function() {
  1211. var value = document.getElementById("modal-add-friend-input").value;
  1212. websocket.send('ADD_FRIEND=' + value);
  1213. IdlePixelPlus.plugins.pvp.sendFR(value)
  1214. }
  1215. //Cache will accept external images now
  1216. Cache.getImage = function(url, pointer) {
  1217. if(!url.startsWith("https")) {url = get_image(url)}
  1218. if(Cache.global_ImageCache[pointer] != null) {
  1219. if (Cache.global_ImageCache[pointer].url == url) {
  1220. return Cache.global_ImageCache[pointer].obj;
  1221. }
  1222. }
  1223. var imageObject = new ImageObject(url);
  1224. Cache.global_ImageCache[pointer] = imageObject;
  1225. return imageObject.obj;
  1226. }
  1227. }
  1228.  
  1229. sendPVPRequest() {
  1230. const enemy = document.getElementById('sendFightName').value;
  1231. const fightOptions = {
  1232. petAlly: document.getElementById('pvpCheck0').checked,
  1233. coldDay: document.getElementById('pvpCheck1').checked,
  1234. defender: document.getElementById('pvpCheck2').checked,
  1235. fireWeakness: document.getElementById('pvpFireWeakness').checked,
  1236. iceWeakness: document.getElementById('pvpIceWeakness').checked,
  1237. area: document.querySelector('input[name=pvpArea]:checked').value,
  1238. itRains: document.getElementById('pvpRain').checked,
  1239. mudRain: document.getElementById('pvpMud').checked,
  1240. noRanged: document.getElementById('pvpCheck3').checked,
  1241. noSpells: document.getElementById('pvpCheck4').checked,
  1242. darkness: document.getElementById('pvpCheck5').checked,
  1243. };
  1244.  
  1245. this.currentEnemy = enemy;
  1246. this.options = fightOptions
  1247. IdlePixelPlus.sendCustomMessage(enemy, {
  1248. content: 'pvpR:' + JSON.stringify(fightOptions),
  1249. timeout: 120000
  1250. });
  1251. document.getElementById('sendPVPModal').close();
  1252. }
  1253.  
  1254. receivePVPRequest(enemy,fightOptions) {
  1255. const battleOptions = JSON.parse(fightOptions);
  1256. this.options = battleOptions
  1257. document.getElementById('receiveFightName').innerText = enemy;
  1258. document.getElementById('receiveFightEnemy').value = enemy;
  1259.  
  1260. document.getElementById('pvpFlag0').style.display = battleOptions.petAlly ? "" : "none",
  1261. document.getElementById('pvpFlag1').style.display = battleOptions.coldDay ? "" : "none",
  1262. document.getElementById('pvpFlag2').style.display = battleOptions.defender ? "" : "none",
  1263. document.getElementById('pvpFlag3').style.display = battleOptions.noRanged ? "" : "none",
  1264. document.getElementById('pvpFlag4').style.display = battleOptions.noSpells ? "" : "none",
  1265. document.getElementById('pvpFlag5').style.display = battleOptions.darkness ? "" : "none",
  1266. document.getElementById('pvpFlag6').style.display = battleOptions.fireWeakness ? "" : "none",
  1267. document.getElementById('pvpFlag7').style.display = battleOptions.iceWeakness ? "" : "none",
  1268. document.getElementById('pvpFlag8').style.display = battleOptions.area == "fields" ? "" : "none",
  1269. document.getElementById('pvpFlag9').style.display = battleOptions.area == "mansion" ? "" : "none",
  1270. document.getElementById('pvpFlag10').style.display = battleOptions.area == "beach" ? "" : "none",
  1271. document.getElementById('pvpFlag11').style.display = battleOptions.itRains ? "" : "none",
  1272. document.getElementById('pvpFlag12').style.display = battleOptions.mudRain ? "" : "none",
  1273.  
  1274. document.getElementById('receivePVPModal').showModal();
  1275. }
  1276.  
  1277. acceptPVPRequest() {
  1278. document.getElementById('receivePVPModal').close();
  1279. this.currentEnemy = document.getElementById('receiveFightEnemy').value;
  1280. IdlePixelPlus.sendCustomMessage(this.currentEnemy, {
  1281. content: 'pvpAccept:' + username,
  1282. });
  1283. this.fighting = true;
  1284. this.startFight(true);
  1285. }
  1286.  
  1287. connectWebSocket(){
  1288. pvpWebSocket = new WebSocket('wss://pvp.magiesugary.site');
  1289.  
  1290. pvpWebSocket.addEventListener('open', () => {
  1291. pvpWebSocket.send("Login=" + username)
  1292. });
  1293. pvpWebSocket.addEventListener('message', (event) => {
  1294. this.handleMessage(event.data);
  1295. });
  1296. pvpWebSocket.addEventListener('close', () => {
  1297. console.log("Connection with the pvp server lost")
  1298. });
  1299. }
  1300.  
  1301. startFight(player1) {
  1302. document.getElementById('pvpLobbyModal').close();
  1303.  
  1304. console.log('Starting pvp with ' + this.currentEnemy);
  1305. pvpWebSocket.send('Fight=' + this.currentEnemy);
  1306. if (player1) {
  1307. pvpWebSocket.send('Config=' + JSON.stringify(this.options));
  1308. }
  1309. const pvpStats = {
  1310. title: currentTitle,
  1311. pet: currentPet,
  1312. petLevel: pets[currentPet]?.level || 0,
  1313. hp: parseInt(var_max_hp),
  1314. maxHp: parseInt(var_max_hp),
  1315. mana: parseInt(var_max_mana),
  1316. maxMana: parseInt(var_max_mana),
  1317. accuracy: parseInt(var_accuracy),
  1318. damage: parseInt(var_melee_damage),
  1319. arrowDamage: parseInt(var_arrow_damage),
  1320. speed: parseInt(var_speed),
  1321. defence: parseInt(var_defence),
  1322. magicBonus: parseInt(var_magic_bonus),
  1323. head: var_head,
  1324. body: var_body,
  1325. legs: var_legs,
  1326. boots: var_boots,
  1327. gloves: var_gloves,
  1328. amulet: var_amulet,
  1329. shield: var_shield,
  1330. weapon: var_weapon,
  1331. arrows: var_arrows,
  1332. }
  1333. pvpWebSocket.send('SetPlayer=' + JSON.stringify(pvpStats));
  1334. }
  1335.  
  1336. endFight(){
  1337. console.log('PVP with ' + this.currentEnemy + ' ended');
  1338. clearInterval(IdlePixelPlus.plugins.pvp.fight.tick);
  1339. setTimeout(() => {
  1340. delete IdlePixelPlus.plugins.pvp.fightHitplat[IdlePixelPlus.plugins.pvp.currentEnemy]
  1341. IdlePixelPlus.plugins.pvp.currentEnemy = null;
  1342. IdlePixelPlus.plugins.pvp.fight = {};
  1343. IdlePixelPlus.plugins.pvp.fighting = false;
  1344. }, 2000)
  1345. document.getElementById("combat-rain").style.display = "none";
  1346. document.getElementById("combat-tar-rain").style.display = "none";
  1347. document.getElementById("notification-dpvp-combat").style.display = "none";
  1348. }
  1349.  
  1350. handleMessage(message) {
  1351. let key;
  1352. let value;
  1353. let value_array;
  1354. if (message.includes('=')) {
  1355. [key, value] = message.split("=");
  1356. if (value.includes('~')) {
  1357. value_array = value.split('~');
  1358. }
  1359. } else {
  1360. key = message;
  1361. }
  1362.  
  1363. switch (key) {
  1364. case "Lobby":
  1365. const lobby = JSON.parse(value);
  1366. lobby.forEach((player) => {
  1367. IdlePixelPlus.plugins.pvp.addLobbyPlayer(player);
  1368. })
  1369. break;
  1370. case "Join":
  1371. this.addLobbyPlayer(value);
  1372. break;
  1373. case "Leave":
  1374. document.getElementById("pvpLobbyPlayer-" + value).remove();
  1375. break;
  1376. case "UserToken":
  1377. userToken = value;
  1378. localStorage.setItem("dPVP-" + username + "Token", userToken);
  1379. break;
  1380. case "Fight":
  1381. const parsedValue = JSON.parse(value);
  1382. this.fight = parsedValue;
  1383. this.fightHitplat[this.currentEnemy] = {};
  1384. this.fightHitplat[username] = {};
  1385. this.startPVP();
  1386. break
  1387. case "Rain":
  1388. document.getElementById("combat-rain").style.display = "";
  1389. break;
  1390. case "Mud":
  1391. document.getElementById("combat-tar-rain").style.display = "";
  1392. break;
  1393. case "StopRain":
  1394. document.getElementById("combat-rain").style.display = "none";
  1395. document.getElementById("combat-tar-rain").style.display = "none";
  1396. break;
  1397. case "HitSplat":
  1398. this.addHitSplat(value_array[0], value_array[1], value_array[2], value_array[3], value_array[4], value_array[5]);
  1399. break;
  1400. case "Reflect":
  1401. this.fight[value].isReflecting = !this.fight[value].isReflecting;
  1402. break;
  1403. case "Invisibility":
  1404. this.fight[value].isInvisible = !this.fight[value].isInvisible;
  1405. break;
  1406. case "SpellCooldown":
  1407. this.spellCooldown(value_array[0],value_array[1]);
  1408. break;
  1409. case "Poison":
  1410. this.fight[value].isPoisoned = true;
  1411. break;
  1412. case "UpdateStats":
  1413. const stats = JSON.parse(value);
  1414. for (let player in stats) {
  1415. for (let key in stats[player]) {
  1416. this.fight[player][key] = stats[player][key];
  1417. }
  1418. }
  1419. this.updateStatsBars();
  1420. break;
  1421. case "RefreshPlayer":
  1422. this.refreshPlayer(value_array[0],value_array[1],value_array[2]);
  1423. break;
  1424. case "FightResult":
  1425. let result = [this.currentEnemy,value,get_utc_time()]
  1426. fightHistory.push(result);
  1427. localStorage.setItem("dPVP-" + username + "fightHistory", JSON.stringify(fightHistory));
  1428. this.addFightHistory(result);
  1429. this.endFight();
  1430. this.fightResult(value);
  1431. break;
  1432. case "NewTitle":
  1433. titles.push(value);
  1434. document.getElementById("dpvp" + value).style.display = "";
  1435. break;
  1436. default:
  1437. console.log(key, value);
  1438. break;
  1439. }
  1440. }
  1441.  
  1442. fightCooldown(value) {
  1443. if (value > 0) {
  1444. document.getElementById("dpvp-fighting-countdown").style.display = "";
  1445. document.getElementById("dpvp-fighting-countdown").innerText = "FIGHT IN " + value;
  1446. setTimeout(() => {
  1447. this.fightCooldown(value - 1);
  1448. }, 1000);
  1449. } else {
  1450. document.getElementById("dpvp-fighting-countdown").style.display = "none";
  1451. }
  1452. }
  1453.  
  1454. startPVP() {
  1455. this.fightCooldown(3);
  1456. this.refreshPresetIcons();
  1457. document.getElementById("dpvp-fighting-hero-label").innerText = username
  1458. document.getElementById("dpvp-fighting-hero-title").innerText = displayTitles[currentTitle]
  1459. document.getElementById("dpvp-fighting-enemy-label").innerText = this.currentEnemy
  1460. document.getElementById("dpvp-fighting-enemy-title").innerText = displayTitles[this.fight[this.currentEnemy].title]
  1461. if (this.fight.config.noSpells || (this.fight.config.petAlly && this.fight[username].pet == "whiteBunny")) {
  1462. document.getElementById("dpvpSpells").style.display = "none";
  1463. } else {
  1464. document.getElementById("dpvpSpells").style.display = "";
  1465. document.getElementById("dpvp-fighting-spell-label-heal").innerHTML = 'Heal <span class="color-grey" style="color: rgb(128, 128, 128);">(Q)</span>';
  1466. document.getElementById("dpvp-fighting-spell-label-fire").innerHTML = 'Fire <span class="color-grey" style="color: rgb(128, 128, 128);">(W)</span>';
  1467. document.getElementById("dpvp-fighting-spell-label-reflect").innerHTML = 'Reflect <span class="color-grey" style="color: rgb(128, 128, 128);">(E)</span>';
  1468. document.getElementById("dpvp-fighting-spell-label-invisibility").innerHTML = 'Invisibility <span class="color-grey" style="color: rgb(128, 128, 128);">(R)</span>';
  1469. if (this.fight.config.petAlly && petsWithSpell.includes(this.fight[username].pet) && (this.fight[username].pet !== "blackChicken" || this.fight[username].petLevel > 1)) {
  1470. document.getElementById("dpvp-fighting-spell-label-pet").innerHTML = 'Pet Spell <span class="color-grey" style="color: rgb(128, 128, 128);">(T)';
  1471. document.getElementById("dpvp-fighting-spell-image-pet").src = imagePath + this.fight[username].pet + ".png";
  1472. document.getElementById("dpvp-fighting-spell-pet").style.display = "";
  1473. } else {
  1474. document.getElementById("dpvp-fighting-spell-pet").style.display = "none";
  1475. }
  1476. }
  1477. this.updateStatsBars();
  1478. this.fight.tick = setInterval(function() {
  1479. IdlePixelPlus.plugins.pvp.tick();
  1480. }, 1000 / 60);
  1481. switch_panels('panel-dounfordPVPCombat');
  1482. document.getElementById("menu-bar").style.display = "none";
  1483. document.getElementById("notification-dpvp-combat").style.display = "";
  1484. }
  1485.  
  1486. refreshPresetIcons() {
  1487. for(let i = 1; i < 6 ; i++) {
  1488. document.getElementById("dpvp-in-combat-presets-icon-" + i).src = get_image("images/" + Items.getItem("combat_preset_icon_" + i));
  1489. document.getElementById("dpvp-in-combat-presets-icon-" + i).style.backgroundColor = Items.getItemString("combat_preset_color_" + i);
  1490. }
  1491. }
  1492.  
  1493. refreshPlayer(attribute, value, name) {
  1494. if (intStats.includes(attribute)) {
  1495. value = parseInt(value);
  1496. }
  1497. this.fight[name][attribute] = value;
  1498. this.updateStatsBars();
  1499. }
  1500.  
  1501. castSpell(spellName) {
  1502. if (this.fight[username].cooldowns[spellName] == 0 && this.fight[username].mana >= manaCost[spellName]) {
  1503. pvpWebSocket.send("Cast=" + spellName);
  1504. }
  1505. }
  1506.  
  1507. spellCooldown(spellName, time) {
  1508. if(this.fight[username]) {
  1509. this.fight[username].cooldowns[spellName] = Math.max(0,time);
  1510. if (time > 0) {
  1511. document.getElementById("dpvp-fighting-spell-label-" + spellName).innerText = time;
  1512. setTimeout(function() {IdlePixelPlus.plugins.pvp.spellCooldown(spellName, time - 1)}, 1000);
  1513. } else {
  1514. if (this.fight[username].mana < manaCost[spellName]) {
  1515. document.getElementById("dpvp-fighting-spell-label-" + spellName).innerText = 'NO MANA';
  1516. return
  1517. }
  1518. switch (spellName) {
  1519. case "heal":
  1520. document.getElementById("dpvp-fighting-spell-label-heal").innerHTML = 'Heal <span class="color-grey" style="color: rgb(128, 128, 128);">(Q)</span>';
  1521. break;
  1522. case "fire":
  1523. document.getElementById("dpvp-fighting-spell-label-fire").innerHTML = 'Fire <span class="color-grey" style="color: rgb(128, 128, 128);">(W)</span>';
  1524. break;
  1525. case "reflect":
  1526. document.getElementById("dpvp-fighting-spell-label-reflect").innerHTML = 'Reflect <span class="color-grey" style="color: rgb(128, 128, 128);">(E)</span>';
  1527. break;
  1528. case "invisibility":
  1529. document.getElementById("dpvp-fighting-spell-label-invisibility").innerHTML = 'Invisibility <span class="color-grey" style="color: rgb(128, 128, 128);">(R)</span>';
  1530. break;
  1531. case "pet":
  1532. document.getElementById("dpvp-fighting-spell-label-pet").innerHTML = 'Pet Spell <span class="color-grey" style="color: rgb(128, 128, 128);">(T)</span>';
  1533. }
  1534. }
  1535. }
  1536. }
  1537.  
  1538. updateStatsBars() {
  1539. //Hero
  1540. document.getElementById("dpvp_combat_hp").innerText= Math.max(0,this.fight[username].hp) + "/" + this.fight[username].maxHp; //Set the number on the hero hp bar
  1541. let heroHpPercentage = Math.max(this.fight[username].hp / this.fight[username].maxHp,0) * 100;
  1542. document.getElementById("dpvp-hero-progress-bar-hp").style.width = heroHpPercentage.toFixed() + "%"; // Set the hero hp bar background
  1543. document.getElementById("dpvp_combat_mana").innerText = Math.max(0,this.fight[username].mana) + "/" + this.fight[username].maxMana; //Set the number on the hero mana bar
  1544. let heroManaPercentage = Math.max(this.fight[username].mana / this.fight[username].maxMana,0) * 100;
  1545. document.getElementById("dpvp-hero-progress-bar-mana").style.width = heroManaPercentage.toFixed() + "%"; // Set the mana hp bar background
  1546. //Enemy
  1547. document.getElementById("dpvp_combat_enemy_hp").innerText = Math.max(0,this.fight[this.currentEnemy].hp) + "/" + this.fight[this.currentEnemy].maxHp; //Set the number on the enemy hp bar
  1548. let enemyHpPercentage = Math.max(this.fight[this.currentEnemy].hp / this.fight[this.currentEnemy].maxHp,0) * 100;
  1549. document.getElementById("dpvp-enemy-progress-bar-hp").style.width = enemyHpPercentage.toFixed() + "%"; // Set the enemy hp bar background
  1550. document.getElementById("dpvp_combat_enemy_mana").innerText = Math.max(0,this.fight[this.currentEnemy].mana) + "/" + this.fight[this.currentEnemy].maxMana; //Set the number on the hero mana bar
  1551. let enemyManaPercentage = Math.max(this.fight[this.currentEnemy].mana / this.fight[this.currentEnemy].maxMana,0) * 100;
  1552. document.getElementById("dpvp-enemy-progress-bar-mana").style.width = enemyManaPercentage.toFixed() + "%"; // Set the mana hp bar background
  1553. }
  1554.  
  1555. addHitSplat(label, icon, label_color, background_color, border_color, source) {
  1556. let splat = new HitSplat(label, icon, label_color, background_color, border_color, 150, 450);
  1557. let random_key = rand(1,500000);
  1558. this.fightHitplat[source][random_key] = splat;
  1559. setTimeout(
  1560. function(){
  1561. delete IdlePixelPlus.plugins.pvp.fightHitplat[source][random_key];
  1562. }
  1563. ,1000)
  1564. }
  1565.  
  1566. //Evething that should be called each second
  1567. tick() {
  1568. if(this.fighting == false) return;
  1569. //Hero Stats
  1570. document.getElementById("dpvp_combat_hero_accuracy").innerText = this.fight[username].accuracy + this.fight[username].bonusAccuracy;
  1571. document.getElementById("dpvp_combat_hero_melee_damage").innerText = this.fight[username].damage + this.fight[username].bonusDamage;
  1572. document.getElementById("dpvp_combat_hero_arrow_damage").innerText = this.fight[username].arrowDamage + this.fight[username].bonusDamage;
  1573. document.getElementById("dpvp_combat_hero_magic_bonus").innerText = var_magic_bonus;
  1574. document.getElementById("dpvp_combat_hero_speed").innerText = this.fight[username].speed + this.fight[username].bonusSpeed;
  1575. document.getElementById("dpvp_combat_hero_defence").innerText = this.fight[username].defence + this.fight[username].bonusDefence;
  1576. //Enemy Stats
  1577. document.getElementById("dpvp_combat_enemy_accuracy").innerText = this.fight[this.currentEnemy].accuracy + this.fight[this.currentEnemy].bonusAccuracy;
  1578. document.getElementById("dpvp_combat_enemy_melee_damage").innerText = this.fight[this.currentEnemy].damage + this.fight[this.currentEnemy].bonusDamage;
  1579. document.getElementById("dpvp_combat_enemy_arrow_damage").innerText = this.fight[this.currentEnemy].arrowDamage + this.fight[this.currentEnemy].bonusDamage;
  1580. document.getElementById("dpvp_combat_enemy_magic_bonus").innerText = this.fight[this.currentEnemy].magicBonus;
  1581. document.getElementById("dpvp_combat_enemy_speed").innerText = this.fight[this.currentEnemy].speed + this.fight[this.currentEnemy].bonusSpeed;
  1582. document.getElementById("dpvp_combat_enemy_defence").innerText = this.fight[this.currentEnemy].defence + this.fight[this.currentEnemy].bonusDefence;
  1583.  
  1584. this.tickCanvas();
  1585. this.manageHitplats();
  1586. }
  1587.  
  1588. tickCanvas() {
  1589. this.heroContext.clearRect(0, 0, 300, 600);
  1590. this.enemyContext.clearRect(0, 0, 300, 600);
  1591. if (this.fight[username].isInvisible > 0) {
  1592. this.heroContext.fillStyle = "white";
  1593. this.heroContext.globalAlpha = 0.1;
  1594. this.heroContext.fillRect(155, 20, 50, 50);
  1595. this.heroContext.drawImage(Cache.getImage("images/ghost_icon.png","hero_invisible"), 155, 20);
  1596. } else {
  1597. this.heroContext.globalAlpha = 1.0;
  1598. };
  1599. if (this.fight[this.currentEnemy].isInvisible > 0) {
  1600. this.enemyContext.fillStyle = "white";
  1601. this.enemyContext.globalAlpha = 0.1;
  1602. this.enemyContext.fillRect(155, 20, 50, 50);
  1603. this.enemyContext.drawImage(Cache.getImage("images/ghost_icon.png","hero_invisible"), 155, 20);
  1604. } else {
  1605. this.enemyContext.globalAlpha = 1.0;
  1606. };
  1607. if (this.fight[username].isReflecting == true) {
  1608. this.heroContext.fillStyle = "white";
  1609. this.heroContext.fillRect(95, 20, 50, 50);
  1610. this.heroContext.drawImage(Cache.getImage("images/reflect_spell.png","hero_reflecting"), 95, 20);
  1611. };
  1612. if (this.fight[this.currentEnemy].isReflecting == true) {
  1613. this.enemyContext.fillStyle = "white";
  1614. this.enemyContext.fillRect(95, 20, 50, 50);
  1615. this.enemyContext.drawImage(Cache.getImage("images/reflect_spell.png","hero_reflecting"), 95, 20);
  1616. };
  1617.  
  1618. this.heroContext.drawImage(Cache.getImage("images/hero_head_" + Items.getItemString('head') + ".png","hero_dpvp_head"), 0, 300);
  1619. this.heroContext.drawImage(Cache.getImage("images/hero_body_" + Items.getItemString('body') + ".png","hero_dpvp_body"), 0, 300);
  1620. this.heroContext.drawImage(Cache.getImage("images/hero_gloves_" + Items.getItemString('gloves') + ".png","hero_dpvp_gloves"), 0, 300);
  1621. this.heroContext.drawImage(Cache.getImage("images/hero_legs_" + Items.getItemString('legs') + ".png","hero_dpvp_legs"), 0, 300);
  1622. this.heroContext.drawImage(Cache.getImage("images/hero_boots_" + Items.getItemString('boots') + ".png","hero_dpvp_boots"), 0, 300);
  1623. this.heroContext.drawImage(Cache.getImage("images/hero_amulet_" + Items.getItemString('amulet') + ".png","hero_dpvp_amulet"), 0, 300);
  1624. this.heroContext.drawImage(Cache.getImage("images/hero_shield_" + Items.getItemString('shield') + ".png","hero_dpvp_shield"), 0, 300);
  1625. this.heroContext.drawImage(Cache.getImage("images/hero_weapon_" + Items.getItemString('weapon') + ".png","hero_dpvp_weapon"), 0, 300);
  1626.  
  1627. if (this.fight.config.petAlly) {
  1628. this.heroContext.save();
  1629. this.heroContext.translate(300, 0);
  1630. this.heroContext.scale(-1,1);
  1631. this.heroContext.drawImage(Cache.getImage("https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/" + this.fight[username].pet + ".png","hero_dpvp_" + this.fight[username].pet), 200, 480, petsSize[this.fight[username].pet],85)
  1632. this.heroContext.restore();
  1633.  
  1634. this.enemyContext.drawImage(Cache.getImage("https://res.cloudinary.com/dmhidlxwq/image/upload/v1724974600/pixel%20pvp/" + this.fight[this.currentEnemy].pet + ".png","hero_dpvp_" + this.fight[this.currentEnemy].pet), 200, 480, petsSize[this.fight[this.currentEnemy].pet],85)
  1635. }
  1636. this.enemyContext.save();
  1637. this.enemyContext.translate(300, 0);
  1638. this.enemyContext.scale(-1,1);
  1639. this.enemyContext.drawImage(Cache.getImage("images/hero_head_" + this.fight[this.currentEnemy].head + ".png","enemy_dpvp_head"), 0, 300);
  1640. this.enemyContext.drawImage(Cache.getImage("images/hero_body_" + this.fight[this.currentEnemy].body + ".png","enemy_dpvp_body"), 0, 300);
  1641. this.enemyContext.drawImage(Cache.getImage("images/hero_gloves_" + this.fight[this.currentEnemy].gloves + ".png","enemy_dpvp_gloves"), 0, 300);
  1642. this.enemyContext.drawImage(Cache.getImage("images/hero_legs_" + this.fight[this.currentEnemy].legs + ".png","enemy_dpvp_legs"), 0, 300);
  1643. this.enemyContext.drawImage(Cache.getImage("images/hero_boots_" + this.fight[this.currentEnemy].boots + ".png","enemy_dpvp_boots"), 0, 300);
  1644. this.enemyContext.drawImage(Cache.getImage("images/hero_amulet_" + this.fight[this.currentEnemy].amulet + ".png","enemy_dpvp_amulet"), 0, 300);
  1645. this.enemyContext.drawImage(Cache.getImage("images/hero_shield_" + this.fight[this.currentEnemy].shield + ".png","enemy_dpvp_shield"), 0, 300);
  1646. this.enemyContext.drawImage(Cache.getImage("images/hero_weapon_" + this.fight[this.currentEnemy].weapon + ".png","enemy_dpvp_weapon"), 0, 300);
  1647. this.enemyContext.restore()
  1648. }
  1649.  
  1650. manageHitplats() {
  1651. for (let key in this.fightHitplat[username]) {
  1652. this.fightHitplat[username][key].draw(this.heroContext);
  1653. };
  1654. for (let key in this.fightHitplat[this.currentEnemy]) {
  1655. this.fightHitplat[this.currentEnemy][key].draw(this.enemyContext);
  1656. };
  1657. }
  1658.  
  1659. sendFR(username) {
  1660. IdlePixelPlus.sendCustomMessage(username, {
  1661. content: `friendRequest`,
  1662. });
  1663. }
  1664.  
  1665. receiveFR(username) {
  1666. document.getElementById('friendRequestName').value = username
  1667. document.getElementById('friendRequestFriend').innerText = username
  1668. document.getElementById('friendRequest').showModal();
  1669. }
  1670.  
  1671. acceptFR() {
  1672. document.getElementById('friendRequest').close();
  1673. const friend = document.getElementById('friendRequestName').value
  1674. websocket.send('ADD_FRIEND=' + friend);
  1675. }
  1676.  
  1677. blockPlayer(player,unblock) {
  1678. if (player == null) {
  1679. player = document.getElementById('pvpBlockUser').value
  1680. }
  1681. if (unblock == true) {
  1682. this.blockedUsers = this.blockedUsers.filter(function(user) {
  1683. return user !== player
  1684. })
  1685. document.getElementById('pvpBlocked-' + player).remove()
  1686. } else {
  1687. if (!this.blockedUsers.includes(player)) {
  1688. this.blockedUsers.push(player)
  1689. }
  1690. let blockedDiv = document.createElement('div')
  1691. blockedDiv.id = 'pvpBlocked-' + player
  1692. blockedDiv.classList.add('blockedUser')
  1693. let unblockBtn = document.createElement('button')
  1694. unblockBtn.classList.add('background-primary', 'rounded')
  1695. unblockBtn.innerText = 'Unblock'
  1696. unblockBtn.addEventListener('click', () => {
  1697. this.blockPlayer(player, true)
  1698. })
  1699.  
  1700. blockedDiv.append(player, unblockBtn)
  1701. document.querySelector('#blockListModal .dounfordModalBody').append(blockedDiv)
  1702. }
  1703. let users = JSON.stringify(this.blockedUsers)
  1704. localStorage.setItem('PVP-BlockedUsers', users);
  1705. }
  1706. }
  1707. const plugin = new pvpPlugin();
  1708. IdlePixelPlus.registerPlugin(plugin);
  1709. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址