UnrealKaraulov / newbspguy

Goldsrc map viewer/editor without decompiling. Also can view .MDL models.
The Unlicense
63 stars 13 forks source link

Partial entpatches support #78

Open Qwertyus3D opened 10 months ago

Qwertyus3D commented 10 months ago

Идея такая, сейчас можно грузить целиковые энтпатчи для карты, так вот хотелось бы иметь возможность с "фрагментированными" энтпатчами работать. Т. е. допустим, сохраняешь энтпатч с какими-то предварительно настроенными энтитями, допустим, это будут энтити для воспроизведения спавна монстра с эффектами телепортации - спрайты, звуки, лучи и т. п. И подобно тому, как мы вставляем на карту BSP-объект, точно так же иметь возможность вставлять такой частичный энтпатч. Желательно с возможностью как вставить его с сохранёнными в энтпатче оригинами энтить, так и со вставкой их в произвольном месте, но чтобы они при этом сохранили своё расположение относительно друг друга. Думаю, востребованная функция будет.

UnrealKaraulov commented 10 months ago

@Qwertyus3D А что такое энптачи эти

Qwertyus3D commented 10 months ago

Энтпатч - это вообще .ent-файл, со списком энтить, естественно. Вот я и предполагаю, что можно создать для себя "частичный энтпатч", в котором будут не все энтити карты, а только заранее настроенные точечные энтити. Допустим, какая-то логическая связка из энтить, активирующих друг друга и т. д. Типа префаба, получается, только из одних точечных энтить. Для воспроизведения каких-то типичных скриптовых последовательностей. Ну и как BSP-модель вставляется на карту, по тому же принципу указываешь такой вот энтпатч, и вставляешь все энтити из него группой на карту, а потом редактируешь что-то, по необходимости (ну типа там имена энтить изменяешь или ещё что-то).

Qwertyus3D commented 10 months ago

Собственно, напрашивается и функция создания такого энтпатча путём импорта выделенных точечных энтить в отдельный .ent-файл. Но это уже второстепенно. Создать нужный энтпатч можно и вручную, Блокнотом отредактировав. Главное, чтоб была возможность загружать такие патчи поверх действующего списка энтить.

Qwertyus3D commented 10 months ago

Вот, допустим, для примера. Комбинация спавна монстра монстрмейкером с эффектами телепортации (как это сделано в Enriched на одной из карт:

{ "origin" "-652 -170 -222" "targetname" "spawnin02_mm" "c3a2_spawn01" "0" "c3a2_spawn01#1" "1" "angles" "0 90 0" "classname" "multi_manager" } { "origin" "-614 -354 -184" "pattern" "mmnmmommommnonmmonqnmmo" "style" "40" "targetname" "smtele_light01" "_light" "77 210 130 150" "spawnflags" "1" "angles" "0 90 0" "classname" "light" } { "origin" "-614 -354 -184" "scale" "1" "targetname" "smtele_sprite01a" "framerate" "10.0" "rendercolor" "77 210 130" "renderamt" "255" "rendermode" "3" "renderfx" "14" "spawnflags" "2" "angles" "0 90 0" "model" "sprites/Fexplo1.spr" "classname" "env_sprite" } { "origin" "-614 -354 -184" "scale" "1" "targetname" "smtele_sprite01b" "framerate" "10.0" "rendercolor" "184 250 214" "renderamt" "255" "rendermode" "3" "renderfx" "14" "spawnflags" "2" "angles" "0 90 0" "model" "sprites/XFlare1.spr" "classname" "env_sprite" } { "origin" "-614 -354 -232" "angles" "0 81 0" "m_imaxlivechildren" "1" "delay" "2" "monstercount" "1" "monstertype" "monster_alien_slave" "targetname" "c3a2_spawn01" "target" "c3a2_01mm" "classname" "monstermaker" } { "origin" "-614 -354 -184" "cspinup" "0" "lfomodvol" "0" "lfomodpitch" "0" "lforate" "0" "lfotype" "0" "spindown" "0" "spinup" "0" "pitchstart" "100" "pitch" "100" "fadeout" "0" "fadein" "0" "volstart" "0" "preset" "0" "message" "debris/beamstart2.wav" "health" "10" "targetname" "smtele_sound01a" "spawnflags" "52" "angles" "0 90 0" "classname" "ambient_generic" } { "origin" "-614 -354 -184" "cspinup" "0" "lfomodvol" "0" "lfomodpitch" "0" "lforate" "0" "lfotype" "0" "spindown" "0" "spinup" "0" "pitchstart" "100" "pitch" "100" "fadeout" "0" "fadein" "0" "volstart" "0" "preset" "0" "message" "debris/beamstart7.wav" "health" "10" "targetname" "smtele_sound01b" "spawnflags" "52" "angles" "0 90 0" "classname" "ambient_generic" } { "origin" "-614 -354 -184" "renderfx" "0" "damage" "0" "StrikeTime" "-.5" "framestart" "0" "framerate" "0" "TextureScroll" "35" "NoiseAmplitude" "65" "BoltWidth" "18" "life" ".5" "rendercolor" "197 243 169" "renderamt" "150" "Radius" "100" "LightningStart" "smtele_beams01" "targetname" "smtele_beams01" "spawnflags" "6" "angles" "0 90 0" "texture" "sprites/lgtning.spr" "classname" "env_beam" } { "origin" "-614 -354 -184" "targetname" "c3a2_01mm" "smtele_sound01a" "0" "smtele_sprite01b" "0" "smtele_sprite01a" "0" "smtele_sound01b" ".5" "smtele_light01#1" "1" "smtele_beams01#1" "1" "smtele_light01" "0" "smtele_beams01" "0" "angles" "0 90 0" "classname" "multi_manager" }

Энтити и мультименеджер, который их активирует. Такой фрагмент сохраняется отдельным патчем в виде ent-файла и вставляется на карту, с соблюдением расположения энтить относительно друг друга. И можно использовать, как универсальную заготовку для спавна любого моба телепортацией. А в ХЛ подобный эффект сложнее сделан, там ещё лучи раскиданы вокруг монстрмейкера, а не в одной точке.

Qwertyus3D commented 10 months ago

Я по нику догадался про второй акк :) . Локализация - это круто. Буду ждать фиксов и обнов. Кстати, по ходу дела ещё одна проблемка застарелая всплыла - программа виснет с чёрным окном без интерфейса при попытке запустить её просто кликом в Проводнике, без открытия карты. Тоже уже когда-то исправлялось, и вот опять не работает. Дебажная версия такой лог показывает:

