aboutsummaryrefslogtreecommitdiff
path: root/map.go
blob: 3ded174b4727bb3263ac32d7f13688b182c55461 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package main

import (
	"github.com/anon55555/mt"
	"github.com/dragonfireclient/hydra-dragonfire/convert"
	"github.com/yuin/gopher-lua"
	"sync"
)

type MapBlk struct {
	data  *mt.MapBlk
	edges [6]*PathfindEdge
}

type Map struct {
	mu       sync.Mutex
	pathfind bool
	blocks   map[[3]int16]*MapBlk
	userdata *lua.LUserData
}

var mapFuncs = map[string]lua.LGFunction{
	"block": l_map_block,
	"node":  l_map_node,
}

func getMap(l *lua.LState, idx int) *Map {
	return l.CheckUserData(idx).Value.(*Map)
}

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 (mp *Map) process(client *Client, pkt *mt.Pkt) {
	switch cmd := pkt.Cmd.(type) {
	case *mt.ToCltBlkData:
		go func() {
			mp.mu.Lock()
			defer mp.mu.Unlock()

			blk := &MapBlk{}
			blk.data = &cmd.Blk
			if mp.pathfind {
				pfPreprocess(mp, cmd.Blkpos, blk)
			}

			mp.blocks[cmd.Blkpos] = blk
		}()

		client.conn.SendCmd(&mt.ToSrvGotBlks{Blks: [][3]int16{cmd.Blkpos}})
	}
}

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 {
	mp := getMap(l, 1)
	var blkpos [3]int16
	convert.ReadVec3Int16(l, l.Get(2), &blkpos)

	mp.mu.Lock()
	defer mp.mu.Unlock()

	blk, ok := mp.blocks[blkpos]
	if ok {
		l.Push(convert.PushMapBlk(l, *blk.data))
	} else {
		l.Push(lua.LNil)
	}

	return 1
}

func l_map_node(l *lua.LState) int {
	mp := getMap(l, 1)

	var pos [3]int16
	convert.ReadVec3Int16(l, l.Get(2), &pos)
	blkpos, i := mt.Pos2Blkpos(pos)

	mp.mu.Lock()
	defer mp.mu.Unlock()

	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(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 {
		l.Push(lua.LNil)
	}

	return 1
}