# 毕业生跑酷pro-主图

最新更新日期：2023年11月5日

阿兹卡班毕业生神岛个人中心：

{% embed url="<https://dao3.fun/profile/12728135>" %}
阿兹卡班毕业生神岛个人中心
{% endembed %}

地图通关全过程B站视频：&#x20;

{% embed url="<https://www.bilibili.com/video/BV1fe411Q7kL/?share_source=copy_web&vd_source=47fb8dc2c290d3efba51bb252a91c38d>" %}

## **加入q群763919859领地图福利** <a href="#yj5n-1702035241935" id="yj5n-1702035241935"></a>

## index.js <a href="#na5s-1702035241936" id="na5s-1702035241936"></a>

```
/*作者：阿兹卡班毕业生*/
/*未经许可 禁止转载和使用 仅供学习*/
 var admin = ['阿兹卡班毕业生','羽帆','tangyuan儿',,'奶油.','奶油','KyTT','爱肝作品的小诚吖_赤炎宗','意柳','执着的树毛虫','芸游XY','耐心的大黄鸡mSos','怂怂的小彤e2','耐心的大黄鸡mSos','外向的雷电猴(巅峰队)','SAZ','QTK.十字铁路DCB','奶油.','奶油','机智的彩虹兔f2.原一颗狼星','高冷的小魏1y','星光烈火龙']
// var victory = false
var lzxglist = ['JB6tX5vKo/o0R0gN']
var msglist = ['等你发言','等你发言']
var dmm = false;
var zbznc = '';
var dcz = [];
var dctime = 0;
var zbtime = 0;
var beizhuadao = [];
var dmmrenshu=0;/*阿|兹|卡|班|毕|业|生*/
console.clear()

var Storage = storage.getGroupStorage('cundang'); // 获取数据库，名称为 cundang

const CorrespondingName = { // 在此添加排行榜对应的单位和名称（无名称 则表示不显示名称）
    'exp': ['经验', '无名称']
};/*|az|kb|b||y|s*/

const unsavedData = { // 玩家初始无需保存的数据，可增添或删除
    victory: false,
    ingjf: false,
    cankick: true,
    dmmzy: '',/*阿|兹|卡|班|毕|业|生*/
    dmmshoudao: false
};/*|az|kb|b||y|s*/

const savedData = { // 玩家初始需要保存的数据，可增添或删除
    exp: 50,
    bag: [],
    greenlzxg: false,
    zhutu_position_x: 3,/*阿|兹|卡|班|毕|业|生*/
    zhutu_position_y:6,
    zhutu_position_z:4,
    chun_position_x: 3,/*阿|兹|卡|班|毕|业|生*/
    chun_position_y:6,/*|az|kb|b||y|s*/
    chun_position_z:4,/*阿|兹|卡|班|毕|业|生*/
    xia_position_x: 3,/*|az|kb|b||y|s*/
    xia_position_y:6,
    xia_position_z:4,/*阿|兹|卡|班|毕|业|生*/
    qiu_position_x: 3,
    qiu_position_y:6,/*阿|兹|卡|班|毕|业|生*/
    qiu_position_z:4,
    dong_position_x: 3,
    dong_position_y:6,/*阿|兹|卡|班|毕|业|生*/
    dong_position_z:4,
    isadmin: false,
    canplay: true,
    used_duihuanma: []/*阿|兹|卡|班|毕|业|生*/
};

/**
 * 初始化玩家数据
 * 
 * @param {GameEntity} entity
 */
function initPlayer(entity) { // 初始化玩家数据
    Object.assign(entity, savedData);/*阿|兹|卡|班|毕|业|生*/
    Object.assign(entity, unsavedData);
};
/*|az|kb|b||y|s*/
/**
 * 获取玩家数据
 * 
 * @param {GameEntity} entity
 */
function getPlayerData(entity) { // 获取玩家数据
    var data = { 'name': entity.player.name };
    for (let i in savedData) { // 遍历savedData，获取玩家当前数据
        data[i] = entity[i];
    };/*阿|兹|卡|班|毕|业|生*/
    return data;
};
/*阿|兹|卡|班|毕|业|生*/
/**
 * 存档
 * 
 * @param {GameEntity} entity
 */
async function savePlayer(entity) { // 存档
    await Storage.update(entity.player.userId, () => {  // 更新玩家数据存档
        return getPlayerData(entity);
    });
};/*阿|兹|卡|班|毕|业|生*/
/*|az|kb|b||y|s*/
/**
 * 删档
 * 
 * @param {GameEntity} entity
 */
async function deletePlayer(entity) { // 删档
    entity.save = false
    await Storage.remove(entity.player.userId); // 删除玩家数据存档
};

/**
 * 读档
 * 
 * @param {GameEntity} entity
 */
async function loadPlayer(entity) { // 读档
    initPlayer(entity);/*阿|兹|卡|班|毕|业|生*/
    var data = await Storage.get(entity.player.userId); // 获取数据
    if (data) { // 如果数据存在
        Object.assign(entity, data.value);
        entity.player.directMessage('已为您读取数据！');
    } else { // 如果数据不存在
        await Storage.set(entity.player.userId, getPlayerData(entity));
        entity.player.directMessage('已为您创建数据！');
    };
};
/*阿|兹|卡|班|毕|业|生*/
/**
 * 清档
 */
async function deleteAllData() { // 清档
    var sqlDataList = await Storage.list({ // 将数据库内的所有数据分页
        cursor: 0
    });
    world.querySelectorAll('player').forEach(x => x.save = false);
    try {
        while (true) {/*阿|兹|卡|班|毕|业|生*/
            for (let sqlData of sqlDataList.getCurrentPage()) { // 遍历获取数据
                await Storage.remove(sqlData.key)
            }
            if (sqlDataList.isLastPage) break; // 如果已经是最后一页，退出循环
            await sqlDataList.nextPage(); // 下一页
        };
    } catch (e) {}
};

/**
 * 显示排行榜
 * 
 * @param {string} type
 */
async function leaderBoard(type) { // 排行榜
    var list = [];/*阿|兹|卡|班|毕|业|生*/
    var sqlDataList = await Storage.list({ // 将数据库内的所有数据分页
        cursor: 0
    });
    while (true) {
        for (let sqlData of sqlDataList.getCurrentPage()) { // 遍历获取数据
            list.includes([sqlData.value['name'], sqlData.value[type]]) ? null : list.push([sqlData.value['name'], sqlData.value[type]]);
        }
        list = list.sort((a, b) => b[1] - a[1]).slice(0, 100);
        if (sqlDataList.isLastPage) break; // 如果已经是最后一页，退出循环
        await sqlDataList.nextPage(); // 下一页
    };
    return list.map((value, num) => // 将列表里的所有项依次替换成字符串
        `第${num + 1}名 | ${value[0]} | ${value[1]} ${CorrespondingName[type][0]}${CorrespondingName[type][1] != '无名称' ? CorrespondingName[type][1] : ''}`
    ).join("\n"); // 按照 换行 的间隔组合成字符串
};

require('./防止想不开.js')
require('./宠物.js')

function find(name){
    const a = world.querySelectorAll`player`;
    for(let i in a)if(a[i].player.name == name)return a[i];
}

//私聊
async function chats(entity, other, text) {
    other.player.directMessage('收到一条私信')
    const has = await other.player.dialog({
        type: GameDialogType.SELECT,
        title: "私聊",
        titleTextColor: new GameRGBAColor(0, 0, 0, 1),
        titleBackgroundColor: new GameRGBAColor(0.968, 0.702, 0.392, 1),
        content: `${entity.player.name}：\n${text}`,
        options: ['回复', '取消'],
    });
    if (!has || has === null) {
        entity.player.directMessage('你被TA无逝了，呵呵哈哈');
        return;
    }
    if (has.value === '回复') {/*阿|兹|卡|班|毕|业|生*/
        entity.player.directMessage('对方收到了你的私信')
        const returns = await other.player.dialog({
            type: GameDialogType.INPUT,
            title: "私聊-回复",
            titleTextColor: new GameRGBAColor(0, 0, 0, 1),
            titleBackgroundColor: new GameRGBAColor(0.968, 0.702, 0.392, 1),
            content: `${other.player.name}，请输入回复内容`,
            confirmText: '发送',
            placeholder: '输入回复内容',
        });
        if (!returns || returns === null) {
            return;
        }
        chats(other, entity, returns)
    }
    else if (has.value === '取消') {
        entity.player.directMessage('对方收到了你的私信')
    }
}
world.onPlayerJoin(({ entity }) => {
    entity.player.interactTimes = 0;
    entity.enableInteract = true;
    entity.interactRadius = 1.5;
    if(entity.player.name=='阿兹卡班毕业生'||entity.player.name=='奶油.'||entity.player.name=='SAZ'||entity.player.name=='羽帆'){/*阿|兹|卡|班|毕|业|生*/
        entity.interactHint = `与 【作者认证】 ${entity.player.name} 互动`;
    }
    else if(admin.includes(entity.player.name||entity.isadmin==true)){
        entity.interactHint = `与 【管理员认证】 ${entity.player.name} 互动`;
    }
    entity.onInteract(async ({ entity, targetEntity }) => {
        targetEntity.player.directMessage('你被 ' + entity.player.name + ' 访问了')
        while (!entity.destroyed) {
            const others = await entity.player.dialog({
                type: GameDialogType.SELECT,
                title: targetEntity.player.name + '',
                titleTextColor: new GameRGBAColor(0, 0, 0, 1),
                titleBackgroundColor: new GameRGBAColor(0.968, 0.702, 0.392, 1),
                content: `你要干啥`,
                options: ['和TA私聊','没啥，就看看'],
            })
            if (!others || others === null) {
                return;
            }
            if (others.value == '和TA私聊') {
                const chating = await entity.player.dialog({
                    type: GameDialogType.INPUT,
                    title: "私聊",
                    titleTextColor: new GameRGBAColor(0, 0, 0, 1),
                    titleBackgroundColor: new GameRGBAColor(0.968, 0.702, 0.392, 1),
                    content: `${entity.player.name}，请输入私聊内容`,
                    confirmText: '发送',
                    placeholder: '输入私聊内容',
                });
                if (!chating || chating === null) {
                    return;
                }
                chats(entity, targetEntity, chating)
                return;
            }
        }
    })
})


async function dialog(title,content,entity){
    const result = await entity.player.dialog({
        type: GameDialogType.TEXT,
        title: title,
        content: content,
    });
}/*阿|兹|卡|班|毕|业|生*/

world.onPlayerJoin(({entity})=>{
    entity.player.jumpPower=0.7
    entity.player.doubleJumpPower=0.7
    if(admin.includes(entity.player.name)){
        entity.isadmin=true;
    }
})/*阿|兹|卡|班|毕|业|生*/

world.onPlayerJoin(async({ entity }) => {
    // entity.player.enableDoubleJump=false
    const dialog = entity.player.dialog({
        type: GameDialogType.TEXT,
        title: "作者&协作者们",/*阿|兹|卡|班|毕|业|生*/
        content: `${entity.player.name}，欢迎来到毕业生跑酷pro，下面是对于本地图的一些介绍：\n
         · 老版地图不再更新，但关卡与pro版不同，链接：https://box3.codemao.cn/p/bysrun
         · 地图有sql存档，妈妈再也不用担心我把存档搞丢啦！
         · 地图有一个小彩蛋，你能找到吗？
         · 如有bug请在评论区@作者！
         · 经验计算规则：第一次游玩赠送50经验，以后每碰到一个新的存档点经验+1
         · 在游戏中违规被作者看到可能会被踢出/封禁
         · 加入Q群763919859领粒子效果！
         · 与朋友一起竞速吧！
        最后，祝您在毕业生跑酷pro玩得愉快！`,
    });
    const result3 = await entity.player.dialog({
        type: GameDialogType.SELECT,
        title: '注意',
        content: `本地图的通关实况出来啦！是否进入外部网站观看？（不会覆盖当前标签页）`,
        options:['确定','看看','继续','好的','不了','好']
    });
    if(!result3 || result3 === null){
        entity.player.link('https://dao3.fun/play/28072b1e727173f57c25https://www.bilibili.com/video/BV1fe411Q7kL/?share_source=copy_web&vd_source=47fb8dc2c290d3efba51bb252a91c38d');
    }
    else if(result3.value!='不了'){
        entity.player.link('https://www.bilibili.com/video/BV1fe411Q7kL/?share_source=copy_web&vd_source=47fb8dc2c290d3efba51bb252a91c38d');
    }
    const result = entity.player.dialog({
        type: GameDialogType.TEXT,
        title: "作者&协作者们",
        content: `全新附图上新！右键点击“选择附图”查看！！！`,
    });
    const result2 = entity.player.dialog({
        type: GameDialogType.TEXT,
        title: "提示",
        content: `管理员们，管理员docs文档已出，详情看评论区置顶`,
    });
    if(entity.player.name == '阿兹卡班毕业生'||entity.player.name=='羽帆'||entity.player.name=='SAZ'){
        world.say(`作者来辣~`)
    }else{
        world.say(`欢迎${entity.player.name}进入毕业生跑酷pro！`)
    }
});

function addWearable(entity, data) {
    // 这一步是把角度转成弧度
    const orientation = new GameQuaternion(0, 0, 0, 1)
            .rotateZ(data.rotate[2] * Math.PI / 180) 
            .rotateX(data.rotate[0] * Math.PI / 180) 
            .rotateY(data.rotate[1] * Math.PI / 180) 
    // 将上面声明的配置一一对应地传递给传递API
    entity.player.addWearable({
        bodyPart: data.bodyPart,/*阿|兹|卡|班|毕|业|生*/
        mesh: data.mesh,
        orientation: orientation,
        scale: data.scale,
        offset: data.offset,
    })
}
const zuozhe = [
 { bodyPart: GameBodyPart.HEAD, name: '头', mesh: 'mesh/绿宝石块.vb', offset: [1, 0, 0], rotate: [45, 45, 45], scale: [0.5, 0.5, 0.5] },
 { bodyPart: GameBodyPart.HEAD, name: '头', mesh: 'mesh/钻石.vb', offset: [-1, 0, 0], rotate: [45, 45, 45], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.TORSO, name: '躯干', mesh: 'mesh/1楼.vb', offset: [0, 0.1, 0], rotate: [0, 90, 0], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.TORSO, name: '臀部', mesh: 'mesh/光轮2000.vb', offset: [0, -0.3, 0], rotate: [0, 0, 30], scale: [0.7, 0.7, 0.7] },
//  { bodyPart: GameBodyPart.LEFT_UPPER_ARM, name: '左上臂', mesh: 'mesh/1楼.vb', offset: [0.1, 0.07,-0.02], rotate: [-128, 120, -85], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.RIGHT_UPPER_ARM, name: '右上臂', mesh: 'mesh/1楼.vb', offset: [-0.1, 0.07,-0.02], rotate: [-45, -120, -85], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.LEFT_LOWER_ARM, name: '左下臂', mesh: 'mesh/1楼.vb', offset: [0, 0.11, 0], rotate: [-128, 120, -85], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.RIGHT_LOWER_ARM, name: '右下臂', mesh: 'mesh/1楼.vb', offset: [0, 0.09, 0], rotate: [-45, -120, -85], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.LEFT_UPPER_LEG, name: '左上腿', mesh: 'mesh/1楼.vb', offset: [0, -0.05, 0], rotate: [0, 90, 0], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.RIGHT_UPPER_LEG, name: '右上腿', mesh: 'mesh/雾雨魔理沙上腿.vb', offset: [0, -0.1, 0], rotate: [0, 90, 0], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.LEFT_LOWER_LEG, name: '左下腿', mesh: 'mesh/雾雨魔理沙下腿.vb', offset: [0, 0.07, 0], rotate: [0, 90, 0], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.RIGHT_LOWER_LEG, name: '右下腿', mesh: 'mesh/雾雨魔理沙下腿.vb', offset: [0, 0.07, 0], rotate: [0, 90, 0], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.LEFT_FOOT, name: '左脚', mesh: 'mesh/雾雨魔理沙脚.vb', offset: [0, 0.06, 0.05], rotate: [0, 90, 0], scale: [0.5, 0.5, 0.5] },
    // { bodyPart: GameBodyPart.RIGHT_LOWER_ARM, name: '右手', mesh: 'mesh/我的世界_钻石剑.vb', offset: [-0.2, 0.2, 0.2], rotate: [-45, 90, -45], scale: [1, 1, 1] },
//  { bodyPart: GameBodyPart.LEFT_LOWER_ARM, name: '左手', mesh: 'mesh/我的世界·附魔三叉戟.vb', offset: [0.15, 0.15, 0.09], rotate: [110, 243
//  , 180], scale: [0.5, 0.5, 0.5] },
//  { bodyPart: GameBodyPart.RIGHT_LOWER_ARM, name: '右手', mesh: 'mesh/皇冠.vb', offset: [-0.16, 0.05, 0.1], rotate: [-138, 60, 95], scale: [0.5, 0.5, 0.5] },
]
const yufan = [
 { bodyPart: GameBodyPart.HEAD, name: '头', mesh: 'mesh/小鱼干.vb', offset: [1.3, 0, 0], rotate: [45, -45, 45], scale: [0.01, 0.01, 0.01] }
]
const saz = [
{bodyPart: GameBodyPart.RIGHT_LOWER_ARM, name: '右下臂', mesh: 'mesh/我的世界附魔钻石剑.vb', offset: [-0.4, 0.4, 0.25], rotate: [135, 135, 135], scale: [1, 1, 1]},
{bodyPart: GameBodyPart.HEAD_LOWER_ARM, name: '头', mesh: 'mesh/墨镜.vb', offset: [0, 0.8, 0.25], rotate: [0, 90, 0], scale: [0.2, 0.3, 0.3]}
]
function chuandaipeijian(entity){
    if(entity.player.name==`阿兹卡班毕业生`){
        for (const data of zuozhe) {
            addWearable(entity, data)
        }
        entity.player.directMessage(`穿戴配件成功`);
    }
    else if(entity.player.name=='KyTT'||entity.player.name=='羽帆'){
        for (const data of yufan) {
            addWearable(entity, data)
        }
        entity.player.directMessage(`穿戴配件成功`);
    }
    else if(entity.player.name==`SAZ`){
        for (const data of saz) {
            addWearable(entity, data)
        }
         entity.player.directMessage(`穿戴配件成功`);
        }
    // else if(entity.player.name==`KyTT`){
    //     for (const data of kytt) {
    //         addWearable(entity, data)
    //     }
    // }
    // 有bug
    // if(hmd in entity.player.name){
    //     // 隐藏所有身体部件！
    //     for (const bodyPart in entity.player.skinInvisible) {
    //         entity.player.skinInvisible[bodyPart] = true;
    //     }
    // }
    else{
        entity.player.directMessage(`你不符合穿戴配件的条件`);
    }
    if(entity.player.name=='阿兹卡班毕业生'){
        entity.player.name.color = new GameRGBColor(1,0,1)
    }
}
world.onPlayerJoin(async({entity})=>{
    chuandaipeijian(entity)
})

//sql相关
world.onPlayerJoin(async({entity})=>{
    await loadPlayer(entity);
    entity.position.set(entity.zhutu_position_x,entity.zhutu_position_y,entity.zhutu_position_z)
    entity.player.spawnPoint.set(entity.zhutu_position_x,entity.zhutu_position_y,entity.zhutu_position_z)
})
world.onPlayerLeave(async({entity})=>{
    entity.save != false ? await savePlayer(entity) : null; // 存档
    savePlayer(entity);
})
const points = world.querySelectorAll('.存档点')
points.forEach((e)=>{
    e.onEntityContact(({other})=>{
        const spawnPoint = e.position.add({x: 0,y: 2.5,z: 0});
        if(spawnPoint.equals(other.player.spawnPoint))return;
        other.player.spawnPoint = spawnPoint;
        other.zhutu_position_x=e.position.x;
        other.zhutu_position_y=e.position.y+2.5;
        other.zhutu_position_z=e.position.z;
        savePlayer(other);
        other.player.directMessage('存档成功！');
        if(other.victory==false){
            other.exp+=1;
        }
    })
})
world.onFluidEnter(({entity, tick, voxel}) => {
    const voxelName = voxels.name(voxel)
    if (voxelName=='water'&&entity.ingjf==false){
        entity.player.forceRespawn()
        entity.player.directMessage(`落水重生`)
    }
})

world.onChat(({message,entity})=>{
            var huancun = msglist[0];
            msglist[0]=entity.player.name+'：\n'+message;
            for(var i=1;i<=2;i++){
                msglist[i] = huancun;
                huancun = msglist[i+1]
            }
            world.say(`${entity.player.name}：${message}`)
            if(entity.player.name!='阿兹卡班毕业生'&&(message==`ban 阿兹卡班毕业生`||message==`kick 阿兹卡班毕业生`)){
                dialog(`作者`,`胆子很大啊！敢封禁/踢出作者！`,entity);
                entity.position.set(2,6,10);
            }
        })
        world.onPlayerJoin(({entity})=>{
            world.onChat(({message,entity:user})=>{    
                if(user.player.name='阿兹卡班毕业生'){
                    if(message.startsWith('push admin')){
                        console.log(message.slice(11));
                        if(entity.player.name==message.slice(11)){
                            entity.isadmin=true;
                            savePlayer(entity);
                            world.say('恭喜'+entity.player.name+'成为管理员');
                            dialog(`阿兹卡班毕业生`,`恭喜你入选管理员，希望你为毕业生跑酷pro做出贡献\n刷新后生效`,entity);
                        }
                    }
                    else if(message.startsWith('kick')){
                        console.log(message.slice(5));
                        if(entity.player.name==message.slice(5)){
                            entity.position.set(2,6,10);
                            dialog(`阿兹卡班毕业生`,`你被作者踢出，请退出游戏`,entity);
                            entity.player.kick()
                        }
                    }
                    else if(message.startsWith('ban')){
                        console.log(message.slice(5));
                        if(entity.player.name==message.slice(4)){
                            entity.canplay=false;
                            savePlayer(entity);
                            entity.position.set(2,6,10);
                            dialog(`阿兹卡班毕业生`,`你被作者封禁，移至小黑屋，请退出游戏`,entity);
                            world.say(entity.player.name+'被作者封禁');
                        }
                    }
                    else if(message.startsWith('canplay')){
                        console.log(message.slice(8));
                        if(entity.player.name==message.slice(8)){
                            entity.canplay=true;
                            entity.position.set(2,10,10);
                            dialog(`阿兹卡班毕业生`,`已解除封禁\n为了防止sql存档异常，请右键sql存档或者踩一个存档点`,entity);
                            savePlayer(entity);
                        }
                    }
                    else if(message.startsWith('cancommand')){
                        if(entity.player.name==message.slice(11)){
                            entity.cancommand=true;
                        }
                    }
                    else if(message.startsWith('cannotcommand')){
                        if(entity.player.name==message.slice(14)){
                            entity.cancommand=false;
                        }
                    }
                }
            })
    })
// })
// world.onPlayerJoin(({entity})=>{
//     entity.player.onChat(({message,entity:user})=>{world.say(`${user.player.name}：${message}`)})
// })
// npc交互
const xiaoheiwu = world.querySelector('#小黑屋');
xiaoheiwu.enableInteract = true; // 允许进行互动
xiaoheiwu.interactRadius = 5;   // 实体的互动范围
xiaoheiwu.interactHint = `小黑屋\n不想被关进小黑屋就安分守己哦~`; // 互动提示框显示实体的名称
xiaoheiwu.interactColor = new GameRGBColor(1,1,1);  // 互动提示的文字颜色

const tzxyg1 = world.querySelector('#跳转下一关-1');
tzxyg1.enableInteract = true; // 允许进行互动
tzxyg1.interactRadius = 2;   // 实体的互动范围
tzxyg1.interactHint = `互动跳转下一关`; // 互动提示框显示实体的名称
tzxyg1.interactColor = new GameRGBColor(1,1,1);  // 互动提示的文字颜色
tzxyg1.onInteract(({entity})=>{
    entity.position.set(123,15,30)
})

const boat = world.querySelector('#船');
boat.enableInteract = true; // 允许进行互动
boat.interactRadius = 2;   // 实体的互动范围
boat.interactColor = new GameRGBColor(1,1,1);  // 互动提示的文字颜色
boat.interactColor = new GameRGBColor(1,1,1);  // 互动提示的文字颜色
boat.onInteract(({entity})=>{
    dialog(`小船`,`嘿！发现彩蛋啦！\n给你上上色~\n加入Q群763919859领取更多福利！`,entity)
    entity.player.color=new GameRGBColor(0,1,1)
})

const xuanzefutu = world.querySelector('#dream-1');
xuanzefutu.enableInteract = true; // 允许进行互动
xuanzefutu.interactRadius = 5;   // 实体的互动范围
xuanzefutu.interactHint = `选择附图`; // 互动提示框显示实体的名称
xuanzefutu.interactColor = new GameRGBColor(1,1,1);  // 互动提示的文字颜色
xuanzefutu.onInteract(async({entity})=>{
    const result = await entity.player.dialog({
        type: GameDialogType.SELECT,
        title: '选择附图',
        content:`点击附图名称，查看详情`,
        options:['春','夏']
    });
    if(!result || result.value === null){ 
        return; 
    }
    else if(result.value=='春'){
        const result = await entity.player.dialog({
            type: GameDialogType.SELECT,
            title: '地图详情',
            content:`地图主题：春\n\n点击按钮进入地图`,
            options:['进入地图','就是看看']
        });
        if(!result || result.value === null){ 
            return; 
        }
        else if(result.value=='进入地图'){
            entity.player.link('https://dao3.fun/play/6d789dabd5e09ca687ce')
        }
    }
    else if(result.value=='夏'){
        const result = await entity.player.dialog({
            type: GameDialogType.SELECT,
            title: '地图详情',
            content:`地图主题：夏\n\n点击按钮进入地图`,
            options:['进入地图','就是看看']
        });
        if(!result || result.value === null){ 
            return; 
        }
        else if(result.value=='进入地图'){
            entity.player.link('https://dao3.fun/play/54230e5fd4ecbaecc0ee')
        }
    }
})

const tiaoguandream = world.querySelector('#跳关dream');
tiaoguandream.enableInteract = true; // 允许进行互动
tiaoguandream.interactRadius = 5;   // 实体的互动范围
tiaoguandream.interactHint = `跳关`; // 互动提示框显示实体的名称
tiaoguandream.interactColor = new GameRGBColor(1,1,1);  // 互动提示的文字颜色
tiaoguandream.onInteract(async({entity})=>{
    const result = await entity.player.dialog({
        type: GameDialogType.SELECT,
        title: '选择',
        content:`确定花费40exp跳关么`,
        options:['是','否']
    });
    if(!result || result.value === null){ 
        return; 
    }
    else if(result.value=='是'){
        if(entity.exp>=40){
            entity.exp-=40;
            entity.position.set(79,19,18)
            savePlayer(entity)
            entity.player.directMessage('跳关成功')
        }
        else{
            dialog('错误','经验不足',entity)
        }
    }
})

const end = world.querySelector('#终点');
// end.enableInteract = true; // 允许进行互动
// end.interactRadius = 2;   // 实体的互动范围
end.onEntityContact(async({other})=>{
    if(other.victory==false){
        other.position.set(4,7,4)
        other.player.color= new GameRGBColor(0,1,0)
        other.player.canFly=true
        dialog(`系统`,`恭喜你通关了！！！\n已开启您的飞行权限\n经验+50`,other)
        world.say(`恭喜${other.player.name}通关游戏！`)
        other.exp+=50
        savePlayer(other)
        other.victory=true
    }
    else{
        dialog(`系统`,`你已经通过关了，按下右键-重来可以重来`,other)
    }
})

// 碰撞过滤
world.addCollisionFilter('player','player')

// 管理员代码
world.onChat(({ entity, message }) => {
    if(admin.includes(entity.player.name)||entity.isadmin==true||cancommand==true){
        if (message.startsWith('$')&&message.startsWith('$while')==false ) {
            try {
                world.say('<~ ' + eval(message.slice(1)))
            }
            catch (err) {
                world.say('<~ ' + err)
            }
        }
    }
})

const particle_greenCrystal = {
    particleRate: 500,
    particleLifetime: 0.4,
    particleSize: [4, 3, 2, 1, 0.25],
    particleColor: [
        new GameRGBColor(1, 1, 0),
        new GameRGBColor(0, 1, 0),
        new GameRGBColor(0, 1, 0),
        new GameRGBColor(0, 1, 0),
        new GameRGBColor(1, 1, 1)
    ],
}
const test_green = {
    particleRate: 500,
    particleLifetime: 999,
    particleSize: [4, 3, 2, 1, 0.25],
    particleColor: [
        new GameRGBColor(1, 1, 0),/*azkbbys*/
        new GameRGBColor(0, 1, 0),
        new GameRGBColor(0, 1, 0),
        new GameRGBColor(0, 1, 0),
        new GameRGBColor(1, 1, 1)
    ],
}
const particle_purpleCrystal = {
    particleRate: 500,
    particleLifetime: 0.4,
    particleSize: [4, 3, 2, 1, 0.25],
    particleColor: [
        new GameRGBColor(0, 0, 1),
        new GameRGBColor(0, 0, 1),
        new GameRGBColor(1, 0, 1),
        new GameRGBColor(1, 0, 1),
        new GameRGBColor(1, 1, 1)
    ],
}
const wcbl = {
    particleRate: 700,
    particleLifetime: 1.5,
    particleSize: [1.5, 1.5, 1.5, 1.5, 1.5],
    particleColor: [
        new GameRGBColor(0, 1, 0),
        new GameRGBColor(0, 0, 1),
        new GameRGBColor(1, 0, 1),
        new GameRGBColor(0, 1, 1),
        new GameRGBColor(1, 1, 1)
    ],
}
world.onPlayerJoin(async({entity})=>{
    if(entity.player.name=='阿兹卡班毕业生'){
        entity.player.color=new GameRGBColor(1,0,1)
        Object.assign(entity, wcbl)
    }
    else if(admin.includes(entity.player.name)||entity.isadmin==true){
        Object.assign(entity, particle_purpleCrystal)
    }
    else if(entity.greenlzxg==true||lzxglist.includes(entity.player.userKey)||lzxglist.includes(entity.player.name)){
        Object.assign(entity, particle_greenCrystal)
    }
})

// 右键菜单
world.onPress(async({button,entity})=>{
    if(button==='action1'){
        const result = await entity.player.dialog({
            type: GameDialogType.SELECT,
            title: '游戏菜单',
            content:`你有${entity.exp}经验\n`+`你的userkey：${entity.player.userKey}\n`+ `你的血量：`+entity.hp+`/`+entity.maxHp+`\n你的坐标：`+entity.position,
            options:['选择附图','兑换码','sql存档','sql删档','经验排行榜','商店','背包','重来','脱离卡点','进入/离开挂机房','进入/退出俯视全图','切换人称','bug反馈','禁言玩家说话','管理员工具']
        });
        if(!result || result.value === null){ 
            return; 
        }
        else if(result.value=='选择附图'){
            entity.position.set(97,40,74);
            dialog(`系统`,`你已进入附图选择区域，与dream互动即可选择附图，要退出请右键点击“脱离卡点”`,entity)
        }
        /*被删除的代码：兑换码系统（为了防止兑换码泄露，已删除）*/
        else if(result.value=='sql存档'){
            savePlayer(entity);
            dialog(`系统`,`存档成功！\n每次踩到存档点会自动进行所有数据的保存`,entity)
        }
        else if(result.value=='sql删档'){
            const result = await entity.player.dialog({
                type: GameDialogType.SELECT,
                title: '你确定要删档吗？',
                content:`你确定要删档吗？\n删档后一切数据将消失！\n不能后悔！`,
                options:['不确定','算了','没想好','不删','删了吧']
            });
            if(result.value=='删了吧'){
                Object.assign(entity, savedData);
                savePlayer(entity);
                entity.player.kick();
            }
        }
        else if(result.value=='经验排行榜'){
            await entity.player.dialog({
                type: 'select',
                title: '排行',
                content: await leaderBoard('exp'),
                options: ['确认']
            });
        }
        else if(result.value=='商店'){
            const result = await entity.player.dialog({
                type: GameDialogType.SELECT,
                title: '你要买点啥？',
                content:`你要买点啥？\n你有${entity.exp}经验\n说明：名称（价格）（备注）`,
                options:['退出','一次性飞行特权（70exp）（开启飞行权限，仅能在一个地图使用！有效期：2s）','一次性飞行变速器（5exp）（更改飞行速度，仅能在一个地图使用！使用前提：已经开启飞行）','永久绿色粒子效果（150exp）（全图同步）','缩小药水（70exp）（一次性，将角色大小缩小50%，不可叠加使用）','还原药水（1exp）（一次性，将角色大小还原','放大药水（70exp）（一次性，将角色大小增大50%，不可叠加使用）']/*azkbbys*/
            });
            if(!result || result.value === null){ 
                return; 
            }
            else if(result.value=='一次性飞行特权（70exp）（开启飞行权限，仅能在一个地图使用！有效期：2s）'){
                if(entity.exp>=80){
                    entity.exp-=80;
                    entity.bag.push('一次性飞行特权')
                    savePlayer(entity);
                    entity.player.directMessage(`购买成功，已放入背包`)
                }
                else{
                    dialog(`错误`,`经验不够！`,entity)
                }
            }
            else if(result.value=='一次性飞行变速器（5exp）（更改飞行速度，仅能在一个地图使用！使用前提：已经开启飞行）'){
                if(entity.exp>=5){
                    entity.exp-=5;
                    entity.bag.push('一次性飞行变速器')
                    savePlayer(entity);
                    entity.player.directMessage(`购买成功，已放入背包`)
                }
                else{
                    dialog(`错误`,`经验不够！`,entity)
                }
            }
            else if(result.value=='永久绿色粒子效果（150exp）（全图同步）'){
                if(entity.exp>=150){
                    entity.exp-=150;
                    entity.greenlzxg=true;
                    savePlayer(entity);
                    entity.player.directMessage(`购买成功，已自动使用，刷新后生效`)
                }
                else{
                    dialog(`错误`,`经验不够！`,entity)
                }
            }
            else if(result.value=='缩小药水（70exp）（一次性，将角色大小缩小50%，不可叠加使用）'){
                if(entity.exp>=70){
                    entity.exp-=70;
                    entity.bag.push('一次性缩小药水')
                    savePlayer(entity);
                    entity.player.directMessage(`购买成功，已放入背包`)
                }
                else{
                    dialog(`错误`,`经验不够！`,entity)
                }
            }
            else if(result.value=='还原药水（1exp）（一次性，将角色大小还原'){
                if(entity.exp>=1){
                    entity.exp-=1;
                    entity.bag.push('一次性还原药水')
                    savePlayer(entity);
                    entity.player.directMessage(`购买成功，已放入背包`)
                }
                else{
                    dialog(`错误`,`经验不够！`,entity)
                }
            }
            else if(result.value=='放大药水（70exp）（一次性，将角色大小增大50%，不可叠加使用）'){
                if(entity.exp>=70){
                    entity.exp-=70;
                    entity.bag.push('一次性放大药水')
                    savePlayer(entity);
                    entity.player.directMessage(`购买成功，已放入背包`)
                }
                else{
                    dialog(`错误`,`经验不够！`,entity)
                }
            }
        }
        else if(result.value=='背包'){
            const result = await entity.player.dialog({
                type: GameDialogType.SELECT,
                title: '你要使用啥？',
                content:`你要使用啥？\n警告：点击后立即使用无确认\n退出请点X`,
                options:entity.bag
            });
            if(!result || result.value === null){ 
                return; 
            }
            else if(result.value=='一次性飞行特权'){
                entity.player.canFly=true;
                let index = entity.bag.indexOf('一次性飞行特权');
                if (index !== -1) {
                    entity.bag.splice(index, 1);
                }
                savePlayer(entity)
                entity.player.canFly=true;
                entity.player.directMessage('使用成功，2s后降落');
                await sleep(2000);
                entity.player.canFly=false;
            }
            else if(result.value=='一次性飞行变速器'){
                let index = entity.bag.indexOf('一次性飞行变速器');
                if (index !== -1) {
                    entity.bag.splice(index, 1);
                }
                const flyspeed = await entity.player.dialog({
                    type: GameDialogType.INPUT,
                    title: '自定义飞行速度',
                    content: `输入飞行速度，不要试探服务器极限`,
                    confirmText: '确认',
                });
                entity.player.flySpeed=flyspeed
                savePlayer(entity)
                entity.player.directMessage('使用成功')
            }
            else if(result.value=='一次性缩小药水'){
                let index = entity.bag.indexOf('一次性缩小药水');
                if (index !== -1) {
                    entity.bag.splice(index, 1);
                }
                entity.player.scale=0.5
                savePlayer(entity)
                entity.player.directMessage('使用成功')
            }
            else if(result.value=='一次性还原药水'){
                let index = entity.bag.indexOf('一次性还原药水');
                if (index !== -1) {
                    entity.bag.splice(index, 1);
                }
                entity.player.scale=1
                savePlayer(entity)
                entity.player.directMessage('使用成功')
            }
            else if(result.value=='一次性放大药水'){
                let index = entity.bag.indexOf('一次性放大药水');
                if (index !== -1) {
                    entity.bag.splice(index, 1);
                }
                entity.player.scale=1.5
                savePlayer(entity)
                entity.player.directMessage('使用成功')
            }
            else if(result.value=='无限飞行羽翼'){
                entity.player.canFly=true;
                entity.player.directMessage('使用成功')
            }
        }/*© 阿兹卡班毕业生*/
        else if(result.value=='重来'){
            if(entity.canplay==false){
                dialog(`系统`,`你在封禁中，不能出来`,entity)
            }
            else{
                entity.player.directMessage(`重来`)
                entity.victory = false
                entity.player.canFly=false
                entity.hp=100
                entity.player.color = new GameRGBColor(1,1,1)
                entity.position.set(4,5,4)
                entity.ingjf=false;
            }
        }
        else if(result.value=='脱离卡点'){
            if(entity.canplay==false){
                dialog(`系统`,`你在封禁中，不能出来`,entity)
            }
            else{
                entity.player.forceRespawn()
                entity.ingjf=false;
                entity.player.directMessage('脱离成功！')
            }
        }
        else if(result.value=='进入/离开挂机房'){
            if(entity.canplay==false){
                dialog(`系统`,`你在封禁中，不能出来`,entity)
            }
            else{
                if(entity.ingjf==true){
                    entity.player.forceRespawn();
                    entity.ingjf=false;
                }
                else{
                    entity.position.set(97,6,74);
                    entity.ingjf=true;
                }
            }
        }
        else if(result.value=='进入/退出俯视全图'){
            if(entity.fsqting==false){
                const fsqt = world.querySelector('#俯视全图')
                entity.player.cameraEntity=fsqt
                entity.player.directMessage('正在俯视全图，再次点击按钮可退出')
                entity.fsqting=true
            }
            else{
                entity.player.cameraEntity=entity
                entity.fsqting=false
            }
        }
        else if(result.value=='切换人称'){
            if (entity.player.cameraMode === GameCameraMode.FOLLOW) {
                entity.player.cameraMode = GameCameraMode.FPS
                entity.player.directMessage(`切换成功`)
            }
            else {
                entity.player.cameraMode = GameCameraMode.FOLLOW
                entity.player.directMessage(`切换成功`)
            }
        }
        else if(result.value=='bug反馈'){
            dialog(`作者`,`反馈问题请发在评论区，也可以发作者邮箱oyroyroyr@163.com，如果采纳会赠送地图绿色粒子特效`,entity)
        }
        else if(result.value=='禁言玩家说话'){
            const result = await entity.player.dialog({
                type: GameDialogType.INPUT,
                title: '禁言玩家说话',
                content: `你想要说啥`,
                confirmText: '“警告！非禁言玩家尽量不要使用！”',
            });
            if(!result || result === null){
                return; 
            }
            else {
                world.say(entity.player.name+'：'+result)
            }
        }/*© a|z|k|b|b|y|s*/
        else if(result.value=='管理员工具'){
            if(admin.includes(entity.player.name)||entity.isadmin==true){
                const result = await entity.player.dialog({
                    type: GameDialogType.SELECT,
                    title: '管理员工具',
                    content: `选择你需要使用的工具`,
                    options:['飞行','降落','玩家传送器','计时器','广播公告','躲猫猫模式']
                });
                if(!result || result.value === null){ 
                    return; 
                }
                else if(result.value=='飞行'){
                    entity.player.canFly=true
                    entity.player.directMessage('您可以飞行了')
                }
                else if(result.value=='降落'){
                    entity.player.canFly=false
                    entity.player.directMessage('降落成功')
                    const allWearables = entity.player.wearables();
                    // allWearables.forEach((item) => {
                    //     item.remove();
                    // });
                }
                else if(result.value=='玩家传送器'){
                    const result = await entity.player.dialog({
                        type: GameDialogType.INPUT,
                        title: '玩家传送器',
                        content: `你要传送谁到你的位置`,
                        confirmText: '确认该名称',
                    });
                    if(!result || result === null){ 
                        return; 
                    }
                    else{
                        for (const e of world.querySelectorAll('player')){;
                            if(e.player.name==result){;
                                e.position.x=entity.position.x
                                e.position.y=entity.position.y
                                e.position.z=entity.position.z
                                entity.player.directMessage('传送成功！')
                            };
                        };
                    }
                }
                else if(result.value=='计时器'){
                    const result = await entity.player.dialog({
                        type: GameDialogType.INPUT,
                        title: '计时器',
                        content: `你想计时多久`,
                        confirmText: '“确定”',
                    });
                    console.log(entity.count)
                    if(entity.count=true){
                        let s = 0
                        let m = 0
                        let h = 0
                        while(entity.count==true){
                            s++
                            if(s>=60){;m++;s=0}
                            if(m>=60){;h++;m=0}
                            if(h>=3){;entity.player.directMessage('计时最多3小时');return;}
                            entity.player.directMessage(h+':'+m+':'+s)
                            await sleep(1000)
                        }
                    }/*c|o|p|y|r|i|g|h|t|||阿|兹|卡|班|毕|业|生*/
                    else{
                        entity.player.directMessage('计时器关闭！')
                    }
                }
                else if(result.value=='广播公告'){
                    const result = await entity.player.dialog({
                        type: GameDialogType.INPUT,
                        title: '广播公告',
                        content: `输入广播内容`,
                        confirmText: '确认广播',
                    });
                    world.say(result)
                }
                else if(result.value='躲猫猫模式'){
                    // entity.player.directMessage('为了服务器的健康，现在禁用躲猫猫模式')
                    const zbz = await entity.player.dialog({
                        type: GameDialogType.INPUT,
                        title: '躲猫猫模式',
                        content: `输入抓捕者`,
                        confirmText: '确认',
                    });
                    zbznc = zbz;
                    while(1){
                        const result = await entity.player.dialog({
                            type: GameDialogType.INPUT,
                            title: '躲猫猫模式',
                            content: `输入躲藏者昵称，输入@以结束添加`,
                            confirmText: '确认',
                        });
                        if(result!=`@`){
                            dcz.push(result);
                            entity.player.directMessage(`添加成功，${result}`)
                            dmmrenshu+=1;
                        }
                        else{
                            break;
                        }
                    }
                    const a = await entity.player.dialog({
                        type: GameDialogType.INPUT,
                        title: '躲猫猫模式',
                        content: `输入躲藏时间，单位秒，不可包含小数`,
                        confirmText: '确认',
                    });
                    dctime = parseInt(a)*16
                    const b = await entity.player.dialog({
                        type: GameDialogType.INPUT,
                        title: '躲猫猫模式',
                        content: `输入抓捕时间，单位秒，不可包含小数`,
                        confirmText: '确认',
                    });
                    zbtime = parseInt(b)*16;
                    if(dmm==false){
                        dmm = true;
                        world.say(`管理员${entity.player.name}开启了躲猫猫模式`)
                        dialog(`提示`,`已开启躲猫猫模式`,entity)
                    }
                    else{
                        dialog(`提示`,`错误：\n已经有另外一个管理员开启了躲猫猫模式`,entity)
                    }
                }
                else if(result.value='穿戴配件'){
                    chuandaipeijian(entity)
                }
            }
        }
    }
    else if(button=='action3'){
        entity.player.cameraEntity=entity
    }
})
// 模型运动
const lotus_leaf = world.querySelector('#荷叶-2') //获取实体
lotus_leaf.fixed = true//不受外力影响
lotus_leaf.collides = true//允许碰撞
const startPos_lotus_leaf = [63.7, 3.1, 3.7]//初始位置
const endPos_lotus_leaf = [75, 3.1, 3.7]

const ani_lotus_leaf = lotus_leaf.animate([
    { position: startPos_lotus_leaf, duration: 0 },
    { position: startPos_lotus_leaf, duration: 2 },
    { position: endPos_lotus_leaf, duration: 0 },
    { position: endPos_lotus_leaf, duration: 2 },
    { position: startPos_lotus_leaf, duration: 0 },
], {
    duration: 16 * 4, //一个循环共用时
    iterations: 1,//只播放1次
    direction: GameAnimationDirection.WRAP,//让实体从终点回到起点
})/*copyright 阿兹卡班毕业生*/
world.onPlayerJoin(({entity}) => {
    ani_lotus_leaf.play({
            duration: 16 * 4, //播放一个循环共用时20秒(每秒16帧),
            iterations: Infinity,//动画无限次循环播放
            direction: GameAnimationDirection.WRAP,//让动画实体从终点回到起点
        })
})

//gui
const { GameEasyGUI } = require("./GameEasyGUI.js");          //导入GameEasyGUI.js
console.clear();
world.onPlayerJoin(async ({ entity }) => {
    var mygui = new GameEasyGUI("myGUI", entity);
    entity.gui = mygui;           //创建一个gui对象
    var dom = mygui.document;
    var x = dom.createXml("label", {
        height: 20,
        width: 100,
        color: "#fff",
        fontSize: 18,
        x: 10,
        y: 35,
        id:"x"
    });                                                     //创建元素
    var y = dom.createXml("label", {
        height: 20,
        width: 200,
        color: "#fff",
        fontSize: 18,
        x: 10,
        y: 60,
        id:"y"
    });                                                     //创建元素
    var z = dom.createXml("label", {
        height: 20,
        width: 100,
        color: "#fff",
        fontSize: 18,
        x: 10,
        y: 85,
        id:"z"
    });
    var jf = dom.createXml("label", {
        height: 20,
        width: 100,
        color: "#fff",
        fontSize: 18,
        x: 10,
        y: 135,
        id:"jf"
    });
    var group = dom.createXml("group", {
        width: 240,
        height: 160,
        borderColor: "rgba(0,0,0,0)",
        backgroundColor: "rgba(0,0,0,0.45)",
        right:20,
        top:50
    }).appendChild(dom.createXml("label", {
        height: 20,
        width: 100,
        color: "#fff",
        fontSize: 20,
        x: 10,
        y: 10,
        text: "玩家信息"
    })).appendChild(x).appendChild(y).appendChild(z).appendChild(jf);         //将创建好的元素插入group中     
    dom.appendChild(group);                                  //将元素插入document中
    mygui.render();                                            //渲染gui
    mygui.reload();                             //刷新


    var msg = new GameEasyGUI("msg", entity);
    entity.mesg = msg;           //创建一个gui对象
    var dom2 = msg.document;
    var msg1 = dom2.createXml("label", {
        height: 20,
        width: 200,
        color: "#fff",
        fontSize: 18,
        x: 10,
        y: 245,
        id:"msg1"
    });                                                     //创建元素
    var group1 = dom2.createXml("group", {
        width: 240,
        height: 545,
        borderColor: "rgba(0,0,0,0)",
        backgroundColor: "rgba(0,0,0,0.45)",
        right:20,
        top:215
    }).appendChild(dom2.createXml("label", {
        height: 20,
        width: 100,
        color: "#fff",
        fontSize: 20,
        x: 10,
        y: 10,
        text: "新消息"
    })).appendChild(msg1);         //将创建好的元素插入group中     
    dom2.appendChild(group1);                                  //将元素插入document中
    msg.render();                                            //渲染gui
    var button = dom.createXml("button",{
        text:"戳我发消息（防禁言）",
        x:10,
        y:500,
        percentWidth:90,
        height:30,
        color:"#fa0"
    });/*copyright 阿兹卡班毕业生*/
    button.addEventListener("click",async function({entity}){
        const result = await entity.player.dialog({
            type: GameDialogType.INPUT,
            title: '发言',/*阿|兹|卡|班|毕|业|生*/
            content: `你想要说啥`,
            confirmText: '确定发送，反悔请点X',
        });
        if(!result || result === null){
            return; 
        }
        else {
            world.say(entity.player.name+'：'+result)
            msglist[0]=entity.player.name+'：'+result
        }
    })
    group1.appendChild(button);
    msg.reload();                             //刷新
});
//循环显示信息
world.onTick(()=>{
    world.querySelectorAll('player').forEach((e)=>{
        if(e.gui){
            let dom = e.gui.document;
            let x = dom.getElementById("x");/*阿|兹|卡|班|毕|业|生*/
            let y = dom.getElementById("y");
            let z = dom.getElementById("z");
            let jf = dom.getElementById("jf");
            x.setAttribute("text","x："+Math.floor(e.position.x));  //设置元素文本
            y.setAttribute("text","y："+Math.floor(e.position.y));
            z.setAttribute("text","z："+Math.floor(e.position.z));
            jf.setAttribute("text","经验："+Math.floor(e.exp));
        }
        if(e.mesg){
            let dom2 = e.mesg.document;
            let msg1 = dom2.getElementById("msg1");
            msg1.setAttribute("text",msglist[0]);
        }
    })
})

world.onPlayerJoin(({entity})=>{
    world.onTick(({tick})=>{
        if(dmm==true&&entity.dmmshoudao==false){
            if(zbznc==entity.player.name){
                entity.player.directMessage(`你是抓捕者`);
                entity.player.color=new GameRGBColor(1,0,0);
                entity.dmmzy='抓捕';
                dialog(`操作说明`,`碰到躲藏者（黑色的人）即可抓获`,entity)
                entity.dmmshoudao=true;
                entity.position.set(2,6,10);
                entity.player.canFly=true;/*阿|兹|卡|班|毕|业|生*/
            }
            else if(dcz.includes(entity.player.name)){
                entity.player.directMessage(`你是躲藏者，快开始躲藏吧！`);
                entity.dmmzy='躲藏';
                dialog(`操作说明`,`不要被红色昵称的抓捕者碰到！`,entity)
                entity.player.color=new GameRGBColor(0,0,0);
                entity.dmmshoudao=true;
                entity.player.canFly=true;
            }
        }
        if(dmm==true){
            if(dctime==0){
                if(dctime==0&&entity.dmmzy=='抓捕'){
                    entity.player.forceRespawn()
                    // dctime-=16;
                }
            }
        }
    })
})

world.onTick(async({tick})=>{
    if(dmm==true){
        if(dctime>=0){/*阿|兹|卡|班|毕|业|生*//*阿|兹|卡|班|毕|业|生*/
            if(tick%16==0){
                dctime-=16;
                world.say(`躲猫猫-躲藏时间还剩${dctime/16}秒`)
                world.clearCollisionFilters()
                // entity.dmmshoudao=true
            }
        }
        else if(zbtime!=0){
            if(tick%16==0){
                zbtime-=16;
                world.say(`躲猫猫-抓捕时间还剩${zbtime/16}秒`)
            }
        }
        else{
            dmm=false;
            world.say(`躲猫猫结束，如3s后服务器未自行重启（即踢出所有玩家），请管理员输入\$db.sql([''],'') 进行重启`)
            await sleep(3000)
            db.sql([''],'')
        }/*阿|兹|卡|班|毕|业|生*/
    }
})

world.onEntityContact(({entity,other})=>{
    if(entity.dmmzy=='抓捕'){
        if(other.dmmzy=='躲藏'&&beizhuadao.includes(entity.player.name)==false){
            beizhuadao.push(other.player.name);
            world.say(`抓捕者抓到了${other.player.name}`)
            entity.player.directMessage(`恭喜抓到人了！经验+10`);
            entity.exp+=10;
            savePlayer(entity)
            other.player.directMessage(`被抓到了了！经验+5`);
            other.exp+=5;
            savePlayer(other)
            other.player.color=new GameRGBColor(1,1,1);
        }
    }
})

//挂机检测
world.onPlayerJoin(({entity})=>{
    entity.xcundang= 0
    entity.ycundang= 0
    entity.zcundang= 0/*阿|兹|卡|班|毕|业|生*/
    entity.i=0
    world.onTick(async({tick})=>{
        if(tick%16==0){
            if(entity.xcundang==entity.position.x&&entity.ycundang==entity.position.y&&entity.zcundang==entity.position.z){
                entity.i+=1
                console.log('挂机',entity.i)
            }
            else{
                entity.i=0
                entity.xcundang=entity.position.x
                entity.ycundang=entity.position.y
                entity.zcundang=entity.position.z
            }
            if(entity.i==300&&entity.cankick==true){
                dialog('系统','你已在当前位置停留了5min，若继续停留，10s后将踢出游戏！\n挂机会导致服务器变卡，甚至崩服，为了服务器的健康，现在禁止挂机',entity)
            }
            else if(entity.i>=140&&entity.cankick==true){
                entity.i=0/*阿|兹|卡|班|毕|业|生*/
                entity.player.kick()
            }
        }
    })
})
/*copyright 阿兹卡班毕业生*/
```

