mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-04 23:56:40 -05:00
Added npc labels. More mapgen stuff. (#449)
This commit is contained in:
parent
0cef1b0a73
commit
6dae0097b9
@ -12,6 +12,8 @@ type MapEntity interface {
|
||||
Render(target d2render.Surface)
|
||||
Advance(tickTime float64)
|
||||
GetPosition() (float64, float64)
|
||||
GetPositionF() (float64, float64)
|
||||
Name() string
|
||||
}
|
||||
|
||||
// mapEntity represents an entity on the map that can be animated
|
||||
@ -169,3 +171,11 @@ func angleToDirection(angle float64) int {
|
||||
func (m *mapEntity) GetPosition() (float64, float64) {
|
||||
return float64(m.TileX), float64(m.TileY)
|
||||
}
|
||||
|
||||
func (m *mapEntity) GetPositionF() (float64, float64) {
|
||||
return float64(m.TileX) + (float64(m.subcellX)/5.0), float64(m.TileY) + (float64(m.subcellY)/5.0)
|
||||
}
|
||||
|
||||
func (m *mapEntity) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ type NPC struct {
|
||||
repetitions int
|
||||
direction int
|
||||
objectLookup *d2datadict.ObjectLookupRecord
|
||||
name string
|
||||
}
|
||||
|
||||
func CreateNPC(x, y int, object *d2datadict.ObjectLookupRecord, direction int) *NPC {
|
||||
@ -39,6 +40,26 @@ func CreateNPC(x, y int, object *d2datadict.ObjectLookupRecord, direction int) *
|
||||
result.SetMode(object.Mode, object.Class, direction)
|
||||
result.mapEntity.directioner = result.rotate
|
||||
|
||||
switch object.Act {
|
||||
case 1:
|
||||
switch object.Id {
|
||||
case 0:
|
||||
result.name = "Gheed"
|
||||
case 1:
|
||||
result.name = "Cain"
|
||||
case 2:
|
||||
result.name = "Akara"
|
||||
case 5:
|
||||
result.name = "Kashya"
|
||||
case 7:
|
||||
result.name = "Warriv"
|
||||
case 8:
|
||||
result.name = "Charsi"
|
||||
case 9:
|
||||
result.name = "Andariel"
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@ -143,3 +164,7 @@ func (v *NPC) SetMode(animationMode, weaponClass string, direction int) error {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *NPC) Name() string {
|
||||
return m.name
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ type Player struct {
|
||||
Equipment d2inventory.CharacterEquipment
|
||||
Id string
|
||||
direction int
|
||||
Name string
|
||||
name string
|
||||
nameLabel d2ui.Label
|
||||
lastPathSize int
|
||||
isInTown bool
|
||||
@ -59,7 +59,7 @@ func CreatePlayer(id, name string, x, y int, direction int, heroType d2enum.Hero
|
||||
composite: composite,
|
||||
Equipment: equipment,
|
||||
direction: direction,
|
||||
Name: name,
|
||||
name: name,
|
||||
nameLabel: d2ui.CreateLabel(d2resource.FontFormal11, d2resource.PaletteStatic),
|
||||
isRunToggled: true,
|
||||
isInTown: true,
|
||||
@ -126,9 +126,9 @@ func (v *Player) Render(target d2render.Surface) {
|
||||
)
|
||||
defer target.Pop()
|
||||
v.composite.Render(target)
|
||||
v.nameLabel.X = v.offsetX
|
||||
v.nameLabel.Y = v.offsetY - 100
|
||||
v.nameLabel.Render(target)
|
||||
//v.nameLabel.X = v.offsetX
|
||||
//v.nameLabel.Y = v.offsetY - 100
|
||||
//v.nameLabel.Render(target)
|
||||
}
|
||||
|
||||
func (v *Player) SetMode(animationMode, weaponClass string, direction int) error {
|
||||
@ -177,3 +177,7 @@ func (v *Player) rotate(direction int) {
|
||||
v.SetMode(newAnimationMode, v.weaponClass, direction)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Player) Name() string {
|
||||
return v.name
|
||||
}
|
||||
|
@ -267,6 +267,68 @@ func generateWilderness1Contents(mapEngine *d2mapengine.MapEngine, rect d2common
|
||||
}
|
||||
}
|
||||
|
||||
stuff := []*d2mapstamp.Stamp{
|
||||
loadPreset(mapEngine, d2wilderness.StoneFill1, 0),
|
||||
loadPreset(mapEngine, d2wilderness.StoneFill1, 1),
|
||||
loadPreset(mapEngine, d2wilderness.StoneFill1, 2),
|
||||
loadPreset(mapEngine, d2wilderness.StoneFill2, 0),
|
||||
loadPreset(mapEngine, d2wilderness.StoneFill2, 1),
|
||||
loadPreset(mapEngine, d2wilderness.StoneFill2, 2),
|
||||
loadPreset(mapEngine, d2wilderness.Cottages1, 0),
|
||||
loadPreset(mapEngine, d2wilderness.Cottages1, 1),
|
||||
loadPreset(mapEngine, d2wilderness.Cottages1, 2),
|
||||
loadPreset(mapEngine, d2wilderness.Cottages1, 3),
|
||||
loadPreset(mapEngine, d2wilderness.Cottages1, 4),
|
||||
loadPreset(mapEngine, d2wilderness.Cottages1, 5),
|
||||
loadPreset(mapEngine, d2wilderness.FallenCamp1, 0),
|
||||
loadPreset(mapEngine, d2wilderness.FallenCamp1, 1),
|
||||
loadPreset(mapEngine, d2wilderness.FallenCamp1, 2),
|
||||
loadPreset(mapEngine, d2wilderness.FallenCamp1, 3),
|
||||
loadPreset(mapEngine, d2wilderness.Pond, 0),
|
||||
loadPreset(mapEngine, d2wilderness.SwampFill1, 0),
|
||||
loadPreset(mapEngine, d2wilderness.SwampFill2, 0),
|
||||
}
|
||||
|
||||
mapEngine.PlaceStamp(denOfEvil, denOfEvilLoc.X, denOfEvilLoc.Y)
|
||||
|
||||
numPlaced := 0
|
||||
for numPlaced < 25 {
|
||||
stamp := stuff[rand.Intn(len(stuff))]
|
||||
|
||||
stampRect := d2common.Rectangle {
|
||||
Left: rect.Left+ rand.Intn(rect.Width) - stamp.Size().Width,
|
||||
Top: rect.Top+rand.Intn(rect.Height) - stamp.Size().Height,
|
||||
Width: stamp.Size().Width,
|
||||
Height: stamp.Size().Height,
|
||||
}
|
||||
|
||||
if areaEmpty(mapEngine, stampRect) {
|
||||
mapEngine.PlaceStamp(stamp, stampRect.Left, stampRect.Top)
|
||||
numPlaced++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func areaEmpty(mapEngine *d2mapengine.MapEngine, rect d2common.Rectangle) bool {
|
||||
mapHeight := mapEngine.Size().Height
|
||||
mapWidth := mapEngine.Size().Width
|
||||
|
||||
if rect.Bottom() >= mapHeight || rect.Right() >= mapWidth {
|
||||
return false
|
||||
}
|
||||
|
||||
for y := rect.Top; y <= rect.Bottom(); y++ {
|
||||
for x := rect.Left; x <= rect.Right(); x++ {
|
||||
if len(mapEngine.Tile(x, y).Floors) == 0 {
|
||||
continue
|
||||
}
|
||||
floor := mapEngine.Tile(x, y).Floors[0]
|
||||
if floor.Style != 0 || floor.Sequence != 0 || floor.Prop1 != 1 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -240,6 +240,14 @@ func (mr *MapRenderer) renderDebug(debugVisLevel int, target d2render.Surface, s
|
||||
}
|
||||
}
|
||||
|
||||
func (mr *MapRenderer) WorldToScreen(x, y float64) (int, int) {
|
||||
return mr.viewport.WorldToScreen(x, y)
|
||||
}
|
||||
|
||||
func (mr *MapRenderer) WorldToScreenF(x, y float64) (float64, float64) {
|
||||
return mr.viewport.WorldToScreenF(x, y)
|
||||
}
|
||||
|
||||
func (mr *MapRenderer) renderTileDebug(ax, ay int, debugVisLevel int, target d2render.Surface) {
|
||||
subTileColor := color.RGBA{R: 80, G: 80, B: 255, A: 50}
|
||||
tileColor := color.RGBA{R: 255, G: 255, B: 255, A: 100}
|
||||
|
@ -51,6 +51,10 @@ func (v *Viewport) WorldToScreen(x, y float64) (int, int) {
|
||||
return v.OrthoToScreen(v.WorldToOrtho(x, y))
|
||||
}
|
||||
|
||||
func (v *Viewport) WorldToScreenF(x, y float64) (float64, float64) {
|
||||
return v.OrthoToScreenF(v.WorldToOrtho(x, y))
|
||||
}
|
||||
|
||||
func (v *Viewport) ScreenToWorld(x, y int) (float64, float64) {
|
||||
return v.OrthoToWorld(v.ScreenToOrtho(x, y))
|
||||
}
|
||||
@ -81,6 +85,13 @@ func (v *Viewport) OrthoToScreen(x, y float64) (int, int) {
|
||||
return orthoX, orthoY
|
||||
}
|
||||
|
||||
func (v *Viewport) OrthoToScreenF(x, y float64) (float64, float64) {
|
||||
camOrthoX, camOrthoY := v.getCameraOffset()
|
||||
orthoX := x - camOrthoX + float64(v.screenRect.Left)
|
||||
orthoY := y - camOrthoY + float64(v.screenRect.Top)
|
||||
return orthoX, orthoY
|
||||
}
|
||||
|
||||
func (v *Viewport) IsTileVisible(x, y float64) bool {
|
||||
orthoX1, orthoY1 := v.WorldToOrtho(x-3, y)
|
||||
orthoX2, orthoY2 := v.WorldToOrtho(x+3, y)
|
||||
|
@ -56,11 +56,14 @@ func (v *Game) Render(screen d2render.Surface) error {
|
||||
v.gameClient.RegenMap = false
|
||||
v.mapRenderer.RegenerateTileCache()
|
||||
}
|
||||
|
||||
screen.Clear(color.Black)
|
||||
v.mapRenderer.Render(screen)
|
||||
|
||||
if v.gameControls != nil {
|
||||
v.gameControls.Render(screen)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package d2player
|
||||
import (
|
||||
"image/color"
|
||||
"log"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
@ -37,6 +38,8 @@ type GameControls struct {
|
||||
escapeMenu *EscapeMenu
|
||||
inputListener InputCallbackListener
|
||||
FreeCam bool
|
||||
lastMouseX int
|
||||
lastMouseY int
|
||||
|
||||
// UI
|
||||
globeSprite *d2ui.Sprite
|
||||
@ -44,6 +47,7 @@ type GameControls struct {
|
||||
menuButton *d2ui.Sprite
|
||||
skillIcon *d2ui.Sprite
|
||||
zoneChangeText *d2ui.Label
|
||||
nameLabel *d2ui.Label
|
||||
runButton d2ui.Button
|
||||
isZoneTextShown bool
|
||||
actionableRegions []ActionableRegion
|
||||
@ -76,6 +80,11 @@ func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine,
|
||||
label.Color = color.RGBA{R: 255, G: 88, B: 82, A: 255}
|
||||
label.Alignment = d2ui.LabelAlignCenter
|
||||
|
||||
nameLabel := d2ui.CreateLabel(d2resource.FontFormal11, d2resource.PaletteStatic)
|
||||
nameLabel.Alignment = d2ui.LabelAlignCenter
|
||||
nameLabel.SetText("")
|
||||
nameLabel.Color = color.White
|
||||
|
||||
gc := &GameControls{
|
||||
hero: hero,
|
||||
mapEngine: mapEngine,
|
||||
@ -84,6 +93,7 @@ func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine,
|
||||
inventory: NewInventory(),
|
||||
heroStats: NewHeroStats(),
|
||||
escapeMenu: NewEscapeMenu(),
|
||||
nameLabel: &nameLabel,
|
||||
zoneChangeText: &label,
|
||||
actionableRegions: []ActionableRegion{
|
||||
{leftSkill, d2common.Rectangle{Left: 115, Top: 550, Width: 50, Height: 50}},
|
||||
@ -191,12 +201,15 @@ func (g *GameControls) OnMouseButtonRepeat(event d2input.MouseEvent) bool {
|
||||
}
|
||||
|
||||
func (g *GameControls) OnMouseMove(event d2input.MouseMoveEvent) bool {
|
||||
mx, my := event.X, event.Y
|
||||
g.lastMouseX = mx
|
||||
g.lastMouseY = my
|
||||
|
||||
if g.escapeMenu.IsOpen() {
|
||||
g.escapeMenu.OnMouseMove(event)
|
||||
return false
|
||||
}
|
||||
|
||||
mx, my := event.X, event.Y
|
||||
for i := range g.actionableRegions {
|
||||
// Mouse over a game control element
|
||||
if g.actionableRegions[i].Rect.IsInRect(mx, my) {
|
||||
@ -327,6 +340,26 @@ func (g *GameControls) updateLayout() {
|
||||
|
||||
// TODO: consider caching the panels to single image that is reused.
|
||||
func (g *GameControls) Render(target d2render.Surface) {
|
||||
for entityIdx := range *g.mapEngine.Entities() {
|
||||
entity := (*g.mapEngine.Entities())[entityIdx]
|
||||
if entity.Name() == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
entScreenXf, entScreenYf := g.mapRenderer.WorldToScreenF(entity.GetPositionF())
|
||||
entScreenX := int(math.Floor(entScreenXf))
|
||||
entScreenY := int(math.Floor(entScreenYf))
|
||||
|
||||
if ((entScreenX-20) <= g.lastMouseX) && ((entScreenX+20) >= g.lastMouseX) &&
|
||||
((entScreenY-80) <= g.lastMouseY) && (entScreenY>= g.lastMouseY) {
|
||||
g.nameLabel.SetText(entity.Name())
|
||||
g.nameLabel.SetPosition(entScreenX, entScreenY - 100)
|
||||
g.nameLabel.Render(target)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
g.inventory.Render(target)
|
||||
g.heroStats.Render(target)
|
||||
g.escapeMenu.Render(target)
|
||||
|
Loading…
Reference in New Issue
Block a user