mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-20 23:47:16 -05:00
Feature/player equipment ui (#419)
* Add basic EquipmentSlot struct * Add Load function to EquipmentSlot * Move EquipmentSlot struct to inventory_grid.go * Add equipmentSlots arg to ItemGrid struct * Add basic rendering of equipment slots. * Change rendering of equipment slots to simply use their static x and y * Add ChangeEquippedSlot function * Add initialization to all equipped slots types. * Fix Y locations of equipment slots * Move default equipment slots to a genEquipmentSlotsMap function. * Change Item to item * Fix coordinates * Change usage of string to EquippedSlotType when dealing with different slots in rendering. * Fix import error * Remove neck example * Add loading sprites of equipped items. * Clean code in Inventory rendering * Clean code in Inventory rendering * Clean code in Inventory rendering * Change default items that get rendered. * Change default items that get rendered. * Add width and height to EquipementSlot struct * Fill in width and height to current equipment slots. * Fix Y setting of equipment slots * Rename variables for clean code. * Change handling nil itemSprite to condition instead of loop return. * Split Render function to 2 functions. * Add TODO * Change comment to start with capital I
This commit is contained in:
parent
b640385623
commit
2332bd7b58
16
d2common/d2enum/equipped_slot_type.go
Normal file
16
d2common/d2enum/equipped_slot_type.go
Normal file
@ -0,0 +1,16 @@
|
||||
package d2enum
|
||||
|
||||
type EquippedSlotType int
|
||||
|
||||
const (
|
||||
Head EquippedSlotType = 1
|
||||
Torso EquippedSlotType = 2
|
||||
Legs EquippedSlotType = 3
|
||||
RightArm EquippedSlotType = 4
|
||||
LeftArm EquippedSlotType = 5
|
||||
LeftHand EquippedSlotType = 6
|
||||
RightHand EquippedSlotType = 7
|
||||
Neck EquippedSlotType = 8
|
||||
Belt EquippedSlotType = 9
|
||||
Gloves EquippedSlotType = 10
|
||||
)
|
86
d2game/d2player/equipment_slot.go
Normal file
86
d2game/d2player/equipment_slot.go
Normal file
@ -0,0 +1,86 @@
|
||||
package d2player
|
||||
|
||||
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
|
||||
type EquipmentSlot struct {
|
||||
item InventoryItem
|
||||
x int
|
||||
y int
|
||||
width int
|
||||
height int
|
||||
}
|
||||
|
||||
func genEquipmentSlotsMap() map[d2enum.EquippedSlotType]EquipmentSlot {
|
||||
return map[d2enum.EquippedSlotType]EquipmentSlot{
|
||||
d2enum.LeftArm: {
|
||||
item: nil,
|
||||
x: 418,
|
||||
y: 224,
|
||||
width: 61,
|
||||
height: 116,
|
||||
},
|
||||
d2enum.RightArm: {
|
||||
item: nil,
|
||||
x: 648,
|
||||
y: 224,
|
||||
width: 61,
|
||||
height: 116,
|
||||
},
|
||||
d2enum.Head: {
|
||||
item: nil,
|
||||
x: 532,
|
||||
y: 125,
|
||||
width: 62,
|
||||
height: 62,
|
||||
},
|
||||
d2enum.Neck: {
|
||||
item: nil,
|
||||
x: 604,
|
||||
y: 125,
|
||||
width: 32,
|
||||
height: 32,
|
||||
},
|
||||
d2enum.Torso: {
|
||||
item: nil,
|
||||
x: 532,
|
||||
y: 224,
|
||||
width: 62,
|
||||
height: 90,
|
||||
},
|
||||
d2enum.Belt: {
|
||||
item: nil,
|
||||
x: 533,
|
||||
y: 269,
|
||||
width: 62,
|
||||
height: 32,
|
||||
},
|
||||
d2enum.LeftHand: {
|
||||
item: nil,
|
||||
x: 491,
|
||||
y: 268,
|
||||
width: 32,
|
||||
height: 32,
|
||||
},
|
||||
d2enum.RightHand: {
|
||||
item: nil,
|
||||
x: 606,
|
||||
y: 268,
|
||||
width: 32,
|
||||
height: 32,
|
||||
},
|
||||
d2enum.Gloves: {
|
||||
item: nil,
|
||||
x: 417,
|
||||
y: 299,
|
||||
width: 62,
|
||||
height: 62,
|
||||
},
|
||||
d2enum.Legs: {
|
||||
item: nil,
|
||||
x: 648,
|
||||
y: 299,
|
||||
width: 62,
|
||||
height: 62,
|
||||
},
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package d2player
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2inventory"
|
||||
@ -49,14 +50,22 @@ func (g *Inventory) Load() {
|
||||
|
||||
animation, _ = d2asset.LoadAnimation(d2resource.InventoryCharacterPanel, d2resource.PaletteSky)
|
||||
g.panel, _ = d2ui.LoadSprite(animation)
|
||||
|
||||
items := []InventoryItem{
|
||||
d2inventory.GetWeaponItemByCode("wnd"),
|
||||
d2inventory.GetWeaponItemByCode("sst"),
|
||||
d2inventory.GetWeaponItemByCode("jav"),
|
||||
d2inventory.GetArmorItemByCode("buc"),
|
||||
d2inventory.GetWeaponItemByCode("clb"),
|
||||
// TODO: Load the player's actual items
|
||||
}
|
||||
g.grid.ChangeEquippedSlot(d2enum.LeftArm, d2inventory.GetWeaponItemByCode("wnd"))
|
||||
g.grid.ChangeEquippedSlot(d2enum.RightArm, d2inventory.GetArmorItemByCode("buc"))
|
||||
g.grid.ChangeEquippedSlot(d2enum.Head, d2inventory.GetArmorItemByCode("crn"))
|
||||
g.grid.ChangeEquippedSlot(d2enum.Torso, d2inventory.GetArmorItemByCode("plt"))
|
||||
g.grid.ChangeEquippedSlot(d2enum.Legs, d2inventory.GetArmorItemByCode("vbt"))
|
||||
g.grid.ChangeEquippedSlot(d2enum.Belt, d2inventory.GetArmorItemByCode("vbl"))
|
||||
g.grid.ChangeEquippedSlot(d2enum.Gloves, d2inventory.GetArmorItemByCode("lgl"))
|
||||
// TODO: Load the player's actual items
|
||||
g.grid.Add(items...)
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package d2player
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
@ -24,23 +25,25 @@ var ErrorInventoryFull = errors.New("inventory full")
|
||||
// Reusable grid for use with player and merchant inventory.
|
||||
// Handles layout and rendering item icons based on code.
|
||||
type ItemGrid struct {
|
||||
items []InventoryItem
|
||||
width int
|
||||
height int
|
||||
originX int
|
||||
originY int
|
||||
sprites map[string]*d2ui.Sprite
|
||||
slotSize int
|
||||
items []InventoryItem
|
||||
equipmentSlots map[d2enum.EquippedSlotType]EquipmentSlot
|
||||
width int
|
||||
height int
|
||||
originX int
|
||||
originY int
|
||||
sprites map[string]*d2ui.Sprite
|
||||
slotSize int
|
||||
}
|
||||
|
||||
func NewItemGrid(width int, height int, originX int, originY int) *ItemGrid {
|
||||
return &ItemGrid{
|
||||
width: width,
|
||||
height: height,
|
||||
originX: originX,
|
||||
originY: originY,
|
||||
slotSize: 29,
|
||||
sprites: make(map[string]*d2ui.Sprite),
|
||||
width: width,
|
||||
height: height,
|
||||
originX: originX,
|
||||
originY: originY,
|
||||
slotSize: 29,
|
||||
sprites: make(map[string]*d2ui.Sprite),
|
||||
equipmentSlots: genEquipmentSlotsMap(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +72,12 @@ func (g *ItemGrid) GetSlot(x int, y int) InventoryItem {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *ItemGrid) ChangeEquippedSlot(slot d2enum.EquippedSlotType, item InventoryItem) {
|
||||
var curItem = g.equipmentSlots[slot]
|
||||
curItem.item = item
|
||||
g.equipmentSlots[slot] = curItem
|
||||
}
|
||||
|
||||
// Add places a given set of items into the first available slots.
|
||||
// Returns a count of the number of items which could be inserted.
|
||||
func (g *ItemGrid) Add(items ...InventoryItem) (int, error) {
|
||||
@ -89,15 +98,9 @@ func (g *ItemGrid) Add(items ...InventoryItem) (int, error) {
|
||||
return added, err
|
||||
}
|
||||
|
||||
// Load reads the inventory sprites for items into local cache for rendering.
|
||||
func (g *ItemGrid) Load(items ...InventoryItem) {
|
||||
var itemSprite *d2ui.Sprite
|
||||
|
||||
for _, item := range items {
|
||||
if _, exists := g.sprites[item.GetItemCode()]; exists {
|
||||
// Already loaded, don't reload.
|
||||
continue
|
||||
}
|
||||
func (g *ItemGrid) loadItem(item InventoryItem) {
|
||||
if _, exists := g.sprites[item.GetItemCode()]; !exists {
|
||||
var itemSprite *d2ui.Sprite
|
||||
|
||||
// TODO: Put the pattern into D2Shared
|
||||
animation, err := d2asset.LoadAnimation(
|
||||
@ -106,13 +109,26 @@ func (g *ItemGrid) Load(items ...InventoryItem) {
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("failed to load sprite for item (%s): %v", item.GetItemCode(), err)
|
||||
continue
|
||||
return
|
||||
}
|
||||
itemSprite, err = d2ui.LoadSprite(animation)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Failed to load sprite, error: " + err.Error())
|
||||
}
|
||||
g.sprites[item.GetItemCode()] = itemSprite
|
||||
}
|
||||
}
|
||||
|
||||
// Load reads the inventory sprites for items into local cache for rendering.
|
||||
func (g *ItemGrid) Load(items ...InventoryItem) {
|
||||
for _, item := range items {
|
||||
g.loadItem(item)
|
||||
}
|
||||
for _, eq := range g.equipmentSlots {
|
||||
if eq.item != nil {
|
||||
g.loadItem(eq.item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Walk from top left to bottom right until a position large enough to hold the item is found.
|
||||
@ -183,23 +199,38 @@ func (g *ItemGrid) Remove(item InventoryItem) {
|
||||
g.items = g.items[:n]
|
||||
}
|
||||
|
||||
func (g *ItemGrid) Render(target d2render.Surface) {
|
||||
for _, item := range g.items {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
itemSprite := g.sprites[item.GetItemCode()]
|
||||
if itemSprite == nil {
|
||||
// In case it failed to load.
|
||||
// TODO: fallback to something
|
||||
continue
|
||||
}
|
||||
|
||||
slotX, slotY := g.SlotToScreen(item.InventoryGridSlot())
|
||||
_, h := itemSprite.GetCurrentFrameSize()
|
||||
itemSprite.SetPosition(slotX, slotY+h)
|
||||
func (g *ItemGrid) renderItem(item InventoryItem, target d2render.Surface, x int, y int) {
|
||||
itemSprite := g.sprites[item.GetItemCode()]
|
||||
if itemSprite != nil {
|
||||
itemSprite.SetPosition(x, y)
|
||||
itemSprite.GetCurrentFrameSize()
|
||||
_ = itemSprite.Render(target)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ItemGrid) Render(target d2render.Surface) {
|
||||
g.renderInventoryItems(target)
|
||||
g.renderEquippedItems(target)
|
||||
}
|
||||
|
||||
func (g *ItemGrid) renderInventoryItems(target d2render.Surface) {
|
||||
for _, item := range g.items {
|
||||
itemSprite := g.sprites[item.GetItemCode()]
|
||||
slotX, slotY := g.SlotToScreen(item.InventoryGridSlot())
|
||||
_, h := itemSprite.GetCurrentFrameSize()
|
||||
slotY = slotY + h
|
||||
g.renderItem(item, target, slotX, slotY)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ItemGrid) renderEquippedItems(target d2render.Surface) {
|
||||
for _, eq := range g.equipmentSlots {
|
||||
if eq.item != nil {
|
||||
itemSprite := g.sprites[eq.item.GetItemCode()]
|
||||
itemWidth, itemHeight := itemSprite.GetCurrentFrameSize()
|
||||
var x = eq.x + ((eq.width - itemWidth) / 2)
|
||||
var y = eq.y - ((eq.height - itemHeight) / 2)
|
||||
g.renderItem(eq.item, target, x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user