Exemple #1
0
func distBetweenEnts(e1, e2 *game.Entity) int {
	x1, y1 := e1.Pos()
	dx1, dy1 := e1.Dims()
	x2, y2 := e2.Pos()
	dx2, dy2 := e2.Dims()

	var xdist int
	switch {
	case x1 >= x2+dx2:
		xdist = x1 - (x2 + dx2)
	case x2 >= x1+dx1:
		xdist = x2 - (x1 + dx1)
	default:
		xdist = 0
	}

	var ydist int
	switch {
	case y1 >= y2+dy2:
		ydist = y1 - (y2 + dy2)
	case y2 >= y1+dy1:
		ydist = y2 - (y1 + dy1)
	default:
		ydist = 0
	}

	if xdist > ydist {
		return xdist
	}
	return ydist
}
Exemple #2
0
func (a *Move) AiMoveToPos(ent *game.Entity, dst []int, max_ap int) game.ActionExec {
	base.Log().Printf("PATH: Request move to %v", dst)
	graph := ent.Game().Graph(ent.Side(), false, nil)
	src := []int{ent.Game().ToVertex(ent.Pos())}
	_, path := algorithm.Dijkstra(graph, src, dst)
	base.Log().Printf("PATH: Found path of length %d", len(path))
	ppx, ppy := ent.Pos()
	if path == nil {
		return nil
	}
	_, xx, yy := ent.Game().FromVertex(path[len(path)-1])
	base.Log().Printf("PATH: %d,%d -> %d,%d", ppx, ppy, xx, yy)
	if ent.Stats.ApCur() < max_ap {
		max_ap = ent.Stats.ApCur()
	}
	path = limitPath(ent, src[0], path, max_ap)
	_, xx, yy = ent.Game().FromVertex(path[len(path)-1])
	base.Log().Printf("PATH: (limited) %d,%d -> %d,%d", ppx, ppy, xx, yy)
	if len(path) <= 1 {
		return nil
	}
	var exec moveExec
	exec.SetBasicData(ent, a)
	exec.Path = path
	return &exec
}
Exemple #3
0
func (a *AoeAttack) AiBestTarget(ent *game.Entity, extra_dist int, spec AiAoeTarget) (x, y int, targets []*game.Entity) {
	ex, ey := ent.Pos()
	max := 0
	best_dist := 10000
	var bx, by int
	var radius int
	if a.Range > 0 {
		radius += a.Range
	}
	if extra_dist > 0 {
		radius += extra_dist
	}
	for x := ex - radius; x <= ex+radius; x++ {
		for y := ey - radius; y <= ey+radius; y++ {
			if !ent.HasLos(x, y, 1, 1) {
				continue
			}
			targets = a.getTargetsAt(ent.Game(), x, y)
			ok := true
			count := 0
			for i := range targets {
				if targets[i].Side() != ent.Side() {
					count++
				} else if ent.Side() == game.SideHaunt && spec == AiAoeHitMinionsOk {
					if targets[i].HauntEnt == nil || targets[i].HauntEnt.Level != game.LevelMinion {
						ok = false
					}
				} else if spec != AiAoeHitAlliesOk {
					ok = false
				}
			}
			dx := x - ex
			if dx < 0 {
				dx = -dx
			}
			dy := y - ey
			if dy < 0 {
				dy = -dy
			}
			dist := dx
			if dy > dx {
				dist = dy
			}
			if ok && (count > max || count == max && dist < best_dist) {
				max = count
				best_dist = dist
				bx, by = x, y
			}
		}
	}
	return bx, by, a.getTargetsAt(ent.Game(), bx, by)
}
Exemple #4
0
func rangedDistBetween(e1, e2 *game.Entity) int {
	e1x, e1y := e1.Pos()
	e2x, e2y := e2.Pos()
	dx := e1x - e2x
	dy := e1y - e2y
	if dx < 0 {
		dx = -dx
	}
	if dy < 0 {
		dy = -dy
	}
	if dx > dy {
		return dx
	}
	return dy
}
Exemple #5
0
func (a *Interact) findDoors(ent *game.Entity, g *game.Game) []*house.Door {
	room_num := ent.CurrentRoom()
	room := g.House.Floors[0].Rooms[room_num]
	x, y := ent.Pos()
	dx, dy := ent.Dims()
	ent_rect := makeIntFrect(x, y, x+dx, y+dy)
	var valid []*house.Door
	for _, door := range room.Doors {
		if door.AlwaysOpen() {
			continue
		}
		if ent_rect.Overlaps(makeRectForDoor(room, door)) {
			valid = append(valid, door)
		}
	}
	return valid
}
Exemple #6
0
func (a *Interact) AiInteractWithObject(ent, object *game.Entity) game.ActionExec {
	if ent.Stats.ApCur() < a.Ap {
		return nil
	}
	if distBetweenEnts(ent, object) > a.Range {
		return nil
	}
	x, y := object.Pos()
	dx, dy := object.Dims()
	if !ent.HasLos(x, y, dx, dy) {
		return nil
	}
	var exec interactExec
	exec.SetBasicData(ent, a)
	exec.Target = object.Id
	return &exec
}
Exemple #7
0
func (exec *moveExec) measureCost(ent *game.Entity, g *game.Game) int {
	if len(exec.Path) == 0 {
		base.Error().Printf("Zero length path")
		return -1
	}
	if g.ToVertex(ent.Pos()) != exec.Path[0] {
		base.Error().Printf("Path doesn't begin at ent's position, %d != %d", g.ToVertex(ent.Pos()), exec.Path[0])
		return -1
	}
	graph := g.Graph(ent.Side(), true, nil)
	v := g.ToVertex(ent.Pos())
	cost := 0
	for _, step := range exec.Path[1:] {
		dsts, costs := graph.Adjacent(v)
		ok := false
		prev := v
		base.Log().Printf("Adj(%d):", v)
		for j := range dsts {
			base.Log().Printf("Node %d", dsts[j])
			if dsts[j] == step {
				cost += int(costs[j])
				v = dsts[j]
				ok = true
				break
			}
		}
		base.Log().Printf("%d -> %d: %t", prev, v, ok)
		if !ok {
			return -1
		}
	}
	return cost
}
Exemple #8
0
func (a *BasicAttack) validTarget(source, target *game.Entity) bool {
	if source.Stats == nil || target.Stats == nil {
		return false
	}
	if distBetweenEnts(source, target) > a.Range {
		return false
	}
	x2, y2 := target.Pos()
	dx, dy := target.Dims()
	if !source.HasLos(x2, y2, dx, dy) {
		return false
	}
	if target.Stats.HpCur() <= 0 {
		return false
	}
	if source.Side() == target.Side() && !a.Target_allies {
		return false
	}
	if source.Side() != target.Side() && !a.Target_enemies {
		return false
	}
	return true
}