Прежде чем перейти к реализации оружия, давайте взглянем на некоторые изменения в коде. Вместе с последним обновление появилась странная ошибка, в результате которой на карте появлялись фантомные предметы. На карту добавлялся идентификатор предмета и ничего больше. Глядя на код генерации предметов питания я обнаружил, что перечисление, используемое в генераторе случайных чисел, было изменено. Вместо того, чтобы верхняя граница задавалась 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
Большая часть кода этой функции осталась прежней, мы просто сделали некоторую его реорганизацию для более удобной обработки условия использования двуручного оружия. Как и раньше, мы получаем список предметов, которые могут быть одеты или взяты в руки и предоставляем выбор игроку. После того, как выбор сделан, мы проверяем, может ли персонаж использовать этот предмет.
Обратите внимание, мы изменили часть программы где проверяется пустой слот. Это необходимо, так как персонаж может взять оружие как в правую, так и в левую руку, если для его использования достаточно одной руки (первичный и вторичный слоты). Персонаж может держать в руках также и щит. Вначале мы проверяем первый слот, и если он занят, то проверяем второй. В первой итерации кода, мы имеем дело только со щитами, нам небыло необходимости проверять оба слота, но сейчас она появилась, так как у нас есть несколько разных предметов, которые могут быть в разных руках персонажа.
Следующее что нам необходимо сделать, это определить, является ли выбранный предмет доспехами, оружием или щитом. Оружие имеет требование на количество свободных рук, а броня и щиты — требование по показателю силы персонажа, так что нам необходимо проверить эти ограничения чтобы убедится, что персонаж может использовать выбранный предмет. Для оружия мы проверяем количество свободных рук у персонажа, для брони и щитов — значение параметра силы, как мы делали это и раньше. Если любая из проверок не удалась, то мы выводим об этом сообщение, чтобы дать понять игроку о не успешности попытки воспользоваться предметом. Если же проверки прошли успешно, то также как и раньше, мы убираем предмет из инвентаря персонажа и помещаем его в слот для используемых предметов.
Теперь у нас уже есть оружие и мы можем использовать его в игре. Следующее что нам нужно сделать, это добавить некоторое количество монстров, и мы будем готовы сражаться с обитателями Подземелья Судьбы.
Такое впечатление, что статьи как будто писались на русском. Отличный перевод. Спасибо.
ОтветитьУдалитьприятно видеть что это кому то полезно, да еще и нравиться перевод (мне просто книга понравилась и я, в основном, для себя захотел перевести). и это учитывая то, что не учил английский ни в школе. ни в универе. методом тыка пришлось выучить. сейчас вот работаю в компании, где ни одного русскоязычного человека нет. только арабский и английский (и то - не все английский знают), так что приходится на английском шпрехать, иногда вставляя слова на арабском :).
ОтветитьУдалить