private static float ActionCost(Creature.MoveType action) { switch (action) { case Creature.MoveType.Walk: return(1.0f); case Creature.MoveType.Jump: return(10.0f); case Creature.MoveType.Climb: return(2.0f); case Creature.MoveType.Swim: return(20.0f); case Creature.MoveType.Fall: return(10.0f); case Creature.MoveType.Fly: return(2.0f); default: return(1.0f); } }
/// <summary> /// Given two voxels, and an action taken between the voxels, returns the cost of moving /// between the two voxels given that action. /// </summary> /// <param name="a">The source voxel of the action.</param> /// <param name="b">The destination voxel of the action.</param> /// <param name="action">The action taken to get between voxels.</param> /// <param name="movement">The creature making the movement.</param> /// <returns>The cost of going from a to b using the given action.</returns> public static float GetDistance(Voxel a, Voxel b, Creature.MoveType action, CreatureMovement movement) { // If trying to move through a non-empty voxel, the cost is just a big number. if (!b.IsEmpty) { return(100000); } // Otherwise, the cost is the distance between the voxels multiplied by the intrinsic cost // of an action. float score = (a.Position - b.Position).LengthSquared() * ActionCost(movement, action); return(score); }
public static float GetDistance(Voxel a, Voxel b, Creature.MoveType action, ChunkManager chunks) { if (!b.IsEmpty) { return(100000); } else { float score = (a.Position - b.Position).LengthSquared() * ActionCost(action); return(score); } }
/// <summary> /// Returns the intrinsic cost of an action. /// </summary> private static float ActionCost(CreatureMovement movement, Creature.MoveType action) { return(movement.Cost(action)); }
public List <Creature.MoveAction> GetMoveActions(Voxel voxel) { List <Creature.MoveAction> toReturn = new List <Creature.MoveAction>(); CollisionManager objectHash = PlayState.ComponentManager.CollisionManager; Voxel[,,] neighborHood = GetNeighborhood(voxel); int x = (int)voxel.GridPosition.X; int y = (int)voxel.GridPosition.Y; int z = (int)voxel.GridPosition.Z; bool inWater = (neighborHood[1, 1, 1] != null && neighborHood[1, 1, 1].WaterLevel > 5); bool standingOnGround = (neighborHood[1, 0, 1] != null && !neighborHood[1, 0, 1].IsEmpty); bool topCovered = (neighborHood[1, 2, 1] != null && !neighborHood[1, 2, 1].IsEmpty); bool hasNeighbors = HasNeighbors(neighborHood); List <Creature.MoveAction> successors = new List <Creature.MoveAction>(); //Climbing ladders List <IBoundedObject> bodiesInside = objectHash.Hashes[CollisionManager.CollisionType.Static].GetItems( new Point3(MathFunctions.FloorInt(voxel.Position.X), MathFunctions.FloorInt(voxel.Position.Y), MathFunctions.FloorInt(voxel.Position.Z))); if (bodiesInside != null) { bool hasLadder = bodiesInside.OfType <GameComponent>() .Any(component => component.Tags.Contains("Climbable")); if (hasLadder) { ; } { successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 2, 1), MoveType = Creature.MoveType.Climb }); if (!standingOnGround) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 0, 1), MoveType = Creature.MoveType.Climb }); } standingOnGround = true; } } if (standingOnGround || inWater) { Creature.MoveType moveType = inWater ? Creature.MoveType.Swim : Creature.MoveType.Walk; if (IsEmpty(neighborHood[0, 1, 1])) { // +- x successors.Add(new Creature.MoveAction() { Diff = new Vector3(0, 1, 1), MoveType = moveType }); } if (IsEmpty(neighborHood[2, 1, 1])) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(2, 1, 1), MoveType = moveType }); } if (IsEmpty(neighborHood[1, 1, 0])) { // +- z successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 1, 0), MoveType = moveType }); } if (IsEmpty(neighborHood[1, 1, 2])) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 1, 2), MoveType = moveType }); } if (!hasNeighbors) { if (IsEmpty(neighborHood[2, 1, 2])) { // +x + z successors.Add(new Creature.MoveAction() { Diff = new Vector3(2, 1, 2), MoveType = moveType }); } if (IsEmpty(neighborHood[2, 1, 0])) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(2, 1, 0), MoveType = moveType }); } if (IsEmpty(neighborHood[0, 1, 2])) { // -x -z successors.Add(new Creature.MoveAction() { Diff = new Vector3(0, 1, 2), MoveType = moveType }); } if (IsEmpty(neighborHood[0, 1, 0])) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(0, 1, 0), MoveType = moveType }); } } } if (!topCovered && (standingOnGround || inWater)) { for (int dx = 0; dx <= 2; dx++) { for (int dz = 0; dz <= 2; dz++) { if (dx == 1 && dz == 1) { continue; } if (!IsEmpty(neighborHood[dx, 1, dz])) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(dx, 2, dz), MoveType = Creature.MoveType.Jump }); } } } } // Falling if (!inWater && !standingOnGround) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 0, 1), MoveType = Creature.MoveType.Fall }); } foreach (Creature.MoveAction v in successors) { Voxel n = neighborHood[(int)v.Diff.X, (int)v.Diff.Y, (int)v.Diff.Z]; if (n != null && (n.IsEmpty || n.WaterLevel > 0)) { Creature.MoveAction newAction = v; newAction.Voxel = n; toReturn.Add(newAction); } } return(toReturn); }
public List<Creature.MoveAction> GetMoveActions(Voxel voxel) { List<Creature.MoveAction> toReturn = new List<Creature.MoveAction>(); CollisionManager objectHash = PlayState.ComponentManager.CollisionManager; Voxel[,,] neighborHood = GetNeighborhood(voxel); int x = (int)voxel.GridPosition.X; int y = (int)voxel.GridPosition.Y; int z = (int)voxel.GridPosition.Z; bool inWater = (neighborHood[1, 1, 1] != null && neighborHood[1, 1, 1].WaterLevel > 5); bool standingOnGround = (neighborHood[1, 0, 1] != null && !neighborHood[1, 0, 1].IsEmpty); bool topCovered = (neighborHood[1, 2, 1] != null && !neighborHood[1, 2, 1].IsEmpty); bool hasNeighbors = HasNeighbors(neighborHood); List<Creature.MoveAction> successors = new List<Creature.MoveAction>(); //Climbing ladders IEnumerable<IBoundedObject> objectsInside = objectHash.Hashes[CollisionManager.CollisionType.Static].GetItems( new Point3(MathFunctions.FloorInt(voxel.Position.X), MathFunctions.FloorInt(voxel.Position.Y), MathFunctions.FloorInt(voxel.Position.Z))); bool blockedByObject = false; if (objectsInside != null) { var bodies = objectsInside.OfType<GameComponent>(); var enumerable = bodies as IList<GameComponent> ?? bodies.ToList(); // TODO: This is supposed to be done when the door is a NEIGHBOR of this voxel only!! foreach (GameComponent body in enumerable) { Door door = body.GetRootComponent().GetChildrenOfType<Door>(true).FirstOrDefault(); if (door != null) { if ( PlayState.Diplomacy.GetPolitics(door.TeamFaction, Creature.Faction).GetCurrentRelationship() == Relationship.Hateful) { if (IsEmpty(neighborHood[0, 1, 1])) // +- x successors.Add(new Creature.MoveAction() { Diff = new Vector3(0, 1, 1), MoveType = Creature.MoveType.DestroyObject, InteractObject = door, Voxel = neighborHood[0, 1, 1] }); if (IsEmpty(neighborHood[2, 1, 1])) successors.Add(new Creature.MoveAction() { Diff = new Vector3(2, 1, 1), MoveType = Creature.MoveType.DestroyObject, InteractObject = door, Voxel = neighborHood[2, 1, 1] }); if (IsEmpty(neighborHood[1, 1, 0])) // +- z successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 1, 0), MoveType = Creature.MoveType.DestroyObject, InteractObject = door, Voxel = neighborHood[1, 1, 0] }); if (IsEmpty(neighborHood[1, 1, 2])) successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 1, 2), MoveType = Creature.MoveType.DestroyObject, InteractObject = door, Voxel = neighborHood[1, 1, 2] }); blockedByObject = true; } } } if (blockedByObject) { return successors; } if (CanClimb) { bool hasLadder = enumerable.Any(component => component.Tags.Contains("Climbable")); if (hasLadder) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 2, 1), MoveType = Creature.MoveType.Climb }); if (!standingOnGround) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 0, 1), MoveType = Creature.MoveType.Climb }); } standingOnGround = true; } } } if (standingOnGround || (CanSwim && inWater)) { Creature.MoveType moveType = inWater ? Creature.MoveType.Swim : Creature.MoveType.Walk; if (IsEmpty(neighborHood[0, 1, 1])) // +- x successors.Add(new Creature.MoveAction() { Diff = new Vector3(0, 1, 1), MoveType = moveType }); if (IsEmpty(neighborHood[2, 1, 1])) successors.Add(new Creature.MoveAction() { Diff = new Vector3(2, 1, 1), MoveType = moveType }); if (IsEmpty(neighborHood[1, 1, 0])) // +- z successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 1, 0), MoveType = moveType }); if (IsEmpty(neighborHood[1, 1, 2])) successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 1, 2), MoveType = moveType }); if (!hasNeighbors) { if (IsEmpty(neighborHood[2, 1, 2])) // +x + z successors.Add(new Creature.MoveAction() { Diff = new Vector3(2, 1, 2), MoveType = moveType }); if (IsEmpty(neighborHood[2, 1, 0])) successors.Add(new Creature.MoveAction() { Diff = new Vector3(2, 1, 0), MoveType = moveType }); if (IsEmpty(neighborHood[0, 1, 2])) // -x -z successors.Add(new Creature.MoveAction() { Diff = new Vector3(0, 1, 2), MoveType = moveType }); if (IsEmpty(neighborHood[0, 1, 0])) successors.Add(new Creature.MoveAction() { Diff = new Vector3(0, 1, 0), MoveType = moveType }); } } if (!topCovered && (standingOnGround || (CanSwim && inWater))) { for (int dx = 0; dx <= 2; dx++) { for (int dz = 0; dz <= 2; dz++) { if (dx == 1 && dz == 1) continue; if (!IsEmpty(neighborHood[dx, 1, dz])) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(dx, 2, dz), MoveType = Creature.MoveType.Jump }); } } } } // Falling if (!inWater && !standingOnGround) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(1, 0, 1), MoveType = Creature.MoveType.Fall }); } if (CanFly) { for (int dx = 0; dx <= 2; dx++) { for (int dz = 0; dz <= 2; dz++) { for (int dy = 0; dy <= 2; dy++) { if (dx == 1 && dz == 1 && dy == 1) continue; if (IsEmpty(neighborHood[dx, 1, dz])) { successors.Add(new Creature.MoveAction() { Diff = new Vector3(dx, dy, dz), MoveType = Creature.MoveType.Fly }); } } } } } foreach (Creature.MoveAction v in successors) { Voxel n = neighborHood[(int)v.Diff.X, (int)v.Diff.Y, (int)v.Diff.Z]; if (n != null && (n.IsEmpty || n.WaterLevel > 0)) { Creature.MoveAction newAction = v; newAction.Voxel = n; toReturn.Add(newAction); } } return toReturn; }