## GameEasyGUI.js <a href="#mnip-1702035241936" id="mnip-1702035241936"></a>

```
"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);/*阿|兹|卡|班|毕|业|生*/
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
exports.__esModule = true;
var GameEasyGUI = /** @class */ (function () {
    function GameEasyGUI(name, entity) {
        this.name = name;
        this.entity = entity;
        this.document = new GUIDocument(this);
        this.rendered = false;
    }
    GameEasyGUI.prototype.render = function () {
        var _a;
        this.rendered = true;
        gui.init(this.entity, (_a = {},
            _a[this.name] = {
                bindings: this.document.getBindings(),
                display: true,/*阿|兹|卡|班|毕|业|生*/
                data: this.document.toString()
            },
            _a));
    };
    GameEasyGUI.prototype.reload = function () {
        if (this.document.childrens.length < 1)
            return;
        for (var _i = 0, _a = this.document.childrens; _i < _a.length; _i++) {
            var i = _a[_i];
            gui.remove(this.entity, i.selector);
        }
        this.render();
    };
    return GameEasyGUI;
}());
module.exports = { GameEasyGUI: GameEasyGUI, GUINode: GUINode, NodeEventListener: NodeEventListener, GUIDocument: GUIDocument };
function key(node) {
    if (!node.parent)
        throw new Error("this element have not been append to other elements.So,please append to other elements and then make a key for this elements!");
    var length = 16;
    var k = "";
    var a = [[48, 57], [65, 90], [97, 122]];
    for (var i = 0; i < length; i++) {
        var r = a[Math.floor(Math.random() * 3)];
        k += String.fromCharCode(Math.floor(Math.random() * (r[1] - r[0])) + r[0]);
    }/*阿|兹|卡|班|毕|业|生*/
    if (node.gui && node.gui.document.getElementByKey(k) != null)
        return key(node);
    else
        return k;
}
var GUINode = /** @class */ (function () {
    function GUINode(name, attributes) {
        this.name = name;
        this.attributes = attributes;
        this.childrens = [];
        this.listeners = [];
        this.getSelector = function () {
            /*let s: string = this.name + (this.attributes.id ? ("#" + this.attributes.id) : "") + (this.attributes.name ? ("." + this.attributes.name) : ""), length: number = 0;
            let d: string = "";
            for (let i in this.attributes) {
                if (!["id","name","x","y","top","left","button","right","height","width","borderWidth","fontSize"].includes(i)) {
                    length++;
                    d += "[" + i + "=" + "\"" + this.attributes[i] + "\"]";
                }
            }
            if (length > 0) s += d;
            if(this.parent&&this.parent.getSelector)s = this.parent.getSelector() + ">" + s;
            return s;*/
            return this.name + "[guiKey=\"" + this.attributes.guiKey + "\"]";
        };
    }
    GUINode.prototype.toString = function () {/*阿|兹|卡|班|毕|业|生*/
        var a = "", c = "";
        for (var i in this.attributes)
            a += " " + i + "=" + "\"" + this.attributes[i] + "\"";
        for (var _i = 0, _a = this.childrens; _i < _a.length; _i++) {
            var i = _a[_i];
            c += i.toString();
        }
        return "<" + this.name + a + ">\r\n" + c + "</" + this.name + ">\r\n";
    };
    GUINode.prototype.getEventListeners = function () {
        var b = this.listeners;
        for (var _i = 0, _a = this.childrens; _i < _a.length; _i++) {
            var i = _a[_i];
            b = b.concat(i.getEventListeners());
        }
        return b;
    };
    GUINode.prototype.appendChild = function (node) {
        if (node.selector)
            throw new Error("this element has been appended to another element.");
        this.childrens.push(node);
        node.parent = this;
        node.gui = this.gui;
        function setGUI(node, a) {
            for (var _i = 0, _a = node.childrens; _i < _a.length; _i++) {
                var i = _a[_i];
                i.gui = a, setGUI(i, a);
            }
        }
        if (this.gui)
            setGUI(node, this.gui);
        node.attributes.guiKey = key(node);
        node.selector = node.getSelector();
        return this;
    };
    GUINode.prototype.remove = function () {
        var pos = this.parent.childrens.indexOf(this);
        if (pos == -1)
            throw new Error("can not find this element in " + this.parent.selector + ".Please check have you ever appended this element.");
        this.parent.childrens.splice(pos, 1);
        if (this.gui && this.gui.rendered)
            gui.remove(this.gui.entity, this.selector);
        delete this;
    };
    GUINode.prototype.addEventListener = function (e, listener) {
        var _this = this;
        this.listeners.push(new NodeEventListener(e, listener, this));
        gui.onMessage(function (data) {
            if (data.name == _this.getSelector())
                listener(data);
        });
    };
    GUINode.prototype.setAttribute = function (a, b) {/*阿|兹|卡|班|毕|业|生*/
        this.attributes[a] = String(b);
        if (this.gui && this.gui.rendered)
            gui.setAttribute(this.gui.entity, this.selector, a, b);
    };
    GUINode.prototype.removeAttribute = function (a) {
        this.attributes[a] && function (b) {
            if (b.gui && b.gui.rendered)
                gui.setAttribute(b.gui.entity, b.selector, a, "");
            delete this.attributes[a];
        }(this);
    };
    GUINode.prototype.show = function () {
        this.setAttribute("display", "block");
        this.setAttribute("height", this.attributes.height0);
        this.setAttribute("width", this.attributes.width0);
        this.setAttribute("height0", "");
        this.setAttribute("width0", "");
    };
    GUINode.prototype.hide = function () {
        this.setAttribute("display", "none");
        this.setAttribute("height0", this.attributes.height);
        this.setAttribute("width0", this.attributes.width);
        this.setAttribute("height", "0");
        this.setAttribute("width", "0");
    };
    return GUINode;
}());
var NodeEventListener = /** @class */ (function () {
    function NodeEventListener(e, listener, node) {
        this.event = e;
        this.listener = listener;
        this.node = node;
    }
    return NodeEventListener;
}());
var GUIDocument = /** @class */ (function (_super) {
    __extends(GUIDocument, _super);
    function GUIDocument(gui) {
        var _this = _super.call(this, "document", {}) || this;
        _this.selector = "document";
        _this.gui = gui;
        _this.getSelector = undefined;
        return _this;
    }
    GUIDocument.prototype.toString = function () {
        var c = "";
        for (var _i = 0, _a = this.childrens; _i < _a.length; _i++) {
            var i = _a[_i];
            c += i.toString();
        }/*阿|兹|卡|班|毕|业|生*/
        return c;
    };
    GUIDocument.prototype.createXml = function (name, attributes) {
        return new GUINode(name, attributes);
    };
    GUIDocument.prototype.getBindings = function () {
        var e = this.getEventListeners(), b = new Array();
        for (var _i = 0, e_1 = e; _i < e_1.length; _i++) {
            var i = e_1[_i];
            var s = i.node.getSelector();
            b.push({ action: "sendMessage", event: i.event, messageName: s, selector: s });
        }
        return b;
    };
    GUIDocument.prototype.remove = function () {
        throw new Error("can not remove document!");
    };
    GUIDocument.prototype.getElementById = function (id) {
        var e = null;
        function find(node, id) {
            for (var _i = 0, _a = node.childrens; _i < _a.length; _i++) {
                var i = _a[_i];
                if (i.attributes.id == id)/*阿|兹|卡|班|毕|业|生*/
                    return e = i;
                find(i, id);
            }
        }
        find(this, id);
        return e;
    };
    GUIDocument.prototype.getElementByKey = function (key) {
        var e = null;
        function find(node, key) {
            for (var _i = 0, _a = node.childrens; _i < _a.length; _i++) {
                var i = _a[_i];
                if (i.attributes.key == key)
                    return e = i;
                find(i, key);/*阿|兹|卡|班|毕|业|生*/
            }
        }
        find(this, key);/*阿|兹|卡|班|毕|业|生*/
        return e;
    };
    GUIDocument.prototype.getElementsByName = function (name) {
        var e = [];
        function find(node, name) {
            for (var _i = 0, _a = node.childrens; _i < _a.length; _i++) {
                var i = _a[_i];
                if (i.attributes.name == name)
                    return e.push(node);
                find(i, name);
            }
        }
        find(this, name);
        return e;
    };
    return GUIDocument;
}(GUINode));
```

