1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-11-04 17:27:16 -05:00

Added support for all object layers. (#127)

This commit is contained in:
Tim Sarbin 2019-11-09 23:37:02 -05:00 committed by GitHub
parent 09e713b1cb
commit 3555578c0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 159 additions and 78 deletions

View File

@ -3,7 +3,6 @@ package common
import ( import (
"fmt" "fmt"
"image" "image"
"math"
"strings" "strings"
"time" "time"
@ -12,18 +11,19 @@ import (
"github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten"
) )
var DccLayerNames = []string{"HD", "TR", "LG", "RA", "LA", "RH", "LH", "SH", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8"}
// AnimatedEntity represents an entity on the map that can be animated // AnimatedEntity represents an entity on the map that can be animated
type AnimatedEntity struct { type AnimatedEntity struct {
// LocationX represents the tile X position of the entity // LocationX represents the tile X position of the entity
LocationX float64 LocationX float64
// LocationY represents the tile Y position of the entity // LocationY represents the tile Y position of the entity
LocationY float64 LocationY float64
dcc *DCC dccLayers map[string]*DCC
cof *Cof Cof *Cof
palette palettedefs.PaletteType palette palettedefs.PaletteType
base string base string
token string token string
tr string
animationMode string animationMode string
weaponClass string weaponClass string
lastFrameTime time.Time lastFrameTime time.Time
@ -31,8 +31,9 @@ type AnimatedEntity struct {
animationSpeed int animationSpeed int
direction int direction int
currentFrame int currentFrame int
frames []*ebiten.Image frames map[string][]*ebiten.Image
frameLocations []Rectangle frameLocations map[string][]Rectangle
object Object
} }
// CreateAnimatedEntity creates an instance of AnimatedEntity // CreateAnimatedEntity creates an instance of AnimatedEntity
@ -40,11 +41,12 @@ func CreateAnimatedEntity(object Object, fileProvider FileProvider, palette pale
result := &AnimatedEntity{ result := &AnimatedEntity{
base: object.Lookup.Base, base: object.Lookup.Base,
token: object.Lookup.Token, token: object.Lookup.Token,
tr: object.Lookup.TR, object: object,
palette: palette, palette: palette,
} }
result.LocationX = math.Floor(float64(object.X) / 5) result.dccLayers = make(map[string]*DCC)
result.LocationY = math.Floor(float64(object.Y) / 5) result.LocationX = float64(object.X) / 5
result.LocationY = float64(object.Y) / 5
return result return result
} }
@ -53,14 +55,69 @@ var DirectionLookup = []int{3, 15, 4, 8, 0, 9, 5, 10, 1, 11, 6, 12, 2, 13, 7, 14
// SetMode changes the graphical mode of this animated entity // SetMode changes the graphical mode of this animated entity
func (v *AnimatedEntity) SetMode(animationMode, weaponClass string, direction int, provider FileProvider) { func (v *AnimatedEntity) SetMode(animationMode, weaponClass string, direction int, provider FileProvider) {
dccPath := fmt.Sprintf("%s/%s/tr/%str%s%s%s.dcc", v.base, v.token, v.token, v.tr, animationMode, weaponClass) cofPath := fmt.Sprintf("%s/%s/Cof/%s%s%s.Cof", v.base, v.token, v.token, animationMode, weaponClass)
v.dcc = LoadDCC(dccPath, provider) v.Cof = LoadCof(cofPath, provider)
cofPath := fmt.Sprintf("%s/%s/cof/%s%s%s.cof", v.base, v.token, v.token, animationMode, weaponClass)
v.cof = LoadCof(cofPath, provider)
v.animationMode = animationMode v.animationMode = animationMode
v.weaponClass = weaponClass v.weaponClass = weaponClass
v.direction = direction v.direction = direction
v.cacheFrames() if v.direction >= v.Cof.NumberOfDirections {
v.direction = v.Cof.NumberOfDirections - 1
}
v.frames = make(map[string][]*ebiten.Image)
v.frameLocations = make(map[string][]Rectangle)
v.dccLayers = make(map[string]*DCC)
for _, cofLayer := range v.Cof.CofLayers {
layerName := DccLayerNames[cofLayer.Type]
v.dccLayers[layerName] = v.LoadLayer(layerName, provider)
if v.dccLayers[layerName] == nil {
continue
}
v.cacheFrames(layerName)
}
}
func (v *AnimatedEntity) LoadLayer(layer string, fileProvider FileProvider) *DCC {
layerName := "tr"
switch strings.ToUpper(layer) {
case "HD": // Head
layerName = v.object.Lookup.HD
case "TR": // Torso
layerName = v.object.Lookup.TR
case "LG": // Legs
layerName = v.object.Lookup.LG
case "RA": // RightArm
layerName = v.object.Lookup.RA
case "LA": // LeftArm
layerName = v.object.Lookup.LA
case "RH": // RightHand
layerName = v.object.Lookup.RH
case "LH": // LeftHand
layerName = v.object.Lookup.LH
case "SH": // Shield
layerName = v.object.Lookup.SH
case "S1": // Special1
layerName = v.object.Lookup.S1
case "S2": // Special2
layerName = v.object.Lookup.S2
case "S3": // Special3
layerName = v.object.Lookup.S3
case "S4": // Special4
layerName = v.object.Lookup.S4
case "S5": // Special5
layerName = v.object.Lookup.S5
case "S6": // Special6
layerName = v.object.Lookup.S6
case "S7": // Special7
layerName = v.object.Lookup.S7
case "S8": // Special8
layerName = v.object.Lookup.S8
}
if len(layerName) == 0 {
return nil
}
dccPath := fmt.Sprintf("%s/%s/%s/%s%s%s%s%s.dcc", v.base, v.token, layer, v.token, layer, layerName, v.animationMode, v.weaponClass)
return LoadDCC(dccPath, fileProvider)
} }
// Render draws this animated entity onto the target // Render draws this animated entity onto the target
@ -72,23 +129,35 @@ func (v *AnimatedEntity) Render(target *ebiten.Image, offsetX, offsetY int) {
v.currentFrame = 0 v.currentFrame = 0
} }
} }
for idx := 0; idx < v.Cof.NumberOfLayers; idx++ {
opts := &ebiten.DrawImageOptions{} priority := v.Cof.Priority[v.direction][v.currentFrame][idx]
opts.GeoM.Translate(float64(v.frameLocations[v.currentFrame].Left+offsetX), float64(v.frameLocations[v.currentFrame].Top+offsetY+40)) if int(priority) >= len(DccLayerNames) {
target.DrawImage(v.frames[v.currentFrame], opts) continue
}
frameName := DccLayerNames[priority]
if v.frames[frameName] == nil {
continue
}
// TODO: Transparency op maybe, but it'l murder batch calls
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Translate(float64(v.frameLocations[frameName][v.currentFrame].Left+offsetX),
float64(v.frameLocations[frameName][v.currentFrame].Top+offsetY+40))
target.DrawImage(v.frames[frameName][v.currentFrame], opts)
}
} }
func (v *AnimatedEntity) cacheFrames() { func (v *AnimatedEntity) cacheFrames(layerName string) {
dcc := v.dccLayers[layerName]
v.currentFrame = 0 v.currentFrame = 0
animationData := AnimationData[strings.ToLower(v.token+v.animationMode+v.weaponClass)][0] animationData := AnimationData[strings.ToLower(v.token+v.animationMode+v.weaponClass)][0]
v.animationSpeed = int(1000.0 / ((float64(animationData.AnimationSpeed) * 25.0) / 256.0)) v.animationSpeed = int(1000.0 / ((float64(animationData.AnimationSpeed) * 25.0) / 256.0))
v.framesToAnimate = animationData.FramesPerDirection v.framesToAnimate = animationData.FramesPerDirection
v.lastFrameTime = time.Now() v.lastFrameTime = time.Now()
minX := int32(2147483647) minX := int32(10000)
minY := int32(2147483647) minY := int32(10000)
maxX := int32(-2147483648) maxX := int32(-10000)
maxY := int32(-2147483648) maxY := int32(-10000)
for _, layer := range v.dcc.Directions { for _, layer := range dcc.Directions {
minX = MinInt32(minX, int32(layer.Box.Left)) minX = MinInt32(minX, int32(layer.Box.Left))
minY = MinInt32(minY, int32(layer.Box.Top)) minY = MinInt32(minY, int32(layer.Box.Top))
maxX = MaxInt32(maxX, int32(layer.Box.Right())) maxX = MaxInt32(maxX, int32(layer.Box.Right()))
@ -96,17 +165,17 @@ func (v *AnimatedEntity) cacheFrames() {
} }
frameW := maxX - minX frameW := maxX - minX
frameH := maxY - minY frameH := maxY - minY
v.frames = make([]*ebiten.Image, v.framesToAnimate) v.frames[layerName] = make([]*ebiten.Image, v.framesToAnimate)
v.frameLocations = make([]Rectangle, v.framesToAnimate) v.frameLocations[layerName] = make([]Rectangle, v.framesToAnimate)
for frameIndex := range v.frames { for frameIndex := range v.frames[layerName] {
v.frames[frameIndex], _ = ebiten.NewImage(int(frameW), int(frameH), ebiten.FilterNearest) v.frames[layerName][frameIndex], _ = ebiten.NewImage(int(frameW), int(frameH), ebiten.FilterNearest)
priorityBase := (v.direction * animationData.FramesPerDirection * v.cof.NumberOfLayers) + (frameIndex * v.cof.NumberOfLayers) for layerIdx := 0; layerIdx < v.Cof.NumberOfLayers; layerIdx++ {
for layerIdx := 0; layerIdx < v.cof.NumberOfLayers; layerIdx++ { transparency := byte(255)
comp := v.cof.Priority[priorityBase+layerIdx] if v.Cof.CofLayers[layerIdx].Transparent {
if _, found := v.cof.CompositeLayers[comp]; !found { transparency = byte(128)
continue
} }
direction := v.dcc.Directions[v.direction]
direction := dcc.Directions[v.direction]
frame := direction.Frames[frameIndex] frame := direction.Frames[frameIndex]
img := image.NewRGBA(image.Rect(0, 0, int(frameW), int(frameH))) img := image.NewRGBA(image.Rect(0, 0, int(frameW), int(frameH)))
for y := 0; y < direction.Box.Height; y++ { for y := 0; y < direction.Box.Height; y++ {
@ -122,13 +191,13 @@ func (v *AnimatedEntity) cacheFrames() {
img.Pix[(actualX*4)+(actualY*int(frameW)*4)] = color.R img.Pix[(actualX*4)+(actualY*int(frameW)*4)] = color.R
img.Pix[(actualX*4)+(actualY*int(frameW)*4)+1] = color.G img.Pix[(actualX*4)+(actualY*int(frameW)*4)+1] = color.G
img.Pix[(actualX*4)+(actualY*int(frameW)*4)+2] = color.B img.Pix[(actualX*4)+(actualY*int(frameW)*4)+2] = color.B
img.Pix[(actualX*4)+(actualY*int(frameW)*4)+3] = 255 img.Pix[(actualX*4)+(actualY*int(frameW)*4)+3] = transparency
} }
} }
newImage, _ := ebiten.NewImageFromImage(img, ebiten.FilterNearest) newImage, _ := ebiten.NewImageFromImage(img, ebiten.FilterNearest)
img = nil img = nil
v.frames[frameIndex] = newImage v.frames[layerName][frameIndex] = newImage
v.frameLocations[frameIndex] = Rectangle{ v.frameLocations[layerName][frameIndex] = Rectangle{
Left: int(minX), Left: int(minX),
Top: int(minY), Top: int(minY),
Width: int(frameW), Width: int(frameW),

View File

@ -31,6 +31,7 @@ func (v *BitMuncher) GetBit() uint32 {
func (v *BitMuncher) SkipBits(bits int) { func (v *BitMuncher) SkipBits(bits int) {
v.Offset += bits v.Offset += bits
v.BitsRead += bits
} }
func (v *BitMuncher) GetByte() byte { func (v *BitMuncher) GetByte() byte {

View File

@ -204,7 +204,7 @@ type Cof struct {
CofLayers []*CofLayer CofLayers []*CofLayer
CompositeLayers map[CompositeType]int CompositeLayers map[CompositeType]int
AnimationFrames []AnimationFrame AnimationFrames []AnimationFrame
Priority []CompositeType Priority [][][]CompositeType
} }
func LoadCof(fileName string, fileProvider FileProvider) *Cof { func LoadCof(fileName string, fileProvider FileProvider) *Cof {
@ -235,10 +235,16 @@ func LoadCof(fileName string, fileProvider FileProvider) *Cof {
result.AnimationFrames[i] = AnimationFrame(animationFrameBytes[i]) result.AnimationFrames[i] = AnimationFrame(animationFrameBytes[i])
} }
priorityLen := result.FramesPerDirection * result.NumberOfDirections * result.NumberOfLayers priorityLen := result.FramesPerDirection * result.NumberOfDirections * result.NumberOfLayers
result.Priority = make([]CompositeType, priorityLen) result.Priority = make([][][]CompositeType, result.NumberOfDirections)
priorityBytes, _ := streamReader.ReadBytes(priorityLen) priorityBytes, _ := streamReader.ReadBytes(priorityLen)
for i := range priorityBytes { for direction := 0; direction < result.NumberOfDirections; direction++ {
result.Priority[i] = CompositeType(priorityBytes[i]) result.Priority[direction] = make([][]CompositeType, result.FramesPerDirection)
for frame := 0; frame < result.FramesPerDirection; frame++ {
result.Priority[direction][frame] = make([]CompositeType, result.NumberOfLayers)
for i := 0; i < result.NumberOfLayers; i++ {
result.Priority[direction][frame][i] = CompositeType(priorityBytes[i])
}
}
} }
return result return result
} }

View File

@ -2,7 +2,6 @@ package common
import ( import (
"log" "log"
"sync"
) )
type DCCPixelBufferEntry struct { type DCCPixelBufferEntry struct {
@ -52,7 +51,7 @@ type DCCDirection struct {
EncodingTypeBitsreamSize int EncodingTypeBitsreamSize int
RawPixelCodesBitstreamSize int RawPixelCodesBitstreamSize int
Frames []*DCCDirectionFrame Frames []*DCCDirectionFrame
PaletteEntries []byte PaletteEntries [256]byte
Box Rectangle Box Rectangle
Cells []*DCCCell Cells []*DCCCell
PixelData []byte PixelData []byte
@ -71,6 +70,11 @@ type DCC struct {
var crazyBitTable = []byte{0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 26, 28, 30, 32} var crazyBitTable = []byte{0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 26, 28, 30, 32}
var pixelMaskLookup = []int{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4} var pixelMaskLookup = []int{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}
var dccDir4 = []byte{0, 1, 2, 3}
var dccDir8 = []byte{4, 0, 5, 1, 6, 2, 7, 3}
var dccDir16 = []byte{4, 8, 0, 9, 5, 10, 1, 11, 6, 12, 2, 13, 7, 14, 3, 15}
var dccDir32 = []byte{4, 16, 8, 17, 0, 18, 9, 19, 5, 20, 10, 21, 1, 22, 11, 23,
6, 24, 12, 25, 2, 26, 13, 27, 7, 28, 14, 29, 3, 30, 15, 31}
func CreateDCCDirectionFrame(bits *BitMuncher, direction *DCCDirection) *DCCDirectionFrame { func CreateDCCDirectionFrame(bits *BitMuncher, direction *DCCDirection) *DCCDirectionFrame {
result := &DCCDirectionFrame{} result := &DCCDirectionFrame{}
@ -82,11 +86,15 @@ func CreateDCCDirectionFrame(bits *BitMuncher, direction *DCCDirection) *DCCDire
result.NumberOfOptionalBytes = int(bits.GetBits(direction.OptionalDataBits)) result.NumberOfOptionalBytes = int(bits.GetBits(direction.OptionalDataBits))
result.NumberOfCodedBytes = int(bits.GetBits(direction.CodedBytesBits)) result.NumberOfCodedBytes = int(bits.GetBits(direction.CodedBytesBits))
result.FrameIsBottomUp = bits.GetBit() == 1 result.FrameIsBottomUp = bits.GetBit() == 1
result.Box = Rectangle{ if result.FrameIsBottomUp {
result.XOffset, log.Panic("Bottom up frames are not implemented.")
result.YOffset - result.Height - 1, } else {
result.Width, result.Box = Rectangle{
result.Height, result.XOffset,
result.YOffset - result.Height + 1,
result.Width,
result.Height,
}
} }
return result return result
} }
@ -164,10 +172,10 @@ func CreateDCCDirection(bm *BitMuncher, file *DCC) *DCCDirection {
result.OptionalDataBits = int(crazyBitTable[bm.GetBits(4)]) result.OptionalDataBits = int(crazyBitTable[bm.GetBits(4)])
result.CodedBytesBits = int(crazyBitTable[bm.GetBits(4)]) result.CodedBytesBits = int(crazyBitTable[bm.GetBits(4)])
result.Frames = make([]*DCCDirectionFrame, file.FramesPerDirection) result.Frames = make([]*DCCDirectionFrame, file.FramesPerDirection)
minx := 9223372036854775807 minx := 100000
miny := 9223372036854775807 miny := 100000
maxx := -9223372036854775808 maxx := -100000
maxy := -9223372036854775808 maxy := -100000
// Load the frame headers // Load the frame headers
for frameIdx := 0; frameIdx < file.FramesPerDirection; frameIdx++ { for frameIdx := 0; frameIdx < file.FramesPerDirection; frameIdx++ {
result.Frames[frameIdx] = CreateDCCDirectionFrame(bm, result) result.Frames[frameIdx] = CreateDCCDirectionFrame(bm, result)
@ -176,7 +184,7 @@ func CreateDCCDirection(bm *BitMuncher, file *DCC) *DCCDirection {
maxx = int(MaxInt32(int32(result.Frames[frameIdx].Box.Right()), int32(maxx))) maxx = int(MaxInt32(int32(result.Frames[frameIdx].Box.Right()), int32(maxx)))
maxy = int(MaxInt32(int32(result.Frames[frameIdx].Box.Bottom()), int32(maxy))) maxy = int(MaxInt32(int32(result.Frames[frameIdx].Box.Bottom()), int32(maxy)))
} }
result.Box = Rectangle{minx, miny, maxx - minx, maxy - miny} result.Box = Rectangle{minx, miny, (maxx - minx), (maxy - miny)}
if result.OptionalDataBits > 0 { if result.OptionalDataBits > 0 {
log.Panic("Optional bits in DCC data is not currently supported.") log.Panic("Optional bits in DCC data is not currently supported.")
} }
@ -189,24 +197,14 @@ func CreateDCCDirection(bm *BitMuncher, file *DCC) *DCCDirection {
result.RawPixelCodesBitstreamSize = int(bm.GetBits(20)) result.RawPixelCodesBitstreamSize = int(bm.GetBits(20))
} }
// PixelValuesKey // PixelValuesKey
paletteEntries := make([]bool, 0)
paletteEntryCount := 0 paletteEntryCount := 0
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
valid := bm.GetBit() != 0 valid := bm.GetBit() != 0
paletteEntries = append(paletteEntries, valid)
if valid { if valid {
result.PaletteEntries[paletteEntryCount] = byte(i)
paletteEntryCount++ paletteEntryCount++
} }
} }
result.PaletteEntries = make([]byte, paletteEntryCount)
paletteOffset := 0
for i := 0; i < 256; i++ {
if !paletteEntries[i] {
continue
}
result.PaletteEntries[paletteOffset] = byte(i)
paletteOffset++
}
// HERE BE GIANTS: // HERE BE GIANTS:
// Because of the way this thing mashes bits together, BIT offset matters // Because of the way this thing mashes bits together, BIT offset matters
// here. For example, if you are on byte offset 3, bit offset 6, and // here. For example, if you are on byte offset 3, bit offset 6, and
@ -343,10 +341,12 @@ func (v *DCCDirection) GenerateFrames(pcd *BitMuncher) {
func (v *DCCDirection) FillPixelBuffer(pcd, ec, pm, et, rp *BitMuncher) { func (v *DCCDirection) FillPixelBuffer(pcd, ec, pm, et, rp *BitMuncher) {
lastPixel := uint32(0) lastPixel := uint32(0)
pixelStack := make([]uint32, 4)
maxCellX := 0 maxCellX := 0
maxCellY := 0 maxCellY := 0
for _, frame := range v.Frames { for _, frame := range v.Frames {
if frame == nil {
continue
}
maxCellX += frame.HorizontalCellCount maxCellX += frame.HorizontalCellCount
maxCellY += frame.VerticalCellCount maxCellY += frame.VerticalCellCount
} }
@ -366,11 +366,9 @@ func (v *DCCDirection) FillPixelBuffer(pcd, ec, pm, et, rp *BitMuncher) {
frameIndex++ frameIndex++
originCellX := (frame.Box.Left - v.Box.Left) / 4 originCellX := (frame.Box.Left - v.Box.Left) / 4
originCellY := (frame.Box.Top - v.Box.Top) / 4 originCellY := (frame.Box.Top - v.Box.Top) / 4
frameCellIndex := 0
for cellY := 0; cellY < frame.VerticalCellCount; cellY++ { for cellY := 0; cellY < frame.VerticalCellCount; cellY++ {
currentCellY := cellY + originCellY currentCellY := cellY + originCellY
for cellX := 0; cellX < frame.HorizontalCellCount; cellX++ { for cellX := 0; cellX < frame.HorizontalCellCount; cellX++ {
frameCellIndex++
currentCell := originCellX + cellX + (currentCellY * v.HorizontalCellCount) currentCell := originCellX + cellX + (currentCellY * v.HorizontalCellCount)
nextCell := false nextCell := false
tmp := 0 tmp := 0
@ -392,6 +390,7 @@ func (v *DCCDirection) FillPixelBuffer(pcd, ec, pm, et, rp *BitMuncher) {
continue continue
} }
// Decode the pixels // Decode the pixels
var pixelStack [4]uint32
lastPixel = 0 lastPixel = 0
numberOfPixelBits := pixelMaskLookup[pixelMask] numberOfPixelBits := pixelMaskLookup[pixelMask]
encodingType := 0 encodingType := 0
@ -415,7 +414,7 @@ func (v *DCCDirection) FillPixelBuffer(pcd, ec, pm, et, rp *BitMuncher) {
} }
if pixelStack[i] == lastPixel { if pixelStack[i] == lastPixel {
pixelStack[i] = 0 pixelStack[i] = 0
i = numberOfPixelBits // Just break here.... break
} else { } else {
lastPixel = pixelStack[i] lastPixel = pixelStack[i]
decodedPixel++ decodedPixel++
@ -514,15 +513,22 @@ func LoadDCC(path string, fileProvider FileProvider) *DCC {
directionOffsets[i] = int(bm.GetInt32()) directionOffsets[i] = int(bm.GetInt32())
} }
result.Directions = make([]*DCCDirection, result.NumberOfDirections) result.Directions = make([]*DCCDirection, result.NumberOfDirections)
var wg sync.WaitGroup
wg.Add(result.NumberOfDirections)
for i := 0; i < result.NumberOfDirections; i++ { for i := 0; i < result.NumberOfDirections; i++ {
go func(i int) { dir := byte(0)
defer wg.Done() switch result.NumberOfDirections {
result.Directions[i] = CreateDCCDirection(CreateBitMuncher(fileData, directionOffsets[i]*8), result) case 1:
}(i) dir = 0
case 4:
dir = dccDir4[i]
case 8:
dir = dccDir8[i]
case 16:
dir = dccDir16[i]
case 32:
dir = dccDir32[i]
}
result.Directions[dir] = CreateDCCDirection(CreateBitMuncher(fileData, directionOffsets[i]*8), result)
} }
wg.Wait()
return result return result
} }

View File

@ -15,8 +15,7 @@ func CreateNPC(object Object, fileProvider FileProvider) *NPC {
AnimatedEntity: CreateAnimatedEntity(object, fileProvider, palettedefs.Units), AnimatedEntity: CreateAnimatedEntity(object, fileProvider, palettedefs.Units),
Paths: object.Paths, Paths: object.Paths,
} }
result.AnimatedEntity.SetMode(object.Lookup.Mode, object.Lookup.Class, 0, fileProvider) result.AnimatedEntity.SetMode(object.Lookup.Mode, object.Lookup.Class, 1, fileProvider)
return result return result
} }

View File

@ -147,7 +147,7 @@ func (v *Region) loadObjects(fileProvider common.FileProvider) {
npc := common.CreateNPC(object, fileProvider) npc := common.CreateNPC(object, fileProvider)
v.NPCs = append(v.NPCs, npc) v.NPCs = append(v.NPCs, npc)
case common.ObjectTypeItem: case common.ObjectTypeItem:
if object.ObjectInfo == nil || !object.ObjectInfo.Draw || object.Lookup.Base == "" || object.Lookup.Token == "" || object.Lookup.TR == "" { if object.ObjectInfo == nil || !object.ObjectInfo.Draw || object.Lookup.Base == "" || object.Lookup.Token == "" {
return return
} }
entity := common.CreateAnimatedEntity(object, fileProvider, palettedefs.Units) entity := common.CreateAnimatedEntity(object, fileProvider, palettedefs.Units)