Прежде чем перейти к реализации оружия, давайте взглянем на некоторые изменения в коде. Вместе с последним обновление появилась странная ошибка, в результате которой на карте появлялись фантомные предметы. На карту добавлялся идентификатор предмета и ничего больше. Глядя на код генерации предметов питания я обнаружил, что перечисление, используемое в генераторе случайных чисел, было изменено. Вместо того, чтобы верхняя граница задавалась supBottleOil (бутылка с маслом), почему то была указана броня armPlate. Я не знаю как это произошло, но это и являлось причиной создания фантомных предметов. Я исправил эту проблему и добавил в нескольких местах кода проверки, чтобы сразу знать что происходит нечто странное, если такая же ситуация повторится. (Примечание: бутылка масла была удалена из кода последующих глав, так как у нас не будет темных подземелий. Смотри раздел примечаний, где описаны идеи того, как можно добавить темные подземелья в игру).
inv.bi
Case Else
inv.desc = "Uknown Supply"
inv.supply.noise = 0
inv.icon = Chr(63)
inv.iconclr = fbYellow
inv.supply.eval = FALSE
inv.supply.use = useNoneВ подпрограмму генерации предметов я добавил Case Else конструкцию, которая будет сигнализировать нам о том, что тип сгенерированного предмета не определился. Т. е. мы создадим предмет с описанием «Uknown Supply» что поможет нам в более быстром обнаружении места ошибки и, что главное, этот код нисколько не повлияет на производительность нашей программы.
Еще одно изменение я внес в функцию GetFullDesc, которая используется подпрограммой ProcessInspect. Раньше тут был ряд вложенных конструкций Select Case, но вложенный Select необходим только для предметов еды, поэтому можно упростить код.
inv.bi'Возвращает подробное описание предмета.
Sub GetFullDesc(lines() As String, inv As invtype)
Dim As Integer idx = 0
'Очистим массив.
ReDim lines(0 To idx) As String
'Убедимся что задан идентификатор типа предмета.
If inv.classid <> clNone Then
'Выберем предмет.
Select Case inv.classid
Case clSupplies
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = GetInvItemDesc(inv)
Select Case inv.supply.id
Case supHealingHerb
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Adds 50% max HP to current HP"
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Magic: Max healing"
Case supHunkMeat
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Adds 25% max HP to current HP"
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Magic: Bonus to STR stat"
Case supBread
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Adds 10% max HP to current HP"
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Magic: Cure poison"
Case supBottleOil
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Fuel for lantern"
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Magic: See all tiles on map"
End Select
idx += 1
ReDim Preserve lines(0 to idx) As String
If IsEval(inv) = TRUE Then
lines(idx) = "* Item is evaluated"
Else
lines(idx) = "* Item is not evaluated"
End If
Case clArmor
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = GetInvItemDesc(inv)
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* " & (inv.armor.dampct * 100) & "% damage reduction"
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Strength Required: " & inv.armor.struse
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Magic: Defense and Healing"
idx += 1
ReDim Preserve lines(0 to idx) As String
If IsEval(inv) = TRUE Then
lines(idx) = "* Item is evaluated"
Else
lines(idx) = "* Item is not evaluated"
End If
Case clShield
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = GetInvItemDesc(inv)
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* " & (inv.shield.dampct * 100) & "% damage reduction"
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Strength Required: " & inv.shield.struse
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Magic: Defense and Healing"
idx += 1
ReDim Preserve lines(0 to idx) As String
If IsEval(inv) = TRUE Then
lines(idx) = "* Item is evaluated"
Else
lines(idx) = "* Item is not evaluated"
End If
Case clWeapon
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = GetInvItemDesc(inv)
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* " & inv.weapon.dam & " weapon damage"
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Hands Required: " & inv.weapon.hands
idx += 1
ReDim Preserve lines(0 to idx) As String
lines(idx) = "* Magic: Offense and Defense"
idx += 1
ReDim Preserve lines(0 to idx) As String
If IsEval(inv) = TRUE Then
lines(idx) = "* Item is evaluated"
Else
lines(idx) = "* Item is not evaluated"
End If
End Select
EndIf
End SubОбратите внимание, что для доспехов, щитов и оружия нет вложенных Select-ов, так как они, на самом деле, не нужны. В результате код становится проще и его легче модифицировать. Теперь настала очередь оружия.
Как мы уже делали для других типов предметов, нам нужно создать список идентификаторов для оружия и определить тип данных.
inv.bi'Идентификаторы оружия.
Enum weaponids
wpNone
wpClub '1 ручное, dam 4 chr:33
wpWarclub '1 ручное, dam 4
wpCudgel '1 ручное, dam 5
wpDagger '1 ручное, dam 4 chr: 173
wpLongknife '1 ручное, dam 6
wpSmallsword '1 ручное, dam 4
wpShortsword '1 ручное, dam 6
wpRapier '1 ручное, dam 9
wpBroadsword '1 ручное, dam 12
wpScimitar '1 ручное, dam 10
wpKatana '2 ручное, dam 12
wpLongsword '2 ручное, dam 14
wpClaymore '2 ручное, dam 16
wpGreatsword '2 ручное, dam 18
wpOdinsword '2 ручное, dam 20
wpHellguard '2 ручное, dam 30
wpQuarterstaff '2 ручное, dam 4
wpLongstaff '2 ручное, dam 6
wpPolearm '2 ручное, dam 8
wpLightspear '2 ручное, dam 7 chr: 179
wpHeavyspear '2 ручное, dam 9
wpTrident '2 ручное, dam 10
wpGlaive '2 ручное, dam 12
wpHandaxe '1 ручное, dam 6 chr: 244
wpBattleaxe '1 ручное, dam 9
wpGothicbattleaxe '2 ручное, dam 12
wpWaraxe '2 ручное, dam 14
wpHalberd '2 ручное, dam 16
wpPoleaxe '2 ручное, dam 18
wpGreataxe '2 ручное, dam 20
wpSmallmace '1 ручное, dam 6 chr: 226
wpBattlemace '1 ручное, dam 8
wpSpikedmace '1 ручное, dam 10
wpDoubleballmace '1 ручное, dam 12
wpWarhammer '1 ручное, dam 14
wpMaul '2 ручное, dam 16
wpGreatMaul '2 ручное, dam 20
wpHellMaul '2 ручное, dam 30
wpBullwhip '1 ручное, dam 4 chr: 231
wpBallflail '1 ручное, dam 6
wpSpikedflail '1 ручное, dam 8
wpMorningstar '1 ручное, dam 10
wpBattleflail '2 ручное, dam 12
wpBishopsflail '2 ручное, dam 14
wpSling '1 ручное, dam 2 chr: 125
wpShortbow '2 ручное, dam 8
wpLongbow '2 ручное, dam 10
wpBonebow '2 ручное, dam 14
wpAdaminebow '2 ручное, dam 20
wpLightcrossbow '2 ручное, dam 10 chr: 209
wpHeavycrossbow '2 ручное, dam 14
wpBarrelcrossbow '2 ручное, dam 18
wpAdaminecrossbow '2 ручное, dam 25
End Enum
'Описание типа для оружия.
Type weapontype
id As weaponids 'Идентификатор
evaldr As Integer 'Сложность опознания. Если > 0 то есть магия.
eval As Integer 'Если предмет опознан.
effect As integer 'Наложенное заклинание.
sdesc As String * 30 'Секретное описание для магических предметов. Доступно если опознан.
noise As Integer 'Кол-во генерируемого шума.
use As itemuse 'Как используется.
dam As integer 'Наносимые повреждения.
hands As Integer 'Сколько рук необходимо для использования.
wslot(1 To 2) As wieldpos 'Слоты для размещения когда используется.
End Type(В оригинальной книге в описании типа weapontype для параметра id был задан тип shieldids, но это, разумеется, ошибка, поэтому здесь я это исправил (примечание переводчика)).
Список оружия предоставляет хорошие варианты его выбора, с различными требованиями и уровнем наносимых повреждений. Каждая группа оружия имеет свою собственную значок для отображения, но все оружие рисуется одним цветом, поэтому игрок будет знать что это оружие, когда увидит его на экране. Мы будем использовать различные иконки для разных типов оружия чтобы дат наглядное представление о том, что данное оружие делает. Со временем игрок научится определять тип оружия просто по его изображению. Мы могли бы использовать один значок для всех типов, но разные иконки добавляют разнообразия. Мы хотим заинтересовать игрока и часть этого — процесс исследования окружающего персонаж мира и его разнообразие.
Описание типа предмета для оружия, на данном этапе, должно быть вам уже хорошо знакомо. Оно такое же как и для остальных предметов, за исключением полей указывающих на количество повреждений, наносимых данным оружием и необходимое количество рук для его использование. Магическое оружие, как и магическая броня, может содержать какое либо заклинание, поэтому, когда мы дойдем до реализации магии, мы вернемся к коду оружия и доспехов чтобы добавить необходимые изменения. В настоящее время мы просто резервируем место для хранения заклинаний, связанных с оружием.
Я говорил в прошлой главе, что очень просто добавлять новые типы предметов в игру, и это на самом деле так. Все что нужно для добавления оружия, это добавить новые варианты выбора в команды Select — case или If в подпрограммах работы с предметами. Так как вы уже несколько раз видели подобный код, то я оставляю эту задачу для вас. Вам теперь должно быть очевидно, что каждый новый подраздел кода, это продолжение уже написанного ранее, и так все и останется, если мы не изменим основной код работы с инвентарем.
Новый код у нас находится только в подпрограмме генерации оружия.
inv.bi'Создаем оружие.
Sub GenerateWeapon(inv As invtype, currlevel As Integer, wpid As weaponids = wpNone)
Dim item As weaponids = wpid
Dim As Integer isMagic = ItemIsMagic(currlevel)
'Создадим тип предмета, если не указан.
If item = wpNone Then
item = RandomRange(wpClub, wpAdaminecrossbow)
EndIf
'Общее для всех типов оружия.
inv.weapon.id = item
inv.iconclr = fbCadmiumYellow
inv.weapon.use = useWieldWear
inv.weapon.eval = FALSE
inv.weapon.wslot(1) = wPrimary
inv.weapon.wslot(2) = wSecondary
'Предмет содержит магию.
If IsMagic = TRUE Then
inv.weapon.evaldr = RandomRange(currlevel, currlevel * 2)
inv.weapon.effect = 0
EndIf
'Заполним характеристики оружия.
Select Case item
Case wpClub '1 ручное, dam 4 chr:33
inv.desc = "Club"
inv.icon = Chr(33)
inv.weapon.noise = 1
inv.weapon.dam = 4
inv.weapon.hands = 1
Case wpCudgel '1 ручное, dam 5
inv.desc = "Cudgel"
inv.icon = Chr(33)
inv.weapon.noise = 2
inv.weapon.dam = 5
inv.weapon.hands = 1
Case wpWarclub '1 ручное, dam 6
inv.desc = "War Club"
inv.icon = Chr(33)
inv.weapon.noise = 3
inv.weapon.dam = 6
inv.weapon.hands = 1
Case wpDagger '1 ручное, dam 4 chr: 173
inv.desc = "Dagger"
inv.icon = Chr(173)
inv.weapon.noise = 1
inv.weapon.dam = 4
inv.weapon.hands = 1
Case wpLongknife '1 ручное, dam 5
inv.desc = "Dagger"
inv.icon = Chr(173)
inv.weapon.noise = 2
inv.weapon.dam = 5
inv.weapon.hands = 1
Case wpSmallsword '1 ручное, dam 6
inv.desc = "Small Sword"
inv.icon = Chr(173)
inv.weapon.noise = 3
inv.weapon.dam = 6
inv.weapon.hands = 1
Case wpShortsword '1 ручное, dam 8
inv.desc = "Short Sword"
inv.icon = Chr(173)
inv.weapon.noise = 4
inv.weapon.dam = 8
inv.weapon.hands = 1
Case wpRapier '1 ручное, dam 10
inv.desc = "Rapier"
inv.icon = Chr(173)
inv.weapon.noise = 5
inv.weapon.dam = 10
inv.weapon.hands = 1
Case wpBroadsword '1 ручное, dam 12
inv.desc = "Broadsword"
inv.icon = Chr(173)
inv.weapon.noise = 6
inv.weapon.dam = 12
inv.weapon.hands = 1
Case wpScimitar '1 ручное, dam 12
inv.desc = "Scimitar"
inv.icon = Chr(173)
inv.weapon.noise = 7
inv.weapon.dam = 12
inv.weapon.hands = 1
Case wpLongsword '2 ручное, dam 14
inv.desc = "Longsword"
inv.icon = Chr(173)
inv.weapon.noise = 8
inv.weapon.dam = 16
inv.weapon.hands = 2
Case wpKatana '2 ручное, dam 16
inv.desc = "Katana"
inv.icon = Chr(173)
inv.weapon.noise = 9
inv.weapon.dam = 16
inv.weapon.hands = 2
Case wpClaymore '2 ручное, dam 18
inv.desc = "Claynore"
inv.icon = Chr(173)
inv.weapon.noise = 12
inv.weapon.dam = 18
inv.weapon.hands = 2
Case wpGreatsword '2 ручное, dam 20
inv.desc = "Greatsword"
inv.icon = Chr(173)
inv.weapon.noise = 16
inv.weapon.dam = 20
inv.weapon.hands = 2
Case wpOdinsword '2 ручное, dam 30
inv.desc = "Odinsword"
inv.icon = Chr(173)
inv.weapon.noise = 20
inv.weapon.dam = 30
inv.weapon.hands = 2
Case wpHellguard '2 ручное, dam 40
inv.desc = "Hellguard"
inv.icon = Chr(173)
inv.weapon.noise = 30
inv.weapon.dam = 40
inv.weapon.hands = 2
Case wpQuarterstaff '2 ручное, dam 4 chr: 179
inv.desc = "Quarterstaff"
inv.icon = Chr(179)
inv.weapon.noise = 1
inv.weapon.dam = 4
inv.weapon.hands = 2
Case wpLongstaff '2 ручное, dam 6
inv.desc = "Longstaff"
inv.icon = Chr(179)
inv.weapon.noise = 2
inv.weapon.dam = 6
inv.weapon.hands = 2
Case wpLightspear '2 ручное, dam 7
inv.desc = "Light Spear"
inv.icon = Chr(179)
inv.weapon.noise = 3
inv.weapon.dam = 7
inv.weapon.hands = 2
Case wpPolearm '2 ручное, dam 8
inv.desc = "Polearm"
inv.icon = Chr(179)
inv.weapon.noise = 4
inv.weapon.dam = 8
inv.weapon.hands = 2
Case wpHeavyspear '2 ручное, dam 9
inv.desc = "Heavy Spear"
inv.icon = Chr(179)
inv.weapon.noise = 5
inv.weapon.dam = 9
inv.weapon.hands = 2
Case wpTrident '2 ручное, dam 10
inv.desc = "Trident"
inv.icon = Chr(179)
inv.weapon.noise = 6
inv.weapon.dam = 10
inv.weapon.hands = 2
Case wpGlaive '2 ручное, dam 12
inv.desc = "Glaive"
inv.icon = Chr(179)
inv.weapon.noise = 7
inv.weapon.dam = 12
inv.weapon.hands = 2
Case wpHandaxe '1 ручное, dam 6 chr: 244
inv.desc = "Hand Axe"
inv.icon = Chr(244)
inv.weapon.noise = 2
inv.weapon.dam = 6
inv.weapon.hands = 1
Case wpBattleaxe '1 ручное, dam 9
inv.desc = "Battle Axe"
inv.icon = Chr(244)
inv.weapon.noise = 3
inv.weapon.dam = 9
inv.weapon.hands = 1
Case wpGothicbattleaxe '2 ручное, dam 12
inv.desc = "Gothic Battle Axe"
inv.icon = Chr(244)
inv.weapon.noise = 4
inv.weapon.dam = 12
inv.weapon.hands = 2
Case wpWaraxe '2 ручное, dam 14
inv.desc = "War Axe"
inv.icon = Chr(244)
inv.weapon.noise = 5
inv.weapon.dam = 14
inv.weapon.hands = 2
Case wpHalberd '2 ручное, dam 16
inv.desc = "Halberd"
inv.icon = Chr(244)
inv.weapon.noise = 6
inv.weapon.dam = 16
inv.weapon.hands = 2
Case wpPoleaxe '2 ручное, dam 18
inv.desc = "Pole Axe"
inv.icon = Chr(244)
inv.weapon.noise = 8
inv.weapon.dam = 18
inv.weapon.hands = 2
Case wpGreataxe '2 ручное, dam 20
inv.desc = "Great Axe"
inv.icon = Chr(244)
inv.weapon.noise = 10
inv.weapon.dam = 20
inv.weapon.hands = 2
Case wpSmallmace '1 ручное, dam 6 chr: 226
inv.desc = "Small Mace"
inv.icon = Chr(226)
inv.weapon.noise = 1
inv.weapon.dam = 6
inv.weapon.hands = 1
Case wpBattlemace '1 ручное, dam 8
inv.desc = "Battle Mace"
inv.icon = Chr(226)
inv.weapon.noise = 4
inv.weapon.dam = 8
inv.weapon.hands = 1
Case wpSpikedmace '1 ручное, dam 10
inv.desc = "Spiked Mace"
inv.icon = Chr(226)
inv.weapon.noise = 6
inv.weapon.dam = 10
inv.weapon.hands = 1
Case wpDoubleballmace '1 ручное, dam 12
inv.desc = "Double-Ball Mace"
inv.icon = Chr(226)
inv.weapon.noise = 8
inv.weapon.dam = 12
inv.weapon.hands = 1
Case wpWarhammer '1 ручное, dam 14
inv.desc = "War Hammer"
inv.icon = Chr(226)
inv.weapon.noise = 10
inv.weapon.dam = 14
inv.weapon.hands = 1
Case wpMaul '2 ручное, dam 16
inv.desc = "Maul"
inv.icon = Chr(226)
inv.weapon.noise = 12
inv.weapon.dam = 16
inv.weapon.hands = 2
Case wpBullwhip '1 ручное, dam 4 chr: 231
inv.desc = "Bull Whip"
inv.icon = Chr(231)
inv.weapon.noise = 2
inv.weapon.dam = 4
inv.weapon.hands = 1
Case wpBallflail '1 ручное, dam 6
inv.desc = "Ball Flail"
inv.icon = Chr(231)
inv.weapon.noise = 4
inv.weapon.dam = 6
inv.weapon.hands = 1
Case wpSpikedflail '1 ручное, dam 8
inv.desc = "Spiked Flail"
inv.icon = Chr(231)
inv.weapon.noise = 6
inv.weapon.dam = 8
inv.weapon.hands = 1
Case wpMorningstar '1 ручное, dam 10
inv.desc = "Morning Star"
inv.icon = Chr(231)
inv.weapon.noise = 8
inv.weapon.dam = 10
inv.weapon.hands = 1
Case wpBattleflail '2 ручное, dam 12
inv.desc = "Battle Flail"
inv.icon = Chr(231)
inv.weapon.noise = 10
inv.weapon.dam = 12
inv.weapon.hands = 2
Case wpBishopsflail '2 ручное, dam 14
inv.desc = "Bishop's Flail"
inv.icon = Chr(231)
inv.weapon.noise = 12
inv.weapon.dam = 14
inv.weapon.hands = 2
Case wpSling '1 ручное, dam 2 chr: 125
inv.desc = "Sling"
inv.icon = Chr(125)
inv.weapon.noise = 1
inv.weapon.dam = 2
inv.weapon.hands = 1
Case wpShortbow '2 ручное, dam 8
inv.desc = "Short Bow"
inv.icon = Chr(125)
inv.weapon.noise = 4
inv.weapon.dam = 8
inv.weapon.hands = 2
Case wpLongbow '2 ручное, dam 10
inv.desc = "Long Bow"
inv.icon = Chr(125)
inv.weapon.noise = 6
inv.weapon.dam = 10
inv.weapon.hands = 2
Case wpBonebow '2 ручное, dam 14
inv.desc = "Dragon Bone Bow"
inv.icon = Chr(125)
inv.weapon.noise = 10
inv.weapon.dam = 14
inv.weapon.hands = 2
Case wpAdaminebow '2 ручное, dam 20
inv.desc = "Adamine Bow"
inv.icon = Chr(125)
inv.weapon.noise = 12
inv.weapon.dam = 20
inv.weapon.hands = 2
Case wpLightcrossbow '2 ручное, dam 10 chr: 209
inv.desc = "Light Crossbow"
inv.icon = Chr(209)
inv.weapon.noise = 4
inv.weapon.dam = 10
inv.weapon.hands = 2
Case wpHeavycrossbow '2 ручное, dam 14
inv.desc = "Heavy Crossbow"
inv.icon = Chr(209)
inv.weapon.noise = 8
inv.weapon.dam = 14
inv.weapon.hands = 2
Case wpBarrelcrossbow '2 ручное, dam 18
inv.desc = "Barrel Crossbow"
inv.icon = Chr(209)
inv.weapon.noise = 12
inv.weapon.dam = 18
inv.weapon.hands = 2
Case wpAdaminecrossbow '2 ручное, dam 25
inv.desc = "Adamine Crossbow"
inv.icon = Chr(209)
inv.weapon.noise = 16
inv.weapon.dam = 25
inv.weapon.hands = 2
Case Else
inv.desc = "Unknown Weapon"
inv.icon = Chr(63)
inv.weapon.noise = 0
inv.weapon.dam = 0
inv.weapon.hands = 0
End Select
'Установим полное описание.
If IsMagic = TRUE Then
inv.weapon.sdesc = inv.desc
Else
inv.weapon.sdesc = inv.desc
EndIf
End SubКак вы можете убедится, процесс такой же как для брони и щитов. Для того, чтобы мы могли создавать этой подпрограммой определенные предметы оружия у нее есть дополнительный параметр weaponids, так же как и в процедуре генерации доспехов. Мы этим воспользуемся, например, чтобы создать нож с которым персонаж начинает игру по умолчанию. Если этот параметр не задан, то используется значение по умолчанию wpNone и генерируется случайное оружие. Если вы сравните процедуры генерации различных типов предметов, то заметите, что их код идентичен. Все предметы имеют схожие свойства, которые задаются данными подпрограммами, в результате вы можете просто скопировать уже написанную процедуру генерации предметов и вставить ее в код для генерации предметов другого типа, внеся в нее лишь небольшие изменения. Однако, здесь нужно быть очень осторожным и не стоит этого вообще делать, если вы досконально не понимаете как данная процедура работает.
Нам осталось только внести изменения в команду инвентаря «Одеть/Взять в руки».
dod.bas'Команда «Одеть/Взять в руки».
Function ProcessEquip() As Integer
Dim As String res, mask, desc, msg
Dim As Integer i, iret, iitem, idx, ret = FALSE, freecnt
Dim As invtype inv
Dim As tWidgets.btnID btn
Dim As tWidgets.tInputbox ib
Dim As vec mvec
Dim slot As Integer
'Убедимся что есть что одеть/взять в руки.
For i = pchar.LowInv To pchar.HighInv
iitem = pchar.HasInvItem(i)
If iitem = TRUE Then
'Получим предмет из инвентаря.
pchar.GetInventoryItem i, inv
'Если предмет можно одеть/взять.
iret = MatchUse(inv, useWieldWear)
If iret = TRUE Then
'Построим маску.
mask &= Chr(i)
End If
EndIf
Next
If Len(mask) = 0 Then
ShowMsg "Equip Items", "Nothing to equip.", tWidgets.MsgBoxType.gmbOK
Else
'Нарисум поле для ввода.
ib.Title = "Equip Items"
ib.Prompt = "Select item(s) to equip (" & mask & ")"
ib.Row = 39
ib.EditMask = mask
ib.MaxLen = Len(mask)
ib.InputLen = Len(mask)
btn = ib.Inputbox(res)
'Переберем все предметы из списка.
If (btn <> tWidgets.btnID.gbnCancel) And (Len(res) > 0) Then
'Проверим список предметов.
For i = 1 To Len(res)
iitem = Asc(res, i) 'Получим индекс в инвентаре.
'Получим предмет.
pchar.GetInventoryItem iitem, inv
'Получим описание предмета.
desc = GetInvItemDesc(inv)
iret = FALSE
idx = 0
'Проверим слот 1.
slot = GetInvWSlot(inv, 1)
If slot <> wNone Then
'Проверим, свободен ли слот у персонажа.
If pchar.HasInvItem(slot) = FALSE Then
idx = slot
iret = TRUE
EndIf
End If
'Если первый занят.
If iret = FALSE Then
'Проверим слот 2.
slot = GetInvWSlot(inv, 2)
If slot <> wNone Then
'Проверим, свободен ли слот у персонажа.
If pchar.HasInvItem(slot) = FALSE Then
idx = slot
iret = TRUE
EndIf
End If
EndIf
'Нет свободных слотов.
If iret = FALSE Then
msg = "No empty slots to equip " & desc & "."
Else
'Если это оружие и необходимо более одной свободной руки.
If inv.classid = clWeapon then
freecnt = 0
'Проверим свободные слоты.
If pchar.HasInvItem(wPrimary) = FALSE Then
freecnt += 1
EndIf
If pchar.HasInvItem(wSecondary) = FALSE Then
freecnt += 1
EndIf
If inv.weapon.hands > freecnt Then
iret = FALSE
msg = "Not enough free hands to equip " & desc & "."
EndIf
End If
'Может ли персонаж воспользоваться щитом или оружием?
If inv.classid = clArmor Or inv.classid = clShield Then
If pchar.CanWear(inv) = false Then
iret = FALSE
msg = "Not enough strength to equip " & desc & "."
End If
EndIf
End If
'Пустой слот найден?
If iret = TRUE Then
'Поместим в него предмет.
pchar.AddInvItem idx, inv
'Уберем из инвентаря.
ClearInv inv
'Обновим состояние слотов.
pchar.AddInvItem iitem, inv
ret = TRUE
desc &= " was equipped."
ShowMsg "Equip Items", desc, tWidgets.MsgBoxType.gmbOK
Else
ShowMsg "Equip Items", msg, tWidgets.MsgBoxType.gmbOK
End If
Next
EndIf
EndIf
Return ret
End FunctionБольшая часть кода этой функции осталась прежней, мы просто сделали некоторую его реорганизацию для более удобной обработки условия использования двуручного оружия. Как и раньше, мы получаем список предметов, которые могут быть одеты или взяты в руки и предоставляем выбор игроку. После того, как выбор сделан, мы проверяем, может ли персонаж использовать этот предмет.
Обратите внимание, мы изменили часть программы где проверяется пустой слот. Это необходимо, так как персонаж может взять оружие как в правую, так и в левую руку, если для его использования достаточно одной руки (первичный и вторичный слоты). Персонаж может держать в руках также и щит. Вначале мы проверяем первый слот, и если он занят, то проверяем второй. В первой итерации кода, мы имеем дело только со щитами, нам небыло необходимости проверять оба слота, но сейчас она появилась, так как у нас есть несколько разных предметов, которые могут быть в разных руках персонажа.
Следующее что нам необходимо сделать, это определить, является ли выбранный предмет доспехами, оружием или щитом. Оружие имеет требование на количество свободных рук, а броня и щиты — требование по показателю силы персонажа, так что нам необходимо проверить эти ограничения чтобы убедится, что персонаж может использовать выбранный предмет. Для оружия мы проверяем количество свободных рук у персонажа, для брони и щитов — значение параметра силы, как мы делали это и раньше. Если любая из проверок не удалась, то мы выводим об этом сообщение, чтобы дать понять игроку о не успешности попытки воспользоваться предметом. Если же проверки прошли успешно, то также как и раньше, мы убираем предмет из инвентаря персонажа и помещаем его в слот для используемых предметов.
Теперь у нас уже есть оружие и мы можем использовать его в игре. Следующее что нам нужно сделать, это добавить некоторое количество монстров, и мы будем готовы сражаться с обитателями Подземелья Судьбы.

Такое впечатление, что статьи как будто писались на русском. Отличный перевод. Спасибо.
ОтветитьУдалитьприятно видеть что это кому то полезно, да еще и нравиться перевод (мне просто книга понравилась и я, в основном, для себя захотел перевести). и это учитывая то, что не учил английский ни в школе. ни в универе. методом тыка пришлось выучить. сейчас вот работаю в компании, где ни одного русскоязычного человека нет. только арабский и английский (и то - не все английский знают), так что приходится на английском шпрехать, иногда вставляя слова на арабском :).
ОтветитьУдалить