## 宠物.js <a href="#ezla-1702035241936" id="ezla-1702035241936"></a>

```
console.clear()/*阿|兹|卡|班|毕|业|生*/
const mscale = 1 / 16
const Quat = new GameQuaternion(0, 0, 0, 1)
/*阿|兹|卡|班|毕|业|生*/
function buddyFollow(entity, mesh, y) {
    const buddy = world.createEntity({
        mesh,
        position: entity.position,
        meshScale: [mscale, mscale, mscale],
        gravity: false, //不受重力影响
        fixed: false, //可推移
        collides: false, //不可碰撞
        friction: 0, //无摩擦力
        mass: 0.01, //非常轻
    })

    const tgPos = entity.position
    const budPos = buddy.position
    const facing = entity.player.facingDirection//玩家的朝向
    const ratio = 0.1//追随的灵敏度, 最好设在0.5左右, 1.0表示立即移到玩家位置
/*阿|兹|卡|班|毕|业|生*/
    const dist = 2 //与玩家保持的距离
    const yOffset = y //y轴位移, 保持僚机在头顶或脚下

    const ticker = world.onTick(() => {

        //要让小精灵跟在玩家背后, 需要计算xz轴的位移: 玩家朝向的反方向
        const xOffset = -facing.x * dist
        const zOffset = -facing.z * dist/*阿|兹|卡|班|毕|业|生*/

        //当前位置与目标位置在xyz轴的差距
        const xDiff = tgPos.x - budPos.x
        const yDiff = tgPos.y - budPos.y
        const zDiff = tgPos.z - budPos.z

        //计算xyz方向上 当前位置向目标位置靠拢的速度
        const vx = (xDiff + xOffset) * ratio
        const vy = (yDiff + yOffset) * ratio
        const vz = (zDiff + zOffset) * ratio
/*阿|兹|卡|班|毕|业|生*/
        buddy.velocity.set(vx, vy, vz)//设置僚机速度

        if (buddy.velocity.sqrMag() > 0.005) {//速度要足够大, 才触发转向, 防止抖动
            buddy.meshOrientation = Quat.rotateY(Math.atan2(zDiff, xDiff)) //让小精灵一直面向玩家
        }
    })

    return () => {
        ticker.cancel() //关掉tick循环
        buddy.destroy() //移除实体
    }
}

world.onPlayerJoin(({ entity }) => {
    entity.setPet = buddyFollow(entity, 'mesh/皮卡丘.vb', -1) //给玩家增加宠物
})

world.onPlayerLeave(({ entity }) => {
    //玩家离开地图时, 切记一定要关掉tick循环以及销毁小精灵实体, 否则随着人数增加, 服务器积累到一定程度就会崩溃
    entity.setPet() //干掉宠物
})/*阿|兹|卡|班|毕|业|生*/
```