Open editor with empty map.
Start bspguy editor with:
Load settings from : D:\Games\Xash3D\_Tools_\BSPGuy/bspguy.cfg
Texture with data : objIcon 128/128 is loaded.
Load texture objIcon with 128/128 size
Texture with data : faceIcon 128/128 is loaded.
Load texture faceIcon with 128/128 size
Loaded empty map.
Parsing _Res_/fgd/halflife_2022_op4.fgd
Move camera to first entity...
Texture: white 1/1 is loaded.
Texture: grey 1/1 is loaded.
Texture: red 1/1 is loaded.
Texture: yellow 1/1 is loaded.
Texture: black 1/1 is loaded.
Texture: blue 1/1 is loaded.
Load texture white with 1/1 size
Load texture red with 1/1 size
Load texture yellow with 1/1 size
Load texture grey with 1/1 size
Load texture black with 1/1 size
Load texture blue with 1/1 size
Texture with data : missing 16/16 is loaded.
Load texture missing with 16/16 size
Created 0 solid render groups (0 world, 0 entity)
Texture: LIGHTMAP 512/512 is loaded.
Created 0 solid render groups (0 world, 0 entity)
Calculating lightmaps
Loaded 0 clipnode leaves
Loaded 0 lightmaps into 1 atlases
Generated 160 point entities cubes
Qwertyus3D commented 9 months ago

@UnrealKaraulov Исправился незапуск без карты.

Qwertyus3D commented 9 months ago

Ну, наподобие префаба, только это тупо текстовый файл с данными точечных энтить. Грубо говоря, просто обрезок полного ent-патча карты. Тот же формат абсолютно, даже расширение можно оставить .ent. Ну, если хочешь, можно назвать .entp или .enp (entity prefab file!), чтобы не путалось с полноценными энт-патчами.

Насчёт target и targetname - ну это же 2 разные функции, targetname - имя самой энтити, а target - другая целевая энтить, которая будет активизирована при помощи первой.

Qwertyus3D commented 9 months ago

Не пойму, в чём вопрос-то? Кому надо "давать разные имена"? Если энтитям, то не нужно никаких дополнительных имён. Как пользователь всё настроил, так и будет. Это же точечные энтити. Выше ведь пример: https://github.com/UnrealKaraulov/newbspguy/issues/78#issuecomment-1836703772 Это один цельный файл будет, и в нём сразу несколько энтить прописаны. А не каждая энтить в отдельном файле.

