From 132e0877830e0e28a2ae415e30b7e18fe9e479a1 Mon Sep 17 00:00:00 2001 From: NatureFreshMilk Date: Fri, 8 Feb 2019 11:45:56 +0100 Subject: [PATCH] smartshop impl --- server/mapblockparser/mapblock.go | 14 ++++++++ server/mapobject/setup.go | 46 ++++++++++++++++++++++++- server/mapobject/smartshop.go | 56 +++++++++++++++++++++++++++---- 3 files changed, 108 insertions(+), 8 deletions(-) diff --git a/server/mapblockparser/mapblock.go b/server/mapblockparser/mapblock.go index 7792c39..fd7756b 100644 --- a/server/mapblockparser/mapblock.go +++ b/server/mapblockparser/mapblock.go @@ -41,6 +41,20 @@ func getNodePos(x, y, z int) int { return x + (y * 16) + (z * 256) } +func (inv *Inventory) IsEmpty() bool { + if inv.Size == 0 || len(inv.Items) == 0 { + return true + } + + for _, item := range inv.Items { + if item.Name != "" && item.Count > 0 { + return false + } + } + + return true +} + func (mb *MapBlock) GetNodeId(x, y, z int) int { pos := getNodePos(x, y, z) return mb.Mapdata.ContentId[pos] diff --git a/server/mapobject/setup.go b/server/mapobject/setup.go index 6228794..9dae1a9 100644 --- a/server/mapobject/setup.go +++ b/server/mapobject/setup.go @@ -13,15 +13,24 @@ type MapObjectListener interface { onMapObject(x, y, z int, block *mapblockparser.MapBlock) *mapobjectdb.MapObject } +type MapMultiObjectListener interface { + onMapObject(x, y, z int, block *mapblockparser.MapBlock) []*mapobjectdb.MapObject +} + type Listener struct { ctx *app.App objectlisteners map[string]MapObjectListener + multiobjectlisteners map[string]MapMultiObjectListener } func (this *Listener) AddMapObject(blockname string, ol MapObjectListener) { this.objectlisteners[blockname] = ol } +func (this *Listener) AddMapMultiObject(blockname string, ol MapMultiObjectListener) { + this.multiobjectlisteners[blockname] = ol +} + func (this *Listener) OnEvent(eventtype string, o interface{}) { if eventtype != eventbus.MAPBLOCK_RENDERED { return @@ -37,6 +46,36 @@ func (this *Listener) OnEvent(eventtype string, o interface{}) { this.ctx.WebEventbus.Emit("mapobjects-cleared", block.Pos) for id, name := range block.BlockMapping { + + for k, v := range this.multiobjectlisteners { + if k == name { + //block matches + mapblockparser.IterateMapblock(func(x,y,z int){ + nodeid := block.GetNodeId(x, y, z) + if nodeid == id { + fields := logrus.Fields{ + "mbpos": block.Pos, + "x": x, + "y": y, + "z": z, + "type": name, + "nodeid": nodeid, + } + log.WithFields(fields).Debug("OnEvent()") + + objs := v.onMapObject(x, y, z, block) + + if len(objs) > 0 { + for _, obj := range objs { + this.ctx.Objectdb.AddMapData(obj) + this.ctx.WebEventbus.Emit("mapobject-created", obj) + } + } + } + }) + } // k==name + } //for k,v + for k, v := range this.objectlisteners { if k == name { //block matches @@ -63,6 +102,7 @@ func (this *Listener) OnEvent(eventtype string, o interface{}) { }) } // k==name } //for k,v + } //for id, name } @@ -70,6 +110,7 @@ func Setup(ctx *app.App) { l := Listener{ ctx: ctx, objectlisteners: make(map[string]MapObjectListener), + multiobjectlisteners: make(map[string]MapMultiObjectListener), } //mapserver stuff @@ -135,7 +176,10 @@ func Setup(ctx *app.App) { //jumpdrive, TODO: fleet controller l.AddMapObject("jumpdrive:engine", &JumpdriveBlock{}) - //TODO: atm, digiterms, signs/banners, spacecannons, shops (smart, fancy) + //smartshop + l.AddMapMultiObject("smartshop:shop", &SmartShopBlock{}) + + //TODO: atm, shops (smart, fancy) ctx.BlockAccessor.Eventbus.AddListener(&l) } diff --git a/server/mapobject/smartshop.go b/server/mapobject/smartshop.go index 8298dc7..863fbad 100644 --- a/server/mapobject/smartshop.go +++ b/server/mapobject/smartshop.go @@ -3,21 +3,63 @@ package mapobject import ( "mapserver/mapblockparser" "mapserver/mapobjectdb" + "strconv" + "math" ) type SmartShopBlock struct{} -func (this *SmartShopBlock) onMapObject(x, y, z int, block *mapblockparser.MapBlock) *mapobjectdb.MapObject { +func (this *SmartShopBlock) onMapObject(x, y, z int, block *mapblockparser.MapBlock) []*mapobjectdb.MapObject { + list := make([]*mapobjectdb.MapObject, 4) + md := block.Metadata.GetMetadata(x, y, z) + invMap := block.Metadata.GetInventoryMapAtPos(x, y, z) + mainInv := invMap["main"] - o := mapobjectdb.NewMapObject(block.Pos, x, y, z, "shop") - o.Attributes["type"] = "smartshop" - //TODO: 4 objects per coordinate + if mainInv.IsEmpty() { + return list + } - //invMap := block.Metadata.GetInventoryMapAtPos(x, y, z) + for i := 1; i <= 4; i++ { + payInvName := "pay" + strconv.Itoa(i) + giveInvName := "give" + strconv.Itoa(i) + pay := invMap[payInvName] + give := invMap[giveInvName] - o.Attributes["index"] = md["index"] + if pay.IsEmpty() || give.IsEmpty() { + continue + } - return o + o := mapobjectdb.NewMapObject(block.Pos, x, y, z, "shop") + o.Attributes["type"] = "smartshop" + o.Attributes["owner"] = md["owner"] + + in_item := pay.Items[0].Name + in_count := math.Max(1, float64(pay.Items[0].Count)) + + out_item := give.Items[0].Name + out_count := math.Max(1, float64(give.Items[0].Count)) + + stock := 0 + + for _, item := range mainInv.Items { + if item.Name == out_item { + stock += item.Count + } + } + + //multiples of out_count + stock_factor := math.Floor( float64(stock) / float64(out_count) ) + + o.Attributes["in_item"] = in_item + o.Attributes["in_count"] = strconv.Itoa(int(in_count)) + o.Attributes["out_item"] = out_item + o.Attributes["out_count"] = strconv.Itoa(int(out_count)) + o.Attributes["stock"] = strconv.Itoa(int(stock_factor)) + + list = append(list, o) + } + + return list }