Files
wsmud/world/cmd/extend/biwu.js
2026-05-26 16:41:20 +08:00

446 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
this.inherits(COMMAND);
this.command = "biwu";
this.allow_busy = true;
this.allow_state = true;
this.allow_die = true;
this.biwu_state = {
allow_busy: false,
allow_state: false,
allow_die: false,
allow_die: false
};
const STATS = WORLD.STATS;
this.regex = /^(emei|wudang|shaolin|huashan|xiaoyao|gaibang|shashou|none)?\s*(\d+)(?:\s+(ok))?$/;
this.enter = function (me, fam, type, par) {
if (!me.can_trans()) return;
if (!WORLD.COMMANDS.events.check_command(this.biwu_state, me)) return;
let index = parseInt(type);
if (!(index > 0 && index < 11)) return me.notify('错误的对手编号。');
if (fam && me.family.id !== fam.toUpperCase())
return me.notify('你只能挑战自己门派的高手榜单。');
const top_key = fam ? "top_fam" : "top";
let top = me.query_temp(top_key, 999);
if (top === index) {
return me.notify('你不能挑战自己。');
// return me.send_commands('biwu recopy', '更新擂台使用的技能和装备属性');
}
if (top <= index)
return me.notify('你只能挑战积分比你高的对手。');
let max = Math.floor(me.query_temp("ex_jl", 0) / 40);
let count = me.query_temp('top_c', 0);
if (count >= max) return me.notify('你今天的挑战次数已经用尽每日精力每消耗40增加一次挑战机会。');
if (!par) {
me.notify(`<hig>当你每消耗40精力后增加一次挑战机会当前可挑战次数${count}/${max}</hig>`);
if (count < max) {
fam = fam ? (fam + " ") : "";
return me.send_commands('biwu ' + fam + type + " ok", '确定挑战');
}
return;
}
if (me.state) return me.send('你正在' + me.state.title + "。");
if (me.status && me.status.length)
return me.send('你需要清理掉自身的增益效果才可上擂台挑战。');
if (me.hp / me.max_hp < 0.9 || me.mp / me.max_mp < 0.9)
return me.send('你先调整好自身的状态再来挑战吧。');
this.start_biwu(me, fam, index - 1);
}
this.start_biwu = function (me, fam, index) {
let tops = STATS.TOPS;
if (fam) tops = STATS['tops_' + fam.toUpperCase()];
if (!tops) return me.send('错误的对手,无法挑战。');
var npc = tops[index];
if (!npc) {
return me.send(me, "错误的对手。");
}
if (me.moveto('yz/leitai/leitai') === false) return;
npc = this.create_npc(npc);
let room = me.environment;
me.die = challenge_end;
npc.die = challenge_end;
room.on_heart_beat = this.on_heart_beat;
room.biwu_step = 0;
me.auto_pfm = true;
me.check_pfms = this.check_pfms;
me.init_pfms = this.init_pfms;
npc.fight_type = 0;
room.item_changed(npc, true, npc.name + "跳上了擂台。");
npc.full();
me.add_temp('top_c', 1, UTIL.diff_time());
me.set_temp('biwu_fam', fam);
me.call_interval(x => {
me.send_message("\n<hic>挑战还有" + (3 - x) + "秒钟正式开始!</hic>", true);
},
1000,
3,
function () {
npc.do_kill(me);
}
);
me.send('{type:"dialog",dialog:"stats",close:true}');
}
this.surrender = function (me) {
// if (!me.fight_type)
// return me.send('你还没开始战斗呢。');
let npc = me.environment.items[1];
if (npc.is_player) {
npc = me.environment.items[0];
}
me.end_fight();
npc.end_fight();
challenge_over(me, 2);
challenge_fail(me);
}
this.on_heart_beat = function (dt) {
this.biwu_step++;
if (this.biwu_step < 60) return;
if (!this.items.length) {
return;
}
let me = this.items[0], npc = this.items[1];
if (npc && npc.is_player) {
me = npc;
npc = this.items[0];
}
me.end_fight();
npc?.end_fight();
challenge_over(me, 2);
challenge_fail(me);
me.notify("<yel>挑战超时,自动离开擂台。</yel>");
}
function challenge_end(killer) {
if (this.on_die && this.on_die(killer) === false) {
this.hp = 1;
return false;
}
let me = killer, npc = this;
if (this.is_player) {
npc = killer, me = this;
}
if (me.hp <= 0) me.hp = 1;
me.end_fight();
npc.end_fight();
if (killer === me) {
challenge_over(me, 1, npc);
challenge_success(me, npc);
} else {
challenge_over(me, 0, npc);
challenge_fail(me, npc);
// me.notify("<cyn>挑战失败,你的积分保持不变。</cyn>");
}
}
function challenge_over(me, result, npc) {
me.environment.on_heart_beat = null;
me.die = USER.prototype.die
me.auto_pfm = false;
me.auto_skills = null;
me.check_pfms = USER.prototype.check_pfms;
me.init_pfms = USER.prototype.init_pfms;
let leitai = me.environment;
if (result === 0)
me.moveto('yz/leitai/ltx', null, me.name +
"被" + npc.name + "一脚踢下了擂台。", 'fightend');
else if (result === 1) {
me.moveto('yz/leitai/ltx', null, me.name +
"走了下来。", 'fightend');
} else {
me.moveto('yz/leitai/ltx', null, me.name +
"被赶下来。", 'fightend');
}
leitai.items.length = 0;
me.clear_downside(true);
}
function challenge_fail(me, npc) {
me.notify("<cyn>挑战失败,擂台积分保持不变。</cyn>");
me.remove_temp('biwu_fam');
}
function challenge_success(me, npc) {
const fam = me.query_temp('biwu_fam');
let top_key = fam ? "top_fam_sc" : "top_sc";
let sc = me.query_temp(top_key, 0);
let target_sc = npc.score ?? 0;
let add = Math.floor((target_sc - sc) / 2);
if (add === 0) {
add = 1;
}
if (add > 0) {
sc += add;
me.set_temp(top_key, sc);
} else {
add = 0;
}
if (fam)
me.notify("<hig>挑战成功,当前" + me.family.name + "榜单积分" + sc + "。</hig>");
else
me.notify("<hig>挑战成功,当前总榜积分" + sc + "。</hig>");
if (add > 0)
WORLD.COMMANDS.biwu.updatePlayerStats(me, sc, fam);
me.remove_temp('biwu_fam');
}
const COPY_TEMPS = ["copy_pfm_sword",//"copy_pfm",
"copy_pfm_unarmed", "jiuyang", "zyy"];
const COPY_PROPS = ["str", "con", "dex", "int", "gender", "max_mp", "exp", "pot", "kar", "per"
, "name", "hp", "max_hp", "mp"];
this.create_npc = function (player, fam) {
var npc = NPC.CLONE('pub/gaoshou1');
for (var i = 0; i < COPY_PROPS.length; i++) {
npc[COPY_PROPS[i]] = player[COPY_PROPS[i]];
}
npc.equipment = [];
if (player.equipment) {
var eqs = player.equipment;
for (var i = 0; i < eqs.length; i++) {
if (!eqs[i]) continue;
var obj = eqs[i].clone(player);
npc.equipment[obj.eq_type] = obj;
if (obj.on_eq) obj.on_eq(npc);
}
}
npc.skills = {};
if (player.skills) {
for (var sk in player.skills) {
let item = player.skills[sk];
npc.skills[sk] = { ...item };
}
}
npc.attack_count = 3;
if (player.is_player) {
npc.title = player.query_title("family");
npc.age = player.query_age();
npc.userid = player.id;
npc.score = player.query_temp(fam ? 'top_fam_sc' : "top_sc", 0);
npc.top_index = player.query_temp(fam ? 'top_fam' : "top", 0);
npc.id = "top_" + (fam ? fam.toUpperCase() : "") + "_" + (npc.top_index - 1);
} else {
npc.title = player.title;
npc.age = player.age;
npc.userid = player.userid;
npc.score = player.score;
npc.top_index = player.top_index;
}
for (let key of COPY_TEMPS) {
let value = player.query_temp(key);
if (value) {
npc.set_temp(key, value);
}
}
npc.clear_prop();
npc.init();
npc.recount = this.recount;
npc.recount();
npc.check_pfms = this.check_pfms;
npc.init_pfms = this.init_pfms;
if (npc.force_skill.on_relive) {
npc.force_skill.on_relive(npc);
}
npc.hp = npc.max_hp;
return npc;
}
this.recount = function () {
this.max_hp = parseInt(this.con * 5 + (this.max_mp * this.query_force_rad() + this.query_prop("max_hp") + this.query_prop("con") * this.con) * (100 + this.query_prop("hp_per")) / 100);
this.max_hp = this.max_hp;
if (this.max_hp < 1) this.max_hp = 1;
if (this.hp > this.max_hp) this.hp = this.max_hp;
this.gjsd = 4000 - this.query_prop("gjsd");
if (this.gjsd > 500) {
this.gjsd = parseInt(this.gjsd - (this.gjsd * this.query_prop("gjsd_per") / 100));
}
if (this.gjsd < 500) this.gjsd = 500;
this.gj = parseInt(this.str + (this.query_prop("gj") + this.query_prop("str") * this.str / 10) * (100 + this.query_prop("gj_per")) / 100);
this.fy = parseInt(((this.str + this.con) / 10 + this.query_prop("fy") + this.query_prop("con") * this.con / 10) * (100 + this.query_prop("fy_per")) / 100);
this.mz = parseInt((this.dex / 2 + this.query_prop("mz")) * (100 + this.query_prop("mz_per")) / 100);
this.ds = parseInt((this.dex / 2 + this.query_prop("ds") + this.query_prop("dex") * this.dex / 10) * (100 + this.query_prop("ds_per")) / 100);
this.zj = parseInt((this.str / 2 + this.query_prop("zj") + this.query_prop("str") * this.str / 10) * (100 + this.query_prop("zj_per")) / 100);
this.bj = parseInt(this.dex / 10 + this.query_prop("bj_per"));
if (this.parry_skill && this.parry_skill.on_recount_parry) {
this.zj += this.parry_skill.on_recount_parry(this);
}
if (this.dodge_skill && this.dodge_skill.on_recount_dodge) {
this.ds += this.dodge_skill.on_recount_dodge(this);
}
this.diff_sh_per = this.query_prop('diff_sh_per');
if (this.diff_sh_per > 80) {
this.diff_sh_per = 80 + Math.sqrt((this.diff_sh_per - 80) * 4);
if (this.diff_sh_per > 99.9999) this.diff_sh_per = 99.9999;
}
this.diff_sh_per += this.query_prop('diff_sh_per2');
}
this.check_pfms = function (target) {
if (!this.auto_skills) this.init_pfms()
if (!this.equipment[0] && this.items[0] && this.random(3) === 0) {
return this.equip(this.items[0]);
}
if (this.auto_eqs.length > 0 && this.random(3) === 1) {
let eqs = [];
for (var i = 0; i < this.auto_eqs.length; i++) {
let obj = this.auto_eqs[i];
let key = "disobj_" + (obj.distype || obj.id);
if (obj.distime && this.query_temp(key)) {
continue;
}
eqs.push(obj);
}
if (eqs.length > 0) {
let obj = eqs.random();
if (obj.on_use(this) !== false) {
if (obj.distime) {
this.set_temp("disobj_" + (obj.distype || obj.id), 1, obj.distime);
}
return;
}
}
}
return CHARACTER.prototype.check_pfms.call(this, target);
}
this.init_pfms = function () {
CHARACTER.prototype.init_pfms.call(this);
this.auto_eqs = [];
for (var i = 1; i < this.equipment.length; i++) {
if (this.equipment[i] && this.equipment[i].on_use) {
this.auto_eqs.push(this.equipment[i]);
}
}
}
const TOPS = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"];
this.setStatsTitle = function (player, index, fam) {
if (fam) return;//门派称号先不用
if (index < 10) {
let title = "天下第" + TOPS[index];
player.add_title(title, "top");
player.notify('<hiy>你的高手榜称号变动为【'
+ title + '】。</hiy>');
}
else
player.add_title(null, "top");
}
this.checkStats = function (player) {
let top = player.query_temp("top");
if (top) {
this.check_fams_stats(player, STATS.TOPS, top);
}
top = player.query_temp("top_fam");
if (top) {
this.check_fams_stats(player, STATS['tops_' + player.family.id], top, player.family.id);
}
}
this.check_fams_stats = function (player, tops, top, fam) {
let npc = tops[top - 1];
if (!npc) return;
let top_key = fam ? "top_fam" : "top";
if (npc.userid !== player.id) {
for (let i = 0; i < tops.length; i++) {
if (tops[i].userid === player.id) {
player.set_temp(top_key, i + 1);
return this.setStatsTitle(player, i, fam);
}
}
player.remove_temp(top_key);
this.setStatsTitle(player, 9999, fam);
}
}
this.updateTopStats = function (top, index, fam) {
let top_user = top.userid ? WORLD.getUser(top.userid) : null;
let top_key = fam ? "top_fam" : "top";
if (index > 0) {
top.top_index = index + 1;
top.id = "top_" + (fam ? fam.toUpperCase() : "") + "_" + index;
if (top_user) {
top_user.set_temp(top_key, index + 1);
this.setStatsTitle(top_user, index, fam);
}
} else {
top.top_index = -1;
if (top_user) {
top_user.remove_temp(top_key);
this.setStatsTitle(top_user, 10, fam);
}
}
}
this.checkTopindex = function (sc, tops) {
let index = -1;
for (let i = tops.length - 1; i >= 0; i--) {
let item = tops[i];
if (item.score >= sc) return index;
index = i;
}
return 0;
}
this.updatePlayerStats = function (player, sc, fam) {
//玩家挑战没上榜不用管,挑战失败减分也不会下榜,因为没有记录以下的玩家
//这里只会上升不会下降
let tops = STATS.TOPS;
let top_key = "top";
if (fam) {
tops = STATS['tops_' + fam.toUpperCase()];
top_key = "top_fam";
}
if (!tops) return;
let index = this.checkTopindex(sc, tops);
if (index < 0) {
return;
}
let top = player.query_temp(top_key, 0);
if (top > 0) {
tops[top - 1].score = sc;
if (top <= index + 1) return;
tops.splice(top - 1, 1);
}
player.set_temp(top_key, index + 1);
tops.splice(index, 0, this.create_npc(player, fam));
if (tops.length > 10) {
this.updateTopStats(tops.splice(tops.length - 1)[0], -1, fam);
}
if (top == 0) {
top = tops.length;
}
for (let i = index + 1; i < top; i++) {
this.updateTopStats(tops[i], i, fam);
}
if (!fam) {
this.setStatsTitle(player, index);
// player.notify('<hiy>恭喜你获得称号【' + "天下第" + TOPS[index] + '】</hiy>');
}
}
this.biwu_watch = function (me) {
}