ВСЕХ ЗАДОЛБАВШАЯ ПРОДАЖА КНИГ!!!
ЭТА ЗАПИСЬ БЛОГА ДОБАВЛЕНА ДЛЯ САМОЛЮБОВАНИЯ.
Функция продажи, из диалога Йерлинг
scn aaaSFWbtcBooksToCaps
int HowMuchToSale
ref rBook
int Count
int BookPrice
int iRewardXP
Begin Function { HowMuchToSale }
If (GetINIFloat "BooksToCapsOptions:iFixedPrice" "BooksToCaps.ini") > 0
BookPrice = GetINIFloat "BooksToCapsOptions:iFixedPrice" "BooksToCaps.ini"
Else
BookPrice = Ceil ((Player.GetAV Science)/5 + (Player.GetAV Repair)/5 + (Player.GetAV Medicine)/5 + (Player.GetAV Barter)/5 + (Player.GetAV Survival)/5)
EndIf
If (GetINIFloat "BooksToCapsOptions:iRewardXP" "BooksToCaps.ini") > 0
iRewardXP = GetINIFloat "BooksToCapsOptions:iRewardXP" "BooksToCaps.ini"
Else
iRewardXP = 10
EndIf
If aaaSFWbtcBookPerkQuest.BookPerk > 99
foreach rBook <- aaaSFWbtcBooksFormList
Count = (Player.GetItemCount rBook)
If Count > 0
If Count > HowMuchToSale
Count = HowMuchToSale
EndIf
Player.RemoveItem rBook Count
Player.AddItem f (Count * BookPrice)
RewardXP (Count * iRewardXP)
; aaaSFWbtcBookPerkQuest.BookPerk += Count
HowMuchToSale -= Count
If HowMuchToSale == 0
Break
EndIf
EndIf
loop
Else
foreach rBook <- aaaSFWBooksFormList
Count = (Player.GetItemCount rBook)
If Count > 0
If Count > HowMuchToSale
Count = HowMuchToSale
EndIf
Player.RemoveItem rBook Count
Player.AddItem f (Count * BookPrice)
RewardXP (Count * iRewardXP)
aaaSFWbtcBookPerkQuest.BookPerk += Count
HowMuchToSale -= Count
If HowMuchToSale == 0
Break
EndIf
EndIf
loop
EndIf
If aaaSFWbtcBookPerkQuest.DoOnceBookPerk == 0 && aaaSFWbtcBookPerkQuest.BookPerk > 19
aaaSFWbtcBookPerkQuest.DoOnceBookPerk = 1
ShowMessage aaaSFWBookPerkSpoiler
EndIf
If aaaSFWbtcBookPerkQuest.DoOnceBookPerk == 1 && aaaSFWbtcBookPerkQuest.BookPerk > 99
aaaSFWbtcBookPerkQuest.DoOnceBookPerk = 2
Player.AddPerk aaaSFWBookPerk
StartQuest aaaSFWbtcBookPerkQuest
ShowMessage aaaSFWBookPerkMsg
EndIf
End
Как видим, это скрипт-функция, вместе с циклом, но настроенная на то, что если перка продажи книг нет -- продавать обычные книги. В противном случае, при наличии перка, продаются книги из отбраковки перка.
Логика крайне проста: Мы получаем переменную "сколько продать" и идём по всем ячейкам форм-листа, и обрабатываем только те ячейки, внутри которых лежат книги. Пустые, с нулём книг пропускаем.
Дальше интересней -- в том случае, если количество книг в ячейке меньше-равно количества для продажи, то для текущей итерации цикла мы используем количество книг в ячейке, и за эту итерацию мы их продаём. Иначе, если количество больше, чем нужно продать, мы присваиваем переменной Количество Число для Продажи.
После успешной продажи мы отнимаем от числа Продажи значение Количество, и таким образом ничего не забываем.
Когда количество для продажи равно нулю -- мы прерываем цикл, чтобы не гонять его впустую и не вызывать ошибки.
Так-же, при продаже обычных книг (Не отбраковки!) мы прибавляем значение переменной перка.
Стоит упомянуть и то, что мы читаем 3 переменные из конфига BooksToCaps.ini . В конкретно данном скрипте у нас есть цена каждой книги, и получаемый опыт за книгу.
В самом конце скрипта -- рутина, связанная с показом сообщений о перке, и запуском квеста перка. Я специально не делал запуск квеста перка вместе с игрой, со скриптом проверки наличия перка, чтобы сэкономить процессорное время на операциях скрипта, так-что добавляемый перк носит чисто косметический характер.
scn aaaSFWbtcBookPerkScript
int BookPerk ;Used in Function
int DoOnceBookPerk ;Used in Function
int i
float BookRandom
int LuckAffects
int SFWBookGeneric1000Count
int SFWBookGeneric725Count
int SFWBookGeneric450Count
Begin GameMode
If GetGameLoaded || GetGameRestarted
LuckAffects = GetINIFloat "BooksToCapsOptions:bLuckAffects" "BooksToCaps.ini"
EndIf
while (Player.GetItemCount aaaSFWBooksFormList)
If (Player.GetItemCount (ListGetNthForm aaaSFWBooksFormList i))
Player.RemoveItem (ListGetNthForm aaaSFWBooksFormList i) 1 1
If LuckAffects == 1
BookRandom = GetRandomPercent + ((Player.GetAV Luck) / 2)
Else
BookRandom = GetRandomPercent + 2.5
EndIf
If BookRandom > 101
SFWBookGeneric1000Count += 1
ElseIf BookRandom > 99
SFWBookGeneric725Count += 1
ElseIf BookRandom > 96
SFWBookGeneric450Count += 1
Else
Player.AddItem aaaSFWBooksAll 1 1
EndIf
Else
i += 1
If eval i >= (ListGetCount aaaSFWBooksFormList)
i = 0
EndIf
EndIf
loop
If SFWBookGeneric1000Count || SFWBookGeneric725Count || SFWBookGeneric450Count
ShowMessage aaaSFWbtcBooksVALUABLEmsg
EndIf
If SFWBookGeneric1000Count
Player.AddItem SFWBookGeneric1000 SFWBookGeneric1000Count 1
SFWBookGeneric1000Count = 0
EndIf
If SFWBookGeneric725Count
Player.AddItem SFWBookGeneric725 SFWBookGeneric725Count 1
SFWBookGeneric725Count = 0
EndIf
If SFWBookGeneric450Count
Player.AddItem SFWBookGeneric450 SFWBookGeneric450Count 1
SFWBookGeneric450Count = 0
EndIf
End
Begin MenuMode 1009
If GetGameLoaded || GetGameRestarted
LuckAffects = GetINIFloat "BooksToCapsOptions:bLuckAffects" "BooksToCaps.ini"
EndIf
while (Player.GetItemCount aaaSFWBooksFormList)
If (Player.GetItemCount (ListGetNthForm aaaSFWBooksFormList i))
Player.RemoveItem (ListGetNthForm aaaSFWBooksFormList i) 1 1
If LuckAffects == 1
BookRandom = GetRandomPercent + ((Player.GetAV Luck) / 2)
Else
BookRandom = GetRandomPercent + 2.5
EndIf
If BookRandom > 101
SFWBookGeneric1000Count += 1
ElseIf BookRandom > 99
SFWBookGeneric725Count += 1
ElseIf BookRandom > 96
SFWBookGeneric450Count += 1
Else
Player.AddItem aaaSFWBooksAll 1 1
EndIf
Else
i += 1
If eval i >= (ListGetCount aaaSFWBooksFormList)
i = 0
EndIf
EndIf
loop
If SFWBookGeneric1000Count || SFWBookGeneric725Count || SFWBookGeneric450Count
ShowMessage aaaSFWbtcBooksVALUABLEmsg
EndIf
If SFWBookGeneric1000Count
Player.AddItem SFWBookGeneric1000 SFWBookGeneric1000Count 1
SFWBookGeneric1000Count = 0
EndIf
If SFWBookGeneric725Count
Player.AddItem SFWBookGeneric725 SFWBookGeneric725Count 1
SFWBookGeneric725Count = 0
EndIf
If SFWBookGeneric450Count
Player.AddItem SFWBookGeneric450 SFWBookGeneric450Count 1
SFWBookGeneric450Count = 0
EndIf
End
Это скрипт перка. Здесь можно заметить, что цикл выполняется по принципу IF -- если в форм-листе есть книги, то цикл работает, а если нет -- то пропускает выполнение, тоесть, цикл для экономии процессорного времени не гоняет строки массива впустую.
Далее происходит вот что: Цикл обрабатывает одну ячейку форм-листа до те пор, пока она не исчерпается. Этим занят индекс i ... Когда ячейка исчерпывается на предмет наличия книг -- счётчик i прибавляется, и выполнение переходит на следующую ячейку. Конечно, когда счётчик выходит за предел форм-листа, то он сбрасывается на 0.
Принцип работы таков, что за итерацию цикла отнимается одна обычная книга (Не отбраковка!), далее, либо прибавляется книга отбраковки, пригодная для продажи, либо прибавляется счётчик одной из Ценных Книг, от Очень ценной, до "Довольно" ценной.
В конце скрипта проверяются счётчики Ценных Книг -- если хотя-бы одна больше нуля, то выводится сообщение о находке. Далее идёт секция добавления ценных книг согласно счётчику, с последующим обнулением счётчика.
Конечно-же ценные книги / отбраковка добавляются случайно. Здесь есть переменная BookRandom, с типом плавающая запятая. Функция GetRandomPercent даёт число от 0 до 99. И если указано влияние удачи в конфиге, то Удача делённая на 2 прибавляется к случайному числу. Если же влияние удачи отключено, то к рандомному числу прибавляется 2,5 -- эквивалент Удачи 5
Коэффициенты поиска книг указаны как 1%, 2% и 3% -- от самой ценной до менее ценной.
Число не попавшее в диапазон нахождения ценной книги преобразовывается в книгу-отработку
[BooksToCapsOptions]
; Влияет ли удача на нахождение ценных книг
; Если 0 - то нет, если 1 - то да
bLuckAffects=1
; Фиксированная цена в крышках (целое число)
; Если 0 - то цена будет рассчитываться согласно навыкам
iFixedPrice=0
; Количество Очков Опыта за каждую проданную книгу
iRewardXP = 10
Как видим в скрипте предусмотрено всё для того, чтобы не потерять ценные книги.
В том-числе были поправлены условия диалогов Йерлинг, чтобы потеря ценных книг при первой продаже была минимальной, а затем их и вовсе потерять было нельзя.