Как вариант, активацией Classes:ArtiFly а перед этим небольшой толчок ThrustThingZ. Отключить можно с помощью выдачи кастоминвентори с A_TakeInventory("PowerFlight",1)
Void Weaver :
Если же прописать пуффу +EXTREMEDEATH, то будет всегда рвать в мясо
Мне нужно чтобы в мясо рвало только когда сумма урона от всех (их, вроде, 20) паффов ссг приемлема (и как, соответственно этот приемлемый уровень установить)
кастомный пафф для SSG, чтобы только это оружие так кромсало в мясо. А остальное осталось кромсать по прежнему. Это в Смут Думе реализовано с помощью кастомного паффа.
Какой милый брехливый щеночек! Умереть не встать!
К сожалению я таки оказался прав - ССГ там перепилен, но эффект прежде всего не в самой пухе а в куче хитрых кастомных Death стэйтов и их производных у монстров. Так что хочешь такую же волыну - пили соответствующий бестиарий и/или скрипт. В качестве пруфа вот пуфф тамошнего ССГ:
Скрытый текст:
ACTOR BulletPuffGibby : SmoothBulletPuff //Собственно пуфф ССГ (да и всех местных огнестрелов)
{
DamageType GibbyHaynes //Собс-но спец-ДамагТайп, активирующий разные смерти монстров и соответственно разные гибсы
}
ACTOR SmoothBulletPuff Replaces BulletPuff
{
Game Doom
SpawnID 131
+NOBLOCKMAP
+NOGRAVITY
+ALLOWPARTICLES
+RANDOMIZE
RenderStyle Translucent
Alpha 0.7
VSpeed 1
Mass 5
States
{
spawn:
TNT1 A 0
TNT1 A 0 A_JumpIf(CallACS("PuffStyle")==1, "FancyPuff") //Скриптованное условие для спауна графона, но НЕ ГИБСОВ!
spuf abcd 2 bright
spuf efghi 2
stop
FancyPuff:
PUFF A 2 Bright
TNT1 AAAAA 0 A_CustomMissile ("PuffParticles", 0, 0, random (0, 360), 2, random (0, 360)) //Графонистые дымки-хренки
TNT1 AAA 0 A_CustomMissile ("PuffSmoke", 0, 0, random (0, 360), 2, random (0, 360)) //Графонистые дымки-хренки
PUFF B 2
Melee:
PUFF CD 2
Stop
}
}
А ЭТО стэйты смерти всего-лишь ОДНОГО импа :
Скрытый текст:
Death.GibbyHaynes:
TNT1 A 0
TNT1 A 0 A_JumpIf(CallACS("StudioGibbly")==0, "Death")
TNT1 A 0
TNT1 A 0 A_JumpIfCloser(128, "XDeath")
TNT1 A 0
Death:
TNT1 A 0
TNT1 A 0 A_JumpIf(CallACS("MoDeathToggle")==1, "DeathExtra")
TNT1 A 0 A_Jump(255, "Death1")
Goto Death1
DeathExtra:
TNT1 A 0
TNT1 A 0 A_Jump(255, "Death1", "Death2", "Death3", "Death4")
Goto Death1
Death1:
5OSS J 2 A_Scream
5OSS K 2 A_NoBlocking
5OSS LMNO 3
5OSS PQR 3
5OSS ST 3
//TNT1 A 0 a_jumpif(callACS("NukeCheck")==1, "NukeMelt")
5OSS U -1
Stop
Death2:
TSD3 A 3 A_Scream
TSD3 B 2 A_NoBlocking
TSD3 CDEFGHI 3
TSD3 J -1
Stop
Death3:
TRO2 a 3
TRO2 b 3 A_NoBlocking
TRO2 cd 3
TRO2 e 3 A_Scream
TRO2 FGHIJ 2
TRO2 kl 3
TRO2 M -1
stop
Death4:
I2V1 A 4
SROD B 3 A_Scream
SROD C 3
SROD D 3 A_NoBlocking
SROD E 3
SROD F 3
SROD G 3
SROD H 2
SROD I 6
SROD J 3
SROD K 3
SROD L 3
SROD M -1
Stop
XDeath:
TROX ab 2
TNT1 AAAAAAAAAAAAAAA 0 A_CustomMissile ("Gibs1", 32, 0, random (0, 360), 2, random (0, 160))
TNT1 AAAAAAAAAAAAAAAA 0 A_SpawnItem("XBlood2", 0, 40)
TNT1 AA 0 A_CustomMissile ("Gibs2", 32, 0, random (0, 360), 2, random (0, 160))
TROX cd 2 a_xscream
TROX ef 2
TROX gh 2 a_noblocking
TROX ijklmn 2
TROX o -1
stop
А вообще задачка довольно интересная, если какие идеи появятся - сообщу. Кстати можно попробовать задействовать мега-счётчик хпСмертоносца.
Кстати, Герр Смертоносец, не желаете ли поучаствовать в решении этой задачки?
DOOMGABR:
Планируется добавить функцию, чтобы SSG кромсал врагов в мясо, при достаточном уроне. Но пока нет идей, как это реализовать.
Ну пока теоретически-умозрительно:
0. Изначально пули имеют нулевой дамаг.
1. Облачко пуффов с +PUFFONACTORS и +HITTRACER прилетает в цель. Каждый пуфф "знает", в кого он попал.
2. Пуфф даёт трасеру пуффитем.
3. Спустя некоторую задержку пуфф измеряет, сколько пуффитемов собралось в инвентаре у трасера.
_4.1. Если пуффитемов меньше 20, то пуфф наносит обычный урон одной дробины.
_4.2. Если пуффитемов 20, значит цель приняла на себя все дробины, и пуфф наносит ей +EXTREMEDEATH-урон одной дробины.
5. Спустя некоторую задержку пуфф изымает у трасера один пуффитем, после чего растворяется в воздухе.
Подводные камни в задержках между тактами, которые надо тестить. Здесь работает "распределённая одновременность", согласованная работа комплекса независимых акторов, - но на уровне движка одни события обрабатываются позже других, и в разных движках такое может работать по-разному. Поэтому базово надлежит ставить delay>0, а можно ли его сделать 0 - это вскрытие покажет.
Декорейт-онли не гарантируется, однако CountInv("itemname",AAPTR_TRACER) для декорейта работает.
Перспективно конечно, вот только здесь выходит заминка:
Герр Смертоносец:
_4.2. Если пуффитемов 20, значит цель приняла на себя все дробины, и пуфф наносит ей +EXTREMEDEATH-урон одной дробины.
Либо я не умею готовить пуффы, либо их дамаг инфликшн нельзя изменять (напрямую?), ибо ни чейнджфлаг, ни A_SetDamageType("Extreme") не альтерят пуфф при вхождении оного в Спаун стэйт.
Пробовал обойти это через выстрел пуффом другого +EXTREMEDEATH пуффа, но они ведут себя иначе нежели прожектили. _SpawnItemEx пуффа из пуффа не катит поскольку не считается за выстрел, ибо не прожектиль.
Точняк, как же я мог забыть о своей любимой ф-ции!
Герр Смертоносец:
Здесь работает "распределённая одновременность", согласованная работа комплекса независимых акторов, - но на уровне движка одни события обрабатываются позже других
Чё-т не похоже. :\ Зомбимэны с их 20 хп не выдерживают 20 попаданий, а порой даже 2. Может записывать в юзервар ко-во попаданий или это будет "шило на мыло"?
Есть ещё одна проблема. С флагом PUFFONACTORS пуффы не прошивают (т. е. если даже актор сдох от 2 пуль, излишки не летят дальше), а без него не сработает хиттрэйсер. +THRUACTORS не фиксит эту шляпу; есть соображения?
Скрытый текст:
Actor GSSG : SuperShotgun
{
States
{
Fire:
SHT2 A 3
SHT2 A 0 A_FireBullets (11.2, 7.1, 20, 1, "GSSGPuff",FBF_NORANDOM|FBF_USEAMMO)
SHT2 A 7 A_GunFlash
SHT2 B 7
SHT2 C 7 A_CheckReload
SHT2 D 7 A_OpenShotgun2
SHT2 E 7
SHT2 F 7 A_LoadShotgun2
SHT2 G 6
SHT2 H 6 A_CloseShotgun2
SHT2 A 5 A_ReFire
Goto Ready
}
}
Actor GSSGPuff : BulletPuff
{
//+PUFFGETSOWNER
//+THRUACTORS
+PUFFONACTORS //С этим флагом пуффы не прошивают, а без него не сработает хиттрэйсер :/
+HITTRACER
States
{
Crash: //Если выстрел не в моба
PUFF A 4 Bright
PUFF BCD 4
Stop
//XDeath:
Melee:
Spawn:
TNT1 A 0 NoDelay A_GiveInventory("GIBSMark",1,AAPTR_TRACER)
//TNT1 AA 1
TNT1 A 0 A_JumpIf(CountInv("GIBSMark",AAPTR_TRACER)>=8,"VGOVNO") //Если моб хилый то работает только на 1-2 итема
TNT1 A 0 A_DamageTracer((random(1,3)*5)-1,"None")
Goto BlankDeath
VGOVNO:
TNT1 A 0 A_PlaySound("DoomHit", CHAN_WEAPON) //Индикатор джампа
TNT1 A 0 A_DamageTracer((random(1,3)*5)-1,"Extreme")
//TNT1 AA 1
TNT1 A 0 A_TakeInventory("GIBSMark",1,AAPTR_TRACER)
BlankDeath:
PUFF A 4 Bright
PUFF BCD 4
Stop
}
}
Чё-т не похоже. :\ Зомбимэны с их 20 хп не выдерживают 20 попаданий, а порой даже 2. Может записывать в юзервар ко-во попаданий или это будет "шило на мыло"?
Шило на мыло. Он, вероятно, дохнет до того, как всё начнётся.
Ружьё вообще не должно их дамажить "естественным" образом. Т.е. A_FireBullets (11.2, 7.1, 20, 0, "GSSGPuff",FBF_NORANDOM|FBF_USEAMMO) Тогда к тому моменту, когда зомбимена "облепят" пуффы, он будет ещё целенький и готовый к манипуляциям.
Void Weaver:
Есть ещё одна проблема. С флагом PUFFONACTORS пуффы не прошивают (т. е. если даже актор сдох от 2 пуль, излишки не летят дальше), а без него не сработает хиттрэйсер. +THRUACTORS не фиксит эту шляпу; есть соображения?
Очевидно, перестать кормить собаку через задницу и попытаться осознать порочность концепции вообше.
Во-первых, это не логично. Дробь так не работает. Дробины либо летят мимо цели, либо застревают в цели - это не дура 50 калибра. Классический думовский механизм эмулирует, что подстрелянный мгновенно свалился на пол, и остальные дробины пролетели мимо (а не насквозь), что с моей точки зрения чушь собачья. Разрывание дробинами вгавно подразумевает, что для разрывания вгавно вся кинетическая энергия была поглощена тушкой - и, соответственно, дальше ничего лететь уже не может.
Во-вторых, хитскан это в принципе хуёвый костыль, который был хорош для 93 года в силу своей упрощённости. А мы сейчас изобретаем костыль для костыля для костыля, пытаясь на древнем костыле эмулировать сложную баллистику, да ещё и с изначально противоестественными условиями. Это безблагодатно. Как минимум надо отказаться от хитсканов вообще и переходить на FastProjectile с описанным мной в своё время механизмом интеллектуального проникновения риппер/дриллер, и оттуда уже прикручивать свою интерпретацию кинетической энергии дробин и их способности проходить через объекты, совершая над ними комплексное действие. На пуффах тут будет полный онанизм. Можно, конечно, сделать 20 независимых CheckLOF-проверок по траекториям с запоминаемыми координатами, и потом в зависимости от сводящей воедино проверки по каждой координате выпускать хитскановую пулю нужного типа без PUFFONACTORS, но это всё с инженерной точки зрения блядство, разврат, наркотики.
Он, вероятно, дохнет до того, как всё начнётся.
Ружьё вообще не должно их дамажить "естественным" образом. Т.е. A_FireBullets (11.2, 7.1, 20, 0, "GSSGPuff",FBF_NORANDOM|FBF_USEAMMO) Тогда к тому моменту, когда зомбимена "облепят" пуффы, он будет ещё целенький и готовый к манипуляциям.
Логично. Вот только при нулевом уроне пули вообще НЕ спаунятся. Хз что с этим делать. Собс-но поэтому и пришлось поставить 1 дмг в _ФайрБуллетс и дебильную ф-лу (random(1,3)*5)-1 урона в _ДмгТрсер.
Герр Смертоносец:
Классический думовский механизм эмулирует, что подстрелянный мгновенно свалился на пол, и остальные дробины пролетели мимо (а не насквозь)
Зыс. Я именно это имел в виду, сорри за "доходчивое" объяснение.
Герр Смертоносец:
Очевидно, перестать кормить собаку через задницу и попытаться осознать порочность концепции вообше.
Герр Смертоносец:
Во-вторых, хитскан это в принципе хуёвый костыль, который был хорош для 93 года в силу своей упрощённости. А мы сейчас изобретаем костыль для костыля для костыля, пытаясь на древнем костыле эмулировать сложную баллистику, да ещё и с изначально противоестественными условиями. Это безблагодатно.
Блин, ну это реквест ДУМГАБРа, - все вопросы к нему. Просто эта задачка мне показалась интересной как с точки зрения концепта, так и в плане повода для изучения механизма пульпуффов.
Ну твой финт с ревайвом миссайлей был опробован сразу, но остаётся проблема прерывания "риппера" после попадания в актор без летального исхода оного. Так что можно об этом по-подробнее:
Герр Смертоносец:
и оттуда уже прикручивать свою интерпретацию кинетической энергии дробин и их способности проходить через объекты, совершая над ними комплексное действие.
Добавлено спустя 16 минут 45 секунд:
Герр Смертоносец А вот как благородный дон смотрит на такой вариант:
1. ССГ херачит 20 безвредных ТНТ фаст-маслин (+хиттрэйсер, A_GiveInventory("GIBSMark",1,AAPTR_TRACER)) с оффсетами аналогичными таковым ФайрБуллетсам ССГ
2. Следом этот же ССГ херачит уже Варпом другие +хиттрэйсер-маслины со спауном крови в дэсстэйте (если трэйсер не НУЛЛ), считающие GIBSMark с последующим джампом в ДмгТрср "Extreme"
Есть смысл или чушня полная?
Может дать ССГ другой тип дамага, и в стейте смерти от этого дамага проверять насколько сильно просело здоровье?
В зависимости от этого перенаправлять на разрыв в мясо.
Логично. Вот только при нулевом уроне пули вообще НЕ спаунятся.
*Здесь должна быть длинная матерная тирада в адрес всех, кто добавляет костыли в изначально-кастрированном виде.*
Короче, на этом предлагаю похоронить сложные конструкции на пуффах.
Void Weaver:
Ну твой финт с ревайвом миссайлей был опробован сразу, но остаётся проблема прерывания "риппера" после попадания в актор без летального исхода оного. Так что можно об этом по-подробнее:
От простого к сложному:
Вариант 1: на некоторое время включать +RIPPER. (Поскольку собственный дамаг у missle нулевой, она просто пролетит сквозь актора.) Потом выключить. Может некорректно работать в толпе монстров или нанести двойной удар очень толстому монстру, но не требует ACS.
Вариант 2: на некоторое время вешать на трасера +GHOST-флаг, снаряд же изначально оборудован +THRUGHOST-флагом. Тогда маслина пролетит сквозь конкретно этого актора. Вариант на случай отсутствия других GHOST-зависимых конструкций.
Вариант 3: на некоторое время задать трасеру и снаряду SetActorProperty общий случайно сгенерированный "APROP_Species" и флаг +THRUSPECIES. Тогда маслина пролетит сквозь конкретно этого актора. На случай, если параметр Species у монстра уже был задан - перед изменением сохранять его в строковую переменную и позже вернуть на место.
Вариант 4: маслина запоминает свою скорость по трём осям. Зная длину-ширину-высоту трасера, она рассчитывает такую точку позади него, в которую должна была бы попасть, пройдя насквозь. Перед возрождением она варпится в эту точку.
Вариант 5: маслина переключается в медленный режим: понижает свою скорость в несколько раз, активирует флаг +RIPPER (опционально +PAINLESS). В таком виде она свободно путешествует сквозь свою жертву-трасера, постоянно делая проверку A_CheckBlock с CBF_SETMASTER и постпроверку A_JumpIf(IsPointerEqual(AAPTR_TRACER, AAPTR_MASTER) == TRUE,"state"). Джамперы выставлены таким обазом, чтобы выход осуществлялся в двух случаях: либо маслина просто вылетела на открытое место, либо она сразу же влетела в кого-то другого, не являющегося её текущим трасером. При выходе она переключается в быстрый режим: ускоряется и отключает флаг +RIPPER, тем самым становясь способной воспринять новый трасер. Способ с моей точки зрения наиболее прогрессивный и предположительно осуществимый декорейт-онли.
Void Weaver:
1. ССГ херачит 20 безвредных ТНТ фаст-маслин (+хиттрэйсер, A_GiveInventory("GIBSMark",1,AAPTR_TRACER)) с оффсетами аналогичными таковым ФайрБуллетсам ССГ
2. Следом этот же ССГ херачит уже Варпом другие +хиттрэйсер-маслины со спауном крови в дэсстэйте (если трэйсер не НУЛЛ), считающие GIBSMark с последующим джампом в ДмгТрср "Extreme"
А смысл? Все те же действия можно реализовать одним комплектом маслин. Прилетели, остановились, измерили, нахаркали кровью, при необходимости полетели дальше.
Здесь работает "распределённая одновременность", согласованная работа комплекса независимых акторов, - но на уровне движка одни события обрабатываются позже других
действительно как-то работает, но до тех пор пока не будет разобран механизм (и найдены ключи управления к оному) похоже что любые попытки эмуляции выстрела ССГ будут обречены. Т. е. похер чем фигачить кастом пуффами или снарядами - и то и другое будет либо застревать в акторе, либо прошивать.
Допустим мы стреляем в зомбимена в упор из ССГ 20-ю %чем-либо% со стандартным уроном random(1,3)*5, при этом ВСЕ 20 инфликторов попадут в тушку и остановятся. Очевидно что для упокоения зомбы требуется всего от 4 до 2 инфликторов из 20, т. е. остальные 16-18 будут благополучно просраны. Если же мы запиливаем (на декоре) временный пирс каким угодно методом, то пирсить будут все попавшие инфликторы что также по определению не соответствует ванильному поведению ССГ. :\
Возможно я чего-то не догоняю, но без отделения мух от котлет такой дробовик будет весьма полярно далёк от оригинала - либо пирсящая имба, либо убогая хрень с проёбанным крауд контролем.
Как альтернативу "распределённой одновременности" я пока вижу только запуск всех 20 инфликторов с 1 тиковым промежутком между вызовами оных, но в таком случае выстрел окажется ощутимо растянут во времени (18 тиков!), что тоже будет значительно отличаться от стандартного принципа действия ССГ. Да ещё и анимация накроется.
Допустим мы стреляем в зомбимена в упор из ССГ 20-ю %чем-либо% со стандартным уроном random(1,3)*5, при этом ВСЕ 20 инфликторов попадут в тушку и остановятся. Очевидно что для упокоения зомбы требуется всего от 4 до 2 инфликторов из 20, т. е. остальные 16-18 будут благополучно просраны. Если же мы запиливаем (на декоре) временный пирс каким угодно методом, то пирсить будут все попавшие инфликторы что также по определению не соответствует ванильному поведению ССГ. :\
Возможно я чего-то не догоняю, но без отделения мух от котлет такой дробовик будет весьма полярно далёк от оригинала - либо пирсящая имба, либо убогая хрень с проёбанным крауд контролем.
Тому що в оригинале количество пирсящих дробин зависит от здоровья монстра. После здорового и после полудохлого монстра летит разное количество дробин. Хитсканы это механизм с жёстко предписанным сценарием, поэтому для сложных вещей они крайне неудобны.
В нашем случае есть смешной способ реализовать это. Прилетают, значит, в тушку 20 инфликторов (суммарный среднеожидаемый дамаг = 200), а у тушки, предположим, 50хп. Это значит, что вероятность пройти сквозь тушку для каждой дробины составляет 75%. Это значит, что проверка наподобие A_JumpIf( random(1,(200/tracerhealth))>1 ,"state") даст команду на пронзание с вероятностью 75%.
В этом случае примерно 5 из 20 дробин застрянут в тушке, остальные полетят дальше (как это было в оригинальном Doom), при этом мы сохраняем сложносогласованную работу дробин "разрывать вгавно при одновременном прилёте как минимум X дробин" при произвольно заданном X. (Если выставить X<20, то при некоторой удаче можно будет разорвать вгавно несколько хлипких мобов.)
Отмечу, что для этого инфликтору придётся узнавать здоровье цели (либо через ACS, либо тем моим циклом-матрёшкой).
DOOMGABR 1. На фига уменьшать его экшеном, когда скейлинг тупо прописывается в параметрах?
2. Экшен совершается после того, как кадр отыграет. Кадр с длительностью -1 не отыграет никогда.
3. Для экшенов, срабатывающих сразу при спавне, нужна пометка NoDelay.
В общем так:
1. Джамп всё также не совершается при количестве пуль>=(1-2)
2. При таком же количестве пуль>=(1-2) внезапно ИНОГДА возвращает деление_на_ноль-краш:
при том что замер хп производится ДО нанесения урона...
3. Миссайли то ли не ревайвятся, то ли ревайвятся с какой-то задержкой, хотя тот же алгоритм у того анхоли болта работает на-ура.
4. Не получается съэмулировать разлёт дроби. Ну то такое.
Actor GIBSMarker : FastProjectile
{
Height 2
Radius 3
Speed 500
Mass 5
Damage 0
+ALLOWPARTICLES
//+NODAMAGETHRUST
+HITTRACER
var int user_VelX;
var int user_VelY;
var int user_VelZ;
var int user_TracerHealth;
var int user_Stepsize;
States
{
Spawn:
TNT1 A 0 NoDelay A_SetUserVar("user_VelX",VelX)
TNT1 A 0 A_SetUserVar("user_VelY",VelY)
TNT1 A 0 A_SetUserVar("user_VelZ",VelZ)
Goto MissileLife
ReviveMissile:
TNT1 A 0 A_RearrangePointers(AAPTR_DEFAULT,AAPTR_DEFAULT,AAPTR_NULL)
TNT1 A 0 A_ChangeVelocity(user_VelX,user_VelY,user_VelZ,CVF_REPLACE)
TNT1 A 0 A_ChangeFlag("MISSILE",1)
MissileLife:
POSS A 1 //A_ChangeFlag("MISSILE",1)//POSS - тестовая индикация
Loop
Death:
TNT1 A 0 A_JumpIf(IsPointerEqual(AAPTR_TRACER,AAPTR_NULL)==1,"BlankDeath") //Если не попало в моба
TNT1 A 0 A_GiveInventory("GIBSMark",1,AAPTR_TRACER) //Маркируем трэйсера количеством попавших "пуль"
GetTracerHealth: //TRACER's current hp checker-counter BEFORE damage infliction
TNT1 A 0 A_SetUserVar("user_TracerHealth",1000000)
TNT1 A 0 A_SetUserVar("user_Stepsize",100000)
TNT1 A 0 A_JumpIfHealthLower(user_TracerHealth,1,AAPTR_TRACER)
Goto GetTracerHealth+4
TNT1 A 0 A_SetUserVar("user_TracerHealth",user_TracerHealth-user_Stepsize)
Goto GetTracerHealth+2
TNT1 A 0 A_JumpIf(user_Stepsize==1,3)
TNT1 A 0 A_SetUserVar("user_TracerHealth",user_TracerHealth+user_Stepsize)
TNT1 A 0 A_SetUserVar("user_Stepsize",user_Stepsize/10)
TNT1 A 0 A_SetUserVar("user_TracerHealth",user_TracerHealth)
TNT1 A 0 A_JumpIf(CountInv("GIBSMark",AAPTR_TRACER)>=8,"VGOVNO") //ДЖАМП НЕ ПРОХОДИТ
TNT1 A 0 A_DamageTracer(random(1,3)*5,"None")
Goto BloodDeath
VGOVNO:
TNT1 A 0 A_PlaySound("DoomHit", CHAN_WEAPON) //For notice
TNT1 A 0 A_DamageTracer(random(1,3)*5,"Extreme")
BloodDeath:
TNT1 A 0 A_Jump(256,1,2,3)
BLUD CBA 8
TNT1 A 0 A_JumpIf(random(1,200/user_TracerHealth)>1,"ReviveMissile") //ДЕЛЕНИЕ НА НОЛЬ?! ВТФ, КАКОГО?!!! Stop
BlankDeath:
TNT1 A 0 A_SetRenderStyle(0.5,STYLE_Translucent)
PUFF A 4 Bright
PUFF BCD 4
Stop
}
}
Скрытый текст:
Actor GSSG : SuperShotgun //Эмуляция разлёта явно меньше таковой у пуль
{
States
{
Fire:
SHT2 A 3
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,1,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
SHT2 A 0 A_FireCustomMissile("GIBSMarker",0,0,frandom(-11.2,11.2),frandom(-7.1,7.1),FPF_NOAUTOAIM)
//SHT2 A 0 A_PlaySound ("weapons/sshotf", CHAN_WEAPON)
SHT2 A 7 A_GunFlash
SHT2 B 7
SHT2 C 7 A_CheckReload
SHT2 D 7 A_OpenShotgun2
SHT2 E 7
SHT2 F 7 A_LoadShotgun2
SHT2 G 6
SHT2 H 6 A_CloseShotgun2
SHT2 A 5 A_ReFire
Goto Ready
}
}
1. Джамп всё также не совершается при количестве пуль>=(1-2)
2. При таком же количестве пуль>=(1-2) внезапно ИНОГДА возвращает деление_на_ноль-краш:
при том что замер хп производится ДО нанесения урона...
Прозреваю хитрые особенности FastProjectile, использующих что-то вроде дробных тиков: даже при наблюдаемо-одновременном прилёте эти события на самом деле не одновременные (как в релятивистской физике, лол), и возможна ситуация, при которой часть маслин уже нанесли урон, а другие ещё только начали измерять. Если первые N маслин убили монстра - у неуспевших измеренное значение здоровья становится равным нулю, и они испытывают деление на нуль.
Лечение: во-первых, между измерениями и A_DamageTracer должна быть задержка как минимум 1 тик, чтобы все успели измерить и выдать GIBSMark. (И вообще с инженерной точки зрения никогда не начинай вводить в строй такие хитрожопые конструкции без задержек - поначалу их надлежит пихать во все сомнительные места, и лишь потом потихоньку убирать.) Во-вторых, перед джампом с делением фигани аварийую проверку A_JumpIf(user_TracerHealth==0,"ReviveMissile"), ибо мало ли, вдруг однажды монстр от чего-то ещё в критический момент сдохнет.
Void Weaver:
3. Миссайли то ли не ревайвятся, то ли ревайвятся с какой-то задержкой, хотя тот же алгоритм у того анхоли болта работает на-ура.
В свете вышеперечисленного для начала давай убедимся, что снаряды в принципе попадают на ReviveMissile-стейт. (Поставь туда спаун какого-нибудь облачка, чтобы визуально убедиться, что переход происходит.) Скорее всего если пофиксить проблему с задержкой - всё заработает.
Если не заработает - на всякий случай напоминаю про вот этот момент со 173 страницы треда:
Void Weaver:
3. Возникновение статичных "декоративных" снарядов:
Ломал голову дольше всего (вероятно не допёр бы без твоего кода). Причиной являлся какой-то странный лимит стартовой скорости снаряда - при базовых значениях скорости выше 8, снаряд необратимо "умирал" на первом тике, если сталкивался с ЛЮБЫМ актором. Пофиксил понижением базового значения скорости и добавлением A_ScaleVelocity. До сих пор не понимаю с чем связана нестабильность на первом тике... 0_0
Алсо, я вижу, что у тебя отсутствует манипуляция +RIPPER-флагом и замедленное движение ракеты сквозь актора. Рекомендую для начала просто вешать на снаряд +RIPPER сразу же после попадания в ReviveMissile, и если всё будет работать правильно - потом поверх достроишь CheckBlock-систему.
Конечно отыграет и останется на постоянке, просто у человека в коде ошибка (нужно было добавить NoDelay):
States
{
Spawn:
CSAW A -1 NoDelay A_SetScale(0.75, 0.75)
Stop
}
Сама же ошибка заключается в баге порта - на первый стейт спавна вешать экшен можно только как я описал выше или по типу такого:
Spawn:
CSAW A 0
CSAW A 1 A_SetScale(0.75, 0.75)
Loop