Если файлам, то разные имена у файлов могут быть, какое пользователю при экспорте захочется присвоить, наверное. Ну или если не предусматривается пользователя спрашивать об имени файла, то пусть с рандомным именем сохраняет, по шаблону.

Qwertyus3D commented 9 months ago

Или ты имеешь в виду, что при импорте нужно менять имена энтить, которые прописаны в патче? С тем, чтобы после вставки на карту они не смешивались из-за одинаковых имён, если один и тот же патч импортировать несколько раз?

Ну тут хз, но если бы ты смог сделать так, то наверное было бы удобно. Ну типа мы берём исходную энтить:

{ "origin" "-652 -170 -222" "targetname" "spawnin02_mm" "c3a2_spawn01" "0" "c3a2_spawn01#1" "1" "angles" "0 90 0" "classname" "multi_manager" }

И переделываем её при вставке на карту, допустим, так:

{ "origin" "-652 -170 -222" "targetname" "spawnin02_mm-01" "c3a2_spawn01-01" "0" "c3a2_spawn01-01#1" "1" "angles" "0 90 0" "classname" "multi_manager" }

И, соответственно, всем именам энтить из патча (т. е. в поля target и targetname, а также в ключевые значения мультименеджера, как здесь) добавляем вот это -01

И у нас получается группа энтить, которая завязана сама на себя и не смешивается с остальными. Так?

Qwertyus3D commented 9 months ago

Но вообще всё может оказаться не так просто, т. к. у разных энтить бывают и дополнительные ключи, которые могут содержать отсылки на имена других энтить. Это тогда придётся пропарсить все значения target и targetname в патче, и по "упомянутым" именам провести правку всех других совпадающих значений. Либо составить полный список ключей, в которых может быть прописано имя какой-либо энтити, а этот список может быть не таким уж маленьким, если покопаться.

Допустим: targetname(target_source) target(target_destination) / target(string) / target(target_source) killtarget(target_destination) / killtarget(string) globalname(string) netname(string) master(string) changetarget(target_destination) entity(string) listener(string) m_iszEntity(string) moveto(string) m_iszNewTarget(string) laserentity(target_source) LaserTarget(target_destination) TriggerTarget(String)

У path_track вон сколько ссылок (у path_corner первые две): target(target_destination) message(target_destination) - причём тут месседж именно цель altpath(target_destination) netname(target_destination)

У info_bigmomma уникальные: reachtarget(target_destination) reachsequence(string) presequence(string)

env_beam LightningStart(target_destination) LightningEnd(target_destination)

У func_trackchange и func_trackautochange (но это солиды, так что не должны быть в обычном энтпатче): train(target_destination) toptrack(target_destination) bottomtrack(target_destination)

До фига потенциальных ссылок, плюс произвольные поля в мультименеджерах со знаками повторной активации энтить. И это я пробежался по FGD Опфора. А ведь в теории, есть кастомные FGD разные, где могут быть какие-то другие поля, куда тоже может прописываться имя других сущностей, так что готовый список - не полное решение...

Qwertyus3D commented 9 months ago

Есть тупая идея, как это можно сделать проще, но потребует информированности пользователя. Пользователь сам должен вручную указать те значения, которые должны быть заменены при вставке на произвольный порядковый номер. Т. е. должен использовать некий символ, указывающий программе, где именно производить подстановку номера.

Допустим, как со случаем выше:

{ "origin" "-652 -170 -222" "targetname" "spawnin02_mm@@@" "c3a2_spawn01@@@" "0" "c3a2_spawn01@@@#1" "1" "angles" "0 90 0" "classname" "multi_manager" }

Ну и вот эти @@@ заменяются порядковым числом. Символ можно и другой какой-то обозначить, но так, чтобы мала была вероятность случайного использования такой комбинации символов. Допустим, сколько символов вписано, столько и цифр подставляется, минимум две: @@ -> 01, @@@ -> 001 и т. д.

Зато тут уже программа не своевольничает, что-то делая сама (чего, может, и не надо), а делает подмену потому, что есть указание. И сложный код не потребуется.

Qwertyus3D commented 9 months ago

Проще всего в окне импорта дать ссылку на инструкцию, что изменить в ключах энтить перед импортом. Потому что в процессе импорта ХЗ как это организовать. Лучше пусть пользователь знает, как это в принципе работает и имеет возможность ручной правки.