start refactoring on("skill") handler

This commit is contained in:
Kent Rasmussen
2023-11-22 13:07:46 +09:00
parent 00992dacef
commit 4517e74379
+226 -213
View File
@@ -1237,9 +1237,9 @@ function calculate_player_stats(player) {
apply_stats( apply_stats(
player, player,
class_def.offhand[def.wtype] || class_def.offhand[def.wtype] ||
class_def.offhand[def.type] || { class_def.offhand[def.type] || {
no_range: !player.slots.mainhand, no_range: !player.slots.mainhand,
}, },
); );
} }
if (prop.set) { if (prop.set) {
@@ -1968,8 +1968,8 @@ function drop_something(player, monster, share) {
drop = chests[drop_id] = { items: [], cash: 0 }; drop = chests[drop_id] = { items: [], cash: 0 };
drop.gold = drop.gold =
round(1 + GOLD * D.drops.gold.base * share + Math.random() * GOLD * D.drops.gold.random * share) * round(1 + GOLD * D.drops.gold.base * share + Math.random() * GOLD * D.drops.gold.random * share) *
monster.level * monster.level *
monster.mult || 0; // previously 0.75 monster.mult || 0; // previously 0.75
if (monster.extra_gold) { if (monster.extra_gold) {
drop.egold = (drop.egold || 0) + max(0, monster.extra_gold); drop.egold = (drop.egold || 0) + max(0, monster.extra_gold);
} }
@@ -2945,7 +2945,7 @@ function commence_attack(attacker, target, atype) {
if ( if (
attacker.in != target.in || attacker.in != target.in ||
distance(attacker, target, true) > distance(attacker, target, true) >
attacker.range * G.skills.mentalburst.range_multiplier + G.skills.mentalburst.range_bonus attacker.range * G.skills.mentalburst.range_multiplier + G.skills.mentalburst.range_bonus
) { ) {
attacker.socket.emit("game_response", { response: "too_far", id: target.id, dist: dist }); attacker.socket.emit("game_response", { response: "too_far", id: target.id, dist: dist });
return { failed: true, reason: "too_far", place: atype, id: target.id, dist: dist }; return { failed: true, reason: "too_far", place: atype, id: target.id, dist: dist };
@@ -3368,9 +3368,9 @@ function complete_attack(attacker, target, info) {
if (first) { if (first) {
o_attack = attack = -ceil( o_attack = attack = -ceil(
B.heal_multiplier * B.heal_multiplier *
attack * attack *
(0.9 + Math.random() * 0.2) * (0.9 + Math.random() * 0.2) *
damage_multiplier(((target[defense] || 0) - (attacker[pierce] || 0)) / 2.0), damage_multiplier(((target[defense] || 0) - (attacker[pierce] || 0)) / 2.0),
); );
if (target.s.poisoned) { if (target.s.poisoned) {
attack = round(attack * 0.25); attack = round(attack * 0.25);
@@ -4179,7 +4179,7 @@ function init_io() {
} else { } else {
try { try {
socket.emit("game_error", "ERROR!"); socket.emit("game_error", "ERROR!");
} catch (e) {} } catch (e) { }
} }
} catch (e) { } catch (e) {
log_trace("limit_calls", e); log_trace("limit_calls", e);
@@ -6157,22 +6157,22 @@ function init_io() {
grace = max( grace = max(
0, 0,
min(new_level + 1, (item.grace || 0) + min(3, player.p.ugrace[new_level] / 4.5) + item_def.igrace) + min(new_level + 1, (item.grace || 0) + min(3, player.p.ugrace[new_level] / 4.5) + item_def.igrace) +
min(6, S.ugrace[new_level] / 3.0) + min(6, S.ugrace[new_level] / 3.0) +
player.p.ograce / 3.2, player.p.ograce / 3.2,
); );
server_log( server_log(
"Grace num: " + "Grace num: " +
grace + grace +
"\nItem: " + "\nItem: " +
(item.grace || 0) + (item.grace || 0) +
"\nPlayer: " + "\nPlayer: " +
min(3, player.p.ugrace[new_level] / 4.5) + min(3, player.p.ugrace[new_level] / 4.5) +
"\nDef: " + "\nDef: " +
item_def.igrace + item_def.igrace +
"\nOgrace:" + "\nOgrace:" +
player.p.ograce / 3.2 + player.p.ograce / 3.2 +
"\nS.ugrace: " + "\nS.ugrace: " +
min(6, S.ugrace[new_level] / 3.0), min(6, S.ugrace[new_level] / 3.0),
); );
grace = (probability * grace) / new_level + grace / 1000.0; grace = (probability * grace) / new_level + grace / 1000.0;
server_log("Grace-prob: " + grace); server_log("Grace-prob: " + grace);
@@ -8072,178 +8072,191 @@ function init_io() {
xy_emit(player, "emotion", { name: data.name, player: player.name }); xy_emit(player, "emotion", { name: data.name, player: player.name });
}); });
socket.on("skill", function (data) { socket.on("skill", function (data) {
var player = players[socket.id]; const player = players[socket.id];
if (!player) { if (!player) {
return; return;
} }
var target = null; server_log("skill " + JSON.stringify(data));
var cool = true; var cool = true;
var resolve = { response: "data", place: data.name, success: true }; var resolve = { response: "data", place: data.name, success: true };
var reject = null; var reject = null;
player.first = true; player.first = true;
G.skills.attack.cooldown = player.attack_ms; G.skills.attack.cooldown = player.attack_ms;
server_log("skill " + JSON.stringify(data));
if (is_disabled(player)) { if (is_disabled(player)) {
return fail_response("disabled", data.name); return fail_response("disabled", data.name);
} }
if ((player.tskin == "konami" || is_silenced(player)) && data.name != "attack") { if ((player.tskin == "konami" || is_silenced(player)) && data.name != "attack") {
return socket.emit("game_response", { response: "skill_cant_incapacitated", place: data.name, failed: true }); return fail_response("skill_cant_incapacitated", data.name);
} }
if (!G.skills[data.name]) {
return socket.emit("game_response", { response: "no_skill", place: data.name, failed: true }); const gSkill = G.skills[data.name];
if (!gSkill) {
return fail_response("no_skill", data.name);
} }
if ( if (
G.skills[data.name].mp && gSkill.mp &&
player.mp < (G.skills[data.name].mp * (100 - (player.mp_reduction || 0))) / 100.0 && player.mp < (gSkill.mp * (100 - (player.mp_reduction || 0))) / 100.0 &&
!(player.role == "gm" && data.name == "blink") !(player.role == "gm" && data.name == "blink")
) { ) {
return socket.emit("game_response", { response: "no_mp", place: data.name, failed: true }); return fail_response("no_mp", data.name);
} }
if (G.skills[data.name].level && player.level < G.skills[data.name].level) {
return socket.emit("game_response", { response: "no_level", place: data.name, failed: true }); if (gSkill.level && player.level < gSkill.level) {
return fail_response("no_level", data.name);
} }
if (
(G.skills[data.name].cooldown || G.skills[data.name].reuse_cooldown) && let cooldown;
player.last[data.name] && let lastUse;
mssince(player.last[data.name]) < (G.skills[data.name].cooldown || G.skills[data.name].reuse_cooldown) if (gSkill.share) {
) { // This skill shares a cooldown with another skill, use that skill's cooldown
return socket.emit("game_response", { cooldown = G.skills[gSkill.share].cooldown * (gSkill.cooldown_multiplier || 1)
response: "cooldown", lastUse = player.last[gSkill.share]
} else {
cooldown = gSkill.cooldown || gSkill.reuse_cooldown;
lastUse = player.last[data.name];
}
if (cooldown && lastUse && mssince(lastUse) < cooldown) {
return fail_response("cooldown", {
skill: data.name, skill: data.name,
place: data.name,
id: data.id, id: data.id,
ms: (G.skills[data.name].cooldown || G.skills[data.name].reuse_cooldown) - mssince(player.last[data.name]), ms: cooldown - mssince(lastUse),
failed: true,
}); });
} }
if ( if (
G.skills[data.name].share && gSkill.class &&
player.last[G.skills[data.name].share] && !in_arr(player.type, gSkill.class)
mssince(player.last[G.skills[data.name].share]) < && player.role != "gm"
G.skills[G.skills[data.name].share].cooldown * (G.skills[data.name].cooldown_multiplier || 1)
) { ) {
return socket.emit("game_response", { return fail_response("skill_cant_use", data.name);
response: "cooldown",
skill: data.name,
place: data.name,
failed: true,
id: data.id,
ms:
G.skills[G.skills[data.name].share].cooldown * (G.skills[data.name].cooldown_multiplier || 1) -
mssince(player.last[G.skills[data.name].share]),
});
} }
if (G.skills[data.name].class && !in_arr(player.type, G.skills[data.name].class) && player.role != "gm") {
return socket.emit("game_response", { response: "skill_cant_use", place: data.name, failed: true }); if (gSkill.wtype && player.role != "gm") {
let canUse;
if (!player.slots.mainhand) {
canUse = false
} else if (is_array(gSkill.wtype)) {
canUse = in_arr(G.items[player.slots.mainhand.name].wtype, gSkill.wtype)
} else {
canUse = G.items[player.slots.mainhand.name].wtype == gSkill.wtype
}
if (!canUse) {
return fail_response("skill_cant_wtype", data.name)
}
} }
if (
G.skills[data.name].wtype && const gMap = G.maps[player.map];
!is_array(G.skills[data.name].wtype) && if (gSkill.hostile && gMap.safe) {
(!player.slots.mainhand || G.items[player.slots.mainhand.name].wtype != G.skills[data.name].wtype) && return fail_response("skill_cant_safe", data.name);
player.role != "gm"
) {
return socket.emit("game_response", { response: "skill_cant_wtype", place: data.name, failed: true });
} }
if (
is_array(G.skills[data.name].wtype) && // TODO: Figure out other target variables later in this on("skill") function so we can change this to 'let'
(!player.slots.mainhand || !in_arr(G.items[player.slots.mainhand.name].wtype, G.skills[data.name].wtype)) && var target;
player.role != "gm" if (gSkill.target) {
) { const isMonster = "" + parseInt(data.id) === "" + data.id
return socket.emit("game_response", { response: "skill_cant_wtype", place: data.name, failed: true }); const isPlayer = !isMonster
} const canTargetMonster = gSkill.target == "monster" || gSkill.target === true
if (G.skills[data.name].hostile && G.maps[player.map].safe) { const canTargetPlayer = gSkill.target == "player" || gSkill.target === true
return socket.emit("game_response", { response: "skill_cant_safe", place: data.name, failed: true }); if ((isMonster && !canTargetMonster) || (isPlayer && !canTargetPlayer)) {
}
if (G.skills[data.name].target) {
if (
("" + parseInt(data.id) === "" + data.id && G.skills[data.name].target == "player") ||
("" + parseInt(data.id) !== "" + data.id && G.skills[data.name].target == "monster")
) {
return fail_response("invalid_target", data.name, { id: data.id }); return fail_response("invalid_target", data.name, { id: data.id });
} }
if (G.skills[data.name].target != "monster" && players[id_to_id[data.id]]) { if (isPlayer && players[id_to_id[data.id]]) {
target = players[id_to_id[data.id]]; target = players[id_to_id[data.id]];
if (G.skills[data.name].hostile && target.name == player.name) { if (gSkill.hostile && target.name == player.name) {
return socket.emit("game_response", { response: "no_target", place: data.name, failed: true }); // Prevent casting the skill on oneself
return fail_response("no_target", data.name)
} }
} else if (G.skills[data.name].target != "player" && instances[player.in].monsters[data.id]) { } else if (isMonster && instances[player.in].monsters[data.id]) {
target = instances[player.in].monsters[data.id]; target = instances[player.in].monsters[data.id];
} else { } else {
// TODO: Consider adding game_response, too
return socket.emit("disappear", { id: data.id, place: data.name, reason: "not_there" }); return socket.emit("disappear", { id: data.id, place: data.name, reason: "not_there" });
} }
if ( if (
is_invis(target) || is_invis(target) ||
(!G.skills[data.name].global && (target.map != player.map || distance(target, player, true) > B.max_vision)) (!gSkill.global && distance(target, player) > B.max_vision)
) { ) {
// TODO: Consider adding game_response, too
return socket.emit("disappear", { id: data.id, place: data.name, reason: "not_there" }); return socket.emit("disappear", { id: data.id, place: data.name, reason: "not_there" });
} }
} }
if (G.skills[data.name].requirements) {
for (var requirement in G.skills[data.name].requirements) { if (gSkill.requirements) {
if (!player[requirement] || player[requirement] < G.skills[data.name].requirements[requirement]) { for (const requirement in gSkill.requirements) {
return socket.emit("game_response", { if (
response: "skill_cant_requirements", !player[requirement] ||
place: data.name, player[requirement] < gSkill.requirements[requirement]
failed: true, ) {
}); return fail_response("skill_cant_requirements", data.name);
} }
} }
} }
if (G.skills[data.name].slot) {
var found = false; if (gSkill.slot) {
var charges = false; let found = false;
G.skills[data.name].slot.forEach(function (p) { let noCharge = false;
if (player.slots[p[0]] && player.slots[p[0]].name == p[1]) { for (const [slotName, itemName] of gSkill.slot) {
if (G.items[player.slots[p[0]].name].charge) { const slotItem = player.slots[slotName]
if ((player.slots[p[0]].charges || 0) < G.items[player.slots[p[0]].name].charge) { if (!slotItem || slotItem.name !== itemName) continue;
charges = true; found = true;
return;
} const gItem = G.items[itemName]
player.slots[p[0]].charges -= G.items[player.slots[p[0]].name].charge; if (!gItem.charge) continue;
player.cslots[p[0]] = cache_item(player.slots[p[0]]); // This skill requires a charge, check the charge level
} if ((slotItem.charges || 0) < gItem.charge) {
found = true; noCharge = true;
continue;
} }
}); // Charge is sufficient, use this item for the skill
if (charges) { slotItem.charges -= gItem.charge;
return socket.emit("game_response", { response: "skill_cant_charges", place: data.name, failed: true }); player.cslots[slotName] = cache_item(slotItem);
noCharge = false;
break;
} }
if (!found) { if (!found) {
return socket.emit("game_response", { response: "skill_cant_slot", place: data.name, failed: true }); return fail_response("skill_cant_slot", data.name);
}
if (noCharge) {
return fail_response("skill_cant_charges", data.name);
} }
} }
if (player.s.invincible) { if (player.s.invincible) {
delete player.s.invincible; delete player.s.invincible;
player.to_resend = "u+cid"; player.to_resend = "u+cid";
} }
if (data.name == "attack" || data.name == "heal") { if (data.name == "attack" || data.name == "heal") {
var attack = commence_attack(player, target, data.name); const attack = commence_attack(player, target, data.name);
if (!attack.failed) { if (!attack.failed) {
resolve = attack; resolve = attack;
} else { } else {
reject = attack; reject = attack;
cool = false; cool = false;
} }
} } else if (data.name == "invis" && !player.s.invis) {
if (data.name == "invis" && !player.s.invis) {
if (player.s.marked) { if (player.s.marked) {
return socket.emit("game_response", { response: "skill_cant_use", place: data.name, failed: true }); return fail_response("skill_cant_use", data.name);
} }
player.s.invis = { ms: 999999999999999 }; player.s.invis = { ms: 999999999999999 };
xy_emit(player, "disappear", { id: player.id, invis: true, reason: "invis" }); xy_emit(player, "disappear", { id: player.id, invis: true, reason: "invis" });
player.to_resend = " "; player.to_resend = " ";
} }
if (data.name == "pickpocket") { if (data.name == "pickpocket") {
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
player.c[data.name] = { player.c[data.name] = {
ms: ms:
G.skills[data.name].duration_min + gSkill.duration_min +
Math.random() * (G.skills[data.name].duration_max - G.skills[data.name].duration_min), Math.random() * (gSkill.duration_max - gSkill.duration_min),
target: target.name, target: target.name,
}; };
player.to_resend = "u+cid"; player.to_resend = "u+cid";
@@ -8252,7 +8265,7 @@ function init_io() {
if (data.name == "fishing" || data.name == "mining") { if (data.name == "fishing" || data.name == "mining") {
var direction = 0; var direction = 0;
var the_zone = null; var the_zone = null;
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
(G.maps[player.map].zones || []).forEach(function (zone) { (G.maps[player.map].zones || []).forEach(function (zone) {
if (zone.type != data.name || the_zone) { if (zone.type != data.name || the_zone) {
return; return;
@@ -8276,8 +8289,8 @@ function init_io() {
xy_emit(player, "ui", { type: data.name + "_start", name: player.name, direction: direction }); xy_emit(player, "ui", { type: data.name + "_start", name: player.name, direction: direction });
player.c[data.name] = { player.c[data.name] = {
ms: ms:
G.skills[data.name].duration_min + gSkill.duration_min +
Math.random() * (G.skills[data.name].duration_max - G.skills[data.name].duration_min), Math.random() * (gSkill.duration_max - gSkill.duration_min),
drop: the_zone.drop, drop: the_zone.drop,
}; };
} }
@@ -8285,7 +8298,7 @@ function init_io() {
player.to_resend = "u+cid"; player.to_resend = "u+cid";
} }
if (data.name == "light") { if (data.name == "light") {
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
xy_emit(player, "light", { name: player.name }); xy_emit(player, "light", { name: player.name });
player.to_resend = "u+cid"; player.to_resend = "u+cid";
} }
@@ -8295,7 +8308,7 @@ function init_io() {
} }
if (data.name == "dash") { if (data.name == "dash") {
//console.log(data); //console.log(data);
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
var x = parseFloat(data.x) || 0; var x = parseFloat(data.x) || 0;
var y = parseFloat(data.y) || 0; var y = parseFloat(data.y) || 0;
var point = true; var point = true;
@@ -8330,18 +8343,18 @@ function init_io() {
} }
} }
if (data.name == "hardshell" || data.name == "power" || data.name == "xpower") { if (data.name == "hardshell" || data.name == "power" || data.name == "xpower") {
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
player.s[G.skills[data.name].condition] = { player.s[gSkill.condition] = {
ms: G.skills[data.name].duration || G.conditions[G.skills[data.name].condition].duration, ms: gSkill.duration || G.conditions[gSkill.condition].duration,
}; };
player.to_resend = "u+cid"; player.to_resend = "u+cid";
} }
if (data.name == "mshield") { if (data.name == "mshield") {
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
if (player.s[G.skills[data.name].condition]) { if (player.s[gSkill.condition]) {
delete player.s[G.skills[data.name].condition]; delete player.s[gSkill.condition];
} else { } else {
player.s[G.skills[data.name].condition] = { ms: 999999999 }; player.s[gSkill.condition] = { ms: 999999999 };
} }
player.to_resend = "u+cid"; player.to_resend = "u+cid";
} }
@@ -8351,13 +8364,13 @@ function init_io() {
data.name == "massproduction" || data.name == "massproduction" ||
data.name == "massproductionpp" data.name == "massproductionpp"
) { ) {
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
player.s[G.skills[data.name].condition] = { ms: G.conditions[G.skills[data.name].condition].duration }; player.s[gSkill.condition] = { ms: G.conditions[gSkill.condition].duration };
xy_emit(player, "ui", { type: data.name, name: player.name }); xy_emit(player, "ui", { type: data.name, name: player.name });
player.to_resend = "u+cid"; player.to_resend = "u+cid";
} }
if (data.name == "throw") { if (data.name == "throw") {
if (distance(player, target, true) > G.skills[data.name].range + player.level) { if (distance(player, target, true) > gSkill.range + player.level) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
if (target.s.invincible || target.immune) { if (target.s.invincible || target.immune) {
@@ -8408,7 +8421,7 @@ function init_io() {
target.hp = max(1, target.hp - damage); target.hp = max(1, target.hp - damage);
disappearing_text({}, target, "-" + damage, { color: "red", xy: 1 }); disappearing_text({}, target, "-" + damage, { color: "red", xy: 1 });
} }
consume_mp(player, G.skills[data.name].mp, target); consume_mp(player, gSkill.mp, target);
xy_emit(player, "ui", { type: "throw", from: player.name, to: target.id, item: item.name }); xy_emit(player, "ui", { type: "throw", from: player.name, to: target.id, item: item.name });
player.to_resend = "u+cid+reopen"; player.to_resend = "u+cid+reopen";
if (target.is_player) { if (target.is_player) {
@@ -8423,7 +8436,7 @@ function init_io() {
return socket.emit("game_response", { response: "skill_cant_item", place: data.name, failed: true }); return socket.emit("game_response", { response: "skill_cant_item", place: data.name, failed: true });
} }
consume_one(player, data.num); consume_one(player, data.num);
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
player.s.phasedout = { ms: G.conditions.phasedout.duration }; player.s.phasedout = { ms: G.conditions.phasedout.duration };
player.to_resend = "u+cid+reopen"; player.to_resend = "u+cid+reopen";
} }
@@ -8432,7 +8445,7 @@ function init_io() {
return socket.emit("game_response", { response: "skill_cant_item", place: data.name, failed: true }); return socket.emit("game_response", { response: "skill_cant_item", place: data.name, failed: true });
} }
consume_one(player, data.num); consume_one(player, data.num);
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
player.s.poisonous = { ms: G.skills.pcoat.cooldown }; player.s.poisonous = { ms: G.skills.pcoat.cooldown };
player.to_resend = "u+cid+reopen"; player.to_resend = "u+cid+reopen";
} }
@@ -8448,7 +8461,7 @@ function init_io() {
} }
} }
if (data.name == "snowball") { if (data.name == "snowball") {
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
var found = false; var found = false;
@@ -8479,14 +8492,14 @@ function init_io() {
if (target.s.invincible) { if (target.s.invincible) {
return socket.emit("game_response", { response: "target_invincible", place: data.name, failed: true }); return socket.emit("game_response", { response: "target_invincible", place: data.name, failed: true });
} }
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
add_condition(target, "tangled", { ms: G.skills["entangle"].duration }); add_condition(target, "tangled", { ms: G.skills["entangle"].duration });
target.abs = true; target.abs = true;
target.moving = false; target.moving = false;
xy_emit(player, "ui", { type: "entangle", from: player.name, to: target.id }); xy_emit(player, "ui", { type: "entangle", from: player.name, to: target.id });
consume_mp(player, G.skills[data.name].mp, target); consume_mp(player, gSkill.mp, target);
add_pdps(player, target, 4000); add_pdps(player, target, 4000);
if (data.name == "entangle") { if (data.name == "entangle") {
consume_one(player, data.num); consume_one(player, data.num);
@@ -8504,7 +8517,7 @@ function init_io() {
if (target.s.invincible) { if (target.s.invincible) {
return socket.emit("game_response", { response: "target_invincible", place: data.name, failed: true }); return socket.emit("game_response", { response: "target_invincible", place: data.name, failed: true });
} }
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
if (!is_in_pvp(player) && !is_same(player, target, 1)) { if (!is_in_pvp(player) && !is_same(player, target, 1)) {
@@ -8513,7 +8526,7 @@ function init_io() {
add_condition(target, "fingered", { ms: G.skills["4fingers"].duration }); add_condition(target, "fingered", { ms: G.skills["4fingers"].duration });
add_condition(target, "stunned", { duration: G.skills["4fingers"].duration - 2000 }); add_condition(target, "stunned", { duration: G.skills["4fingers"].duration - 2000 });
xy_emit(player, "ui", { type: "4fingers", from: player.name, to: target.name }); xy_emit(player, "ui", { type: "4fingers", from: player.name, to: target.name });
consume_mp(player, G.skills[data.name].mp, target); consume_mp(player, gSkill.mp, target);
add_pdps(player, target, 1000); add_pdps(player, target, 1000);
resend(target, "u+cid"); resend(target, "u+cid");
player.to_resend = "u+cid"; player.to_resend = "u+cid";
@@ -8560,7 +8573,7 @@ function init_io() {
if (!player.items[data.num] || player.items[data.num].name != "essenceoflife") { if (!player.items[data.num] || player.items[data.num].name != "essenceoflife") {
return socket.emit("game_response", { response: "skill_cant_item", place: data.name, failed: true }); return socket.emit("game_response", { response: "skill_cant_item", place: data.name, failed: true });
} }
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
if (!target.rip) { if (!target.rip) {
@@ -8586,7 +8599,7 @@ function init_io() {
var times = 0; var times = 0;
var attack = null; var attack = null;
var c_resolve = null; var c_resolve = null;
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
player.first_burst = true; player.first_burst = true;
player.halt = true; player.halt = true;
if (is_array(data.targets)) { if (is_array(data.targets)) {
@@ -8666,15 +8679,15 @@ function init_io() {
} }
} }
if (data.name == "darkblessing" || data.name == "warcry") { if (data.name == "darkblessing" || data.name == "warcry") {
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
for (var id in instances[player.in].players) { for (var id in instances[player.in].players) {
var target = instances[player.in].players[id]; var target = instances[player.in].players[id];
if ( if (
!target.npc && !target.npc &&
distance(player, target, true) < G.skills[data.name].range && distance(player, target, true) < gSkill.range &&
(!(G.maps[player.map].pvp || is_pvp) || is_same(player, target, 1)) (!(G.maps[player.map].pvp || is_pvp) || is_same(player, target, 1))
) { ) {
target.s[G.skills[data.name].condition] = { ms: G.skills[data.name].duration, f: player.name }; target.s[gSkill.condition] = { ms: gSkill.duration, f: player.name };
resend(target, "u+cid"); resend(target, "u+cid");
add_pdps(player, target, 500); add_pdps(player, target, 500);
} }
@@ -8727,7 +8740,7 @@ function init_io() {
// if(times==1 && attack==null) times=40; // if(times==1 && attack==null) times=40;
}); });
} }
consume_mp(player, G.skills[data.name].mp, reftarget); consume_mp(player, gSkill.mp, reftarget);
player.halt = false; player.halt = false;
player.to_resend = "u+cid"; player.to_resend = "u+cid";
if (!c_resolve) { if (!c_resolve) {
@@ -8766,7 +8779,7 @@ function init_io() {
list.sort(function (a, b) { list.sort(function (a, b) {
return a.dist - b.dist; return a.dist - b.dist;
}); });
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
xy_emit(player, "ui", { type: "track", name: player.name }); xy_emit(player, "ui", { type: "track", name: player.name });
socket.emit("track", list); socket.emit("track", list);
player.to_resend = "u+cid"; player.to_resend = "u+cid";
@@ -8794,23 +8807,23 @@ function init_io() {
ids.push(id); ids.push(id);
} }
} }
consume_mp(player, G.skills[data.name].mp, target); consume_mp(player, gSkill.mp, target);
xy_emit(player, "ui", { type: "agitate", name: player.name, ids: ids }); xy_emit(player, "ui", { type: "agitate", name: player.name, ids: ids });
player.to_resend = "u+cid"; player.to_resend = "u+cid";
add_pdps(player, null, 1000); add_pdps(player, null, 1000);
} }
if (data.name == "absorb") { if (data.name == "absorb") {
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
var ids = []; var ids = [];
if (is_same(player, target, 1)) { if (is_same(player, target, 1)) {
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
} else { } else {
if (player.mp < G.skills[data.name].mp * 6 || player.level < 75) { if (player.mp < gSkill.mp * 6 || player.level < 75) {
return socket.emit("game_response", { response: "non_friendly_target", place: data.name, failed: true }); return socket.emit("game_response", { response: "non_friendly_target", place: data.name, failed: true });
} }
consume_mp(player, G.skills[data.name].mp * 6); consume_mp(player, gSkill.mp * 6);
if (Math.random() < 0.95) { if (Math.random() < 0.95) {
consume_skill(player, data.name); consume_skill(player, data.name);
resend(player, "u+cid"); resend(player, "u+cid");
@@ -8862,14 +8875,14 @@ function init_io() {
} }
} }
} }
consume_mp(player, G.skills[data.name].mp, reftarget); consume_mp(player, gSkill.mp, reftarget);
xy_emit(player, "ui", { type: "stomp", name: player.name, ids: ids }); xy_emit(player, "ui", { type: "stomp", name: player.name, ids: ids });
player.to_resend = "u+cid"; player.to_resend = "u+cid";
resolve = { response: "data", place: data.name, success: true, ids: ids }; resolve = { response: "data", place: data.name, success: true, ids: ids };
} }
if (data.name == "scare") { if (data.name == "scare") {
var ids = []; var ids = [];
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
for (var id in instances[player.in].monsters) { for (var id in instances[player.in].monsters) {
var target = instances[player.in].monsters[id]; var target = instances[player.in].monsters[id];
if (target.target == player.name) { if (target.target == player.name) {
@@ -8892,7 +8905,7 @@ function init_io() {
if (target.is_player && !is_in_pvp(player) && !is_same(player, target, 1)) { if (target.is_player && !is_in_pvp(player) && !is_same(player, target, 1)) {
return socket.emit("game_response", { response: "skill_cant_pve", place: data.name, failed: true }); return socket.emit("game_response", { response: "skill_cant_pve", place: data.name, failed: true });
} }
consume_mp(player, G.skills[data.name].mp, target); consume_mp(player, gSkill.mp, target);
add_condition(target, "marked"); add_condition(target, "marked");
if (target.is_player) { if (target.is_player) {
resend(target, "u+cid"); resend(target, "u+cid");
@@ -8904,7 +8917,7 @@ function init_io() {
player.to_resend = "u+cid"; player.to_resend = "u+cid";
} }
if (data.name == "charm") { if (data.name == "charm") {
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
if (Math.random() > 0.01) { if (Math.random() > 0.01) {
socket.emit("game_response", "charm_failed"); socket.emit("game_response", "charm_failed");
xy_emit(player, "ui", { type: "charm", name: player.name, id: target.id, fail: true }); xy_emit(player, "ui", { type: "charm", name: player.name, id: target.id, fail: true });
@@ -8932,7 +8945,7 @@ function init_io() {
for (var id in instances[player.in].monsters) { for (var id in instances[player.in].monsters) {
var target = instances[player.in].monsters[id]; var target = instances[player.in].monsters[id];
var dist = distance(player, target); var dist = distance(player, target);
if (dist < G.skills[data.name].range) { if (dist < gSkill.range) {
attack = commence_attack(player, target, data.name); attack = commence_attack(player, target, data.name);
if (!attack || !attack.projectile) { if (!attack || !attack.projectile) {
continue; continue;
@@ -8952,7 +8965,7 @@ function init_io() {
for (var id in instances[player.in].players) { for (var id in instances[player.in].players) {
var target = instances[player.in].players[id]; var target = instances[player.in].players[id];
var dist = distance(player, target); var dist = distance(player, target);
if (dist < G.skills[data.name].range && !target.npc && !is_same(player, target, 1)) { if (dist < gSkill.range && !target.npc && !is_same(player, target, 1)) {
attack = commence_attack(player, target, data.name); attack = commence_attack(player, target, data.name);
if (!attack || !attack.projectile) { if (!attack || !attack.projectile) {
continue; continue;
@@ -8970,7 +8983,7 @@ function init_io() {
} }
} }
} }
consume_mp(player, G.skills[data.name].mp, reftarget); consume_mp(player, gSkill.mp, reftarget);
xy_emit(player, "ui", { type: data.name, name: player.name, ids: ids }); xy_emit(player, "ui", { type: data.name, name: player.name, ids: ids });
player.halt = false; player.halt = false;
if (c_resolve) { if (c_resolve) {
@@ -8979,7 +8992,7 @@ function init_io() {
} }
if (data.name == "magiport") { if (data.name == "magiport") {
var pported = false; var pported = false;
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
if (!is_pvp && mode.pve_safe_magiports) { if (!is_pvp && mode.pve_safe_magiports) {
if (!magiportations[player.name]) { if (!magiportations[player.name]) {
magiportations[player.name] = {}; magiportations[player.name] = {};
@@ -9015,7 +9028,7 @@ function init_io() {
player.s.blink.d = data.direction; player.s.blink.d = data.direction;
} }
if (player.role != "gm") { if (player.role != "gm") {
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
} }
// xy_emit(player,"ui",{type:"blinking",name:player.name}); // xy_emit(player,"ui",{type:"blinking",name:player.name});
resend(player, "u+cid"); resend(player, "u+cid");
@@ -9046,37 +9059,37 @@ function init_io() {
player.s.blink.d = data.direction; player.s.blink.d = data.direction;
} }
if (player.role != "gm") { if (player.role != "gm") {
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
} }
// xy_emit(player,"ui",{type:"blinking",name:player.name}); // xy_emit(player,"ui",{type:"blinking",name:player.name});
player.to_resend = "u+cid"; player.to_resend = "u+cid";
// #TODO: Appear animation for non-self's [21/05/18] // #TODO: Appear animation for non-self's [21/05/18]
} }
if (data.name == "mluck") { if (data.name == "mluck") {
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
if ( if (
!target.s[G.skills[data.name].condition] || !target.s[gSkill.condition] ||
!target.s[G.skills[data.name].condition].strong || !target.s[gSkill.condition].strong ||
target.s[G.skills[data.name].condition].f == player.name target.s[gSkill.condition].f == player.name
) { ) {
target.s[G.skills[data.name].condition] = { ms: G.conditions.mluck.duration, f: player.name }; target.s[gSkill.condition] = { ms: G.conditions.mluck.duration, f: player.name };
} }
if (target.owner == player.owner) { if (target.owner == player.owner) {
target.s[G.skills[data.name].condition].strong = true; target.s[gSkill.condition].strong = true;
} }
xy_emit(player, "ui", { type: "mluck", from: player.name, to: target.name }); xy_emit(player, "ui", { type: "mluck", from: player.name, to: target.name });
resend(target, "u+cid"); resend(target, "u+cid");
resend(player, "u+cid"); resend(player, "u+cid");
} }
if (data.name == "rspeed") { if (data.name == "rspeed") {
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
target.s[G.skills[data.name].condition] = { ms: G.conditions.rspeed.duration, f: player.name }; target.s[gSkill.condition] = { ms: G.conditions.rspeed.duration, f: player.name };
xy_emit(player, "ui", { type: "rspeed", from: player.name, to: target.name }); xy_emit(player, "ui", { type: "rspeed", from: player.name, to: target.name });
resend(target, "u+cid"); resend(target, "u+cid");
resend(player, "u+cid"); resend(player, "u+cid");
@@ -9085,11 +9098,11 @@ function init_io() {
} }
} }
if (data.name == "reflection") { if (data.name == "reflection") {
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
target.s[G.skills[data.name].condition] = { ms: G.conditions.reflection.duration, f: player.name }; target.s[gSkill.condition] = { ms: G.conditions.reflection.duration, f: player.name };
xy_emit(player, "ui", { type: "reflection", from: player.name, to: target.name }); xy_emit(player, "ui", { type: "reflection", from: player.name, to: target.name });
resend(target, "u+cid"); resend(target, "u+cid");
resend(player, "u+cid"); resend(player, "u+cid");
@@ -9098,7 +9111,7 @@ function init_io() {
} }
} }
if (data.name == "energize") { if (data.name == "energize") {
if (distance(player, target, true) > G.skills[data.name].range) { if (distance(player, target, true) > gSkill.range) {
return socket.emit("game_response", { response: "too_far", place: data.name, failed: true }); return socket.emit("game_response", { response: "too_far", place: data.name, failed: true });
} }
if (!player.mp) { if (!player.mp) {
@@ -9116,7 +9129,7 @@ function init_io() {
} }
disappearing_text(player.socket, player, "-" + mp, { color: "mana", xy: 1 }); disappearing_text(player.socket, player, "-" + mp, { color: "mana", xy: 1 });
disappearing_text(target.socket, target, "+" + mp, { color: "mana", xy: 1 }); disappearing_text(target.socket, target, "+" + mp, { color: "mana", xy: 1 });
target.s[G.skills[data.name].condition] = { ms: G.conditions[G.skills[data.name].condition].duration }; target.s[gSkill.condition] = { ms: G.conditions[gSkill.condition].duration };
xy_emit(player, "ui", { type: "energize", from: player.name, to: target.name }); xy_emit(player, "ui", { type: "energize", from: player.name, to: target.name });
resend(target, "u+cid"); resend(target, "u+cid");
resend(player, "u+cid"); resend(player, "u+cid");
@@ -9137,7 +9150,7 @@ function init_io() {
} else if (player.level >= 50) { } else if (player.level >= 50) {
rate = 0.86; rate = 0.86;
} }
consume_mp(player, G.skills[data.name].mp); consume_mp(player, gSkill.mp);
xy_emit(player, "ui", { type: "alchemy", name: player.name }); xy_emit(player, "ui", { type: "alchemy", name: player.name });
for (var i = 0; i < player.isize; i++) { for (var i = 0; i < player.isize; i++) {
if (!player.items[i] || player.items[i].l) { if (!player.items[i] || player.items[i].l) {
@@ -9296,21 +9309,21 @@ function init_io() {
if (current === undefined || current >= 2 || going === undefined || going >= 2) { if (current === undefined || current >= 2 || going === undefined || going >= 2) {
server_log( server_log(
"#C cheater: " + "#C cheater: " +
player.name + player.name +
" current: " + " current: " +
current + current +
"[" + "[" +
data.x + data.x +
"," + "," +
data.x + data.x +
"] going: " + "] going: " +
going + going +
"[" + "[" +
player.going_x + player.going_x +
"," + "," +
player.going_y + player.going_y +
"] at " + "] at " +
player.map, player.map,
1, 1,
); );
appengine_log("violation", "move_line: " + player.name + " afk: " + player.afk + " code: " + player.code); appengine_log("violation", "move_line: " + player.name + " afk: " + player.afk + " code: " + player.code);
@@ -9716,7 +9729,7 @@ function init_io() {
} }
try { try {
delete_observer(socket); delete_observer(socket);
} catch (e) {} } catch (e) { }
players[socket.id] = player; players[socket.id] = player;
resume_instance(instances[player.in]); resume_instance(instances[player.in]);
@@ -10494,7 +10507,7 @@ function init_io() {
socket.emit("tavern", { event: "info", edge: house_edge(), max: parseInt((S.gold - house_debt()) * 0.4) }); socket.emit("tavern", { event: "info", edge: house_edge(), max: parseInt((S.gold - house_debt()) * 0.4) });
} }
}); });
socket.on("play", function (data) {}); socket.on("play", function (data) { });
socket.on("pet", function (data) { socket.on("pet", function (data) {
var player = players[socket.id]; var player = players[socket.id];
if (!player) { if (!player) {
@@ -10648,7 +10661,7 @@ function init_io() {
var observer = observers[socket.id]; var observer = observers[socket.id];
try { try {
delete sockets[socket.id]; delete sockets[socket.id];
} catch (e) {} } catch (e) { }
if (player) { if (player) {
player.dc = true; player.dc = true;
try { try {
@@ -11960,7 +11973,7 @@ function update_instance(instance) {
if (player && player.in == monster.in && !player.rip && !is_invis(player)) { if (player && player.in == monster.in && !player.rip && !is_invis(player)) {
if ( if (
distance(player, monster, true) > distance(player, monster, true) >
min(monster.range / 1.6, 240) + min(100, monster.attack / 5.0) + 160 + ((mode.all_smart && 320) || 1) && min(monster.range / 1.6, 240) + min(100, monster.attack / 5.0) + 160 + ((mode.all_smart && 320) || 1) &&
!monster.walk_once !monster.walk_once
) { ) {
stop_pursuit(monster, { cause: "exceeds_range" }); stop_pursuit(monster, { cause: "exceeds_range" });
@@ -12590,7 +12603,7 @@ function update_instance(instance) {
if (def.withdrawal) { if (def.withdrawal) {
add_condition(player, def.withdrawal); add_condition(player, def.withdrawal);
} }
} catch (e) {} } catch (e) { }
player.slots.elixir = null; player.slots.elixir = null;
player.cslots.elixir = null; player.cslots.elixir = null;
resend(player, "reopen+u+cid"); resend(player, "reopen+u+cid");
@@ -13246,7 +13259,7 @@ setInterval(function () {
retries: 5, retries: 5,
item: mitem, item: mitem,
}, },
function (result) {}, function (result) { },
function () { function () {
console.log("#M unsent giveaway, lost item: " + mitem); console.log("#M unsent giveaway, lost item: " + mitem);
}, },
@@ -13413,7 +13426,7 @@ setInterval(function () {
(monster.extra_gold || 0) + (monster.extra_gold || 0) +
((min(min(2400, target.attack) / 220.0 + monster.attack / 1.2, 55) + 19) * ((min(min(2400, target.attack) / 220.0 + monster.attack / 1.2, 55) + 19) *
((gameplay == "hardcore" && 100) || 1)) / ((gameplay == "hardcore" && 100) || 1)) /
(max((target.targets - 1) * (target.targets - 1), 1) || 1); (max((target.targets - 1) * (target.targets - 1), 1) || 1);
} }
} }
} catch (e) { } catch (e) {
@@ -13604,7 +13617,7 @@ function sync_loop() {
server_log("#X SEVERE: sync notingame disconnect for " + player.name, 1); server_log("#X SEVERE: sync notingame disconnect for " + player.name, 1);
try { try {
player.socket.disconnect(); player.socket.disconnect();
} catch (e) {} } catch (e) { }
} }
delete player.sync_call; delete player.sync_call;
}, },
@@ -13636,13 +13649,13 @@ function sync_loop() {
function (result) { function (result) {
server_log( server_log(
"stop_character: " + "stop_character: " +
player.name + player.name +
" owner: " + " owner: " +
player.owner + player.owner +
" bank: " + " bank: " +
bank + bank +
" result: " + " result: " +
JSON.stringify(result), JSON.stringify(result),
1, 1,
); );
if (result.done) { if (result.done) {