]> git.lizzy.rs Git - hydra-dragonfire.git/blob - map.go
Add path finding
[hydra-dragonfire.git] / map.go
1 package main
2
3 import (
4         "github.com/anon55555/mt"
5         "github.com/dragonfireclient/hydra-dragonfire/convert"
6         "github.com/yuin/gopher-lua"
7         "sync"
8 )
9
10 type MapBlk struct {
11         data      *mt.MapBlk
12         pathNodes map[[3]int16]*PathNode
13 }
14
15 type Map struct {
16         mu       sync.Mutex
17         pathfind bool
18         blocks   map[[3]int16]*MapBlk
19         userdata *lua.LUserData
20 }
21
22 var mapFuncs = map[string]lua.LGFunction{
23         "block": l_map_block,
24         "node":  l_map_node,
25         "path":  l_map_path,
26 }
27
28 func getMap(l *lua.LState, idx int) *Map {
29         return l.CheckUserData(idx).Value.(*Map)
30 }
31
32 func newMap(l *lua.LState) *Map {
33         mp := &Map{}
34         mp.blocks = map[[3]int16]*MapBlk{}
35         mp.userdata = l.NewUserData()
36         mp.userdata.Value = mp
37         l.SetMetatable(mp.userdata, l.GetTypeMetatable("hydra.map"))
38         return mp
39 }
40
41 func (mp *Map) process(client *Client, pkt *mt.Pkt) {
42         switch cmd := pkt.Cmd.(type) {
43         case *mt.ToCltBlkData:
44                 go func() {
45                         mp.mu.Lock()
46                         defer mp.mu.Unlock()
47
48                         blk := &MapBlk{}
49                         blk.data = &cmd.Blk
50
51                         if mp.pathfind {
52                                 if oldblk, ok := mp.blocks[cmd.Blkpos]; ok {
53                                         pathRemoveBlock(oldblk)
54                                 }
55
56                                 pathAddBlock(mp, blk, cmd.Blkpos)
57                         }
58
59                         mp.blocks[cmd.Blkpos] = blk
60                 }()
61
62                 client.conn.SendCmd(&mt.ToSrvGotBlks{Blks: [][3]int16{cmd.Blkpos}})
63         }
64 }
65
66 func l_map(l *lua.LState) int {
67         mp := newMap(l)
68         mp.pathfind = l.ToBool(1)
69         l.Push(mp.userdata)
70         return 1
71 }
72
73 func l_map_block(l *lua.LState) int {
74         mp := getMap(l, 1)
75         var blkpos [3]int16
76         convert.ReadVec3Int16(l, l.Get(2), &blkpos)
77
78         mp.mu.Lock()
79         defer mp.mu.Unlock()
80
81         blk, ok := mp.blocks[blkpos]
82         if ok {
83                 l.Push(convert.PushMapBlk(l, *blk.data))
84         } else {
85                 l.Push(lua.LNil)
86         }
87
88         return 1
89 }
90
91 func l_map_node(l *lua.LState) int {
92         mp := getMap(l, 1)
93
94         var pos [3]int16
95         convert.ReadVec3Int16(l, l.Get(2), &pos)
96         blkpos, i := mt.Pos2Blkpos(pos)
97
98         mp.mu.Lock()
99         defer mp.mu.Unlock()
100
101         blk, blk_ok := mp.blocks[blkpos]
102         if blk_ok {
103                 meta, meta_ok := blk.data.NodeMetas[i]
104                 if !meta_ok {
105                         meta = &mt.NodeMeta{}
106                 }
107
108                 lnode := l.NewTable()
109                 l.SetField(lnode, "param0", lua.LNumber(blk.data.Param0[i]))
110                 l.SetField(lnode, "param1", lua.LNumber(blk.data.Param1[i]))
111                 l.SetField(lnode, "param2", lua.LNumber(blk.data.Param2[i]))
112                 l.SetField(lnode, "meta", convert.PushNodeMeta(l, *meta))
113                 l.Push(lnode)
114         } else {
115                 l.Push(lua.LNil)
116         }
117
118         return 1
119 }
120
121 func l_map_path(l *lua.LState) int {
122         mp := getMap(l, 1)
123         if !mp.pathfind {
124                 panic("map not configured to support path finding")
125         }
126
127         var src, dst [3]int16
128         convert.ReadVec3Int16(l, l.Get(2), &src)
129         convert.ReadVec3Int16(l, l.Get(3), &dst)
130
131         mp.mu.Lock()
132         defer mp.mu.Unlock()
133
134         l.Push(pathFind(mp, [2][3]int16{src, dst}, l))
135         return 1
136 }