func (t *Tree) Interact(player world.PlayerLike, action string) { switch action { default: t.Node.Interact(player, action) case "chop": pos := t.Position() if pos == nil { return } x, y := pos.Position() player.SetSchedule(&world.ScheduleSchedule{ Schedules: []world.Schedule{ world.NewWalkSchedule(x, y, true, 0), &GatherSchedule{ Tool: player, Target_: t, Item: func(volume uint64) world.Visible { return world.InitObject(&Logs{ material: t.material.CopyWood(volume), }).(world.Visible) }, }, }, }) } }
func (d *Door) Interact(player world.PlayerLike, action string) { switch action { case "open": pos := d.Position() if pos == nil { return } x, y := pos.Position() px, py := player.Position().Position() if (px == x && py != y-1 && py != y+1) || (py == y && px != x-1 && px != x+1) || (px != x && py != y) { player.SetSchedule(&world.ScheduleSchedule{ Schedules: []world.Schedule{ world.NewWalkSchedule(x, y, true, uint(player.Weight()/player.WeightMax())), &world.ActionSchedule{ Action: "open", Target_: d.Outer().(world.Visible), }, }, }) return } d.mtx.Lock() d.open = true d.mtx.Unlock() pos.Zone().Update(pos, d) case "close": pos := d.Position() if pos == nil { return } x, y := pos.Position() px, py := player.Position().Position() if (px == x && (py < y-1 || py > y+1)) || (py == y && (px < x-1 || px > x+1)) || (px != x && py != y) { player.SetSchedule(&world.ScheduleSchedule{ Schedules: []world.Schedule{ world.NewWalkSchedule(x, y, true, uint(player.Weight()/player.WeightMax())), &world.ActionSchedule{ Action: "close", Target_: d.Outer().(world.Visible), }, }, }) return } d.mtx.Lock() d.open = false d.mtx.Unlock() pos.Zone().Update(pos, d) default: d.VisibleObject.Interact(player, action) } }
func (r *Rock) Interact(player world.PlayerLike, action string) { switch action { default: r.Node.Interact(player, action) case "quarry": pos := r.Position() if pos == nil { return } x, y := pos.Position() player.SetSchedule(&world.ScheduleSchedule{ Schedules: []world.Schedule{ world.NewWalkSchedule(x, y, true, 0), &GatherSchedule{ Tool: player, Target_: r, Item: func(volume uint64) world.Visible { return world.InitObject(&Stone{ material: r.material.CopyStone(volume), }).(world.Visible) }, }, }, }) case "mine": if r.material.MetalColor() == "" { return } pos := r.Position() if pos == nil { return } x, y := pos.Position() player.SetSchedule(&world.ScheduleSchedule{ Schedules: []world.Schedule{ world.NewWalkSchedule(x, y, true, 0), &GatherSchedule{ Tool: player, Target_: r, Item: func(volume uint64) world.Visible { return world.InitObject(&Ore{ material: r.material.CopyMetal(volume), }).(world.Visible) }, }, }, }) } }
func (f *Forge) Interact(player world.PlayerLike, action string) { switch action { default: f.VisibleObject.Interact(player, action) case "smelt": pos := f.Position() ppos := player.Position() if pos == nil || ppos == nil { return } x, y := pos.Position() if px, py := ppos.Position(); px != x || py != y+1 { player.SetSchedule(&world.ScheduleSchedule{ Schedules: []world.Schedule{ world.NewWalkSchedule(x, y, false, uint(player.Weight()/player.WeightMax())), &world.ActionSchedule{ Target_: f, Action: action, }, }, }) return } ores := []interface{}{} for _, v := range player.Inventory() { if o, ok := v.(*Ore); ok { ores = append(ores, map[string]interface{}{ "i": o.NetworkID(), "q": o.Material().Quality(), "v": o.Volume(), "w": o.Weight(), }) } } for _, v := range player.Inventory() { if s, ok := v.(*Stone); ok { ores = append(ores, map[string]interface{}{ "i": s.NetworkID(), "q": s.Material().Quality(), "v": s.Volume(), "w": s.Weight(), }) } } instance := player.Instance(f.Position()) var done time.Time instance.Last(func(last time.Time) time.Time { done = last return last }) contents := []interface{}{} instance.Items(func(items []world.Visible) []world.Visible { for _, i := range items { var sprites []map[string]interface{} for j, c := range i.Colors() { sprites = append(sprites, map[string]interface{}{ "S": i.Sprite(), "C": c, "E": map[string]interface{}{ "y": j, }, }) } contents = append(contents, sprites) // 4 minutes per 5kg of ore done = done.Add(time.Minute * 4 * time.Duration(i.(world.Item).Weight()) / 5000) } if done.Before(time.Now()) && len(items) > 0 { materials := make(map[MetalType]*material) var quality big.Int var totalVolume uint64 var tmp big.Int for _, i := range items { if o, ok := i.(*Ore); ok { for _, m := range o.material.components { if m.metal == nil || m.volume == 0 { continue } mat := materials[*m.metal] if mat == nil { mat = &material{metal: m.metal} materials[*m.metal] = mat } totalVolume += m.volume mat.volume += m.volume tmp.SetUint64(m.volume) quality.Add(&quality, tmp.Mul(&o.material.quality, &tmp)) } } } originalVolume := totalVolume quality.Div(&quality, tmp.SetUint64(totalVolume)) makeIngot := func(volume uint64) { ingot := &Ingot{} world.InitObject(ingot) ingot.material = &Material{ components: make([]*material, 0, len((materials))), quality: quality, } world.InitObject(ingot.material) remaining := originalVolume for _, m := range materials { v := m.volume * volume / remaining remaining -= m.volume volume -= v ingot.material.components = append(ingot.material.components, &material{ metal: m.metal, volume: v, }) } ingot.material.sortComponents() if !player.GiveItem(ingot) { player.Position().Add(ingot) } } for totalVolume != 0 { if totalVolume <= 1000 { makeIngot(totalVolume) break } makeIngot(1000) totalVolume -= 1000 } items = items[:0] contents = contents[:0] } return items }) player.SetHUD("forge", map[string]interface{}{ "O": ores, "C": contents, "T": done, }) } }