diff --git a/docs/directory.py b/docs/directory.py
index 787b496..8e0e0f4 100644
--- a/docs/directory.py
+++ b/docs/directory.py
@@ -63,6 +63,7 @@ docs={
"sell",
"consume",
"equip",
+ "equip_batch",
"unequip",
"lock_item",
"seal_item",
@@ -160,6 +161,7 @@ docs={
"is_array",
],
"documented":[
+ "equip_batch",
"attack",
"heal",
"buy",
@@ -338,4 +340,4 @@ docs={
}
}
-docs["functions"].sort()
\ No newline at end of file
+docs["functions"].sort()
diff --git a/docs/functions/equip_batch.html b/docs/functions/equip_batch.html
new file mode 100644
index 0000000..8dd0306
--- /dev/null
+++ b/docs/functions/equip_batch.html
@@ -0,0 +1,47 @@
+
+ Arguments:
+
* Array - An array of equip definitions
+
+
+ Returns:
+
* Promise
+
+
+Example usages:
+
+
+equip_batch([{ num: 0, slot: "chest" }, { num: 1, slot: "orb" }]);
+equip_batch([{ num: 0, slot: "chest" }, { num: 1, slot: "orb" }]).then(
+ function(data){
+ game_log("Yes!"); // Not all items may have been equipped. All this means is that you send the correct layout of data.
+ },
+ function(data) {
+ game_log("equip_batch failed: " + data.reason);
+ },
+);
+
+
+Promise Reference:
+
+"resolve"
+
+{
+ place: "equip_batch",
+ response: "data",
+ slots: [{ num: 0, slot: "chest" }, "no_item"] // Note that even though equipping the orb failed, we still received a success response.
+}
+
+
+
+"reject"
+
+{
+ place: "equip_batch",
+ failed: true,
+ response: "invalid",
+ reason: "invalid", // You didn't send an array.
+}
+
+
+
+"source"
diff --git a/js/runner_functions.js b/js/runner_functions.js
index 4371deb..d1d8c55 100644
--- a/js/runner_functions.js
+++ b/js/runner_functions.js
@@ -550,6 +550,26 @@ function consume(num) // consumes or uses an inventory item
return parent.push_deferred("equip");
}
+function equip_batch(data) {
+ if (!Array.isArray(data)) {
+ game_log("Can't equip_batch non-array");
+ return rejecting_promise({reason:"invalid"});
+ }
+ if (data.length > 15) {
+ game_log("Can't equip_batch more than 15 items");
+ return rejecting_promise({reason:"invalid"});
+ }
+ for (let i = 0; i < data.length; i++) {
+ let num = data[i].num;
+ if (num < 0) {
+ game_log("Can't equip "+num);
+ return rejecting_promise({reason:"invalid"});
+ }
+ }
+ parent.socket.emit("equip_batch", data);
+ return parent.push_deferred("equip_batch");
+}
+
function equip(num,slot) // slot is optional
{
if(num<0)
@@ -1981,4 +2001,4 @@ if(parent.is_cli)
if(parent.ls_emulation) window._localStorage=parent.ls_emulation;
window.cli_require=parent.cli_require;
}
-code_draw();
\ No newline at end of file
+code_draw();
diff --git a/node/server.js b/node/server.js
index 4ed15f1..a7bc97f 100644
--- a/node/server.js
+++ b/node/server.js
@@ -4092,7 +4092,13 @@ function init_io() {
} else {
climit = round(climit / 4);
}
- if (method == "cm") {
+ if (method == "equip_batch") {
+ var cost = 1;
+ if (Array.isArray(data)) {
+ cost += data.length / 2;
+ }
+ add_call_cost(CC.equip * cost);
+ } else if (method == "cm") {
var add = 1;
var len = JSON.stringify(data.message).length;
var mult = 1;
@@ -6364,6 +6370,71 @@ function init_io() {
return socket.emit("game_response", { response: "exception", place: "upgrade", failed: true });
}
});
+ socket.on("equip_batch", function (data) {
+ let player = players[socket.id];
+ if (!player) {
+ return;
+ }
+ player.c = {};
+ if (Array.isArray(data)) {
+ data.length = min(data.length, 15);
+ let resolve = [];
+ let penalty = 0;
+ for (let i = 0; i < data.length; i++) {
+ let equip_def = data[i];
+ equip_def.num = to_number(equip_def.num);
+ if (equip_def.num >= player.items.length) {
+ resolve.push("invalid");
+ break;
+ }
+ var item = player.items[equip_def.num];
+ if (!item) {
+ resolve.push("no_item");
+ break;
+ }
+ if (item.b) {
+ resolve.push("item_blocked");
+ break;
+ }
+ if (item.name == "placeholder") {
+ resolve.push("item_placeholder");
+ break;
+ }
+ var def = G.items[item.name];
+ def.iname = item.name; //just for orb name checks [08/10/16]
+ if (!def) {
+ resolve.push("no_item");
+ break;
+ }
+ var slot = equip_def.slot || def.type;
+ var comp = can_equip_item(player, def, slot);
+ if (comp == "no") {
+ resolve.push("cant_equip");
+ break;
+ }
+ slot = comp;
+ var existing = player.slots[slot];
+ player.slots[slot] = player.items[equip_def.num];
+ player.cslots[slot] = cache_item(player.slots[slot]);
+ if (existing && existing.b) {
+ existing = null;
+ }
+ player.items[equip_def.num] = existing;
+ player.citems[equip_def.num] = cache_item(existing);
+ penalty += 120;
+ resolve.push({ num: equip_def.num, slot });
+ }
+ if ("penalty_cd" in player.s) {
+ player.s.penalty_cd.ms = min(player.s.penalty_cd.ms + penalty, 120000);
+ } else {
+ player.s.penalty_cd = { ms: penalty };
+ }
+ resend(player, "reopen+u+cid");
+ success_response("data", { slots: resolve });
+ } else {
+ return fail_response("invalid");
+ }
+ });
socket.on("equip", function (data) {
var player = players[socket.id];
if (!player) {
@@ -9240,14 +9311,6 @@ function init_io() {
return fail_response("loot_failed");
}
try {
- if (chest && !chest.pvp && chest.gold > 100000000 && !player.stealth) {
- broadcast("server_message", {
- message: player.name + " looted " + to_pretty_num(server_tax(round(chest.gold * r.goldm), true)) + " gold",
- color: "gold",
- type: "server_gold",
- name: player.name,
- });
- }
if (chest && player.owner && chest.owners && !in_arr(player.owner, chest.owners) && !W.chest[player.owner]) {
W.chest[player.owner] = new Date();
server_log("SEVERE - Cross Loot from " + player.name + " not from " + chest.owners.toString());
@@ -9258,6 +9321,15 @@ function init_io() {
if (!can_add_items(player, all_items)) {
return fail_response("loot_no_space");
}
+ if (chest && !chest.pvp && chest.gold > 100000000 && !player.stealth) {
+ broadcast("server_message", {
+ message:
+ player.name + " looted " + to_pretty_num(server_tax(round(chest.gold * r.goldm), true)) + " gold",
+ color: "gold",
+ type: "server_gold",
+ name: player.name,
+ });
+ }
delete chests[data.id]; // The add_shells routine was at the top, so when inventory was full, attempting to open the chest gave shells infinitely, repeated lesson, always remove before adding, or exceptions [11/07/18]
if (chest && chest.cash) {
add_shells(player, chest.cash, "chest", true, "override");
@@ -9318,6 +9390,15 @@ function init_io() {
r.party = true;
var chest = chests[data.id];
var reopen = {};
+ if (chest && !chest.pvp && chest.gold > 100000000 && !player.stealth) {
+ broadcast("server_message", {
+ message:
+ player.name + " looted " + to_pretty_num(server_tax(round(chest.gold * r.goldm), true)) + " gold",
+ color: "gold",
+ type: "server_gold",
+ name: player.name,
+ });
+ }
delete chests[data.id];
if (chest && chest.cash) {
add_shells(player, chest.cash, "chest", true, "override");
@@ -10497,10 +10578,12 @@ function init_io() {
}
}
});
- socket.on("skin",function(data){
+ socket.on("skin", function (data) {
var player = players[socket.id];
- if(player.role!="gm") return;
- player.tskin=data.name;
+ if (player.role != "gm") {
+ return;
+ }
+ player.tskin = data.name;
resend(player, "u+cid");
});
socket.on("legacify", function (data) {