Здравствуйте
Во время моддинга возник вопрос как соединить два вада в, чтобы всё корректно работало
Простым копированием файлов одного вада в другой вопрос не решился, поэтому я отправляюсь за ответом к вам, профессионалам
Landsberg Правильно хотел сделать. Файлы одного надо переместить в файлы другого. Но только учти, чтобы ты не надедал дубликатов каких-то маркеров, карт, файлов и Т. П. Советую сначала сделать бэкап обеих исходных вадов, а потом уже соединять.
Во время моддинга возник вопрос как соединить два вада в, чтобы всё корректно работало
Как вариант положить ВАД-ы в архив (рк3 или 7зип) Другое дело, если будут возможны конфликты с одноимёнными названиями ресурсов. Тогда подгонять придётся руками.
Желательно, конечно же, использовать *.pk3 . Почему? Потому что формат *.wad морально устарел. Он не поддерживает папки (и, соответственно, пути), требует маркировку ресурсов, патчинг новых текстур и прочие неудобные танцы с бубном . Сейчас вады используются для проектов под Boom и Vanilla, потому что *.pk3 это формат ZDoom и не поддерживается более классическими портами. Достаточно редко вады используются для GZDoom.
есть, вообще, три основных способа
1 - пихаешь в вад классическую картинку неба, в лампе MAPINFO пишешь в параметре уровня
Sky1 = "ИМЯ_ИЗОБРАЖЕНИЯ"
Скрытый текст:
выходит что-т типа этого
map MAP01 ""
{
Sky1 = "RSKY1", 0
}
цифра после запятой - скорость прокрутки
если надо второй - пишешь Sky2 = , нужному сектору ставишь Special равным 200
-
2-пихаешь в вад картинки сторон коробки скайбокса, в лампе GLDEFS задаешь скайбокс
Скрытый текст:
вроде этого
Skybox MYSKY6 fliptop
{
MYSKY6_N
MYSKY6_E
MYSKY6_S
MYSKY6_W
MYSKY6_T
MYSKY6_B
}
fliptop зеркалит картинку потолка, потому что гозза по дефолту понимает его не как другие нормальные программы
MYSKY6_N/E/S итд - имена изображений
затем делаешь штуки с MAPINFO, как в первом способе
-
3 - делаешь отдельную комнату, как, например, делают игры на сурс вроде хл2, и ставишь туда Skybox Viewpoint.
если надо второй - ставишь второй Skybox Viewpoint и задаешь ему TID. потом в нужных секторах ставишь Skybox Picker и указываешь им TID виевпоинта.
1. Как записать ф-цию чтобы она принимала float вместо int, например GiveBody(-1.2) ? Ну т. е. может кто-нибудь объяснить в каком месте кода актора должны записываться подобные переводы чисел: Fixed_point_number?
2. Можно ли задавать юзервары как выражения, например A_SetUserVar("user_A",random(2,5)*4) или A_SetUserVar("user_A",GetMissileDamage(7,1,AAPTR_DEFAULT)) ?
3. Можно ли задавать юзерварам значения из других юзерваров, например A_SetUserVar("user_A",user_B) ?
4. Я правильно понимаю что для получения значения юзервара из кастоминвентори итема, оный юзервар должен быть прописан у получателя этого итема?
5. Что значит термин "clearscope" в SpawnHealth и почему эта ф-ция не определяется в Слэйде (3.1.1.5)?
1. Как записать ф-цию чтобы она принимала float вместо int, например GiveBody(-1.2) ? Ну т. е. может кто-нибудь объяснить в каком месте кода актора должны записываться подобные переводы чисел: Fixed_point_number?
Переводить там где надо получить число с точкой, обычно в вики пишут какого типа надо писать аргумент, к примеру:
bool A_SpawnItem (string type, double distance, float zheight, bool useammo, bool translation)
т.е. к примеру аргумент zheight надо писать с фиксированной точкой! (но можно и целое число писать, просто иногда может получиться не то что ожидаешь)
По поводу конвертирования, там по ссылке очень хорошо все написано, думаю сложностей не должно вызвать https://zdoom.org/wiki/Fixed_point_number Вот еще обрати внимание
"To do multiplies and divides on fixed point numbers in ACS scripts, you can use functions such as FixedMul and FixedDiv." Т.е. числа с точкой нельзя просто так брать и умножать\делить типа (3.1 * 2.5), получишь не правильный ответ.
Вместо этого надо использовать функции
FixedMul(3.1, 2.5)//умножит числа с точкой и вернет результат.
FixedDiv(3.1, 2.5)//делит числа с точкой и вернет результат.
Void Weaver:
2. Можно ли задавать юзервары как выражения, например A_SetUserVar("user_A",random(2,5)*4) или A_SetUserVar("user_A",GetMissileDamage(7,1,AAPTR_DEFAULT)) ?
Да, мог бы это и сам проверить простыми тестами...
Void Weaver:
3. Можно ли задавать юзерварам значения из других юзерваров, например A_SetUserVar("user_A",user_B) ?
Да.
Void Weaver:
4. Я правильно понимаю что для получения значения юзервара из кастоминвентори итема, оный юзервар должен быть прописан у получателя этого итема?
Нет, если ты хочешь получить юзервар кастомитема, то в кастомитеме и надо прописывать юзаервар! Но исключение может быть стейт PickUp: у инвенториитемов, твориться не ведомая х...я с юзерварами во время подбора предмета, т.е. если не ошибаюсь эти юзервары ведут себя не адекватно. Как я понял это из-за того что ГГ подбирает вещь и вещь уже поднята и работает стейт pickup, но все юзервары что пытался получить они были уже юзерварами игрока или мб их вовсе не было.. Короче темный лес.
Void Weaver:
5. Что значит термин "clearscope" в SpawnHealth и почему эта ф-ция не определяется в Слэйде (3.1.1.5)?
Гугл переводит как "прозрачный охват"
Я могу предположить что словом clearscope хотели донести до нас что эта функция возвращает значение жизни актера когда он только заспавнился т.е. не тронутое, чистое оз
А не определяется... Хз, видимо функцию забыли\не захотели добавить в подсветку слейда. В прочем там не только эта функция не подсвечивается. Хочешь что бы подсвечивалась, напиши авторам слейда, может быть они добавят подсветку(обычно они это сами делают, просто версии выходят редко.)
А еще при объявлении юзервара теперь надо писать тип var fixed user_a; var int user_a;. Раньше не надо было т.к. тип с точкой не поддерживался
Еще эти юзервары в декорейте можно использовать так
Void Weaver Хочу дополнить ответ alekv.
1. Мне казалось, что (по крайней мере, в современных gzdoom) в декорейте действительные числа именно с плавающей, а не с фиксированной точкой. Что есть то и другое, можно почитать на Википедии. В пользу этой версии говорит и то, что в декорейте, например, 22.0 равно 22 (число с фиксированной точкой --- тот же int, но как бы "сдвинутый" на 16 бит влево). В ACS плавающей точки нет, есть только фиксированная, но поскольку с типами переменных там тоже проблемы, числа с фиксированной точкой фактически хранятся в intах. 22.0 в ACS будет храниться как 22 * (1 << 16) = 1441792.
В декорейте и особенно зскрипте, повторяю, об этом не нужно заботиться, там арифметика с плавающей точкой.
2, 3. A_SetUserVar рассчитывает свой второй аргумент во время выполнения, так что да, можно.
Если пишешь под новые версии, можно не обращаться к этим громоздким функциям, а работать с переменными напрямую в анонимных функциях (пример показал alekv). Кстати, типа fixed в зскрипте, согласно вики, нет вообще.
4. На вики написано, что
Once used, the CustomInventory item loses access to its variables, gaining direct access to the owner's variables instead.
То есть, после использования (какого использования? Pickup? Use?) вещь теряет доступ к своим переменным, получая взамен прямой доступ к переменным хозяина.
5. clearscope --- это не функция, а ключевое слово (модификатор), связанное с контекстами zscript. Контексты разделяют "области ответственности" функций на собственно игровую (play), отрисовку экрана (ui), а также хранения данных (data). Основные игровые процедуры движка поделены между этими областями; в одной области не всегда можно вызвать процедуру из другой, а clearscope в определении функции позволяет это делать всегда. Я в этом сам не разбираюсь, если интересно, вот статья. Для целей вроде "создать пару акторов" такая штука не пригодится точно, поэтому на неё пока не нужно обращать внимания.
Slade3 редко обновляется. В 3.1.1.5, наверное, ещё и базовой подсветки зскрипта не было.
Переводить там где надо получить число с точкой, обычно в вики пишут какого типа надо писать аргумент, к примеру:
bool A_SpawnItem (string type, double distance, float zheight, bool useammo, bool translation)
т.е. к примеру аргумент zheight надо писать с фиксированной точкой! (но можно и целое число писать, просто иногда может получиться не то что ожидаешь)
Actor DImp : DoomImp
{
//var float user_balldrn;
Health 1000
States
{
See:
TROO AABBCCDD 3 A_Chase
Loop
Melee:
Missile:
TROO EF 8 A_FaceTarget
TROO G 6 A_CustomComboAttack("DrainImpBall", 32, 3 * random(1, 8), "imp/melee")
Goto See
Pain: Goto Super::Pain
Death: Goto Super::Death
XDeath: Goto Super::XDeath
}
}
Actor DrainImpBall : DoomImpBall
{
Damage (random(1,8)*3)
var float user_damage;
var float user_balldrn;
States
{
Spawn:
BAL1 AB 4 Bright A_SetUserVarFloat("user_balldrn",user_damage)
Loop
Death:
BAL1 C 0 Bright A_DamageTarget(-(user_balldrn/2))
BAL1 CDE 6 Bright
Stop
}
}
alekv:
А не определяется... Хз, видимо функцию забыли\не захотели добавить в подсветку слейда. В прочем там не только эта функция не подсвечивается.
N00b2015:
Slade3 редко обновляется. В 3.1.1.5, наверное, ещё и базовой подсветки зскрипта не было.
На счёт забытых подсветок я в курсе, но в случае со SpawnHealth слэйд выдаёт эррор: "Invalid parameter 'spawnhealth'". Или на вики просто ошибочно причислили эту ф-цию к декорэйт категории, перепутав с GetSpawnHealth?
Хм... GiveBody с той же ошибкой.
alekv:
Нет, если ты хочешь получить юзервар кастомитема, то в кастомитеме и надо прописывать юзаервар! Но исключение может быть стейт PickUp: у инвенториитемов, твориться не ведомая х...я с юзерварами во время подбора предмета, т.е. если не ошибаюсь эти юзервары ведут себя не адекватно. Как я понял это из-за того что ГГ подбирает вещь и вещь уже поднята и работает стейт pickup, но все юзервары что пытался получить они были уже юзерварами игрока или мб их вовсе не было.. Короче темный лес.
N00b2015:
На вики написано, что
Once used, the CustomInventory item loses access to its variables, gaining direct access to the owner's variables instead.
То есть, после использования (какого использования? Pickup? Use?) вещь теряет доступ к своим переменным, получая взамен прямой доступ к переменным хозяина.
, чё-т я окончательно запутался. Так может актор А получить значение юзервара актора С через "Pickup:" актора Б?
Не знаю какого эффекта, но кажется user_damage у тебя всегда равен 0, как следствие эта строка бесполезна A_SetUserVarFloat("user_balldrn",user_damage) т.к. user_balldrn как был так и остается равен 0.
Void Weaver:
На счёт забытых подсветок я в курсе, но в случае со SpawnHealth слэйд выдаёт эррор: "Invalid parameter 'spawnhealth'". Или на вики просто ошибочно причислили эту ф-цию к декорэйт категории, перепутав с GetSpawnHealth?
Хм... GiveBody с той же ошибкой.
Думаю если спросишь у разрабов, тебе дадут точный ответ. Я не в курсе. Знаю что версии слейда выходят редко из-за чего часто бывает новые функции остаются долго без подсветки.
Void Weaver:
Так может актор А получить значение юзервара актора С через "Pickup:" актора Б?
Смотря какой актер, ты спрашивал про кастоминвентори. Через pickup хз, возьми да попробуй делов 5мин. Я помню были проблемы которые не решили по сей день и не решат т.к. есть зскрипт.
Там есть еще разные способы, к примеру передать через спавн или acs, но на прямую через декорейт никак.
Смотри есть актер
Actor MyActor_1
{
var int user_A;
States {
Spawn:
MODL A 1
MODL A 1 {user_A = 10;}
Idle:
MODL A -1
Stop
}
}
Есть 2-ой актер который должен получить значение user_A из первого
Actor MyActor_1
{
States {
Spawn:
//MODL A 1 {if(user_A > 0 }//Так не получишь потому что юзер вар это локальная переменная в данном случае актера 1, и актер 2 не знает о ее существовании.
//Остается костылить через ACS, 1 актер должен запустить при спавне скрипт в который запишет значение в ACS переменную типа такого
//int SomeACS_UserVar;//В эту переменную запомним юзервар из декорейта
//script "SaveUserVar" (void)
//{
// SomeACS_UserVar = GetUserVariable(0, "user_A");//Запомнили чему равна USER_A, напоминаю что активатор этого скрипта актер 1.
//}
Далее можно написать скрипт такой
Script "GetDecorateUserVar" (void)
{
SetResultValue(SomeACS_UserVar);
}
Таким образом в декорейте можно будет сделать так
MODL A 1 {if(CallACS("GetDecorateUserVar", 0) == 10 ) {A_PrintBold("Test user_a == 10");}}//Получили значение юзервара из 1-ого актера.
loop
}
}
Вот такие костыли.
Можно еще через A_SpawnItemEx, если спавнить то просто передать при спавне аргументом значение которое надо, но это реже требуется.
Проще делать как выше описал.
Других способов не знаю, если они есть, то был бы рад почитать.
Это каким образом он выдаёт ошибку? Ты имел в виду gzdoom? А ты уверен, что именно вызываешь нечто вроде user_a = SpawnHealth()? Может, конечно, из decorate она действительно не работает, но стоит попробовать и так.
Так может актор А получить значение юзервара актора С через "Pickup:" актора Б?
Опиши, пожалуйста, то, что тебе хотелось бы получить, конкретнее, можно с примером. Мне вот сначала показалось, что ты хочешь дать custominventory некоторому актору и во время pickup ещё что-то сделать с переменными этого актора. Это делается напрямую, без всяких фокусов. Теперь же у тебя добавился какой-то актор А.
alekv Юзервары ведут себя не слишком очевидным образом, но отказываться от них из-за этого не стоит. Я уже писал, что вики утверждает, что:
User defined variables on inventory items will only affect the item itself until picked up; everything afterwards affects only the receiver,
это значит, что перед поднятием вещи custominventory имеет доступ только к своим переменным, а после --- только к чужим.
Однако, по-моему, в zscript есть способ добраться до "своих" переменных после взятия.
Ок, вскрываю карты.
1. Хочу написать мили и миссайль лайфлич для монстр-акторов, причём на декоре ОНЛИ. Докучи хотелось бы привязать визуальный эффект к процессу.
2. Хочу таки реализовать абилку "взрыв трупов" - уничтожение трупа с дамагом базирующемся на СпаунХеалс трупа, также ТОЛЬКО на декоре.
alekv:
Не знаю какого эффекта, но кажется user_damage у тебя всегда равен 0
Эффекта эмуляции лайфлича же. Почему нулю? Вики гласит что user_damage е штатный юзервар урона (хоть и депрекэйтэд). Решено: ну да, затупил. A_SetUserVarFloat("user_damage",Damage)
alekv:
Смотря какой актер, ты спрашивал про кастоминвентори. Через pickup хз, возьми да попробуй делов 5мин.
Ну кастоминвентори мне нужен для спауна оверлэя визуального эффекта лича. Пробовал - не получается, одни ошибки. Поэтому и спрашиваю.
N00b2015:
Это каким образом он выдаёт ошибку? Ты имел в виду gzdoom? А ты уверен, что именно вызываешь нечто вроде user_a = SpawnHealth()?
Да не, эррор выдаётся даже без всяких юзерваров, просто при вызове сабжа в стэйте, при том что GetSpawnHealth подсвечивается и вызывается без всяких траблов на тех же условиях. Решено: просто слишком старая версия гоззы, но подсветки всё равно нет.
N00b2015:
Опиши, пожалуйста, то, что тебе хотелось бы получить, конкретнее, можно с примером. Мне вот сначала показалось, что ты хочешь дать custominventory некоторому актору и во время pickup ещё что-то сделать с переменными этого актора. Это делается напрямую, без всяких фокусов. Теперь же у тебя добавился какой-то актор А.
Ну вкратце см. начало поста. Я вижу это следующим образом:
Actor LifeSteal : CustomInventory //Эта шняга спаунится в момент смерти DrainImpBall
{
//var float user_balldrn;
+Inventory.AlwaysPickup
States
{
Spawn:
TNT1 A 1
Loop
Pickup:
TNT1 A 0 A_SetUserVarFloat("user_balldrn",user_damage) //Соответственно user_balldrn и user_damage берутся из DrainImpBall
TNT1 A 0 A_SpawnItemEx("лайфлич_оверлэй",0,0,0,0,0,0,0,SXF_SETTRACER)
TNT1 A 0 A_DamageSelf(-(user_balldrn/2)) //А это должно похилить импа подобравщего сей итем
Stop
}
}
Актор А (имп) кидает актор С (импболл)=>
актор С в спаун стэйте постоянно чекает и записывает в user_damage собственный рандомный дамаг Damage (random(1,8)*3), значение которого пишется также в user_balldrn=>
когда актор С дохнет, он хилит таргет (актор А) на половину от значения user_balldrn.
Для идеала не хватает оверлэя эффекта. Поэтому я решил что лучше всего в эту цепочку запихнуть промежуточный актор Б (кастоминвентори итем - Actor LifeSteal), который при взятии будет выдавать импу сразу и оверлэй итем и хил из user_balldrn. Как-то так. С взрывом трупов приблизительно схожие соображения.
Здравствуйте
Я добросовестно, но не очень долго покопался в интернете и на этом форуме, но так и не нашёл вразумительный ответ
Вопрос следующий:
Какая команда в слейде меняет музыку в меню(как менять на самих картах - знаю)
А вот нифига дроби не возвращает, а округляет до целого. Мне же нужны выходные числа типа 0.001 или 1.5.
alekv, N00b2015, в общем "вампиризм" на юзерварах пашет но к сожалению не сохраняет нанесённый урон, поэтому рандомно происходит казус что актор "вампирит" хп больше нанесённого урона. Это можно как-нибудь пофиксить?
Actor DrainImpBall : DoomImpBall
{
Damage (frandom(1.0,8.0)*3.0)//(1.5)
-RANDOMIZE
+HITTRACER
var float user_balldrn;
States
{
Spawn:
BAL1 AB 4 Bright A_SetUserVarFloat("user_balldrn",Damage)
Loop
Death:
TNT1 A 0 A_JumpIf(IsPointerEqual(AAPTR_TRACER,AAPTR_NULL)==1,4)
TNT1 A 0 A_CheckSpecies("BlankDeath","DoomImp",AAPTR_TRACER)
TNT1 A 0 A_DamageTarget(-user_balldrn/3-5)
TNT1 A 0 A_SpawnItemEx("LifeStealOverlay",0,0,20,0,0,0,0,SXF_SETTRACER)
BlankDeath:
BAL1 CDE 6 Bright
Stop
}
}
1. Как записать ф-цию чтобы она принимала float вместо int, например GiveBody(-1.2) ? Ну т. е. может кто-нибудь объяснить в каком месте кода актора должны записываться подобные переводы чисел: Fixed_point_number?
Как ты себе это представляешь? Функции, принимающие int, оперируют строго дискретными параметрами, которые дискретны на уровне движка. Не может быть половинки хелса или половинки патрона, например. С дамагом та же история: по какой бы формуле он ни вычислялся, пришедший в цель дамаг всегда будет дискретен. Health вообще правильнее воспринимать, как одно из количественных содержимых инвентаря.
А вот функции типа scaleX и всяких углов наводки жрут дроби, потому что сама сущность оперируемого является дробной.
Обойти это можно было бы разве что в рамках отдельного мода, где к каждому объекту пришит дробный узервар "дробное здоровье", и вся логика повреждений-подыханий реализуется через него.