コード例 #1
0
ファイル: fov.go プロジェクト: karlek/reason
func (c *Creature) FOV(a *area.Area) (cs map[coord.Coord]struct{}) {
	radius := c.Sight
	cs = make(map[coord.Coord]struct{})
	for x := c.X() - radius; x <= c.X()+radius; x++ {
		for y := c.Y() - radius; y <= c.Y()+radius; y++ {
			// Distance between creature x and y coordinates and sight radius.
			dx := float64(x - c.X())
			dy := float64(y - c.Y())

			// Distance between creature and sight radius.
			dist := math.Sqrt(math.Pow(dx, 2) + math.Pow(dy, 2))

			// Discriminate coordinates which are outside of the circle.
			if dist > float64(radius) {
				continue
			}

			// Ignore hero.
			for _, p := range get_line(c.X(), c.Y(), x, y)[1:] {
				if !a.ExistsXY(p.X, p.Y) {
					break
				}

				cs[p] = struct{}{}

				// Terrain that breaks line of sight.
				if !a.IsXYPathable(p.X, p.Y) {
					break
				}
			}
		}
	}
	return cs
}
コード例 #2
0
ファイル: objects.go プロジェクト: karlek/reason
// Objects is a debug function to generate objects.
func Objects(a *area.Area, num int) {
	o := make(map[coord.Coord]area.DrawPather, a.Width*a.Height)

	log.Println(len(object.Objects))
	var objectList = make([]object.Object, len(object.Objects))
	var index int
	for _, o := range object.Objects {
		objectList[index] = o
		index++
	}
	for x := 0; x < a.Width; x++ {
		for y := 0; y < a.Height; y++ {
			if num <= 0 {
				return
			}

			if util.RandInt(0, 50) != 42 {
				continue
			}

			if !a.IsXYPathable(x, y) {
				continue
			}

			c := coord.Coord{X: x, Y: y}
			o[c] = objectList[util.RandInt(0, len(objectList))].New()
		}
	}
	a.Objects = o
}
コード例 #3
0
ファイル: mobs.go プロジェクト: karlek/reason
// Mobs is a debug function to add mobs to the map.
func Mobs(a *area.Area, num int) {
	var mobList = []creature.Creature{
		// creature.Beastiary["echidna"],
		creature.Beastiary["gobbal"],
		creature.Beastiary["tofu"],
		creature.Beastiary["iop"],
		creature.Beastiary["arachnee"],
	}
	for x := 0; x < a.Width; x++ {
		for y := 0; y < a.Height; y++ {
			if num <= 0 {
				return
			}

			if util.RandInt(0, 50) != 42 {
				continue
			}

			if !a.IsXYPathable(x, y) {
				continue
			}

			g := mobList[util.RandInt(0, len(mobList))]
			g.Inventory = make(creature.Inventory)

			c := coord.Coord{X: x, Y: y}

			g.SetX(x)
			g.SetY(y)

			a.Monsters[c] = &g
			num--
		}
	}
}
コード例 #4
0
ファイル: hero.go プロジェクト: karlek/reason
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
}
コード例 #5
0
ファイル: ai.go プロジェクト: karlek/reason
// Action performs simple AI for a creature.
func (c *Creature) Action(a *area.Area) int {
	if i := a.Items[c.Coord()].Peek(); i != nil {
		c.PickUp(a)
		return c.Speed
	}
	if c.Equipment.MainHand == nil && len(c.Inventory) > 0 {
		for _, pos := range item.Positions {
			if i, ok := c.Inventory[pos]; ok {
				if !item.IsEquipable(i) {
					break
				}
				if i.Name() != "Iron Sword" {
					break
				}
				c.Equip(pos)
				return c.Speed
			}
		}
	}

	var col *area.Collision
	var err error
	if c.X() < Hero.X() {
		col, err = a.MoveRight(c)
	} else if c.X() > Hero.X() {
		col, err = a.MoveLeft(c)
	} else if c.Y() < Hero.Y() {
		col, err = a.MoveDown(c)
	} else if c.Y() > Hero.Y() {
		col, err = a.MoveUp(c)
	}
	if err != nil {
		// log.Println("err / collide?")
		return c.Speed
		// return 0
	}
	if col == nil {
		return c.Speed
	}
	if mob, ok := col.S.(*Creature); ok {
		if mob.IsHero() {
			c.Battle(mob, a)
			return c.Speed
		}
	}

	// If all fails, creature waits.
	return c.Speed
}
コード例 #6
0
ファイル: items.go プロジェクト: karlek/reason
// Items is a debug function to add mobs to the map.
func Items(a *area.Area, num int) {
	var itemList = make([]item.DrawItemer, len(item.Items))
	var index int
	for _, i := range item.Items {
		itemList[index] = i
		index++
	}
	for x := 0; x < a.Width; x++ {
		for y := 0; y < a.Height; y++ {
			if num <= 0 {
				return
			}

			if util.RandInt(0, 50) != 42 {
				continue
			}

			if !a.IsXYPathable(x, y) {
				continue
			}

			c := coord.Coord{x, y}
			i := item.New(itemList[util.RandInt(0, len(itemList))])
			if i == nil {
				continue
			}
			i.SetX(x)
			i.SetY(y)

			if a.Items[c] == nil {
				a.Items[c] = new(area.Stack)
			}
			a.Items[c].Push(i)
			num--
		}
	}
}
コード例 #7
0
ファイル: fov.go プロジェクト: karlek/reason
// DrawFOV draws a field of view around a creature as well as the creatures
// memory of already explored areas.
func (c Creature) DrawFOV(a *area.Area) {
	// Clear screen.
	ui.Clear()

	// Get viewport coordinate offset.
	camX, camY := camXY(c, a)

	// Draw already explored areas.
	a.DrawExplored(ui.Area, camX, camY)

	// Draw hero.
	a.Draw(c.X(), c.Y(), camX, camY, ui.Area)

	// Visible coordinates of character.
	cs := c.FOV(a)
	for p := range cs {
		// Set terrain as explored.
		a.Terrain[p.X][p.Y].IsExplored = true

		// TODO(_): refactor cam.
		a.Draw(p.X, p.Y, camX, camY, ui.Area)
	}
}