猫史档案馆


【闲闲闲的发慌】黄鹤楼捉妖代码)))

用户:卑微OIer卑微OIer查看:22 回复:14 评论:22 创建时间:2022-04-26T17:53:09


const CELL_POSITION = {
    x: [66, 197],
    y: [30, 40],
    z: [627, 661],
};
const OBJECT_START_POSITION = {
    x: [102, 162],
    y: [73, 83],
    z: [148, 159],
};
const HUMAN_START_POSITION = {
    x: [116, 150],
    y: [31, 34],
    z: [313, 335],
};

const NOTIFY_INTERVAL = 2 * 1000; // notify间隔时间, 单位毫秒
const CHECK_START_GAME_INTERVAL = 5; // 检测游戏开始的间隔时间, 单位秒
const COUNTDOWN_TIME = 5; // 倒计时多少秒开始游戏
const MIN_GAME_PLAYER_NUM = 2; // 最少多少人才能开始游戏
const GAME_TIME = 3 * 60; // 一局游戏时长, 单位秒
const CATCH_RATIO = 4 / 5; // 抓完多少物品就算人类赢
const TEAM_HUMAN_NAME = '人类队'; // 抓人队名称
const TEAM_OBJECT_NAME = '妖怪队'; // 变身队名称

/* 上面是配置 */

const players = [];
const humanPlayers = new Set();
const objectPlayers = new Set();
let catchCount = 0;
let winCatchNum = 0;
const objects = world.querySelectorAll('*').filter(isSmallEntity);
console.log(`共找到${objects.length}个于玩家变身的实体`);
let resolveHumanWin;

function isSmallEntity(e) {
    return !e.hasTag('大件物品');
}

function randomSetVec3(v, p) {
    v.set(
        randomRange(p.x),
        randomRange(p.y),
        randomRange(p.z),
    );
}

function initPlayer(entity) {
    entity.player.showName = true;
    entity.position.copy(entity.player.spawnPoint);
    entity.mesh = '';
    entity.player.invisible = false;
    entity.player.runSpeed = 0.4;
    entity.player.runAcceleration = 0.35;
    entity.player.walkSpeed = 0.22;
    entity.player.walkAcceleration = 0.19;
    awaitDirectMessage(entity, '请等待新的一局游戏开始');
}

function fakeObject(player, object) {
    player.mesh = object.mesh;
    player.meshOrientation = object.meshOrientation;
    player.meshScale = object.meshScale;
    player.showName = false;
}

function catchObject(p, o) {
    if (!humanPlayers.has(p) || !objectPlayers.has(o)) return;
    objectPlayers.delete(o);
    initPlayer(o);
    if (++catchCount === winCatchNum) {
        notify(`${p.player.name} 找到了最后一名${TEAM_OBJECT_NAME}成员${o.player.name}.`);
        resolveHumanWin(true);
    } else {
        notify(`${p.player.name} 找到了 ${o.player.name}, 当前${TEAM_OBJECT_NAME}还剩下${objectPlayers.size}人.`);
    }
}

const nitifyQueue = [];
let notifying = false;
let notifyFinish = Promise.resolve();
async function notify(s) {
    nitifyQueue.push(s);
    if (notifying) return;
    notifying = true;
    let resolve;
    notifyFinish = new Promise((r) => resolve = r);
    while (nitifyQueue.length > 0) {
        world.say(nitifyQueue.shift());
        await sleep(NOTIFY_INTERVAL);
    }
    notifying = false;
    resolve();
}

function setup() {
    world.onPlayerJoin(({entity}) => {
        randomSetVec3(entity.player.spawnPoint, CELL_POSITION);
        initPlayer(entity);
        players.push(entity);
    });
    
    world.onPlayerLeave(({entity}) => {
        if (!arrayRemoveElement(players, entity)) {
            console.error(`玩家退出时出现错误, 找不到需要删除的玩家${entity.id}`);
        }
        const isHuman = humanPlayers.has(entity);
        const isObject = objectPlayers.has(entity);
        if (isHuman) {
            humanPlayers.delete(entity);
        } else if (isObject) {
            objectPlayers.delete(entity);
            if (objectPlayers.size === 0) {
                resolveHumanWin(true);
            }
        } else {
            return;
        }
        notify(`${entity.player.name} 退出游戏, ${isHuman ? TEAM_HUMAN_NAME : TEAM_OBJECT_NAME}失去了一份力量.`);
    });

    world.onPress(({ entity, button, raycast:{ hitEntity } }) => {
        if (button === 'action0') {
            catchObject(entity, hitEntity);
        }

    });

    world.onEntityContact(({entity, other}) => {
        if (objectPlayers.has(entity) && isSmallEntity(other) && !other.isPlayer) {
            fakeObject(entity, other);
        } else {
            catchObject(entity, other);
        }
    });
}

