Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
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)
}
Beispiel #4
0
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
}
Beispiel #5
0
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)
}
Beispiel #6
0
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
}
Beispiel #7
0
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)
}
Beispiel #8
0
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)
	}
}
Beispiel #9
0
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)
}