{ "manifest": { "id": "base-scripts", "name": "基础实体脚本", "version": "1.0.0", "author": "OES-WEB", "description": "为游戏实体提供默认行为脚本:守卫巡逻、狼群AI、亡灵守卫、蜘蛛毒液等", "priority": 50, "dependencies": [] }, "data": {}, "scripts": { "guard_patrol": { "properties": { "homeX": 0, "homeY": 0, "alertLevel": 0, "patrolAngle": 0, "idleTimer": 0, "state": "idle" }, "handlers": { "OnLoad": "var pos = ctx.entity.getPosition(); ctx.prop('homeX', pos.x); ctx.prop('homeY', pos.y); ctx.log('守卫部署完毕,位置: ' + pos.x + ',' + pos.y);", "OnUpdate": "if (ctx.prop('state') === 'idle') { var t = ctx.prop('idleTimer') + delta; ctx.prop('idleTimer', t); if (t > 3000) { ctx.prop('state', 'patrol'); ctx.prop('idleTimer', 0); } } else if (ctx.prop('state') === 'patrol') { var a = ctx.prop('patrolAngle') + 0.02; ctx.prop('patrolAngle', a); var hx = ctx.prop('homeX'); var hy = ctx.prop('homeY'); var tx = hx + Math.cos(a) * 48; var ty = hy + Math.sin(a) * 48; ctx.entity.setPosition(tx, ty); var t2 = ctx.prop('idleTimer') + delta; ctx.prop('idleTimer', t2); if (t2 > 4000) { ctx.prop('state', 'idle'); ctx.prop('idleTimer', 0); } }", "OnHit": "var al = ctx.prop('alertLevel') + 1; ctx.prop('alertLevel', al); ctx.prop('state', 'idle'); ctx.prop('idleTimer', 0); ctx.log('守卫受到攻击! 警戒等级: ' + al); if (al >= 5) { ctx.effects.apply({ id: 'guard_rage', type: 'buff', attribute: 'damage', magnitude: 10, durationMs: 10000 }); ctx.log('守卫进入狂暴状态!'); }", "OnDeath": "ctx.log('守卫阵亡'); ctx.events.emit('guard:down', { x: ctx.entity.getPosition().x, y: ctx.entity.getPosition().y });" } }, "pack_wolf": { "properties": { "homeX": 0, "homeY": 0, "packSize": 2, "aggroRange": 120, "fleeHealthPct": 0.2, "huntTarget": null }, "handlers": { "OnLoad": "var pos = ctx.entity.getPosition(); ctx.prop('homeX', pos.x); ctx.prop('homeY', pos.y); ctx.log('狼已生成,巢穴: ' + pos.x + ',' + pos.y);", "OnUpdate": "var hp = ctx.entity.getHealth(); var maxHp = 100; if (hp / maxHp < ctx.prop('fleeHealthPct')) { var hx = ctx.prop('homeX'); var hy = ctx.prop('homeY'); var pos = ctx.entity.getPosition(); var dx = pos.x - hx; var dy = pos.y - hy; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 10) { var nx = dx / dist; var ny = dy / dist; ctx.entity.setPosition(pos.x + nx * 2, pos.y + ny * 2); } }", "OnHit": "var hp = ctx.entity.getHealth(); var maxHp = 100; ctx.log('狼被攻击! 生命: ' + hp + '/' + maxHp); if (hp / maxHp < ctx.prop('fleeHealthPct')) { ctx.log('狼因伤势过重逃跑'); } else { ctx.events.emit('wolf:aggro', { x: ctx.entity.getPosition().x, y: ctx.entity.getPosition().y }); }", "OnDeath": "ctx.log('狼被击杀'); ctx.events.emit('wolf:killed', { x: ctx.entity.getPosition().x, y: ctx.entity.getPosition().y });" } }, "draugr_guard": { "properties": { "dormant": true, "wakeRange": 80, "homeX": 0, "homeY": 0, "deathCount": 0 }, "handlers": { "OnLoad": "var pos = ctx.entity.getPosition(); ctx.prop('homeX', pos.x); ctx.prop('homeY', pos.y); ctx.log('亡灵守卫沉睡中...');", "OnUpdate": "if (ctx.prop('dormant')) { var pos = ctx.entity.getPosition(); var nearby = ctx.entities.getNearby(ctx.prop('wakeRange')); for (var i = 0; i < nearby.length; i++) { if (nearby[i].type === 'player') { ctx.prop('dormant', false); ctx.log('亡灵守卫苏醒!'); ctx.effects.apply({ id: 'draugr_awaken', type: 'buff', attribute: 'damage', magnitude: 5, durationMs: 30000 }); break; } } }", "OnHit": "if (ctx.prop('dormant')) { ctx.prop('dormant', false); ctx.log('亡灵守卫被惊醒!'); }", "OnDeath": "var dc = ctx.prop('deathCount') + 1; ctx.prop('deathCount', dc); ctx.log('亡灵倒下 (第 ' + dc + ' 次)'); if (dc < 3) { ctx.prop('dormant', true); ctx.entity.setHealth(ctx.entity.getHealth() + 50); ctx.log('亡灵再次站起!'); } else { ctx.log('亡灵最终被消灭'); }" } }, "frost_spider": { "properties": { "homeX": 0, "homeY": 0, "webCooldown": 0, "poisonStacks": 0 }, "handlers": { "OnLoad": "var pos = ctx.entity.getPosition(); ctx.prop('homeX', pos.x); ctx.prop('homeY', pos.y); ctx.log('冰霜蜘蛛在巢穴待命');", "OnHit": "var stacks = ctx.prop('poisonStacks') + 1; ctx.prop('poisonStacks', stacks); if (stacks >= 3) { ctx.log('蜘蛛毒液叠满3层! 施加冰冻效果'); ctx.effects.apply({ id: 'frost_venom', type: 'debuff', attribute: 'speed', magnitude: -0.3, durationMs: 5000, source: 'frost_spider' }); ctx.effects.apply({ id: 'frost_dot', type: 'debuff', attribute: 'health', magnitude: -3, durationMs: 5000, source: 'frost_spider' }); ctx.prop('poisonStacks', 0); } else { ctx.log('蜘蛛毒液层数: ' + stacks); }", "OnUpdate": "var cd = ctx.prop('webCooldown'); if (cd > 0) { ctx.prop('webCooldown', cd - delta); }", "OnDeath": "ctx.log('冰霜蜘蛛被击杀'); ctx.prop('poisonStacks', 0);" } }, "town_elder": { "properties": { "greeted": false, "hintGiven": false }, "handlers": { "OnLoad": "ctx.log('镇长就位');", "OnZoneEnter": "if (!ctx.prop('greeted')) { ctx.prop('greeted', true); ctx.log('镇长: 欢迎来到这片土地。'); }", "OnActivate": "if (!ctx.prop('hintGiven')) { ctx.prop('hintGiven', true); ctx.log('镇长: 北方的古坟里藏着宝物,但要小心亡灵。'); ctx.events.emit('elder:hint', { hint: '北方古坟有宝藏' }); } else { ctx.log('镇长: 祝你旅途平安。'); }", "OnDeath": "ctx.log('镇长遇害! 村庄失去领导者'); ctx.events.emit('elder:killed', {});" } } } }