## 防止想不开.js <a href="#hcjx-1702035241936" id="hcjx-1702035241936"></a>

```
world.onPlayerJoin(({entity})=>{/*阿|兹|卡|班|毕|业|生*/
    world.onTick(({tick})=>{/*阿|兹|卡|班|毕|业|生*/
        if(entity.position.x<0){/*阿|兹|卡|班|毕|业|生*/
            entity.velocity.x=1;/*阿|兹|卡|班|毕|业|生*/
            entity.player.directMessage('别想不开啊，跳虚空干啥？')/*阿|兹|卡|班|毕|业|生*/
        }/*阿|兹|卡|班|毕|业|生*/
        else if(entity.position.x>127){/*阿|兹|卡|班|毕|业|生*/
            entity.velocity.x=-1;/*阿|兹|卡|班|毕|业|生*/
            entity.player.directMessage('别想不开啊，跳虚空干啥？')/*阿|兹|卡|班|毕|业|生*/
        }/*阿|兹|卡|班|毕|业|生*/
        if(entity.position.z<0){/*阿|兹|卡|班|毕|业|生*/
            entity.velocity.z=1;/*阿|兹|卡|班|毕|业|生*/
            entity.player.directMessage('别想不开啊，跳虚空干啥？')/*阿|兹|卡|班|毕|业|生*/
        }/*阿|兹|卡|班|毕|业|生*/
        else if(entity.position.z>127){/*阿|兹|卡|班|毕|业|生*/
            entity.velocity.z=-1;/*阿|兹|卡|班|毕|业|生*/
            entity.player.directMessage('别想不开啊，跳虚空干啥？')/*阿|兹|卡|班|毕|业|生*/
        }/*阿|兹|卡|班|毕|业|生*/
    })/*阿|兹|卡|班|毕|业|生*/
})/*阿|兹|卡|班|毕|业|生*/
```

## 文档纠错

点击跳转[欢迎](/azkbbys/welcome.md#wen-dang-jiu-cuo)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://azkbbys.gitbook.io/azkbbys/open-source/bysrunpro-mainmap.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
