Доброго времени суток.
Стоит задача:
При клике на предмет выдается что-то одно из:
С 15% случайное оружее
С 20% случайная часть доспеха
С 20% случайный реагент
С 25% случайное зелье
Если ничего из этого не выпало, то выдается 1 Bandage
LOCAL.HELL_QUEST_CHEST_GEN=<R100>
IF (15 > <DLOCAL.HELL_QUEST_CHEST_GEN>)
SERV.NEWITEM=I_RANDOM_WEAPON
ELIF (35 > <DLOCAL.HELL_QUEST_CHEST_GEN>)
SERV.NEWITEM=I_RANDOM_ARMOR
ELIF (55 > <DLOCAL.HELL_QUEST_CHEST_GEN>)
SERV.NEWITEM=I_RANDOM_REAGENT
ELIF (80 > <DLOCAL.HELL_QUEST_CHEST_GEN>)
SERV.NEWITEM=I_RANDOM_BOTTLE
ELSE
SERV.NEWITEM=I_BANDAGE
ENDIF
local.item = {1 15 2 20 3 20 4 25 5 (100-(15+20+20+25))}
слушай, а тебе самому то удобно читать это 15 > random?
если задача была не в этом...
то надо просто рандом в каждой проверке заново высчитывать, вот тогда логика будет соответствовать задаче.
if rand(100) < 15
Неудобно. В этом часть сути вопроса.
А что, если при выпадении вероятности будет давать
DORAND 2
SERV.NEWITEM=I_RANDOM_WEAPON_1
SERV.NEWITEM=I_RANDOM_WEAPON_2
ENDDO
то local.item = вариант не подходит. Хочется универсальный, читабельный вариант.
------------------------------------
Если такой вариант:
if rand(100) < 15
IF (15 > <R100>)
SERV.NEWITEM=I_RANDOM_WEAPON
ELIF (20 > <R100>)
SERV.NEWITEM=I_RANDOM_ARMOR
ELIF (20 > <R100>)
SERV.NEWITEM=I_RANDOM_REAGENT
ELIF (25 > <R100>)
SERV.NEWITEM=I_RANDOM_BOTTLE
ELSE
SERV.NEWITEM=I_BANDAGE
ENDIF
local.item = {item1 15 item2 20 item3 20 item4 25 item5 <eval(100-(15+20+20+25))>}
и чего он не читабельный то?
Читабельный.
Для решения задачи хотелось-бы видеть универсальный вариант где для события задается количество исходов и их вероятности. А далее этот массив использовать как шанс выпадения предмета, или запуска функции.
Считать каждый раз в конце (100-(15+20+20+25)) цифры, так как порой исходов может быть 20+ и 50+ и шансы разные, утомительно.
К сожалению DORAND X выбирает случайный исход с одинаковой вероятностью.
Т.е. указать проценты для 50 предметов, чтобы они влезли в 100% не утомительно? В любом случае придется складывать все проценты, чтобы вычислять величину от которой RAND считать. Это я на глаз прикинул, что они именно в 100 влезают.
local.count = 3
local.item1 = item1
local.chance1 = chance1
local.item2 = item2
local.chance2 = chance2
local.item3 = item3
local.chance3 = chance3
for 1 3
Если я правильно понял тогда под это
const runDropArr = [dropОружие, dropДоспех, dropРеагент, dropЗелье];
const dropOrNo = false;
for (i=0; i < runDropArr.length; i++) {
dropOrNo = runDropArr[i]();
}
if (!runDropArr) dropБинт();
dropОружие() {
if (rand_100 <= шанс) {
<генерируем выпадение предмета>
return false;
}
return false;
}
Спасибо Sirocco меня твой кусочек натолкнул на мысль хороший дроп из драконов так сделать.
Хочется универсальный, читабельный вариант.
IF (15 > <R100>)
SERV.NEWITEM=I_RANDOM_WEAPON
ELIF (20 > <R100>)
SERV.NEWITEM=I_RANDOM_ARMOR
ELIF (20 > <R100>)
SERV.NEWITEM=I_RANDOM_REAGENT
ELIF (25 > <R100>)
SERV.NEWITEM=I_RANDOM_BOTTLE
ELSE
SERV.NEWITEM=I_BANDAGE
ENDIF
DORAND 2
SERV.NEWITEM=I_RANDOM_WEAPON_1
SERV.NEWITEM=I_RANDOM_WEAPON_2
ENDDO
С 15% случайное оружее - 15 строчек
С 20% случайная часть доспеха - 20 строчек
С 20% случайный реагент - 20 строчек
С 25% случайное зелье - 25 строчек
(20% бинт) - 20 строчек
С 15% случайное оружее - 15*2/10=3 строчек
С 20% случайная часть доспеха - 4 строчек
С 20% случайный реагент - 4 строчек
С 25% случайное зелье - 5 строчек
(20% бинт) - 4 строчек
DORAND 20
SERV.NEWITEM=I_RANDOM_WEAPON_1
SERV.NEWITEM=I_RANDOM_WEAPON_1
SERV.NEWITEM=I_RANDOM_WEAPON_1
SERV.NEWITEM=I_RANDOM_ARMOR
SERV.NEWITEM=I_RANDOM_ARMOR
SERV.NEWITEM=I_RANDOM_ARMOR
SERV.NEWITEM=I_RANDOM_ARMOR
SERV.NEWITEM=I_RANDOM_REAGENT
SERV.NEWITEM=I_RANDOM_REAGENT
SERV.NEWITEM=I_RANDOM_REAGENT
SERV.NEWITEM=I_RANDOM_REAGENT
SERV.NEWITEM=I_RANDOM_BOTTLE
SERV.NEWITEM=I_RANDOM_BOTTLE
SERV.NEWITEM=I_RANDOM_BOTTLE
SERV.NEWITEM=I_RANDOM_BOTTLE
SERV.NEWITEM=I_RANDOM_BOTTLE
SERV.NEWITEM=I_BANDAGE
SERV.NEWITEM=I_BANDAGE
SERV.NEWITEM=I_BANDAGE
SERV.NEWITEM=I_BANDAGE
ENDDO
Согласен Ozzy Osbourne
DORAND 4
TEST 1
TEST 2
TEST 3
TEST 4
ENDDO
У каждого исхода шанс 25%
Но указанный алгоритм тоже сложен для воспринятия когда много исходов.
local.count = 3
local.func1 = dropОружие
local.chance1 = 15
local.func2 = dropДоспех
local.chance2 = 20
local.func3 = dropРеагент
local.chance3 = 20
local.failfunc = dropБинты
call f_check_lootchance
[FUNCTION f_check_lootchance]
for i 1 <local.count>
local.check = <f_check_dropchance <dlocal.i> <local.chance<dlocal.i>>>
if <local.check>
local.arraycount += 1
local.array_<dlocal.arraycount> = <local.check>
endif
endfor
if <local.arraycount>
local.result = <eval({1 <local.arraycount>})>
try <local.func<dlocal.array_<dlocal.result>>>
else
try <local.failfunc>
endif
[FUNCTION f_check_dropchance]
if rand(100) <= <argn2>
return <argn1>
else
return 0
[FUNCTION f_check_lootchance]
local.array = ""
for i 1 <local.count>
local.check = <f_check_dropchance <dlocal.i> <local.chance<dlocal.i>>>
if <local.check>
local.array = <qval <local.success>?<local.array> <local.check> 1:<local.check> 1>
local.success = 1
endif
endfor
if <local.success>
local.result = <eval({<local.array>})>
try <local.func<dlocal.result>>
else
try <local.failfunc>
endif
Я тут придумал:
[FUNCTION DROP_CHANSE_TEST]
DORAND 3
DROP_1 15,I_DAGGER
DROP_2 30,I_PLATEMAIL_CHEST
DROP_3 55,I_BANDAGE
ENDDO
[FUNCTION DROP_1]
LOCAL.ROLL=<R100>
IF <ARGV[0]> > <DLOCAL.ROLL>
SERV.NEWITEM=<ARGV[1]>
NEW.CONT=<FINDLAYER.21.UID>
SAY @0487 DROP_1 [<ARGV[0]> < <DLOCAL.ROLL>]
ELSE
SAY <ARGV[0]> < <DLOCAL.ROLL>
DROP_CHANSE_TEST
ENDIF
[FUNCTION DROP_2]
LOCAL.ROLL=<R100>
IF <ARGV[0]> > <DLOCAL.ROLL>
SERV.NEWITEM=<ARGV[1]>
NEW.CONT=<FINDLAYER.21.UID>
SAY @0487 DROP_2 [<ARGV[0]> < <DLOCAL.ROLL>]
ELSE
SAY <ARGV[0]> < <DLOCAL.ROLL>
DROP_CHANSE_TEST
ENDIF
[FUNCTION DROP_3]
LOCAL.ROLL=<R100>
IF <ARGV[0]> > <DLOCAL.ROLL>
SERV.NEWITEM=<ARGV[1]>
NEW.CONT=<FINDLAYER.21.UID>
SAY @0487 DROP_3 [<ARGV[0]> < <DLOCAL.ROLL>]
ELSE
SAY <ARGV[0]> < <DLOCAL.ROLL>
DROP_CHANSE_TEST
ENDIF
Какая замечательная рекурсия.
Осталось добавить счетчик... чтобы при 3х из нее выкидывало.
А я сразу не понял, что бинты это FAIL. Так выходит надо опять вручную шансы считать?
А какие у меня проблемы с визуальностью решения?
https://forum.uokit.com/index.php?s=&showtopic=71439&view=findpost&p=445663
[FUNCTION DROP_CHANSE_TEST]
DORAND 3
DROP_UNIQUE_F 15,I_DAGGER,1
DROP_UNIQUE_F 20,RANDOM_PLATEMAIL_ARMOR,1
DROP_UNIQUE_F 20,RANDOM_REAGENT,1
DROP_UNIQUE_F 25,RANDOM_POTION,1
DROP_UNIQUE_F 20,I_BANDAGE,3
ENDDO
[FUNCTION DROP_UNIQUE_F]
LOCAL.ROLL=<R100>
IF <ARGV[0]> > <DLOCAL.ROLL>
SERV.NEWITEM=<ARGV[1]>
NEW.AMOUNT-<ARGV[2]>
NEW.CONT=<FINDLAYER.21.UID>
SERV.LOG [<ARGV[0]> > <DLOCAL.ROLL>] Drop: <ARGV[1]>,<ARGV[2]>
ELSE
DROP_CHANSE_TEST
ENDIF
А где тут: если ничего не прокнуло, выдать бинты?
и в зелёный цвет персонажа покрасить)) я сейчас делаю систему присасывания к дракону персонажей и он их огнём сжигает. Когда я вижу вар это мне напоминает тёплый нордский мёд, а локалсы это для модников
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)