package main
import (
- "github.com/anon55555/mt"
"github.com/dragonfireclient/hydra-dragonfire/convert"
+ "github.com/dragonfireclient/mt"
"github.com/yuin/gopher-lua"
"sync"
)
+type MapBlk struct {
+ data *mt.MapBlk
+ pathNodes map[[3]int16]*PathNode
+}
+
type Map struct {
- client *Client
mu sync.Mutex
- blocks map[[3]int16]*mt.MapBlk
+ pathfind bool
+ blocks map[[3]int16]*MapBlk
userdata *lua.LUserData
}
var mapFuncs = map[string]lua.LGFunction{
- "clear": l_map_clear,
"block": l_map_block,
"node": l_map_node,
+ "path": l_map_path,
}
-func getMap(l *lua.LState) *Map {
- return l.CheckUserData(1).Value.(*Map)
-}
-
-func (mtmap *Map) create(client *Client, l *lua.LState) {
- mtmap.client = client
- mtmap.blocks = map[[3]int16]*mt.MapBlk{}
- mtmap.userdata = l.NewUserData()
- mtmap.userdata.Value = mtmap
- l.SetMetatable(mtmap.userdata, l.GetTypeMetatable("hydra.map"))
-}
-
-func (mtmap *Map) push() lua.LValue {
- return mtmap.userdata
+func getMap(l *lua.LState, idx int) *Map {
+ return l.CheckUserData(idx).Value.(*Map)
}
-func (mtmap *Map) connect() {
+func newMap(l *lua.LState) *Map {
+ mp := &Map{}
+ mp.blocks = map[[3]int16]*MapBlk{}
+ mp.userdata = l.NewUserData()
+ mp.userdata.Value = mp
+ l.SetMetatable(mp.userdata, l.GetTypeMetatable("hydra.map"))
+ return mp
}
-func (mtmap *Map) process(pkt *mt.Pkt) {
+func (mp *Map) process(client *Client, pkt *mt.Pkt) {
switch cmd := pkt.Cmd.(type) {
case *mt.ToCltBlkData:
- mtmap.mu.Lock()
- mtmap.blocks[cmd.Blkpos] = &cmd.Blk
- mtmap.client.conn.SendCmd(&mt.ToSrvGotBlks{Blks: [][3]int16{cmd.Blkpos}})
- mtmap.mu.Unlock()
- }
-}
+ mp.mu.Lock()
+ defer mp.mu.Unlock()
-func l_map_clear(l *lua.LState) int {
- mtmap := getMap(l)
+ blk := &MapBlk{}
+ blk.data = &cmd.Blk
- mtmap.mu.Lock()
- defer mtmap.mu.Unlock()
+ if mp.pathfind {
+ if oldblk, ok := mp.blocks[cmd.Blkpos]; ok {
+ pathRemoveBlock(oldblk)
+ }
- var cmd mt.ToSrvDeletedBlks
- for pos := range mtmap.blocks {
- cmd.Blks = append(cmd.Blks, pos)
- }
+ pathAddBlock(mp, blk, cmd.Blkpos)
+ }
- mtmap.blocks = map[[3]int16]*mt.MapBlk{}
+ mp.blocks[cmd.Blkpos] = blk
- mtmap.client.conn.SendCmd(&cmd)
+ client.conn.SendCmd(&mt.ToSrvGotBlks{Blks: [][3]int16{cmd.Blkpos}})
+ }
+}
- return 0
+func l_map(l *lua.LState) int {
+ mp := newMap(l)
+ mp.pathfind = l.ToBool(1)
+ l.Push(mp.userdata)
+ return 1
}
func l_map_block(l *lua.LState) int {
- mtmap := getMap(l)
+ mp := getMap(l, 1)
var blkpos [3]int16
convert.ReadVec3Int16(l, l.Get(2), &blkpos)
- mtmap.mu.Lock()
- defer mtmap.mu.Unlock()
+ mp.mu.Lock()
+ defer mp.mu.Unlock()
- block, ok := mtmap.blocks[blkpos]
+ blk, ok := mp.blocks[blkpos]
if ok {
- l.Push(convert.PushMapBlk(l, *block))
+ l.Push(convert.PushMapBlk(l, *blk.data))
} else {
l.Push(lua.LNil)
}
}
func l_map_node(l *lua.LState) int {
- mtmap := getMap(l)
+ mp := getMap(l, 1)
var pos [3]int16
convert.ReadVec3Int16(l, l.Get(2), &pos)
blkpos, i := mt.Pos2Blkpos(pos)
- mtmap.mu.Lock()
- defer mtmap.mu.Unlock()
+ mp.mu.Lock()
+ defer mp.mu.Unlock()
- block, block_exists := mtmap.blocks[blkpos]
- if block_exists {
- meta, meta_exists := block.NodeMetas[i]
- if !meta_exists {
+ blk, blk_ok := mp.blocks[blkpos]
+ if blk_ok {
+ meta, meta_ok := blk.data.NodeMetas[i]
+ if !meta_ok {
meta = &mt.NodeMeta{}
}
lnode := l.NewTable()
- l.SetField(lnode, "param0", lua.LNumber(block.Param0[i]))
- l.SetField(lnode, "param1", lua.LNumber(block.Param1[i]))
- l.SetField(lnode, "param2", lua.LNumber(block.Param2[i]))
+ l.SetField(lnode, "param0", lua.LNumber(blk.data.Param0[i]))
+ l.SetField(lnode, "param1", lua.LNumber(blk.data.Param1[i]))
+ l.SetField(lnode, "param2", lua.LNumber(blk.data.Param2[i]))
l.SetField(lnode, "meta", convert.PushNodeMeta(l, *meta))
l.Push(lnode)
} else {
return 1
}
+
+func l_map_path(l *lua.LState) int {
+ mp := getMap(l, 1)
+ if !mp.pathfind {
+ panic("map not configured to support path finding")
+ }
+
+ var src, dst [3]int16
+ convert.ReadVec3Int16(l, l.Get(2), &src)
+ convert.ReadVec3Int16(l, l.Get(3), &dst)
+
+ mp.mu.Lock()
+ defer mp.mu.Unlock()
+
+ l.Push(pathFind(mp, [2][3]int16{src, dst}, l))
+ return 1
+}