Package squidpony.squidai
Class Technique
java.lang.Object
squidpony.squidai.Technique
- All Implemented Interfaces:
Serializable
public class Technique extends Object implements Serializable
A simple struct-like class that stores various public fields which describe the targeting properties of a skill,
spell, tech, or any other game-specific term for a targeted (typically offensive) ability we call a Technique.
The typical usage of a Technique is:
A Technique always has an AOE implementation that it uses to determine which cells it actually affects, and Techniques that do not actually affect an area use the default single-cell "Area of Effect" implementation, PointAOE. You typically will need to construct the implementing class of the AOE interface in a different way for each implementation; BeamAOE, LineAOE, and ConeAOE depend on the user's position, BurstAOE and BlastAOE treat radii differently from BeamAOE and LineAOE, and CloudAOE has a random component that can be given a seed.
A Technique has a String name, which typically should be in a form that can be presented to a user, and a String id, which defaults to the same value as name but can be given some value not meant for users that records any additional identifying characteristics the game needs for things like comparisons. Created by Tommy Ettinger on 7/27/2015.
The typical usage of a Technique is:
- Construct any AOE implementation the Technique would use (if the Technique affects multiple grid cells).
- Construct the Technique (passing the AOE as a parameter if needed).
- Call
setMap(char[][])
before considering the Technique if it has not been called yet, if the physical map (including doors and obstacles) has changed since setMap() was last called, or simply on every Technique every time the map changes if there are few enemies with few Techniques. PERFORMING ANY SUBSEQUENT STEPS WITHOUT SETTING THE MAP TO THE CURRENT ACTUAL PHYSICAL MAP WILL HAVE BAD CONSEQUENCES FOR LOGIC AND MAY CAUSE CRASHING BUGS DUE TO ARRAY BOUNDS VIOLATIONS IF YOU HAVEN'T SET THE MAP ARRAY IN THE FIRST PLACE. The map should be bounded by wall chars ('#'), which is done automatically byDungeonGenerator
and similar classes, and can be done withDungeonUtility.wallWrap(char[][])
as well. - When the Technique is being considered by an AI, call
idealLocations(Coord, Set, Set, Set)
with the values of targets, lesserTargets, and/or priorityTargets set to beings that the AI can see (likely using FOV) and wants to affect with this Technique (enemies for offensive Techniques, allies for supporting ones), and requiredExclusions typically set to allies for offensive Techniques that can cause friendly-fire damage, or to null for supporting ones or Techniques that don't affect allies. - If the Technique is being used for a player action, you can show the player what cells are valid targets with
possibleTargets(Coord)
or its other overload, or can validate choices without telling the player beforehand usingcanTarget(Coord, Coord)
(this may be useful for cases where the player is activating an unknown magic item like a scroll, and the actual range hasn't been revealed). - When an ideal location has been determined from the previous step, and the player or AI decides to use this
Technique on a specific target point, call
apply(Coord, Coord)
with the user position as a Coord and the chosen Coord, and proceed to process the effects of the Technique as fitting for your game on the returned Map of Coord keys to Double values denoting how affected (from 0.0 for unaffected to 1.0 for full power) that Coord is. An AI might decide which Technique to use by an aggression ("aggro" or "hatred") level tracked per-enemy, by weights on Techniques for different situations, by choosing at random, or some combination of factors.
A Technique always has an AOE implementation that it uses to determine which cells it actually affects, and Techniques that do not actually affect an area use the default single-cell "Area of Effect" implementation, PointAOE. You typically will need to construct the implementing class of the AOE interface in a different way for each implementation; BeamAOE, LineAOE, and ConeAOE depend on the user's position, BurstAOE and BlastAOE treat radii differently from BeamAOE and LineAOE, and CloudAOE has a random component that can be given a seed.
A Technique has a String name, which typically should be in a form that can be presented to a user, and a String id, which defaults to the same value as name but can be given some value not meant for users that records any additional identifying characteristics the game needs for things like comparisons. Created by Tommy Ettinger on 7/27/2015.
- See Also:
- Serialized Form
-
Field Summary
-
Constructor Summary
Constructors Constructor Description Technique()
Creates a Technique that can target any adjacent single Coord, using Chebyshev (8-way square) distance.Technique(String name)
Creates a Technique that can target any adjacent single Coord, using Chebyshev (8-way square) distance.Technique(String name, String id, AOE aoe)
Creates a Technique that can target a Coord at a range specified by the given AOE's minRange and maxRange, using a distance metric from the AOE, and use that target Coord for the given AOE.Technique(String name, AOE aoe)
Creates a Technique that can target a Coord at a range specified by the given AOE's minRange and maxRange, using a distance metric from the AOE, and use that target Coord for the given AOE. -
Method Summary
Modifier and Type Method Description OrderedMap<Coord,Double>
apply(Coord user, Coord aimAt)
This does one last validation of the location aimAt (checking that it is within the valid range for this Technique) before getting the area affected by the AOE targeting that cell.boolean
canTarget(Coord user, Coord possibleTarget)
A quick yes-or-no check for whether auser
at a given Coord can use this Technique to target the given Coord of apossibleTarget
.OrderedMap<Coord,ArrayList<Coord>>
idealLocations(Coord user, Collection<Coord> targets, Collection<Coord> requiredExclusions)
Get a mapping of Coord keys representing locations to apply this Technique to, to ArrayList of Coord values representing which targets (by their location) are affected by choosing that Coord.OrderedMap<Coord,ArrayList<Coord>>
idealLocations(Coord user, Set<Coord> priorityTargets, Set<Coord> lesserTargets, Set<Coord> requiredExclusions)
Get a mapping of Coord keys representing locations to apply this Technique to, to ArrayList of Coord values representing which targets (by their location) are effected by choosing that Coord.GreasedRegion
possibleTargets(Coord user)
Gets all possible target-able Coords when using this technique from the given Coorduser
, returning them in a GreasedRegion.GreasedRegion
possibleTargets(Coord user, double[][] resistanceMap)
Gets all possible target-able Coords when using this technique from the given Coorduser
, returning them in a GreasedRegion.void
setMap(char[][] map)
VITAL: Call this method before any calls to idealLocations() or apply(), and call it again if the map changes.
-
Field Details
-
Constructor Details
-
Technique
public Technique()Creates a Technique that can target any adjacent single Coord, using Chebyshev (8-way square) distance. -
Technique
Creates a Technique that can target any adjacent single Coord, using Chebyshev (8-way square) distance.- Parameters:
name
- An identifier that may be displayed to the user. Also used for id.
-
Technique
Creates a Technique that can target a Coord at a range specified by the given AOE's minRange and maxRange, using a distance metric from the AOE, and use that target Coord for the given AOE.- Parameters:
name
- An identifier that may be displayed to the user. Also used for id.aoe
- An implementation of the AOE interface; typically needs construction beforehand.
-
Technique
Creates a Technique that can target a Coord at a range specified by the given AOE's minRange and maxRange, using a distance metric from the AOE, and use that target Coord for the given AOE. Takes an id parameter.- Parameters:
name
- An identifier that may be displayed to the user.id
- An identifier that should always be internal, and will probably never be shown to the user.aoe
- An implementation of the AOE interface; typically needs construction beforehand.
-
-
Method Details
-
setMap
VITAL: Call this method before any calls to idealLocations() or apply(), and call it again if the map changes. This simple method sets the map that this Technique can find targets in to a given char 2D array with '#' for walls and any other character (including characters for open and closed doors) treated as a floor for most purposes (certain AOE implementations may treat open and closed doors differently, specifically any that use FOV internally and can yield values other than 1.0 from their findArea() method, like BlastAOE and ConeAOE).- Parameters:
map
- A char 2D array like one generated by squidpony.squidgrid.mapping.DungeonGenerator, with '#' for walls and bounded edges.
-
idealLocations
public OrderedMap<Coord,ArrayList<Coord>> idealLocations(Coord user, Collection<Coord> targets, Collection<Coord> requiredExclusions)Get a mapping of Coord keys representing locations to apply this Technique to, to ArrayList of Coord values representing which targets (by their location) are affected by choosing that Coord. All targets with this method are valued equally, and the ideal location affects as many as possible without hitting any requiredExclusions. YOU MUST CALL setMap() with the current map status at some point before using this method, and call it again if the map changes. Failure to do so can cause serious bugs, from logic errors where monsters consider a door closed when it is open or vice versa, to an ArrayIndexOutOfBoundsException being thrown if the player moved to a differently-sized map and the Technique tries to use the previous map with coordinates from the new one.- Parameters:
user
- The location of the user of this Techniquetargets
- Set of Coord of desirable targets to include in the area of this Technique, as many as possible.requiredExclusions
- Set of Coord where each value is something this Technique will really try to avoid.- Returns:
- OrderedMap of Coord keys representing target points to pass to apply, to ArrayList of Coord values representing what targets' locations will be affected.
-
idealLocations
public OrderedMap<Coord,ArrayList<Coord>> idealLocations(Coord user, Set<Coord> priorityTargets, Set<Coord> lesserTargets, Set<Coord> requiredExclusions)Get a mapping of Coord keys representing locations to apply this Technique to, to ArrayList of Coord values representing which targets (by their location) are effected by choosing that Coord. This method will strongly prefer including priorityTargets in its area, especially multiple one if possible, and primarily uses lesserTargets as a tiebreaker if two locations have the same number of included priorityTargets but one has more lesserTargets in its area. YOU MUST CALL setMap() with the current map status at some point before using this method, and call it again if the map changes. Failure to do so can cause serious bugs, from logic errors where monsters consider a door closed when it is open or vice versa, to an ArrayIndexOutOfBoundsException being thrown if the player moved to a differently-sized map and the Technique tries to use the previous map with coordinates from the new one.- Parameters:
user
- The location of the user of this TechniquepriorityTargets
- Set of Coord of important targets to include in the area of this Technique, preferring to target a single priorityTarget over four lesserTargets.lesserTargets
- Set of Coord of desirable targets to include in the area of this Technique, as many as possible without excluding priorityTargets.requiredExclusions
- Set of Coord where each value is something this Technique will really try to avoid.- Returns:
- OrderedMap of Coord keys representing target points to pass to apply, to ArrayList of Coord values representing what targets' locations will be affected.
-
apply
This does one last validation of the location aimAt (checking that it is within the valid range for this Technique) before getting the area affected by the AOE targeting that cell. It considers the origin of the AOE to be the Coord parameter user, for purposes of directional limitations and for AOE implementations that need the user's location, such as ConeAOE and LineAOE. YOU MUST CALL setMap() with the current map status at some point before using this method, and call it again if the map changes. Failure to do so can cause serious bugs, from logic errors where monsters consider a door closed when it is open or vice versa, to an ArrayIndexOutOfBoundsException being thrown if the player moved to a differently-sized map and the Technique tries to use the previous map with coordinates from the new one.- Parameters:
user
- The position of the Technique's user, x first, y second.aimAt
- A target Coord typically obtained from idealLocations that determines how to position the AOE.- Returns:
- a HashMap of Coord keys to Double values from 1.0 (fully affected) to 0.0 (unaffected).
-
canTarget
A quick yes-or-no check for whether auser
at a given Coord can use this Technique to target the given Coord of apossibleTarget
. There doesn't need to be a creature in the possibleTarget cell, since area of effect Techniques could still affect nearby creatures. Returns true if possibleTarget is a viable target cell for the given user Coord with this Technique, or false otherwise.- Parameters:
user
- the Coord of the starting cell of this Technique, usually the position of the Technique's userpossibleTarget
- a Coord that could maybe be a viable target- Returns:
- true if this Technique can be used to target
possibleTarget
from the positionuser
, or false otherwise
-
possibleTargets
Gets all possible target-able Coords when using this technique from the given Coorduser
, returning them in a GreasedRegion. Note that a GreasedRegion can be used as a Collection of Coord with a fairly fastGreasedRegion.contains(Coord)
method, or at least faster than an ArrayList of Coord. GreasedRegion values are mutable, like arrays, so if you want to edit the returned value you can do so without constructing additional objects. This works by getting a FOV map (using shadowcasting and the same metric/radius type as theaoe
field on this Technique) to figure out what cells are visible, then eliminating cells that don't match the minimum range on the AOE or aren't legal targets because of its AimLimit.
This method isn't especially efficient because it needs to construct a temporary 2D array for the FOV to use as well as an additional temporary 2D array for resistances. This generates its resistance map withDungeonUtility.generateSimpleResistances(char[][])
every time; if you want other resistances, you should usepossibleTargets(Coord, double[][])
instead.- Parameters:
user
- the position of the user of this Technique- Returns:
- all possible Coord values that can be used as targets for this Technique from the given starting Coord, as a GreasedRegion
-
possibleTargets
Gets all possible target-able Coords when using this technique from the given Coorduser
, returning them in a GreasedRegion. This takes a 2D double array as a resistance map, the same kind used byFOV
, which can be obtained withDungeonUtility.generateResistances(char[][])
orDungeonUtility.generateSimpleResistances(char[][])
. Note that a GreasedRegion can be used as a Collection of Coord with a fairly fastGreasedRegion.contains(Coord)
method, or at least faster than an ArrayList of Coord. GreasedRegion values are mutable, like arrays, so if you want to edit the returned value you can do so without constructing additional objects. This works by getting a FOV map (using shadowcasting and the same metric/radius type as theaoe
field on this Technique) to figure out what cells are visible, then eliminating cells that don't match the minimum range on the AOE or aren't legal targets because of its AimLimit.
This method isn't especially efficient because it needs to construct a temporary 2D array for the FOV to use, but it is more efficient thanpossibleTargets(Coord)
, which needs to construct an additional temporary 2D array. You may also want to reuse an existing resistance map, and you can with this method.- Parameters:
user
- the position of the user of this TechniqueresistanceMap
- a 2D double array where walls are 1.0 and other values are less; often produced byDungeonUtility.generateSimpleResistances(char[][])
- Returns:
- all possible Coord values that can be used as targets for this Technique from the given starting Coord, as a GreasedRegion
-