Так это же сдвинуть на определённый диапазон относительно того, где остановился каждый потолок, а мне нужно сдвинуть все потолки на глобальную координату карты.
А почему тогда на вики написано: "Moves the ceiling of affected sectors to an absolute height."? Может если этот экшн скомбинить с TagWait то получится выравнивать крашеры?
Кстати на гоззе недавно детально разбирали области применения последнего.
-------------
Zeberpal_98
1. Чек на "ISMONSTER" НЕ имеет смысла размещать ВНУТРИ 'XDeath' стэйта, за исключением тех случаев когда ты желаешь чтобы при попадании пуффа происходили различные действия для монстров, игроков и неопределённых кровоточащих акторов.
Размещение этого чека в иных стэйтах нужно чтобы войти в 'XDeath' стэйт даже если у монстра в которого попал пуф нет крови, т. е. выставлен +NOBLOOD.
2. Похоже что ты просто скопировал чек но не учёл что пуля не знает кто является AAPTR_TRACER по отношению к ней. Для этого нужно выставить +HITTRACER в пулю (пуфф).
А вот как это будет выглядеть в итоге:
Actor MyPuff : BulletPuff //replaces BulletPuff //Опционально, если надо заменить оригинальные пуффы
{
+HITTRACER //Флаг-маркер: того кого ударит пуфф станет ТРЭЙСЕРом последнего
+PUFFONACTORS //Флаг-активатор: позволит спаунить пуфф (в том числе невидимый TNT1) на живых акторах, если прописан XDeath
States
{
Spawn:
TNT1 A 0 NoDelay A_CheckFlag("ISMONSTER","XDeath",AAPTR_TRACER) //Даже если пуля попала в "бескровного" монстра то всё равно прыгнет в XDeath,
Goto Super::Spawn //иначе проигрываем обычную анимацию ванильного буллетпуффа.
XDeath:
TNT1 A 0 A_ChangeFlag("ALLOWPARTICLES",0) //Чтобы вместе с кровью не спавнились серые партикли.
//TNT1 A 0 A_JumpIf(CheckClass("PlayerPawn",AAPTR_TRACER,1),2) //Открой строку если не желаешь чтобы работало на игроках.
TNT1 A 0 A_JumpIfInventory("предмет С",1,"GiveSuccessMark",AAPTR_TRACER) //Если у ТРЭЙСЕРа (того, в кого попала пуля) есть "предмет С" то прыг на "GiveSuccessMark"...
//TNT1 A 0 //Открой строку если не желаешь чтобы работало на игроках.
Stop
GiveSuccessMark:
TNT1 A 0 A_GiveInventory("предмет B",1,AAPTR_TRACER) //... в котором дай "предмет B" ТРЭЙСЕРу (тому, в кого попала пуля).
Stop
}
}
Всегда пожалуйста. ^_^
Про избирательное отключение пафф-партиклей я сам допёр буквально неделю назад. А вообще логика пуффов ощутимо отличается от таковой снарядов.
Скрытый текст:
Д Е К О Р Е Й Т - это таки ЗСкрипт для "бедных", такша если соображалка позволяет то лучше сразу штудировать ЗСкрипт. Хотя бы потому, что на базе зскриптовых акторов можно пилить декорные, а вот наоборот - низзя.
Хотя конечно при прямых руках даже на "чистом" декоре можно запилить немало чудес.
Пробовал по всякому потолками управлять после запуска их как прессов, не двигаются, даже если Ceiling_CrushStop был запущен.
попробуй добавить в каждом потолке мелкие сектора (квадратик 1х1 без текстур чтобы их не было видно как отверстие) и их оставить на нужной высоте т.е. они не двигаются во время работы прессов, а затем в скрипте отключения прессов через delay прописать "Ceiling RaiseToHighest" это должно сработать, поднять и выровнять все потолки согласно спрятанным, неподвижным секторам.
Нашёл в чём проблема. Если потолок хотя бы раз запускается как пресс, то после этого неважно остановил его или нет, этим потолком больше нельзя управлять с помощью дверных и потолочных спешелов, на нём будут работать только прессовые спешелы. Возможно в самой гозе недоработка или я чего-то не понял.
Пробовал по всякому потолками управлять после запуска их как прессов, не двигаются, даже если Ceiling_CrushStop был запущен.
Это не недоработка гоззы, гозза просто в данном случае воспроизводит еще ванильную логику. Вот цитата entryway'я, когда в похожей ситуации смастерил тест-уровень с тремя триггерами (уровень за давностью времен не сохранился, но вроде там были давилка, давилка-стоп и что-то еще):
После синего акшена зеленый не работает, даже если воспользоваться красным.
entryway:
да, не работает. очевидно, что так и должно быть (раз есть). где это описано сейчас искать лень, но по коду видно, что при остановке пола ему выставляется флаг in_stasis (заморожено) и в последствии при попытке движения пола проверяется это состояние. вывести из заморозки плат можно пройдясь по первому лайндефу (запустив систему опять). но в состоянии движения туда сюда третья линия опять же работать не будет. вот такой вот бесконечный цикло-стейт получается...
попробуй добавить в каждом потолке мелкие сектора (квадратик 1х1 без текстур чтобы их не было видно как отверстие) и их оставить на нужной высоте т.е. они не двигаются во время работы прессов, а затем в скрипте отключения прессов через delay прописать "Ceiling RaiseToHighest" это должно сработать, поднять и выровнять все потолки согласно спрятанным, неподвижным секторам.
Пробовал и так, не пашет. Если бы был спешл типо Crusher_clear который обнуляет потолки на которых был запущен спешл пресса, то тогда сработало бы, и то не уверен, я не программист.
Actor MyPuff
{
+HITTRACER
+PUFFONACTORS
States
{
Spawn:
PUFF A 4 Bright
PUFF B 4
XDeath:
TNT1 A 0 A_JumpIfInventory("ThingyC",1,"GiveSuccessMark",AAPTR_TRACER)
Goto Failure
Failure:
TNT1 A 0 ACS_NamedExecuteAlways("S_FAILSHOT", 0)
Stop
GiveSuccessMark: //в данной ситуации не важно
TNT1 A 0 A_GiveInventory("ThingyB",1,AAPTR_TRACER)
Stop
}
}
script "S_FAILSHOT" (void)
{
PrintBold(s:"It's a fail");
}
Задумка: пуфф при попадании в геометрию, а не в актора переходит в стейт Failure и проигрывает скрипт.
Но этого не происходит. При попадании пуффа в акторы стейт Failure как раз срабатывает, если пролетает мимо - нет. В дискорде объяснили, что мол переход в XDeath происходит только при попадании в актор.
В нормальной ситуации я бы переместил Активацию скрипта "S_FAILSHOT" в стейт Spawn. Но мне необходимо, чтобы пуфф сначала чекал попадание в актор, и только после этого, если он в него не попадает, минуя A_JumpIfInventory, срабатывала бы активация скрипта "S_FAILSHOT". Есть ли какой-нибудь хак на этот случай?
Задумка: пуфф при попадании в геометрию, а не в актора переходит в стейт Failure и проигрывает скрипт.
Но этого не происходит. При попадании пуффа в акторы стейт Failure как раз срабатывает, если пролетает мимо - нет. В дискорде объяснили, что мол переход в XDeath происходит только при попадании в актор.
Не-а, не просто в актор, а именно в актор который может кровоточить! Именно поэтому в Спауне стоит чек A_CheckFlag("ISMONSTER","XDeath",AAPTR_TRACER).
Тут даже не нужен внешний скрипт:
Actor MyPuff : BulletPuff
{
+HITTRACER
+PUFFONACTORS
States
{
Spawn:
TNT1 A 0 NoDelay A_CheckFlag("ISMONSTER","XDeath",AAPTR_TRACER)
TNT1 A 0 A_JumpIf(IsPointerEqual(AAPTR_TRACER,AAPTR_NULL),1) //Если AAPTR_TRACER = AAPTR_NULL (т. е. ТРЭЙСЕР НЕ существует), то значит это НЕ шутэбл актор а значит с 95% вероятностью архитектурная плоскость, тогда...
Goto Super::Spawn
TNT1 A 0 A_PrintBold("It's a fail") //... прыг сюда и расскажи о промахе... //Хотя тут конечно можно ставить вызов любого необходимого скрипта
Goto Super::Spawn //... и проиграй обычную анимацию.
XDeath:
TNT1 A 0 A_ChangeFlag("ALLOWPARTICLES",0)
//TNT1 A 0 A_JumpIf(CheckClass("PlayerPawn",AAPTR_TRACER,1),2)
TNT1 A 0 A_JumpIfInventory("ThingyC",1,"GiveSuccessMark",AAPTR_TRACER)
//TNT1 A 0
Stop
GiveSuccessMark:
TNT1 A 0 A_GiveInventory("предмет B",1,AAPTR_TRACER)
Stop
}
}
Вот как простому смертному узнать, что существует IsPointerEqual?
Void Weaver Спасибо! Работает не очень стабильно, в 65% случаев, попробую завтра на свежую голову, чувствую проблема в A_GiveInventory монстрам, и тем что из этого следует.
Вот как простому смертному узнать, что существует IsPointerEqual?
В отличии от львиной доли ЗСкриптовых функций о декорных\ацсных можно легко узнать на вики: IsPointerEqual.
Правда меня самого о ней просветил Герр Смертоносец.
Ну видимо да, наверное причина в каких-то твоих доработках потому что базовая конструкция на ванильных монстрах работает как часы.
Не совсем ясно мне, почему при вызове альтфайра в игре это оружие не переходит в режим прицельного выстрела, не смотря на то, что альтфайр и ссылка на новый актор прописаны. Помогите найти ошибку в коде. https://yadi.sk/d/pLM2hv6um_tyuQ
Один фундаментальный вопрос: как именно должно работать это оружие?
Ибо если те нужна просто снайперка то это делается куда проще и изящнее, без всего того писца который представлен в твоём коде.
Ибо если те нужна просто снайперка то это делается куда проще и изящнее, без всего того писца который представлен в твоём коде.
Да, мне нужна просто снайперка. Но она там откидывает врагов при попадании, прошивает их насквозь(как я понял из соотв опр отрывков кода по здум вики(это моё первое оружие)). Она должна переходить в сн режим с разным увеличением. В идеале там должна быть перезарядка магазинная и рукой-затвором, но это потом.
Подскажи, как изящнее?
Сорян за сумбурное повествование - у меня 2 часа ночи, пвтаюсь доделать код😂😂😂
Я наверное туплю но таки не понял - те нужна просто снайперка с несколькими степенями зума (сколькими именно?) или всё же прошивающая снайперка?
Просто куда целесообразнее написать всё с нуля чем править твой код.
Итак.
Прошивающая снайперка с 2х и 8х зумом,
тихой стрельбой (не ближе 512) в режиме зума,
снижением скорости перемещения в режиме зума,
повышающимся уроном в режимах зума,
повышающейся кинетикой в режимах зума,
магазином на 8 выстрелов,
и возможностью ДОзарядки (клавишей релоад):
Скрытый текст:
Actor DragunovSniperRifle : Weapon
{
+WEAPON.NOALERT
+WEAPON.NOAUTOAIM
Weapon.SlotNumber 4
Weapon.SlotPriority 1
Weapon.AmmoType "RifleAmmo"
Weapon.AmmoGive 10
Weapon.AmmoUse 1
Inventory.PickupMessage "You got the SVD"
Inventory.PickupSound "misc/w_pkup"
Weapon.SelectionOrder 50
Weapon.Kickback 150
Decal BulletChip
States
{
Spawn:
RIFL A -1
Select:
RIFG A 1 A_Raise
Loop
Deselect:
TNT1 A 0 A_TakeInventory("ZoomToken")
TNT1 A 0 A_ZoomFactor(1.0)
TNT1 A 0 A_SetSpeed(1)
DeselectL:
RIFG A 1 A_Lower
Loop
Ready:
TNT1 A 0 A_JumpIfInventory("ZoomToken",1,"ReadyScope") //Если есть хотя бы 1 зум-токен, значит это зум Рэди
RIFG A 1 A_WeaponReady(WRF_ALLOWRELOAD)
Loop
ReadyScope:
LDHR T 1 A_WeaponReady(WRF_ALLOWRELOAD|WRF_NOBOB)
Loop
Fire:
TNT1 A 0 A_JumpIfInventory("ZoomToken",1,"FireScope") //Если есть хотя бы 1 зум-токен, значит это зум атака
TNT1 A 0 A_PlayWeaponSound("Weapons/RifleFire")
TNT1 A 0 A_AlertMonsters(8192,AMF_TARGETEMITTER) //Обычная атака слышна хорошо
RIFG A 0 A_GunFlash
RIFG A 4 A_FireBullets(1.5,1.5,1,10,"BulletPuff",FBF_NORANDOMPUFFZ/*|FBF_USEAMMO|FBF_NORANDOM*/,16384)
RIFG BCDCB 2
RIFG A 3
TNT1 A 0 A_GiveInventory("CurrentMagRemainsToken") //Используем для того что бы знать сколько патронов нужно ДОЗАРЯДИТЬ
TNT1 A 0 A_CheckForReload(8,"Ready") //8 - при магазине на 8 патронов
//==================БЛОК ПЕРЕЗАРЯДКИ==================//
//* //Закрой этот блок для отключения магазинной перезарядки.
//НЕ ЗАБУДЬ ВКЛЮЧИТЬ ПОТРЕБЛЕНИЕ ПАТРОНОВ ОТ ОБЫЧНЫХ АТАК!!!
Reload: //Дефолтный стэйт перезарядки, в данном случае используем для перезарядки и ДОЗАРЯДКИ оружия!
TNT1 A 0 A_WeaponReady(WRF_NOFIRE|WRF_DISABLESWITCH|WRF_NOSWITCH|WRF_NOBOB) //Запрещаем смену оружия во время перезарядки чтобы смена оружия не сломала алгоритм перезарядки!
TNT1 A 0 A_JumpIf(CountInv("CurrentMagRemainsToken")==0,"Ready") //Если магазин полон, то возвращаемся к Рэди-стэйтам
TNT1 A 0 A_ZoomFactor(1.0) //Нормализуем зум на время перезарядки
TNT1 A 0 A_SetSpeed(1) //Нормализуем скорость на время перезарядки
//Помести сюда соответствующую анимационную последовательность и звуки
ReloadSequence:
TNT1 A 0 A_PlayWeaponSound("weapons/sshoto")
RIFG ABCD 7
TNT1 A 0 A_PlayWeaponSound("weapons/sshotl")
RIFG DC 7
TNT1 A 0 A_PlayWeaponSound("weapons/sshotc")
RIFG BA 7
//^Помести сюда соответствующую анимационную последовательность и звуки
TNT1 A 0 A_TakeInventory("RifleAmmo",CountInv("CurrentMagRemainsToken")) //Забираем столько патронов сколько у нас "накопилось" токенов отстрелянных патронов
TNT1 A 0 A_TakeInventory("CurrentMagRemainsToken") //Обнуляем токены растраты патронов, теперь магазин полон
TNT1 A 0 A_ResetReloadCounter
TNT1 A 0 A_JumpIfInventory("ZoomToken",2,2) //Если есть 2 зум-токена то...
TNT1 A 0 A_Jump(256,"Check2ndZoomTokenForSlowDown")
TNT1 A 0 A_ZoomFactor(8.0) //... то увеличиваем зум до 8...
TNT1 A 0 A_SetSpeed(Speed/16) //Замедляем ходьбу в 16 раз //Заблочь строку если не хочешь замедления игрока в режиме зума
Goto ReadyScope //... и возвращаемся к ReadyScope, иначе...
Check2ndZoomTokenForSlowDown:
TNT1 A 0 A_JumpIfInventory("ZoomToken",1,1) //... иначе проверяем есть ли хотя бы 1 зум-токен. Если есть то...
Goto Ready
TNT1 A 0 A_ZoomFactor(2.0) //... то увеличиваем зум до 2...
TNT1 A 0 A_SetSpeed(Speed/4) //Замедляем ходьбу в 4 раза //Заблочь строку если не хочешь замедления игрока в режиме зума
Goto ReadyScope //... и возвращаемся к ReadyScope
//*/ //^Закрой этот блок для отключения магазинной перезарядки.
//==================^БЛОК ПЕРЕЗАРЯДКИ^==================//
Goto Ready
FireScope:
TNT1 A 0 A_PlayWeaponSound("Weapons/RifleFire")
TNT1 A 0 A_AlertMonsters(512,AMF_TARGETEMITTER) //Атака из зума "тише"
//TNT1 A 0 A_TakeInventory("RifleAmmo",1) //Изымаем аммо для альт-атаки. НЕ НУЖНО ПРИ МАГАЗИННОЙ ПЕРЕЗАРЯДКЕ!
//Стреляем невидимой рельсой для того чтобы прошивало цели,
//таже выставлен множитель урона от зума "CountInv("ZoomToken")*2+1" - чем больше зум тем мощнее выстрел
TNT1 A 0 A_RailAttack((CountInv("ZoomToken")*2+1)*random(1,3)*10,0,0,"None","None",RGF_SILENT/*|RGF_NORANDOMPUFFZ*/,0,"SniperRailPuff",frandom(-0.5,0.5),frandom(-0.5,0.5),32768,1,100,0.0)
LDHR T 17
TNT1 A 0 A_GiveInventory("CurrentMagRemainsToken") //Используем для того что бы знать сколько патронов нужно ДОЗАРЯДИТЬ
TNT1 A 0 A_CheckForReload(8,"ReadyScope")
Goto Reload //Закрой этот джамп для отключения магазинной перезарядки...
//Goto ReadyScope //... и открой этот.
AltFire:
AltHold:
TNT1 A 0 A_PlayWeaponSound("HuntingRifle/Scope")
TNT1 A 0 A_JumpIfInventory("ZoomToken",2,"ZoomOut") //Если УЖЕ есть 2 зум-токена, то выходим из зума
TNT1 A 0 A_JumpIfInventory("ZoomToken",1,"ZoomX8") //Если УЖЕ есть 1 зум-токен, то увеличиваем зум ЕЩЁ
//Если СЕЙЧАС нет ни 1 зум-токена, то...
ZoomX2:
TNT1 A 0 A_GiveInventory("ZoomToken",1) //Добавляем первый зум-токен...
TNT1 A 0 A_ZoomFactor(2.0) //... и включаем зум
TNT1 A 0 A_SetSpeed(Speed/4) //Замедляем ходьбу в 4 раза //Заблочь строку если не хочешь замедления игрока в режиме зума
Goto AltEnd
ZoomX8:
TNT1 A 0 A_GiveInventory("ZoomToken",1) //Добавляем второй зум-токен...
TNT1 A 0 A_ZoomFactor(8.0) //... и увеличиваем зум
TNT1 A 0 A_SetSpeed(Speed/4) //Замедляем ходьбу ЕЩЁ в 4 раза //Заблочь строку если не хочешь замедления игрока в режиме зума
Goto AltEnd
ZoomOut:
TNT1 A 0 A_TakeInventory("ZoomToken") //Изымаем зум-токены...
TNT1 A 0 A_ZoomFactor(1.0) //... и нормализуем обзор
TNT1 A 0 A_SetSpeed(1) //Восстанавливаем нормальную скорость //Заблочь строку если не хочешь замедления игрока в режиме зума
AltEnd:
LDHR T 10
Goto Ready
Flash:
RIFF A 2 Bright A_Light1
RIFF B 2 Bright A_Light2
TNT1 A 0 A_Light0
Stop
}
}
Actor SniperRailPuff : BulletPuff //Пуфф для рельс-аттаки
{
Radius 4
Height 4
+ALWAYSPUFF
+FORCEDECAL
+PUFFGETSOWNER
//+EXTREMEDEATH
//-THRUGHOST
States
{
XDeath:
TNT1 A 0 A_ChangeFlag("ALLOWPARTICLES",0) //Чтобы не спавнились серые партикли на монстрах
TNT1 A 0 A_RadiusThrust(CountInv("ZoomToken",AAPTR_TARGET)*10000,8,RTF_NOIMPACTDAMAGE) //Кинетика пули, увеличена в зуме. Да, не реалистично, так для фана.
Stop
}
}
Actor ZoomToken : Inventory //Зум-токен
{
Inventory.MaxAmount 2
}
Actor CurrentMagRemainsToken : Inventory //Счётчик остатка патронов в магазине //Но чтобы отображался магазин и текущее ко-во патронов в нём к сожалению нужно скриптить соотв. худ и отдельный актор магаза. :|
{
Inventory.MaxAmount 0x7FFFFFFF
}
Кстати ещё можно замхать в функции урона множители базирующиеся на дистанции до цели, но это уже сам впихнёшь если надо. Пример как раз в начале предыдущей страницы.
А ещё разрывные пули... чёт меня опять заносит.