func tick(a *area.Area) (err error) { // Save file. var sav *save.Save switch state.Stack.Pop() { case state.Init: // Load or create new game. // Load old values or initalize a new area and hero. sav, err = initGameSession(a) if err != nil { return errutil.Err(err) } state.Stack.Push(state.Intro) case state.Intro: // Show entry screen, and ask player for character name. name := intro.Intro() status.Println(fmt.Sprintf("%s. You will change the world.", name), termbox.ColorWhite) status.Println("Find Echidna and kill her.", termbox.ColorRed+termbox.AttrBold) state.Stack.Push(state.Wilderness) case state.Wilderness: turn.Proccess(sav, a) case state.Inventory: fallthrough case state.Drop: fallthrough default: state.Stack.Push(state.Wilderness) } return nil }
func HeroMovement(ev termbox.Event, a *area.Area) int { var col *area.Collision var err error switch ev.Key { case ui.MoveUpKey: col, err = a.MoveUp(&creature.Hero) case ui.MoveDownKey: col, err = a.MoveDown(&creature.Hero) case ui.MoveLeftKey: col, err = a.MoveLeft(&creature.Hero) case ui.MoveRightKey: col, err = a.MoveRight(&creature.Hero) default: return 0 } // Creature moved out of bounds. if err != nil { return 0 } stk, ok := a.Items[creature.Hero.Coord()] if ok && stk.Len() > 0 { if stk.Len() > 1 { status.Println("You find a heap of items on the ground:", termbox.ColorWhite) } else { status.Println("You find a single item on the ground:", termbox.ColorWhite) } print := " " for _, s := range []area.DrawPather(*stk) { i, _ := s.(item.DrawItemer) if stk.Len() < 4 { print += i.Name() + ", " } else { print += string(i.Graphic().Ch) + ", " } } status.Println(print[:len(print)-2], termbox.ColorBlack+termbox.AttrBold) } // Successful movement. if col == nil { return creature.Hero.Speed } // Another creature occupied that tile -> battle! if c, ok := col.S.(*creature.Creature); ok { creature.Hero.Battle(c, a) return creature.Hero.Speed } // Hero walked into an object. if obj, ok := a.Objects[col.Coord()].(*object.Object); ok { // If the hero walked into a door -> open! switch obj.Name() { case "door (closed)": a.Objects[col.Coord()] = object.Objects["door (open)"].New() status.Println("You open the closed door.", termbox.ColorBlack+termbox.AttrBold) return creature.Hero.Speed } } return 0 }
func (c *Creature) use(i item.Itemer) { switch i.(type) { case *item.Potion: status.Println("You drink the potion.", termbox.ColorWhite) case *item.Tool: switch i.Name() { case "Star-Eye Map": status.Println("You try to read the map.", termbox.ColorWhite) } } status.Print(i.UseText(), termbox.ColorWhite) }
func (c *Creature) PickUp(a *area.Area) (actionTaken bool) { msg := "There's no item here." i, err := c.pickUp(a) if i == nil { return false } // Print status message if hero's inventory is full. if c.IsHero() { if err != nil { msg = err.Error() } else { msg = fmt.Sprintf("%c - %s picked up.", i.Hotkey(), i.String()) } } else { msg = fmt.Sprintf("%s picked up %s.", strings.Title(c.Name()), i.String()) } // If the distance to the creature is within the sight radius, print the // status message. if c.dist() <= Hero.Sight { status.Println(msg, termbox.ColorWhite) } return true }
func NarrativeEquip(pos rune) { i := creature.Hero.Equip(pos) if i == nil { status.Println(unableToEquip, termbox.ColorRed+termbox.AttrBold) return } var equipStr string if item.IsStackable(i) { equipStr += fmt.Sprintf("%d ", i.Count()) if i.Count() > 1 { inflections.Pluralize(i.Name()) } else { equipStr += i.Name() } } else { equipStr += i.Name() } status.Println(fmt.Sprintf("You equipped %s.", equipStr), termbox.ColorWhite) }
func (attacker *Creature) damage(defender *Creature, a *area.Area) (s string) { lossOfHp := attacker.power() - defender.defense() if lossOfHp < 0 { lossOfHp = 0 } if defender.IsHero() { s = fmt.Sprintf("You take %d damage from %s!", lossOfHp, attacker.Name()) } else if attacker.IsHero() { s = fmt.Sprintf("You inflict %d damage to %s!", lossOfHp, defender.Name()) } else { s = fmt.Sprintf("%s takes %d damage from %s!", strings.Title(defender.Name()), lossOfHp, attacker.Name()) } defender.Hp -= lossOfHp if defender.Hp <= 0 { if defender.IsHero() { Hero.DrawFOV(a) status.Println(s, termbox.ColorWhite) status.Println("You die. Press any key to quit.", termbox.ColorWhite) status.Update() termbox.Flush() termbox.PollEvent() util.Quit() } else if attacker.IsHero() { s += fmt.Sprintf(" You killed %s!", defender.Name()) } a.Monsters[coord.Coord{defender.X(), defender.Y()}] = nil _, ok := a.Items[defender.Coord()] if !ok { a.Items[defender.Coord()] = new(area.Stack) } for _, i := range defender.Inventory { a.Items[defender.Coord()].Push(i) } a.Items[defender.Coord()].Push(defender.Corpse()) } return s }
func (c *Creature) Use(i item.Itemer) { if !item.IsUsable(i) { status.Println("You can't use that item!", termbox.ColorRed+termbox.AttrBold) return } if !item.IsPermanent(i) { if i.Count() > 1 { i.SetCount(i.Count() - 1) } else { delete(c.Inventory, i.Hotkey()) } } c.use(i) }
func (c *Creature) DropItem(pos rune, a *area.Area) { i := c.Inventory[pos] c.UnEquip(i) delete(c.Inventory, pos) cor := c.Coord() if a.Items[cor] == nil { a.Items[cor] = new(area.Stack) } a.Items[cor].Push(i) // If the item couldn't be dropped (cursed for example), print unable to // drop message. if i == nil { status.Println(UnableToDrop, termbox.ColorRed+termbox.AttrBold) return } fmtStr := "%s dropped %s." cName := strings.Title(c.Name()) if c.IsHero() { cName = "You" } iName := i.Name() if item.IsStackable(i) { name := i.Name() if i.Count() > 1 { name = inflections.Pluralize(name) } iName = strconv.Itoa(i.Count()) + " " + name } if c.dist() <= Hero.Sight { status.Println(fmt.Sprintf(fmtStr, cName, iName), termbox.ColorWhite) } }
func (c *Creature) UnEquip(i item.Itemer) { if !c.IsEquipped(i) { return } switch obj := i.(type) { case (*item.Weapon): if c.Equipment.MainHand == obj { c.Equipment.MainHand = nil } if c.Equipment.OffHand == obj { c.Equipment.OffHand = nil } case (*item.Headgear): if c.Equipment.Head == obj { c.Equipment.Head = nil } case (*item.Amulet): if c.Equipment.Amulet == obj { c.Equipment.Amulet = nil } case (*item.Ring): c.removeRing(obj) case (*item.Boots): if c.Equipment.Boots == obj { c.Equipment.Boots = nil } case (*item.Gloves): if c.Equipment.Gloves == obj { c.Equipment.Gloves = nil } case (*item.Chestwear): if c.Equipment.Chestwear == obj { c.Equipment.Chestwear = nil } case (*item.Legwear): if c.Equipment.Legwear == obj { c.Equipment.Legwear = nil } } status.Println(fmt.Sprintf("You unequip %s.", i.Name()), termbox.ColorWhite) }