- ACT_COUNT/RUN_LENGTH 3→5, ACT_MAPS map01~map05 (반복 런 기반 확장) - MAP_ROWS 7→6 (걷는 행 6 + 보스 = depth 최대 7), 막 배율 0.6→0.45 완화 - 노드 타입 인접 금지를 elite 단독 → rest/shop/elite 3종으로 일반화 (Lua GenerateMap + rogue-map.mjs JS 미러 동시 수정, 테스트 9/9 통과) - 맵 파일 생성기 카운트 11→5, map06~map11 삭제, SectorConfig 정리(stale 제거) - 산출물 재생성(ui/codeblock/map01~05). 검증 헬퍼 tools/verify/count.mjs 추가 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
84 lines
2.6 KiB
JavaScript
84 lines
2.6 KiB
JavaScript
import { readFileSync, writeFileSync } from 'node:fs';
|
|
|
|
const AI_COMPONENTS = new Set([
|
|
'MOD.Core.AIWanderComponent',
|
|
'MOD.Core.AIChaseComponent',
|
|
]);
|
|
|
|
const mapFiles = Array.from({ length: 5 }, (_, i) => `map/map${String(i + 1).padStart(2, '0')}.map`);
|
|
const modelFiles = [
|
|
'Global/MoveMonster.model',
|
|
'Global/ChaseMonster.model',
|
|
'RootDesk/MyDesk/Models/Monsters/Model_monster-43.model',
|
|
];
|
|
|
|
function isMonster(entity) {
|
|
return (entity.componentNames || '').includes('script.Monster');
|
|
}
|
|
|
|
function component(entity, type) {
|
|
return entity.jsonString['@components'].find((c) => c['@type'] === type);
|
|
}
|
|
|
|
function patchMonsterEntity(entity) {
|
|
const components = entity.jsonString['@components'];
|
|
entity.jsonString['@components'] = components.filter((c) => !AI_COMPONENTS.has(c['@type']));
|
|
entity.componentNames = entity.jsonString['@components'].map((c) => c['@type']).join(',');
|
|
|
|
const movement = component(entity, 'MOD.Core.MovementComponent');
|
|
if (movement) {
|
|
movement.Enable = false;
|
|
movement.InputSpeed = 0;
|
|
}
|
|
|
|
const rigidbody = component(entity, 'MOD.Core.RigidbodyComponent');
|
|
if (rigidbody) {
|
|
rigidbody.MoveVelocity = { x: 0, y: 0 };
|
|
rigidbody.RealMoveVelocity = { x: 0, y: 0 };
|
|
}
|
|
|
|
const transform = component(entity, 'MOD.Core.TransformComponent');
|
|
if (transform?.Scale) {
|
|
transform.Scale.x = Math.abs(transform.Scale.x || 1);
|
|
transform.Scale.y = Math.abs(transform.Scale.y || 1);
|
|
}
|
|
|
|
const stateAnimation = component(entity, 'MOD.Core.StateAnimationComponent');
|
|
const renderer = component(entity, 'MOD.Core.SpriteRendererComponent');
|
|
const stand = stateAnimation?.ActionSheet?.stand;
|
|
if (renderer && stand) {
|
|
renderer.SpriteRUID = stand;
|
|
}
|
|
}
|
|
|
|
function patchMap(file) {
|
|
const data = JSON.parse(readFileSync(file, 'utf8'));
|
|
for (const entity of data.ContentProto.Entities.filter(isMonster)) {
|
|
patchMonsterEntity(entity);
|
|
}
|
|
writeFileSync(file, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
|
|
}
|
|
|
|
function patchModel(file) {
|
|
const data = JSON.parse(readFileSync(file, 'utf8'));
|
|
const json = data.ContentProto.Json;
|
|
json.Components = (json.Components || []).filter((name) => !AI_COMPONENTS.has(name));
|
|
json.Values = (json.Values || []).filter((value) => !AI_COMPONENTS.has(value.TargetType));
|
|
for (const value of json.Values) {
|
|
if (value.TargetType === 'MOD.Core.MovementComponent' && value.Name === 'InputSpeed') {
|
|
value.Value = 0;
|
|
}
|
|
}
|
|
writeFileSync(file, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
|
|
}
|
|
|
|
for (const file of mapFiles) {
|
|
patchMap(file);
|
|
}
|
|
|
|
for (const file of modelFiles) {
|
|
patchModel(file);
|
|
}
|
|
|
|
console.log('Turn-combat monster movement disabled.');
|