feat(monster): CombatMonster 마커(EnemyId·자기등록) + 11맵 몬스터 패치
This commit is contained in:
72
tools/monster/gen-combat-monster.mjs
Normal file
72
tools/monster/gen-combat-monster.mjs
Normal file
@@ -0,0 +1,72 @@
|
||||
import { readFileSync, writeFileSync } from 'node:fs';
|
||||
|
||||
// 맵 몬스터에 적 타입(EnemyId)을 부여하고, BeginPlay 시 /common 컨트롤러에 자기등록하는 마커.
|
||||
// 카드 전투 시 컨트롤러가 등록 목록으로 인카운터를 구성한다.
|
||||
const MAP_NUMBERS = Array.from({ length: 11 }, (_, i) => i + 1); // map01~11
|
||||
const NAME_TO_ENEMY = { '주황버섯': 'orange_mushroom', '파란버섯': 'blue_mushroom' };
|
||||
const DEFAULT_ENEMY = 'orange_mushroom';
|
||||
|
||||
function prop(Type, Name, DefaultValue = 'nil') {
|
||||
return { Type, DefaultValue, SyncDirection: 0, Attributes: [], Name };
|
||||
}
|
||||
function method(Name, Code, Arguments = [], ExecSpace = 6) {
|
||||
return {
|
||||
Return: { Type: 'void', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: null },
|
||||
Arguments, Code, Scope: 2, ExecSpace, Attributes: [], Name,
|
||||
};
|
||||
}
|
||||
|
||||
function writeCodeblock() {
|
||||
const cb = {
|
||||
Id: '', GameId: '', EntryKey: 'codeblock://combatmonster', ContentType: 'x-mod/codeblock',
|
||||
Content: '', Usage: 0, UsePublish: 1, UseService: 0, CoreVersion: '26.5.0.0', StudioVersion: '', DynamicLoading: 0,
|
||||
ContentProto: { Use: 'Json', Json: {
|
||||
CoreVersion: { Major: 0, Minor: 2 }, ScriptVersion: { Major: 1, Minor: 0 },
|
||||
Description: '', Id: 'CombatMonster', Language: 1, Name: 'CombatMonster', Type: 1, Source: 0, Target: null,
|
||||
Properties: [prop('string', 'EnemyId', '""'), prop('number', 'RegTries', '0')],
|
||||
Methods: [
|
||||
method('OnBeginPlay', `self.RegTries = 0
|
||||
local eventId = 0
|
||||
local function reg()
|
||||
self.RegTries = self.RegTries + 1
|
||||
local c = _EntityService:GetEntityByPath("/common")
|
||||
if c ~= nil and c.SlayDeckController ~= nil then
|
||||
c.SlayDeckController:RegisterMonster(self.Entity, self.EnemyId)
|
||||
_TimerService:ClearTimer(eventId)
|
||||
elseif self.RegTries > 50 then
|
||||
_TimerService:ClearTimer(eventId)
|
||||
end
|
||||
end
|
||||
eventId = _TimerService:SetTimerRepeat(reg, 0.1)`),
|
||||
],
|
||||
EntityEventHandlers: [],
|
||||
} },
|
||||
};
|
||||
writeFileSync('RootDesk/MyDesk/CombatMonster.codeblock', JSON.stringify(cb, null, 2), 'utf8');
|
||||
}
|
||||
|
||||
const isMonster = (e) => (e.componentNames || '').includes('script.Monster');
|
||||
|
||||
function patchMap(nn) {
|
||||
const tag = String(nn).padStart(2, '0');
|
||||
const file = `map/map${tag}.map`;
|
||||
const map = JSON.parse(readFileSync(file, 'utf8'));
|
||||
let count = 0;
|
||||
for (const e of map.ContentProto.Entities.filter(isMonster)) {
|
||||
const name = (e.jsonString && e.jsonString.name) || '';
|
||||
const enemyId = NAME_TO_ENEMY[name] || DEFAULT_ENEMY;
|
||||
const comps = e.jsonString['@components'];
|
||||
e.jsonString['@components'] = comps.filter((c) => c['@type'] !== 'script.CombatMonster');
|
||||
e.jsonString['@components'].push({ '@type': 'script.CombatMonster', Enable: true, EnemyId: enemyId });
|
||||
const names = (e.componentNames || '').split(',').filter((s) => s && s !== 'script.CombatMonster');
|
||||
names.push('script.CombatMonster');
|
||||
e.componentNames = names.join(',');
|
||||
count++;
|
||||
}
|
||||
writeFileSync(file, JSON.stringify(map, null, 2), 'utf8');
|
||||
return `map${tag}(${count})`;
|
||||
}
|
||||
|
||||
writeCodeblock();
|
||||
const patched = MAP_NUMBERS.map(patchMap);
|
||||
console.log('CombatMonster codeblock written; patched maps:', patched.join(', '));
|
||||
Reference in New Issue
Block a user