Объясню проще )
У игрока с начала игры есть актор броня слабая бесконечная.
Есть 1 актор итем(назову армор), он лежит в инвентаре, при его использовании он дает 3 патрона и когда у игрока есть 3 патрона acs должен дать броню(актора которого заранее пропишу)посильнее. При повторном использовании итема армор что в инвентаре он забирает 3 патрона, acs должен отобрать броню посильнее и дать ту что была в начале игры тоесть слабую.
Как хотябы такое реализовать в acs?
Вот как я вижу такой скрипт в acs, он не рабочий т.к. незнаю как правильно эго записать:
Defence это актор патроны(ammo). MageHelmArm это актор брони с разной защитой.
Скрытый текст:
Script 28 Enter
{
If(CheckInventory("Defence")==3) //если 3 патрона, забирает всю броню и дает броню3
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("MageHelmArm3",1);
Terminate;
}
Else If(CheckInventory("Defence")==9) //если 9 патронов, забирает всю броню и дает броню9
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("MageHelmArm9",1);
Terminate;
}
Else If(CheckInventory("Defence")==6) //если 6 патронов забирает всю броню, и дает броню6
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("MageHelmArm6",1);
Terminate;
}
}
Вот как то так, только мне надо что бы он всегда работал, тоесть всегда проверял кол. патронов. Если патронов например 3, скрипт выполнит первое If и будет ждать пока кол. патронов не изменится.
Тут такой вопрос - какие на самом деле планируются перспективы у этой системы.
Если использование итема должно апгрейдить броню и уровней брони несколько, то это одно
А если просто одетьснять броню то это другое немного.
Для варианта "одетьснять" можно сделать два идентичных итема, но один при использовании одевает броню на игрока (и валяется на картах), а второй снимает. В случае спавна второго типа предмета нужно превращать его в первый тип итема( если он с игроков выпадать надумает ).
В скрипте всё довольно просто делается по идее:
Script "SetPlayerArmor" ( int type )
{
if ( type == 1 ) {
TakeInventory("СтараяБроня", 255); //Забрать вообще всю
GiveInventory("НоваяБроня");
} else {
TakeInventory("НоваяБроня", 255); //Забрать вообще всю
GiveInventory("СтараяБроня");
}
}
В декорейте скрипты можно вызывать как-то так
ACS_NamedExecuteAlways("SetPlayerArmor", 0, )
та цифра которая передаётся в скрипт в переменную .
возможно ли в принципе создание тхинга-транспорта (например, танк или бтр), который умещает в себя больше одного игрока и который, естественно, управляем одним из них?
ТЕОРЕТИЧЕСКИ возможно конечно. Как вариант предложу сделать за картой много комнат, где находятся нужное количество игроков во время поездки (можно сделать окна, а за окнами камератекстуры, транслирующие изображение с камер у танка). Собственно, управление через GetPlayerInput() и SetActorVelocity() (можешь глянуть этот мультиплеерный вад (summon vehiclepyria, summon vehiclephoenix) )
Добавлено спустя 1 минуту 13 секунд:
Можно и без спецкомнат, конечно. Просто переключить всех игроков на камеры на танке, например.
Тут такой вопрос - какие на самом деле планируются перспективы у этой системы.
Если использование итема должно апгрейдить броню и уровней брони несколько, то это одно
А если просто одетьснять броню то это другое немного.
Вот скрин:
Скрытый текст:
На скрине шлем, юбка и ботинки. Все три шмотки разные итемы, они снимаются и одеваются при этом из инвентаря не пропадают вообще, их можно только продать/подобрать/купить/получить в квестах. Таких комплектов брони 7 шт.(в 1 комплект входит 5 шмоток)Каждая шмотка дает по 3 патрона если одета и забирает если снята.
Как только игрок одел шлем, ему дается 3 патрона(Defence : ammo), одел юбку дается еще +3 патрона, снял забирается 3 патрона.
В acs нужна проверка патронов defence, и в зависимости от кол. патронов отбирало всю броню и давало разные виды брони, которые я заранее пропишу в декорейте.
Тоесть если ammo=3 забирает всю бронь, дает игроку броню3. Если аммо=6 забирает всю бронь, дает игроку броню6 и т.д.
Как я это представляю, acs проверяет только кол. defence : аммо. И в зависимости от количества defence : аммо отбирает броню полностью и дает броню новую. Только скрипт должен всегда работать, реагировать на изменения кол. патронов.
Просто в ACS можно не заморачиваться так сильно, а сделать проверку непосредственно какие шмотки одеты. Одеватьснимать можно через те самые переключаемые предметы (заодно можно возвращать снятый итем если пытаешься одеть другой).
Можно просто через CheckInventory проверять, что сейчас на игрока одето, и с помощью CheckInventory и GiveInventory давать нужное количество брони. Там проблемка только в том, что тип брони выставить нельзя. Можно попробовать забрать всю броню и дать нужную, тогда по идее тип должен смениться. А так в игре тип брони вроде бы в сторону ухудшения менять нельзя. Было бы ещё неплохо посмотреть хексен, там есть четыре шмотки.
В том то все и дело, мне надо именно так как я написал, хексен вариации шмоток совсем не то.
Ухудшать броню нельзя, но можно забирать все и давать нужную.
Делать проверки какие шмотки одеты много мороки.
Как работает нужная мне система смены брони:
Каждая шмотка дает игроку Defence : Ammo 3шт
Одел шлем +3 аммо, одел штаны +6 аммо, одел еще что-то +9 аммо
Также со снятием только забирает -3 аммо.
И ACS проверяет сколько аммо у игрока если аммо=3 забирает бронь, дает актора бронь3, если аммо 6 дает бронь6 и так далее, все очень просто. Я только не знаю как это записать в ACS скрипте что бы он постоянно выполнял:
If(ChekInventory(Defence)==3) //Если у игрока 3 патрона дает, броню 3типа
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("ARMOR3",1);
Terminate;
}
Else(CheckInventory(Defence)==6) //Если у игрока 6 патронов, дает броню 6типа
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("ARMOR6",1);
Terminate;
}
Таким образом если у игрока было 6 патронов, тоесть одето 2 шмотки дает броню 6типа
Если стало патронов 3, значит игрок снял1 шмотку и осталась одетая 1 шмотка и скрипт дает броню 3типа
Ну не знаю как объяснить проще
Вот какой вопрос: зачем иногда перед значениями функции скрипта пишут const:? ну например Sector_Setfade (const:10, 196, 196, 196);. Нафига этот конст нужен? Сроду им не пользовался, все шло нормально.
alekv
Через While будет проще
Например:
While (Checkinventory(Defence)==9);
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("ARMOR9",1);
Terminate;
}
Delay (1);
While (CheckInventory(Defence)==6)
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("ARMOR6",1);
Terminate;
}
Delay (1);
While (CheckInventory(Defence)==3)
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("ARMOR3",1);
Terminate;
}
MasterMind
Как бы подходит, но игрок начинает игру с броней, хотя я этого нигде не прописывал.
Значит цикл дает итемы не смотря на условия ? О_О
Добавлено спустя 26 минут 51 секунду:
Проверил цыкл и понял.
Выполняется только 1 (while==9), причем в начале игры у игрока defence==0, но цикл все равно дает броню и останавливается.
На остальные (While==6 и ==3) не реагирует вобще. Что может быть не так?(Если что в конце скрипта до последней "}" добавлял Restart; что бы скрипт проверял кол. Defence постоянно.)
Добавлено спустя 15 минут 22 секунды:
Все, заработало СПАСИБИЩЕЕ, 2 или 3 дня мучался, не знал как это сделать!
Заработало сделав так:
Скрытый текст:
Script 28 Enter
{
While (Checkinventory("Defence")==9)
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("ARMOR9",1);
GiveInventory("GoldenMoney",1);
Break;
}
Delay (1);
Restart;
}
Script 29 Enter
{
While (CheckInventory("Defence")==6)
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("ARMOR6",1);
GiveInventory("Jump",1);
Break;
}
Delay (1);
Restart;
}
Script 30 Enter
{
While (CheckInventory("Defence")==3)
{
TakeInventory("BasicArmor",0x7fffffff);
GiveInventory("PoisonPotion",1);
GiveInventory("ARMOR3",1);
Break;
}
Delay (1);
Restart;
}
Script 31 Enter
{
While (CheckInventory("Defence")==0)
{
TakeInventory("BasicArmor",0x7fffffff);
Break;
}
Delay (1);
Restart;
}
Только вот боюсь, не будет ли большое кол. цыклов(минимум 30шт.) мешать работе GZDoom?
Вообще так делать нежелательно. Лучше собрать всё маленько иначе:
Script ??? Enter
{
int count;
count = Checkinventory("Defence");
switch ( count ) {
case 0:
/// Если итемов ноль
break;
case 3:
/// Если три итема
break;
case 6:
/// Если 6 итемов
break;
}
while (Checkinventory("Defence") == count) Delay(1);
Restart;
}
Для удобной уборки старой брони можно задублировать весь свитч после while и до Restart, но в его слотах уже не добавлять броню соответствующих типов а забирать её. Тогда оно будет работать примерно так - скрипт узнает и запоминает количество предметов, после чего в свитче даёт нужную броню и в while ждёт, когда количество предметов изменится. Когда оно меняется скрипт забирает выданное обратно и перезапускается. Тут проблема только в том, что тогда нужно чтобы числа патронов шли плотно - 1, 2, 3 и так далее. Если число предметов будет отсутствовать в первом свитче то броня будет забрана, а новая выдана не будет.
c4tnt
Буду пробовать сделать так спасибо, надеюсь смогу разобратся)
Через While работает конечно, но посчитав будет мин. 36 циклов 1 из постоянно будет выполнятся, при этом он за 1тик дает броню и забирает, так пока не не переключится на другой.
Добавлено спустя 1 час 4 минуты:
Попробовал, заработало, удобнее чем через просто While, очень доволен
Вот моя проблема с вводом глобальных переменных(и внутренних или как там их), незнаю как.
Я даже сейчас не понял почему в конце написано именно так =(
While (Checkinventory("Defence") == count) Delay(1);
Restart;
Ну работает и хорошо большое спасибо, надеюсь со временем начну понимать.
c4tnt :
Для удобной уборки старой брони можно задублировать весь свитч
Не понял зачем это надо, но работает отлично и без этого)
Если бы стейт Drop: еще работал в декорейте как надо, то шмотки можно было бы выкидывать вместе с броней.
Кто знает это будут исправлять, или я 1 кто заметил его не правильную работу?
MasterMind
Спасибо. Но есть еще один вопрос. Вот у меня есть статус бар из 0.5:
Синяя шкала - это броня. Но если брони 200 единиц, то шкала начинает уменьшатся только тогда, когда становится 100 и меньше. Как сделать так, что бы по всей шкале показывалось 200 единиц, а не 100?
Как сделать так, что бы по всей шкале показывалось 200 единиц, а не 100?
Ох, в сбаринфо я не очень рублю, извини. Тоже пробовал сделать подобную штуку, но там была такая же фигня. Когда берешь синий броник шкала меняет цвет, но не уменьшается пока не достигнет 100%.
Добавлено спустя 2 минуты 23 секунды:
Поглядел на Вики, нашел такую штукенцию: DrawBar. Проверил, помогло.
Я даже сейчас не понял почему в конце написано именно так
Если про == и = то это взято из языка си и разница там такая. Если стоит одиночное = то слева от него всегда переменная и в эту переменную будет записано число, которое вычислилось справа от =. То есть t = 5 + 1; значит что нужно сложить 5 и 1 и то, что получилось запихать в t;
Это равно - не просто значок, а ещё и бинарный оператор. Тут тоже немного подробностей:
в си есть такая вещь как операторы. Синтаксис у них обычно такой:
<знак><выражение> для унарных операторов. К таким относится, например, оператор -. -100 это на самом деле выражение из цифры 100, к которому применили оператор минус и оно стало отрицательным числом 100. Если использовать скобочки то можно даже два раза без проблем минус применить.
<выражение><знак><выражение> для бинарных операторов - это операторы типа +, -(бинарный), *, / и так далее, их много даже в ACS.
есть ещё тернарный оператор с тремя выражениями, но в ACS его вроде нету.
Смысл операторов в том, что вся запись оператора может быть вычислена и чему-то в итоге равна. Для скрипта 2 + 4 и 6 это по сути одно и то же, но обычно операторы применяют к чему-то более неоднозначному. Например, Checkinventory("Defence") + 10 будет равно количеству предметов Defence в инвентаре плюс ещё десять.
= и == это тоже бинарные операторы, хотя это и может выглядеть странно. Операторы из серии ==, !=(не равно), > и < просто равны нулю если соответствующее им условие не выполняется и чему-то другому (обычно 1 ) если выполняется.
If - тоже довольно простая штука - он имеет формат if (выражение) { код 1 } else { код 2 } и выполняет код 1 если выражение не ноль и код 2 если ноль. Вторую половнку ифа можно пропускать, тогда просто выполняться ничего не будет если выражение равно нулю.
while - выполняет код внутри по кругу пока выражение в скобочках не ноль. Условие проверяется только один раз за проход по этому коду, поэтому блок с кодом выполняется целиком несколько раз или не выполняется вообще. Можно считать, что он сначала проверяет выражение, потом если всё хорошо выполняет код и снова проверяет выражение и выполняет код если оно всё ещё не ноль.
while (Checkinventory("Defence") == count) Delay(1);
Эта строка устроена так. Сначала While должен проверить условие Checkinventory("Defence") == count. Оно будет единицей если полученное из игры количество предметов равно тому, что сейчас в count и ноль если нет. то есть пока количество предметов в инвентаре остаётся таким, каким его запомнили выше, выполняется Delay(1). Как только количество предметов изменится, условие станет 0 и на следующий круг с Delay скрипт уже не пойдёт, а вместо этого начнёт выполняться то, что за while. В том скрипте там сразу Restart, который просто перекидывает на начало по сути. Ну а там опять запоминается количество предметов в count и выдаётся броня, после чего выполнение снова ловится в цикле while пока количество предметов опять не поменяется.
У оператора = немного другие свойства - это тоже бинарный оператор, но он ещё и меняет левую переменную - делает её равной тому, что посчиталось справа. У этого оператора тоже есть результат и он просто равен значению справа. За счёт этого можно делать быстрый if. Что-то типа:
if ( count = Checkinventory("Defence") ) { /// Записать в count количество предметов
/// и если предметов было не ноль то ещё зайти сюда
}
= и == в if - это очень разные вещи в общем.
switch это просто такой экономный if - если нужно в зависимости от значения переменной выбрать какой-то из вариантов кода. Единственное но со switch-ем в том, что выполнение спокойно проходит через case nnn: и если не ставить break, то выполнится и правильная ветка кода и все следующие за ней тоже.
c4tnt
Спасибо, познавательно. Мануалы читал от Nil и VladGuardian, скоро на память буду знать, но пока не пойму то что читаю вряд ли они будут помогать)
По поводу этой строки: "while (Checkinventory("Defence") == count) Delay(1);"
Понятия не имел что она может так работать.
Я просто понимаю это так:
Int Count;
Count=CheckInventory("Defence");--------//count==0 при старте игры
Switch (Count){--------------------------//тут этот 0 запомнился
Case 0: ---------------------------------//если 0, выполнится след. строка и прыгнет на While
TakeInventory("BasicArmor",0x7fffffff);
Break;
While(CheckInventory("Defence") == count) Delay(1); //тут если игрок подобрал 1шт. defence==1, а count все еще 0. Тогда цикл прерывается и прыгает на Restart. Если defence и count равны то продолжает цикл(While;Delay;)
Restart;
Не, Switch это просто разветвлялка. Вообще целиком блок switch всегда выглядит так:
switch( ... ) {
case ???:
break;
case ???:
break;
}
Он просто смотрит что в count и выбирает соответствующий case если есть, и продолжает выполнение скрипта уже оттуда. Касательно while всё так и есть, как написал.
Вообще, я уже подзабыл мануал ниловский немного, поэтому может я и не прав, но почему-то в мануалах часто не рассматривают такие вещи как порядок выполнения программы, а сразу пишут про то, какие операторы что делают. Ну или ссылаются на мистический си, который, видимо, всем положено знать.