async function main() {
    // world.onPress(({ entity, button, raycast:{  hitVoxel, hitPosition } }) => {
    //     if (hitVoxel) {
    //         console.log(`${hitVoxel}: ${Math.floor(hitPosition.x)}, ${Math.floor(hitPosition.y)}, ${Math.floor(hitPosition.z)}`)
    //     }
    // });
    
    // return;
    setup();
    while (true) {
        await sleep(CHECK_START_GAME_INTERVAL * 1000);
        await startGame();
    }
}
main();
async function startGame() {
    if (!await isReady()) return;
    arrayShuffle(players);
    // 当玩家数为奇数是, 人队比物队多一人
    const teamObjectNum = Math.floor(players.length / 2);
    catchCount = 0;
    winCatchNum = Math.ceil(teamObjectNum * CATCH_RATIO);
    for (let i = 0; i < teamObjectNum; i++) {
        const e = players[i];
        objectPlayers.add(e);
        randomSetVec3(e.position, OBJECT_START_POSITION);
        fakeObject(e, arrayRandomPick(objects));
        e.player.invisible = true;
        delayDirectMessage(e, `你属于${TEAM_OBJECT_NAME}, 触碰物品即变身,不要被发现!`);
    }
    for (let i = teamObjectNum; i < players.length; i++) {
        const e = players[i];
        humanPlayers.add(e);
        randomSetVec3(e.position, HUMAN_START_POSITION);
        delayDirectMessage(e, `你属于${TEAM_HUMAN_NAME}, 快去抓假装物品的家伙!`);
        e.player.runSpeed = 0.8;//菲比:给抓人队加速
        e.player.runAcceleration = 0.7;//菲比:给抓人队加速
        e.player.walkSpeed = 0.4;//菲比:给抓人队加速
        e.player.walkAcceleration = 0.25;//菲比:给抓人队加速
    }
    await sleep(NOTIFY_INTERVAL);
    //world.say('开始游戏!');
    const isHumanWin = await new Promise(async (resolve) => {
        resolveHumanWin = resolve;
        await sleep(GAME_TIME * 1000);
        resolve(false);
    });
    notify(`游戏结束, ${isHumanWin ? TEAM_HUMAN_NAME : TEAM_OBJECT_NAME} 胜利!`);
    humanPlayers.forEach(initPlayer);
    objectPlayers.forEach(initPlayer);
    humanPlayers.clear();
    objectPlayers.clear();
}

async function isReady() {
    if (players.length < MIN_GAME_PLAYER_NUM) {
        notify(`当前在线${players.length}人, 达到${MIN_GAME_PLAYER_NUM}人即开始游戏!`);
        return false;
    }
    notify('游戏即将开始!');
    await sleep(NOTIFY_INTERVAL);
    for (let i = COUNTDOWN_TIME; i > 0; i--) {
        world.say(`倒计时 ${i}...`);
        await sleep(1000);
    }
    if (players.size < MIN_GAME_PLAYER_NUM) {
        notify(`有人退出游戏, 导致游戏人数不足, 无法开始游戏!`);
        return false;
    }
    return true;
}

async function awaitDirectMessage(p, m) {
    await notifyFinish;
    p.player.directMessage(m);
}

async function delayDirectMessage(p, m) {
    await sleep(5000);
    p.player.directMessage(m);

}

function randomRange(r) {
    return r[0] + Math.random() * [r[1] - r[0]];
}

function arrayShuffle (array) {
    for (let i = 1; i < array.length; ++i) {
        const temp = array[i];
        const x = (Math.random() * (i + 1)) | 0;
        array[i] = array[x];
        array[x] = temp;
    }
    return array;
}

function arrayRandomIndex(a) {
    return Math.floor(Math.random() * a.length);
}

function arrayRandomPick(a) {
    return a[arrayRandomIndex(a)];
}

function arrayRandomSplice(a) {
    return a.splice(arrayRandomIndex(a), 1)[0];
}

function arrayRemoveElement(a, e) {
    const idx = a.indexOf(e);
    if (idx < 0) return false;
    a.splice(idx, 1);
    return true;
}

//吉吉不要啊))))If we know it easyer


回复

上一页1 页 / 共 1下一页
1086爱编程1086爱编程

惊!

点赞0


评论


卑微OIer卑微OIer

别问我是用什么奇妙的手段获取到的)别问)不问就对了)

点赞0


评论


IDF哲宇MIKEIDF哲宇MIKE

吉吉:封号...

点赞0


评论


卑微OIer卑微OIer

手段:去黄鹤楼获取黄鹤楼的hash,然后checkout断点复制地图

点赞1


评论


难起的名字难起的名字

我们需要的是黄鹤楼的地图大小()——)(()()()()()()()

点赞0


评论


snovsnov

复制了[狗头]

点赞0


评论


云游box3der尖头叉子云游box3der尖头叉子

e,干嘛发这个啊啊啊啊()

点赞0


评论


云游box3der尖头叉子云游box3der尖头叉子

以后别发了,黄鹤楼代码简单就算了()

点赞0


评论


灵清帝王吃爆一切厕所灵清帝王吃爆一切厕所

收藏()

点赞0


评论


YLG_個YLG_個

《菲比》

点赞1


评论


灵清帝王吃爆一切厕所灵清帝王吃爆一切厕所

洋葱(),你的那个前几天发的剧情代码能给我《借鉴一下》吗()我找不到了()()()()

点赞0


评论


化石茄子的铁镐化石茄子的铁镐

发个教程

点赞0


评论


一个普通的岛民一个普通的岛民

 

 

 

center_image

 

 

 

点赞0


评论


xiao998xiao998

遗产

点赞0


评论