]> git.lizzy.rs Git - hydra-dragonfire.git/blob - map.go
Merge pull request #4 from Minetest-j45/master
[hydra-dragonfire.git] / map.go
1 package main
2
3 import (
4         "github.com/dragonfireclient/hydra-dragonfire/convert"
5         "github.com/dragonfireclient/mt"
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                 mp.mu.Lock()
45                 defer mp.mu.Unlock()
46
47                 blk := &MapBlk{}
48                 blk.data = &cmd.Blk
49
50                 if mp.pathfind {
51                         if oldblk, ok := mp.blocks[cmd.Blkpos]; ok {
52                                 pathRemoveBlock(oldblk)
53                         }
54
55                         pathAddBlock(mp, blk, cmd.Blkpos)
56                 }
57
58                 mp.blocks[cmd.Blkpos] = blk
59
60                 client.conn.SendCmd(&mt.ToSrvGotBlks{Blks: [][3]int16{cmd.Blkpos}})
61         }
62 }
63
64 func l_map(l *lua.LState) int {
65         mp := newMap(l)
66         mp.pathfind = l.ToBool(1)
67         l.Push(mp.userdata)
68         return 1
69 }
70
71 func l_map_block(l *lua.LState) int {
72         mp := getMap(l, 1)
73         var blkpos [3]int16
74         convert.ReadVec3Int16(l, l.Get(2), &blkpos)
75
76         mp.mu.Lock()
77         defer mp.mu.Unlock()
78
79         blk, ok := mp.blocks[blkpos]
80         if ok {
81                 l.Push(convert.PushMapBlk(l, *blk.data))
82         } else {
83                 l.Push(lua.LNil)
84         }
85
86         return 1
87 }
88
89 func l_map_node(l *lua.LState) int {
90         mp := getMap(l, 1)
91
92         var pos [3]int16
93         convert.ReadVec3Int16(l, l.Get(2), &pos)
94         blkpos, i := mt.Pos2Blkpos(pos)
95
96         mp.mu.Lock()
97         defer mp.mu.Unlock()
98
99         blk, blk_ok := mp.blocks[blkpos]
100         if blk_ok {
101                 meta, meta_ok := blk.data.NodeMetas[i]
102                 if !meta_ok {
103                         meta = &mt.NodeMeta{}
104                 }
105
106                 lnode := l.NewTable()
107                 l.SetField(lnode, "param0", lua.LNumber(blk.data.Param0[i]))
108                 l.SetField(lnode, "param1", lua.LNumber(blk.data.Param1[i]))
109                 l.SetField(lnode, "param2", lua.LNumber(blk.data.Param2[i]))
110                 l.SetField(lnode, "meta", convert.PushNodeMeta(l, *meta))
111                 l.Push(lnode)
112         } else {
113                 l.Push(lua.LNil)
114         }
115
116         return 1
117 }
118
119 func l_map_path(l *lua.LState) int {
120         mp := getMap(l, 1)
121         if !mp.pathfind {
122                 panic("map not configured to support path finding")
123         }
124
125         var src, dst [3]int16
126         convert.ReadVec3Int16(l, l.Get(2), &src)
127         convert.ReadVec3Int16(l, l.Get(3), &dst)
128
129         mp.mu.Lock()
130         defer mp.mu.Unlock()
131
132         l.Push(pathFind(mp, [2][3]int16{src, dst}, l))
133         return 1
134 }