Lint fixes for the following packages (#505)

* fixed lint issues of the package d2core/d2inventory

* fixed lint issues of the d2script package

* fixed lint issues of the d2common/d2interface package

* fixed lint issues of the d2common/d2resource package

* fixed lint issues of the d2core/d2term package

* fixed conflict errors
This commit is contained in:
Gürkan Kaymak 2020-07-01 00:04:41 +03:00 committed by GitHub
parent d15221c21c
commit ae6bfb839e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 251 additions and 160 deletions

View File

@ -472,7 +472,7 @@ func (p *App) dumpHeap() {
func (p *App) toggleFullScreen() {
fullscreen := !d2render.IsFullScreen()
d2render.SetFullScreen(fullscreen)
p.terminal.OutputInfo("fullscreen is now: %v", fullscreen)
p.terminal.OutputInfof("fullscreen is now: %v", fullscreen)
}
func (p *App) captureFrame(path string) {
@ -494,19 +494,19 @@ func (p *App) stopAnimationCapture() {
func (p *App) toggleVsync() {
vsync := !d2render.GetVSyncEnabled()
d2render.SetVSyncEnabled(vsync)
p.terminal.OutputInfo("vsync is now: %v", vsync)
p.terminal.OutputInfof("vsync is now: %v", vsync)
}
func (p *App) toggleFpsCounter() {
p.showFPS = !p.showFPS
p.terminal.OutputInfo("fps counter is now: %v", p.showFPS)
p.terminal.OutputInfof("fps counter is now: %v", p.showFPS)
}
func (p *App) setTimeScale(timeScale float64) {
if timeScale <= 0 {
p.terminal.OutputError("invalid time scale value")
p.terminal.OutputErrorf("invalid time scale value")
} else {
p.terminal.OutputInfo("timescale changed from %f to %f", p.timeScale, timeScale)
p.terminal.OutputInfof("timescale changed from %f to %f", p.timeScale, timeScale)
p.timeScale = timeScale
}
}

View File

@ -5,11 +5,11 @@ type Filter int
const (
// FilterDefault represents the default filter.
FilterDefault Filter = 0
FilterDefault Filter = iota
// FilterNearest represents nearest (crisp-edged) filter
FilterNearest = Filter(1)
FilterNearest
// FilterLinear represents linear filter
FilterLinear = Filter(2)
FilterLinear
)

View File

@ -1,8 +1,9 @@
package d2interface
// Defines the type of rendering engine to use
// RenderType defines the type of rendering engine to use
type RenderType int
const (
// Ebiten is the render type of ebiten
Ebiten = RenderType(1)
)

View File

@ -1,5 +1,6 @@
package d2interface
// Renderer interface defines the functionality of a renderer
type Renderer interface {
GetRendererName() string
SetWindowIcon(fileName string)

View File

@ -7,6 +7,7 @@ import (
// TermCategory applies styles to the lines in the Terminal
type TermCategory int
// Terminal Category types
const (
TermCategoryNone TermCategory = iota
TermCategoryInfo
@ -26,10 +27,10 @@ type Terminal interface {
Render(surface Surface) error
Execute(command string) error
OutputRaw(text string, category TermCategory)
Output(format string, params ...interface{})
OutputInfo(format string, params ...interface{})
OutputWarning(format string, params ...interface{})
OutputError(format string, params ...interface{})
Outputf(format string, params ...interface{})
OutputInfof(format string, params ...interface{})
OutputWarningf(format string, params ...interface{})
OutputErrorf(format string, params ...interface{})
OutputClear()
IsVisible() bool
Hide()

View File

@ -1,7 +1,9 @@
// Package d2resource stores the paths of the resources inside the mpq files.
package d2resource
var LanguageCode string
// Paths of the resources inside the mpq files.
const (
// --- Screens ---
@ -11,7 +13,7 @@ const (
TrademarkScreen = "/data/global/ui/FrontEnd/trademarkscreenEXP.dc6"
GameSelectScreen = "/data/global/ui/FrontEnd/gameselectscreenEXP.dc6"
TcpIpBackground = "/data/global/ui/FrontEnd/TCPIPscreen.dc6"
TCPIPBackground = "/data/global/ui/FrontEnd/TCPIPscreen.dc6"
Diablo2LogoFireLeft = "/data/global/ui/FrontEnd/D2logoFireLeft.DC6"
Diablo2LogoFireRight = "/data/global/ui/FrontEnd/D2logoFireRight.DC6"
Diablo2LogoBlackLeft = "/data/global/ui/FrontEnd/D2logoBlackLeft.DC6"
@ -207,6 +209,7 @@ const (
MagicSuffix = "/data/global/excel/MagicSuffix.txt"
// --- Monster Prefix/Suffixes (?) ---
RarePrefix = "/data/global/excel/RarePrefix.txt"
RareSuffix = "/data/global/excel/RareSuffix.txt"
UniquePrefix = "/data/global/excel/UniquePrefix.txt"
@ -278,9 +281,9 @@ const (
// --- Enemy Data ---
MonStats = "/data/global/excel/monstats.txt"
MonStats2 = "/data/global/excel/monstats2.txt"
MonPreset = "/data/global/excel/monpreset.txt"
MonStats = "/data/global/excel/monstats.txt"
MonStats2 = "/data/global/excel/monstats2.txt"
MonPreset = "/data/global/excel/monpreset.txt"
SuperUniques = "/data/global/excel/SuperUniques.txt"
// --- Skill Data ---

View File

@ -38,9 +38,9 @@ func Initialize(term d2interface.Terminal) error {
term.BindAction("assetspam", "display verbose asset manager logs", func(verbose bool) {
if verbose {
term.OutputInfo("asset manager verbose logging enabled")
term.OutputInfof("asset manager verbose logging enabled")
} else {
term.OutputInfo("asset manager verbose logging disabled")
term.OutputInfof("asset manager verbose logging disabled")
}
archiveManager.cache.SetVerbose(verbose)
@ -51,12 +51,12 @@ func Initialize(term d2interface.Terminal) error {
})
term.BindAction("assetstat", "display asset manager cache statistics", func() {
term.OutputInfo("archive cache: %f", float64(archiveManager.cache.GetWeight())/float64(archiveManager.cache.GetBudget())*100.0)
term.OutputInfo("file cache: %f", float64(fileManager.cache.GetWeight())/float64(fileManager.cache.GetBudget())*100.0)
term.OutputInfo("palette cache: %f", float64(paletteManager.cache.GetWeight())/float64(paletteManager.cache.GetBudget())*100.0)
term.OutputInfo("palette transform cache: %f", float64(paletteTransformManager.cache.GetWeight())/float64(paletteTransformManager.cache.GetBudget())*100.0)
term.OutputInfo("animation cache: %f", float64(animationManager.cache.GetWeight())/float64(animationManager.cache.GetBudget())*100.0)
term.OutputInfo("font cache: %f", float64(fontManager.cache.GetWeight())/float64(fontManager.cache.GetBudget())*100.0)
term.OutputInfof("archive cache: %f", float64(archiveManager.cache.GetWeight())/float64(archiveManager.cache.GetBudget())*100.0)
term.OutputInfof("file cache: %f", float64(fileManager.cache.GetWeight())/float64(fileManager.cache.GetBudget())*100.0)
term.OutputInfof("palette cache: %f", float64(paletteManager.cache.GetWeight())/float64(paletteManager.cache.GetBudget())*100.0)
term.OutputInfof("palette transform cache: %f", float64(paletteTransformManager.cache.GetWeight())/float64(paletteTransformManager.cache.GetBudget())*100.0)
term.OutputInfof("animation cache: %f", float64(animationManager.cache.GetWeight())/float64(animationManager.cache.GetBudget())*100.0)
term.OutputInfof("font cache: %f", float64(fontManager.cache.GetWeight())/float64(fontManager.cache.GetBudget())*100.0)
})
term.BindAction("assetclear", "clear asset manager cache", func() {

View File

@ -1,5 +1,6 @@
package d2inventory
// CharacterEquipment stores equipments of a character
type CharacterEquipment struct {
Head *InventoryItemArmor `json:"head"` // Head
Torso *InventoryItemArmor `json:"torso"` // TR

View File

@ -4,8 +4,10 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
)
// HeroObjects map contains the hero type to CharacterEquipments
var HeroObjects map[d2enum.Hero]CharacterEquipment
// LoadHeroObjects loads the equipment objects of the hero
func LoadHeroObjects() {
//Mode: d2enum.AnimationModePlayerNeutral.String(),
//Base: "/data/global/chars",

View File

@ -2,6 +2,7 @@ package d2inventory
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
// InventoryItem defines the functionality of an inventory item
type InventoryItem interface {
// GetInventoryItemName returns the name of this inventory item
GetInventoryItemName() string

View File

@ -7,6 +7,7 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
)
// InventoryItemArmor stores the info of an armor item in the inventory
type InventoryItemArmor struct {
InventorySizeX int `json:"inventorySizeX"`
InventorySizeY int `json:"inventorySizeY"`
@ -17,11 +18,13 @@ type InventoryItemArmor struct {
ArmorClass string `json:"armorClass"`
}
// GetArmorItemByCode returns the armor item for the given code
func GetArmorItemByCode(code string) *InventoryItemArmor {
result := d2datadict.Armors[code]
if result == nil {
log.Fatalf("Could not find armor entry for code '%s'", code)
}
return &InventoryItemArmor{
InventorySizeX: result.InventoryWidth,
InventorySizeY: result.InventoryHeight,
@ -31,13 +34,16 @@ func GetArmorItemByCode(code string) *InventoryItemArmor {
}
}
// GetArmorClass returns the class of the armor
func (v *InventoryItemArmor) GetArmorClass() string {
if v == nil || v.ItemCode == "" {
return "lit"
}
return v.ArmorClass
}
// InventoryItemName returns the name of the armor
func (v *InventoryItemArmor) InventoryItemName() string {
if v == nil {
return ""
@ -46,26 +52,32 @@ func (v *InventoryItemArmor) InventoryItemName() string {
return v.ItemName
}
// InventoryItemType returns the item type of the armor
func (v *InventoryItemArmor) InventoryItemType() d2enum.InventoryItemType {
return d2enum.InventoryItemTypeArmor
}
func (v *InventoryItemArmor) InventoryGridSize() (int, int) {
// InventoryGridSize returns the grid size of the armor
func (v *InventoryItemArmor) InventoryGridSize() (sizeX, sizeY int) {
return v.InventorySizeX, v.InventorySizeY
}
func (v *InventoryItemArmor) InventoryGridSlot() (int, int) {
// InventoryGridSlot returns the grid slot coordinates of the armor
func (v *InventoryItemArmor) InventoryGridSlot() (slotX, slotY int) {
return v.InventorySlotX, v.InventorySlotY
}
func (v *InventoryItemArmor) SetInventoryGridSlot(x int, y int) {
// SetInventoryGridSlot sets the InventorySlotX and InventorySlotY of the armor with the given x and y values
func (v *InventoryItemArmor) SetInventoryGridSlot(x, y int) {
v.InventorySlotX, v.InventorySlotY = x, y
}
// Serialize returns the armor object as a byte array
func (v *InventoryItemArmor) Serialize() []byte {
return []byte{}
}
// GetItemCode returns the item code of the armor
func (v *InventoryItemArmor) GetItemCode() string {
if v == nil {
return ""

View File

@ -1,11 +1,13 @@
package d2inventory
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"log"
)
// InventoryItemMisc stores the info of an miscellaneous item in the inventory
type InventoryItemMisc struct {
InventorySizeX int `json:"inventorySizeX"`
InventorySizeY int `json:"inventorySizeY"`
@ -15,11 +17,13 @@ type InventoryItemMisc struct {
ItemCode string `json:"itemCode"`
}
// GetMiscItemByCode returns the miscellaneous item for the given code
func GetMiscItemByCode(code string) *InventoryItemMisc {
result := d2datadict.MiscItems[code]
if result == nil {
log.Fatalf("Could not find misc item entry for code '%s'", code)
}
return &InventoryItemMisc{
InventorySizeX: result.InventoryWidth,
InventorySizeY: result.InventoryHeight,
@ -28,33 +32,41 @@ func GetMiscItemByCode(code string) *InventoryItemMisc {
}
}
// InventoryItemName returns the name of the miscellaneous item
func (v *InventoryItemMisc) InventoryItemName() string {
if v == nil {
return ""
}
return v.ItemName
}
// InventoryItemType returns the item type of the miscellaneous item
func (v *InventoryItemMisc) InventoryItemType() d2enum.InventoryItemType {
return d2enum.InventoryItemTypeItem
}
func (v *InventoryItemMisc) InventoryGridSize() (int, int) {
// InventoryGridSize returns the grid size of the miscellaneous item
func (v *InventoryItemMisc) InventoryGridSize() (sizeX, sizeY int) {
return v.InventorySizeX, v.InventorySizeY
}
func (v *InventoryItemMisc) InventoryGridSlot() (int, int) {
// InventoryGridSlot returns the grid slot coordinates of the miscellaneous item
func (v *InventoryItemMisc) InventoryGridSlot() (slotX, slotY int) {
return v.InventorySlotX, v.InventorySlotY
}
func (v *InventoryItemMisc) SetInventoryGridSlot(x int, y int) {
// SetInventoryGridSlot sets the InventorySlotX and InventorySlotY of the miscellaneous item with the given x and y values
func (v *InventoryItemMisc) SetInventoryGridSlot(x, y int) {
v.InventorySlotX, v.InventorySlotY = x, y
}
// Serialize returns the miscellaneous item object as a byte array
func (v *InventoryItemMisc) Serialize() []byte {
return []byte{}
}
// GetItemCode returns the item code of the miscellaneous item
func (v *InventoryItemMisc) GetItemCode() string {
if v == nil {
return ""

View File

@ -7,6 +7,7 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
)
// InventoryItemWeapon stores the info of an weapon item in the inventory
type InventoryItemWeapon struct {
InventorySizeX int `json:"inventorySizeX"`
InventorySizeY int `json:"inventorySizeY"`
@ -18,12 +19,14 @@ type InventoryItemWeapon struct {
WeaponClassOffHand string `json:"weaponClassOffHand"`
}
// GetWeaponItemByCode returns the weapon item for the given code
func GetWeaponItemByCode(code string) *InventoryItemWeapon {
// TODO: Non-normal codes will fail here...
result := d2datadict.Weapons[code]
if result == nil {
log.Fatalf("Could not find weapon entry for code '%s'", code)
}
return &InventoryItemWeapon{
InventorySizeX: result.InventoryWidth,
InventorySizeY: result.InventoryHeight,
@ -34,50 +37,63 @@ func GetWeaponItemByCode(code string) *InventoryItemWeapon {
}
}
// GetWeaponClass returns the class of the weapon
func (v *InventoryItemWeapon) GetWeaponClass() string {
if v == nil || v.ItemCode == "" {
return "hth"
}
return v.WeaponClass
}
// GetWeaponClassOffHand returns the class of the off hand weapon
func (v *InventoryItemWeapon) GetWeaponClassOffHand() string {
if v == nil || v.ItemCode == "" {
return ""
}
return v.WeaponClassOffHand
}
// InventoryItemName returns the name of the weapon
func (v *InventoryItemWeapon) InventoryItemName() string {
if v == nil {
return ""
}
return v.ItemName
}
// InventoryItemType returns the item type of the weapon
func (v *InventoryItemWeapon) InventoryItemType() d2enum.InventoryItemType {
return d2enum.InventoryItemTypeWeapon
}
func (v *InventoryItemWeapon) InventoryGridSize() (int, int) {
// InventoryGridSize returns the grid size of the weapon
func (v *InventoryItemWeapon) InventoryGridSize() (sizeX, sizeY int) {
return v.InventorySizeX, v.InventorySizeY
}
func (v *InventoryItemWeapon) InventoryGridSlot() (int, int) {
// InventoryGridSlot returns the grid slot coordinates of the weapon
func (v *InventoryItemWeapon) InventoryGridSlot() (slotX, slotY int) {
return v.InventorySlotX, v.InventorySlotY
}
func (v *InventoryItemWeapon) SetInventoryGridSlot(x int, y int) {
// SetInventoryGridSlot sets the InventorySlotX and InventorySlotY of the weapon with the given x and y values
func (v *InventoryItemWeapon) SetInventoryGridSlot(x, y int) {
v.InventorySlotX, v.InventorySlotY = x, y
}
// Serialize returns the weapon object as a byte array
func (v *InventoryItemWeapon) Serialize() []byte {
return []byte{}
}
// GetItemCode returns the item code of the weapon
func (v *InventoryItemWeapon) GetItemCode() string {
if v == nil {
return ""
}
return v.ItemCode
}

View File

@ -1,11 +1,12 @@
package d2term
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
)
func Initialize() (*terminal, error) {
// Initialize creates and initializes the terminal
func Initialize() (d2interface.Terminal, error) {
term, err := createTerminal()
if err != nil {
return nil, err

View File

@ -17,8 +17,10 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
)
// TermCategory applies styles to the lines in the Terminal
type TermCategory d2interface.TermCategory
// Terminal Category types
const (
TermCategoryNone = TermCategory(d2interface.TermCategoryNone)
TermCategoryInfo = TermCategory(d2interface.TermCategoryInfo)
@ -43,15 +45,7 @@ const (
termVisHiding
)
var (
termBgColor = color.RGBA{R: 0x2e, G: 0x34, B: 0x36, A: 0xb0}
termFgColor = color.RGBA{R: 0x55, G: 0x57, B: 0x53, A: 0xb0}
termInfoColor = color.RGBA{R: 0x34, G: 0x65, B: 0xa4, A: 0xb0}
termWarningColor = color.RGBA{R: 0xfc, G: 0xe9, B: 0x4f, A: 0xb0}
termErrorColor = color.RGBA{R: 0xcc, A: 0xb0}
)
type termHistroyEntry struct {
type termHistoryEntry struct {
text string
category d2interface.TermCategory
}
@ -62,7 +56,7 @@ type termActionEntry struct {
}
type terminal struct {
outputHistory []termHistroyEntry
outputHistory []termHistoryEntry
outputIndex int
command string
@ -73,6 +67,12 @@ type terminal struct {
visState termVis
visAnim float64
bgColor color.RGBA
fgColor color.RGBA
infoColor color.RGBA
warningColor color.RGBA
errorColor color.RGBA
actions map[string]termActionEntry
}
@ -98,108 +98,102 @@ func (t *terminal) Advance(elapsed float64) error {
}
func (t *terminal) OnKeyDown(event d2input.KeyEvent) bool {
if t.visState == termVisHiding || t.visState == termVisHidden && event.Key == d2input.KeyGraveAccent {
t.Show()
return true
if event.Key == d2input.KeyGraveAccent {
t.toggleTerminal()
}
if !t.IsVisible() {
return false
}
if event.Key == d2input.KeyGraveAccent {
t.Hide()
return true
}
if event.Key == d2input.KeyEscape {
switch event.Key {
case d2input.KeyEscape:
t.command = ""
return true
}
maxoutputIndex := d2common.MaxInt(0, len(t.outputHistory)-t.lineCount)
if event.Key == d2input.KeyHome {
t.outputIndex = maxoutputIndex
return true
}
if event.Key == d2input.KeyEnd {
case d2input.KeyEnd:
t.outputIndex = 0
return true
}
if event.Key == d2input.KeyPageUp {
if t.outputIndex += t.lineCount; t.outputIndex >= maxoutputIndex {
t.outputIndex = maxoutputIndex
case d2input.KeyHome:
t.outputIndex = d2common.MaxInt(0, len(t.outputHistory)-t.lineCount)
case d2input.KeyPageUp:
maxOutputIndex := d2common.MaxInt(0, len(t.outputHistory)-t.lineCount)
if t.outputIndex += t.lineCount; t.outputIndex >= maxOutputIndex {
t.outputIndex = maxOutputIndex
}
return true
}
if event.Key == d2input.KeyPageDown {
case d2input.KeyPageDown:
if t.outputIndex -= t.lineCount; t.outputIndex < 0 {
t.outputIndex = 0
}
return true
}
if event.Key == d2input.KeyUp {
case d2input.KeyUp:
t.handleKeyUp(event.KeyMod)
case d2input.KeyDown:
if event.KeyMod == d2input.KeyModControl {
t.lineCount = d2common.MaxInt(0, t.lineCount-1)
} else if len(t.commandHistory) > 0 {
t.command = t.commandHistory[t.commandIndex]
if t.commandIndex == 0 {
t.commandIndex = len(t.commandHistory) - 1
} else {
t.commandIndex--
}
t.lineCount = d2common.MinInt(t.lineCount+1, termRowCountMax)
}
return true
}
if event.Key == d2input.KeyDown && event.KeyMod == d2input.KeyModControl {
t.lineCount = d2common.MinInt(t.lineCount+1, termRowCountMax)
return true
}
if event.Key == d2input.KeyEnter && len(t.command) > 0 {
var commandHistory []string
for _, command := range t.commandHistory {
if command != t.command {
commandHistory = append(commandHistory, command)
}
case d2input.KeyEnter:
t.processCommand()
case d2input.KeyBackspace:
if len(t.command) > 0 {
t.command = t.command[:len(t.command)-1]
}
t.commandHistory = append(commandHistory, t.command)
t.Output(t.command)
if err := t.Execute(t.command); err != nil {
t.OutputError(err.Error())
}
t.commandIndex = len(t.commandHistory) - 1
t.command = ""
return true
}
if event.Key == d2input.KeyBackspace && len(t.command) > 0 {
t.command = t.command[:len(t.command)-1]
return true
}
return true
}
func (t *terminal) processCommand() {
if t.command == "" {
return
}
n := 0
for _, command := range t.commandHistory {
if command != t.command {
t.commandHistory[n] = command
n++
}
}
t.commandHistory = t.commandHistory[:n]
t.commandHistory = append(t.commandHistory, t.command)
t.Outputf(t.command)
if err := t.Execute(t.command); err != nil {
t.OutputErrorf(err.Error())
}
t.commandIndex = len(t.commandHistory) - 1
t.command = ""
}
func (t *terminal) handleKeyUp(keyMod d2input.KeyMod) {
if keyMod == d2input.KeyModControl {
t.lineCount = d2common.MaxInt(0, t.lineCount-1)
} else if len(t.commandHistory) > 0 {
t.command = t.commandHistory[t.commandIndex]
if t.commandIndex == 0 {
t.commandIndex = len(t.commandHistory) - 1
} else {
t.commandIndex--
}
}
}
func (t *terminal) toggleTerminal() {
if t.visState == termVisHiding || t.visState == termVisHidden {
t.Show()
} else {
t.Hide()
}
}
func (t *terminal) OnKeyChars(event d2input.KeyCharsEvent) bool {
if !t.IsVisible() {
return false
}
var handled bool
for _, c := range event.Chars {
if c != '`' {
t.command += string(c)
@ -222,7 +216,7 @@ func (t *terminal) Render(surface d2interface.Surface) error {
offset := -int((1.0 - easeInOut(t.visAnim)) * float64(totalHeight))
surface.PushTranslation(0, offset)
surface.DrawRect(totalWidth, outputHeight, termBgColor)
surface.DrawRect(totalWidth, outputHeight, t.bgColor)
for i := 0; i < t.lineCount; i++ {
historyIndex := len(t.outputHistory) - i - t.outputIndex - 1
@ -231,23 +225,26 @@ func (t *terminal) Render(surface d2interface.Surface) error {
}
historyEntry := t.outputHistory[historyIndex]
surface.PushTranslation(termCharWidth*2, outputHeight-(i+1)*termCharHeight)
surface.DrawText(historyEntry.text)
surface.PushTranslation(-termCharWidth*2, 0)
switch historyEntry.category {
case d2interface.TermCategoryInfo:
surface.DrawRect(termCharWidth, termCharHeight, termInfoColor)
surface.DrawRect(termCharWidth, termCharHeight, t.infoColor)
case d2interface.TermCategoryWarning:
surface.DrawRect(termCharWidth, termCharHeight, termWarningColor)
surface.DrawRect(termCharWidth, termCharHeight, t.warningColor)
case d2interface.TermCategoryError:
surface.DrawRect(termCharWidth, termCharHeight, termErrorColor)
surface.DrawRect(termCharWidth, termCharHeight, t.errorColor)
}
surface.Pop()
surface.Pop()
}
surface.PushTranslation(0, outputHeight)
surface.DrawRect(totalWidth, termCharHeight, termFgColor)
surface.DrawRect(totalWidth, termCharHeight, t.fgColor)
surface.DrawText("> " + t.command)
surface.Pop()
@ -274,13 +271,16 @@ func (t *terminal) Execute(command string) error {
if actionType.Kind() != reflect.Func {
return errors.New("action is not a function")
}
if len(actionParams) != actionType.NumIn() {
return errors.New("action requires different argument count")
}
var paramValues []reflect.Value
for i := 0; i < actionType.NumIn(); i++ {
actionParam := actionParams[i]
switch actionType.In(i).Kind() {
case reflect.String:
paramValues = append(paramValues, reflect.ValueOf(actionParam))
@ -289,24 +289,28 @@ func (t *terminal) Execute(command string) error {
if err != nil {
return err
}
paramValues = append(paramValues, reflect.ValueOf(int(value)))
case reflect.Uint:
value, err := strconv.ParseUint(actionParam, 10, 64)
if err != nil {
return err
}
paramValues = append(paramValues, reflect.ValueOf(uint(value)))
case reflect.Float64:
value, err := strconv.ParseFloat(actionParam, 64)
if err != nil {
return err
}
paramValues = append(paramValues, reflect.ValueOf(value))
case reflect.Bool:
value, err := strconv.ParseBool(actionParam)
if err != nil {
return err
}
paramValues = append(paramValues, reflect.ValueOf(value))
default:
return errors.New("action has unsupported arguments")
@ -317,9 +321,10 @@ func (t *terminal) Execute(command string) error {
actionReturnValues := actionValue.Call(paramValues)
if actionReturnValueCount := len(actionReturnValues); actionReturnValueCount > 0 {
t.OutputInfo("function returned %d values:", actionReturnValueCount)
t.OutputInfof("function returned %d values:", actionReturnValueCount)
for _, actionReturnValue := range actionReturnValues {
t.OutputInfo("%v: %s", actionReturnValue.Interface(), actionReturnValue.String())
t.OutputInfof("%v: %s", actionReturnValue.Interface(), actionReturnValue.String())
}
}
@ -328,6 +333,7 @@ func (t *terminal) Execute(command string) error {
func (t *terminal) OutputRaw(text string, category d2interface.TermCategory) {
var line string
for _, word := range strings.Split(text, " ") {
if len(line) > 0 {
line += " "
@ -337,29 +343,29 @@ func (t *terminal) OutputRaw(text string, category d2interface.TermCategory) {
wordLength := len(word)
if lineLength+wordLength >= termColCountMax {
t.outputHistory = append(t.outputHistory, termHistroyEntry{line, category})
t.outputHistory = append(t.outputHistory, termHistoryEntry{line, category})
line = word
} else {
line += word
}
}
t.outputHistory = append(t.outputHistory, termHistroyEntry{line, category})
t.outputHistory = append(t.outputHistory, termHistoryEntry{line, category})
}
func (t *terminal) Output(format string, params ...interface{}) {
func (t *terminal) Outputf(format string, params ...interface{}) {
t.OutputRaw(fmt.Sprintf(format, params...), d2interface.TermCategoryNone)
}
func (t *terminal) OutputInfo(format string, params ...interface{}) {
func (t *terminal) OutputInfof(format string, params ...interface{}) {
t.OutputRaw(fmt.Sprintf(format, params...), d2interface.TermCategoryInfo)
}
func (t *terminal) OutputWarning(format string, params ...interface{}) {
func (t *terminal) OutputWarningf(format string, params ...interface{}) {
t.OutputRaw(fmt.Sprintf(format, params...), d2interface.TermCategoryWarning)
}
func (t *terminal) OutputError(format string, params ...interface{}) {
func (t *terminal) OutputErrorf(format string, params ...interface{}) {
t.OutputRaw(fmt.Sprintf(format, params...), d2interface.TermCategoryError)
}
@ -403,6 +409,7 @@ func (t *terminal) BindAction(name, description string, action interface{}) erro
}
t.actions[name] = termActionEntry{action, description}
return nil
}
@ -419,10 +426,11 @@ func easeInOut(t float64) float64 {
t *= 2
if t < 1 {
return 0.5 * t * t * t * t
} else {
t -= 2
return -0.5 * (t*t*t*t - 2)
}
t -= 2
return -0.5 * (t*t*t*t - 2)
}
func parseCommand(command string) []string {
@ -470,14 +478,19 @@ func parseCommand(command string) []string {
func createTerminal() (*terminal, error) {
terminal := &terminal{
lineCount: termRowCount,
actions: make(map[string]termActionEntry),
lineCount: termRowCount,
bgColor: color.RGBA{R: 0x2e, G: 0x34, B: 0x36, A: 0xb0},
fgColor: color.RGBA{R: 0x55, G: 0x57, B: 0x53, A: 0xb0},
infoColor: color.RGBA{R: 0x34, G: 0x65, B: 0xa4, A: 0xb0},
warningColor: color.RGBA{R: 0xfc, G: 0xe9, B: 0x4f, A: 0xb0},
errorColor: color.RGBA{R: 0xcc, A: 0xb0},
actions: make(map[string]termActionEntry),
}
terminal.OutputInfo("::: OpenDiablo2 Terminal :::")
terminal.OutputInfo("type \"ls\" for a list of actions")
terminal.OutputInfof("::: OpenDiablo2 Terminal :::")
terminal.OutputInfof("type \"ls\" for a list of actions")
terminal.BindAction("ls", "list available actions", func() {
err := terminal.BindAction("ls", "list available actions", func() {
var names []string
for name := range terminal.actions {
names = append(names, name)
@ -485,15 +498,22 @@ func createTerminal() (*terminal, error) {
sort.Strings(names)
terminal.OutputInfo("available actions (%d):", len(names))
terminal.OutputInfof("available actions (%d):", len(names))
for _, name := range names {
entry := terminal.actions[name]
terminal.OutputInfo("%s: %s; %s", name, entry.description, reflect.TypeOf(entry.action).String())
terminal.OutputInfof("%s: %s; %s", name, entry.description, reflect.TypeOf(entry.action).String())
}
})
terminal.BindAction("clear", "clear terminal", func() {
if err != nil {
return nil, fmt.Errorf("failed to bind the '%s' action, err: %w", "ls", err)
}
err = terminal.BindAction("clear", "clear terminal", func() {
terminal.OutputClear()
})
if err != nil {
return nil, fmt.Errorf("failed to bind the '%s' action, err: %w", "clear", err)
}
return terminal, nil
}

View File

@ -9,8 +9,8 @@ import (
type terminalLogger struct {
terminal *terminal
buffer bytes.Buffer
writer io.Writer
buffer bytes.Buffer
writer io.Writer
}
func (tl *terminalLogger) Write(p []byte) (int, error) {
@ -21,19 +21,21 @@ func (tl *terminalLogger) Write(p []byte) (int, error) {
reader := bufio.NewReader(&tl.buffer)
termBytes, _, err := reader.ReadLine()
if err != nil {
return n, err
}
line := string(termBytes[:])
line := string(termBytes)
lineLower := strings.ToLower(line)
if strings.Index(lineLower, "error") > 0 {
tl.terminal.OutputError(line)
} else if strings.Index(lineLower, "warning") > 0 {
tl.terminal.OutputWarning(line)
} else {
tl.terminal.Output(line)
switch {
case strings.Index(lineLower, "error") > 0:
tl.terminal.OutputErrorf(line)
case strings.Index(lineLower, "warning") > 0:
tl.terminal.OutputWarningf(line)
default:
tl.terminal.Outputf(line)
}
return tl.writer.Write(p)

View File

@ -128,7 +128,7 @@ func (v *MainMenu) OnLoad(loading d2screen.LoadingState) {
v.trademarkBackground, _ = d2ui.LoadSprite(animation)
v.trademarkBackground.SetPosition(0, 0)
animation, _ = d2asset.LoadAnimation(d2resource.TcpIpBackground, d2resource.PaletteSky)
animation, _ = d2asset.LoadAnimation(d2resource.TCPIPBackground, d2resource.PaletteSky)
v.tcpIpBackground, _ = d2ui.LoadSprite(animation)
v.tcpIpBackground.SetPosition(0, 0)

View File

@ -3,42 +3,60 @@ package d2script
import (
"fmt"
"io/ioutil"
"path/filepath"
"github.com/robertkrimen/otto"
_ "github.com/robertkrimen/otto/underscore" // This causes the runtime to support underscore.js
)
// ScriptEngine allows running JavaScript scripts
type ScriptEngine struct {
vm *otto.Otto
}
// CreateScriptEngine creates the script engine and returns a pointer to it.
func CreateScriptEngine() *ScriptEngine {
result := &ScriptEngine{
vm: otto.New(),
}
result.vm.Set("debugPrint", func(call otto.FunctionCall) otto.Value {
err := result.vm.Set("debugPrint", func(call otto.FunctionCall) otto.Value {
fmt.Printf("Script: %s\n", call.Argument(0).String())
return otto.Value{}
})
if err != nil {
fmt.Printf("could not bind the 'debugPrint' to the given function in script engine")
}
return result
}
// ToValue converts the given interface{} value to a otto.Value
func (s *ScriptEngine) ToValue(source interface{}) (otto.Value, error) {
return s.vm.ToValue(source)
}
// AddFunction adds the given function to the script engine with the given name.
func (s *ScriptEngine) AddFunction(name string, value interface{}) {
s.vm.Set(name, value)
err := s.vm.Set(name, value)
if err != nil {
fmt.Printf("could not add the '%s' function to the script engine", name)
}
}
// RunScript runs the script file within the given path.
func (s *ScriptEngine) RunScript(fileName string) (*otto.Value, error) {
fileData, _ := ioutil.ReadFile(fileName)
fileData, err := ioutil.ReadFile(filepath.Clean(fileName))
if err != nil {
fmt.Printf("could not read script file: %s\n", err.Error())
return nil, err
}
val, err := s.vm.Run(string(fileData))
if err != nil {
fmt.Printf("Error running script: %s\n", err.Error())
return nil, err
}
return &val, nil
}