Angband
Macros | Enumerations | Functions | Variables
project.h File Reference

projection and helpers More...

#include "list-elements.h"
#include "list-project-environs.h"
#include "list-project-monsters.h"

Go to the source code of this file.

Macros

#define ELEM(a, b, c, d, e, f, g, col)   GF_##a,
#define PROJ_ENV(a, col)   GF_##a,
#define PROJ_MON(a, obv)   GF_##a,
#define PROJECT_NONE   0x000
 NONE: No flags JUMP: Jump directly to the target location without following a path BEAM: Work as a beam weapon (affect every grid passed through) THRU: May continue through the target (used for bolts and beams) STOP: Stop as soon as we hit a monster (used for bolts) GRID: May affect terrain in the blast area in some way ITEM: May affect objects in the blast area in some way KILL: May affect monsters in the blast area in some way HIDE: Disable visual feedback from projection AWARE: Effects are already obvious to the player SAFE: Doesn't affect monsters of the same race as the caster ARC: Projection is a sector of circle radiating from the caster PLAY: May affect the player.
#define PROJECT_JUMP   0x001
#define PROJECT_BEAM   0x002
#define PROJECT_THRU   0x004
#define PROJECT_STOP   0x008
#define PROJECT_GRID   0x010
#define PROJECT_ITEM   0x020
#define PROJECT_KILL   0x040
#define PROJECT_HIDE   0x080
#define PROJECT_AWARE   0x100
#define PROJECT_SAFE   0x200
#define PROJECT_ARC   0x400
#define PROJECT_PLAY   0x800

Enumerations

enum  { GF_MAX }
 Spell types used by project(), and related functions. More...
enum  {
  BOLT_NO_MOTION, BOLT_0, BOLT_45, BOLT_90,
  BOLT_135, BOLT_MAX
}
 Bolt motion (used in prefs.c, project.c) More...

Functions

bool project_f (int who, int r, int y, int x, int dam, int typ)
 Called from project() to affect terrain features.
int inven_damage (struct player *p, int type, int cperc)
 Destroys a type of item on a given percent chance.
bool project_o (int who, int r, int y, int x, int dam, int typ)
 Called from project() to affect objects.
bool project_m (int who, int r, int y, int x, int dam, int typ, int flg)
 Called from project() to affect monsters.
int adjust_dam (struct player *p, int type, int dam, aspect dam_aspect, int resist)
 Adjust damage according to resistance or vulnerability.
bool project_p (int who, int r, int y, int x, int dam, int typ)
 Called from project() to affect the player.
int project_path (struct loc *gp, int range, int y1, int x1, int y2, int x2, int flg)
 Determine the path taken by a projection.
bool projectable (struct chunk *c, int y1, int x1, int y2, int x2, int flg)
 Determine if a bolt spell cast from (y1,x1) to (y2,x2) will arrive at the final destination, assuming that no monster gets in the way, using the project_path() function to check the projection path.
bool gf_force_obvious (int type)
int gf_color (int type)
int gf_num (int type)
random_value gf_denom (int type)
const char * gf_desc (int type)
int gf_name_to_idx (const char *name)
const char * gf_idx_to_name (int type)
bool project (int who, int rad, int y, int x, int dam, int typ, int flg, int degrees_of_arc, byte diameter_of_source)
 

The main project() function and its helpers


Variables

int project_m_n
int project_m_x
int project_m_y
byte gf_to_attr [GF_MAX][BOLT_MAX]
wchar_t gf_to_char [GF_MAX][BOLT_MAX]

Detailed Description

projection and helpers

Macro Definition Documentation

#define ELEM (   a,
  b,
  c,
  d,
  e,
  f,
  g,
  col 
)    GF_##a,
#define PROJ_ENV (   a,
  col 
)    GF_##a,
#define PROJ_MON (   a,
  obv 
)    GF_##a,
#define PROJECT_ARC   0x400

Referenced by project().

#define PROJECT_AWARE   0x100
#define PROJECT_BEAM   0x002
#define PROJECT_GRID   0x010
#define PROJECT_HIDE   0x080
#define PROJECT_ITEM   0x020
#define PROJECT_JUMP   0x001
#define PROJECT_KILL   0x040
#define PROJECT_NONE   0x000

NONE: No flags JUMP: Jump directly to the target location without following a path BEAM: Work as a beam weapon (affect every grid passed through) THRU: May continue through the target (used for bolts and beams) STOP: Stop as soon as we hit a monster (used for bolts) GRID: May affect terrain in the blast area in some way ITEM: May affect objects in the blast area in some way KILL: May affect monsters in the blast area in some way HIDE: Disable visual feedback from projection AWARE: Effects are already obvious to the player SAFE: Doesn't affect monsters of the same race as the caster ARC: Projection is a sector of circle radiating from the caster PLAY: May affect the player.

Referenced by make_attack_spell(), monster_list_collect(), near_permwall(), and target_able().

#define PROJECT_PLAY   0x800
#define PROJECT_SAFE   0x200

Referenced by project_m().

#define PROJECT_STOP   0x008
#define PROJECT_THRU   0x004

Enumeration Type Documentation

anonymous enum

Spell types used by project(), and related functions.

Enumerator:
GF_MAX 
anonymous enum

Bolt motion (used in prefs.c, project.c)

Enumerator:
BOLT_NO_MOTION 
BOLT_0 
BOLT_45 
BOLT_90 
BOLT_135 
BOLT_MAX 

Function Documentation

int adjust_dam ( struct player p,
int  type,
int  dam,
aspect  dam_aspect,
int  resist 
)

Adjust damage according to resistance or vulnerability.

Parameters
pis the player
typeis the attack type we are checking.
damis the unadjusted damage.
dam_aspectis the calc we want (min, avg, max, random).
resistis the degree of resistance (-1 = vuln, 3 = immune).

References AVERAGE, player_state::el_info, equip_notice_element(), EXTREMIFY, gf_denom(), gf_num(), i, MAXIMISE, MINIMISE, minus_ac(), player::race, randcalc(), RANDOMISE, element_info::res_level, player::state, and type.

Referenced by best_spell_power(), effect_handler_TRAP_SPOT_ACID(), effect_handler_TRAP_SPOT_FIRE(), melee_effect_elemental(), and project_p().

int gf_color ( int  type)

References gf_type::color, COLOUR_WHITE, GF_MAX, gf_table, and type.

Referenced by bolt_pict(), and gf_display().

random_value gf_denom ( int  type)

References gf_type::denom, GF_MAX, gf_table, and type.

Referenced by adjust_dam().

const char* gf_desc ( int  type)

References gf_type::desc, GF_MAX, gf_table, and type.

Referenced by project_p().

bool gf_force_obvious ( int  type)

References FALSE, gf_type::force_obvious, GF_MAX, gf_table, and type.

Referenced by project_m().

const char* gf_idx_to_name ( int  type)

References GF_MAX, gf_name_list, and type.

Referenced by gf_display().

int gf_name_to_idx ( const char *  name)

References gf_name_list, i, and my_stricmp().

Referenced by effect_param(), and parse_prefs_gf().

int gf_num ( int  type)

References GF_MAX, gf_table, gf_type::num, and type.

Referenced by adjust_dam().

int inven_damage ( struct player p,
int  type,
int  cperc 
)
bool project ( int  who,
int  rad,
int  y,
int  x,
int  dam,
int  typ,
int  flg,
int  degrees_of_arc,
byte  diameter_of_source 
)


The main project() function and its helpers

Generic "beam"/"bolt"/"ball" projection routine. -BEN-, some changes by -LM-

Parameters
who,:Index of "source" monster (negative for the character)
rad,:Radius of explosion (0 = beam/bolt, 1 to 20 = ball), or maximum length of arc from the source.
y
x,:Target location (or location to travel towards)
dam,:Base damage to apply to monsters, terrain, objects, or player
typ,:Type of projection (fire, frost, dispel demons etc.)
flg,:Extra bit flags that control projection behavior
degrees_of_arc,:How wide an arc spell is (in degrees).
diameter_of_source,:how wide the source diameter is.
Returns
TRUE if any effects of the projection were observed, else FALSE

At present, there are five major types of projections:

Point-effect projection: (no PROJECT_BEAM flag, radius of zero, and either jumps directly to target or has a single source and target grid) A point-effect projection has no line of projection, and only affects one grid. It is used for most area-effect spells (like dispel evil) and pinpoint strikes like the monster Holding prayer.

Bolt: (no PROJECT_BEAM flag, radius of zero, has to travel from source to target) A bolt travels from source to target and affects only the final grid in its projection path. If given the PROJECT_STOP flag, it is stopped by any monster or character in its path (at present, all bolts use this flag).

Beam: (PROJECT_BEAM) A beam travels from source to target, affecting all grids passed through with full damage. It is never stopped by monsters in its path. Beams may never be combined with any other projection type.

Ball: (positive radius, unless the PROJECT_ARC flag is set) A ball travels from source towards the target, and always explodes. Unless specified, it does not affect wall grids, but otherwise affects any grids in LOS from the center of the explosion. If used with a direction, a ball will explode on the first occupied grid in its path. If given a target, it will explode on that target. If a wall is in the way, it will explode against the wall. If a ball reaches z_info->max_range without hitting anything or reaching its target, it will explode at that point.

Arc: (positive radius, with the PROJECT_ARC flag set) An arc is a portion of a source-centered ball that explodes outwards towards the target grid. Like a ball, it affects all non-wall grids in LOS of the source in the explosion area. The width of arc spells is con- trolled by degrees_of_arc. An arc is created by rejecting all grids that form the endpoints of lines whose angular difference (in degrees) from the centerline of the arc is greater than one-half the input "degrees_of_arc". See the table "get_ angle_to_grid" in "util.c" for more information. Note: An arc with a value for degrees_of_arc of zero is actually a beam of defined length.

Projections that effect all monsters in LOS are handled through the use of the PROJECT_LOS effect, which applies a single-grid projection to individual monsters. Projections that light up rooms or affect all monsters on the level are more efficiently handled through special functions.

Variations:

PROJECT_STOP forces a path of projection to stop at the first occupied grid it hits. This is used with bolts, and also by ball spells travelling in a specific direction rather than towards a target.

PROJECT_THRU allows a path of projection towards a target to continue past that target. It also allows a spell to affect wall grids adjacent to a grid in LOS of the center of the explosion.

PROJECT_JUMP allows a projection to immediately set the source of the pro- jection to the target. This is used for all area effect spells (like dispel evil), and can also be used for bombardments.

PROJECT_HIDE erases all graphical effects, making the projection invisible.

PROJECT_GRID allows projections to affect terrain features.

PROJECT_ITEM allows projections to affect objects on the ground.

PROJECT_KILL allows projections to affect monsters.

PROJECT_PLAY allows projections to affect the player.

degrees_of_arc controls the width of arc spells. With a value for degrees_of_arc of zero, arcs act like beams of defined length.

diameter_of_source controls how quickly explosions lose strength with dis- tance from the target. Most ball spells have a source diameter of 10, which means that they do 1/2 damage at range 1, 1/3 damage at range 2, and so on. Caster-centered balls usually have a source diameter of 20, which allows them to do full damage to all adjacent grids. Arcs have source diameters ranging up to 20, which allows the spell designer to fine-tune how quickly a breath loses strength outwards from the breather. It is expected, but not required, that wide arcs lose strength more quickly over distance.

Implementation notes:

If the source grid is not the same as the target, we project along the path between them. Bolts stop if they hit anything, beams stop if they hit a wall, and balls and arcs may exhibit either bahavior. When they reach the final grid in the path, balls and arcs explode. We do not allow beams to be combined with explosions. Balls affect all floor grids in LOS (optionally, also wall grids adjacent to a grid in LOS) within their radius. Arcs do the same, but only within their cone of projection. Because affected grids are only scanned once, and it is really helpful to have explosions that travel outwards from the source, they are sorted by distance. For each distance, an adjusted damage is calculated. In successive passes, the code then displays explosion graphics, erases these graphics, marks terrain for possible later changes, affects objects, monsters, the character, and finally changes features and teleports monsters and characters in marked grids.

Usage and graphics notes:

Only 256 grids can be affected per projection, limiting the effective radius of standard ball attacks to nine units (diameter nineteen). Arcs can have larger radii; an arc capable of going out to range 20 should not be wider than 70 degrees.

Balls must explode BEFORE hitting walls, or they would affect monsters on both sides of a wall.

Note that for consistency, we pretend that the bolt actually takes time to move from point A to point B, even if the player cannot see part of the projection path. Note that in general, the player will always see part of the path, since it either starts at the player or ends on the player.

Hack – we assume that every "projection" is "self-illuminating".

Hack – when only a single monster is affected, we automatically track (and recall) that monster, unless "PROJECT_JUMP" is used.

Note that we must call "handle_stuff()" after affecting terrain features in the blast radius, in case the illumination of the grid was changed, and "update_view()" and "update_monsters()" need to be called.

References ABS, cave, cave_monster(), ddx_ddd, ddy_ddd, distance(), EVENT_BOLT, EVENT_EXPLOSION, event_signal_blast(), event_signal_bolt(), FALSE, get_angle_to_grid, handle_stuff(), health_track(), i, square::info, loc(), los(), angband_constants::max_range, monster::mflag, mflag_has, square::mon, monster_race_track(), ox, oy, panel_contains(), player_has_los_bold(), PROJECT_ARC, PROJECT_BEAM, project_f(), PROJECT_GRID, PROJECT_HIDE, PROJECT_ITEM, PROJECT_JUMP, PROJECT_KILL, project_m(), project_m_n, project_m_x, project_m_y, project_o(), project_p(), project_path(), PROJECT_PLAY, PROJECT_THRU, player::px, player::py, monster::race, sqinfo_off, sqinfo_on, square_in_bounds(), square_ispassable(), square_isproject(), square_isprojectable(), square_monster(), chunk::squares, player::timed, TRUE, player_upkeep::update, update_stuff(), player::upkeep, loc::x, loc::y, and z_info.

Referenced by effect_handler_BALL(), effect_handler_BIZARRE(), effect_handler_BREATH(), effect_handler_DARKEN_AREA(), effect_handler_LIGHT_AREA(), effect_handler_PROJECT_LOS(), effect_handler_STAR(), effect_handler_STAR_BALL(), effect_handler_SWARM(), project_aimed(), and project_touch().

bool project_f ( int  who,
int  r,
int  y,
int  x,
int  dam,
int  typ 
)

Called from project() to affect terrain features.

Called for projections with the PROJECT_GRID flag set, which includes beam, ball and breath effects.

Parameters
whois the monster list index of the caster
ris the distance from the centre of the effect
y
xthe coordinates of the grid being handled
damis the "damage" from the effect at distance r from the centre
typis the projection (GF_) type
Returns
whether the effects were obvious

Note that this function determines if the player can see anything that happens by taking into account: blindness, line-of-sight, and illumination.

Hack – effects on grids which are memorized but not in view are also seen.

References FALSE, feature_handlers, and project_feature_handler_context_s::obvious.

Referenced by project().

bool project_m ( int  who,
int  r,
int  y,
int  x,
int  dam,
int  typ,
int  flg 
)

Called from project() to affect monsters.

Called for projections with the PROJECT_KILL flag set, which includes bolt, beam, ball and breath effects.

Parameters
whois the monster list index of the caster
ris the distance from the centre of the effect
y
xthe coordinates of the grid being handled
damis the "damage" from the effect at distance r from the centre
typis the projection (GF_) type
flgconsists of any relevant PROJECT_ flags
Returns
whether the effects were obvious

Note that this routine can handle "no damage" attacks (like teleport) by taking a zero damage, and can even take parameters to attacks (like confuse) by accepting a "damage", using it to calculate the effect, and then setting the damage to zero. Note that actual damage should be already adjusted for distance from the "epicenter" when passed in, but other effects may be influenced by r.

Note that "polymorph" is dangerous, since a failure in "place_monster()"' may result in a dereference of an invalid pointer. XXX XXX XXX

Various messages are produced, and damage is applied.

Just casting an element (e.g. plasma) does not make you immune, you must actually be made of that substance, or breathe big balls of it.

We assume that "Plasma" monsters, and "Plasma" breathers, are immune to plasma.

We assume "Nether" is an evil, necromantic force, so it doesn't hurt undead, and hurts evil less. If can breath nether, then it resists it as well. This should actually be coded into monster records rather than aasumed - NRM

Damage reductions use the following formulas: Note that "dam = dam * 6 / (randint1(6) + 6);" gives avg damage of .655, ranging from .858 to .500 Note that "dam = dam * 5 / (randint1(6) + 6);" gives avg damage of .544, ranging from .714 to .417 Note that "dam = dam * 4 / (randint1(6) + 6);" gives avg damage of .444, ranging from .556 to .333 Note that "dam = dam * 3 / (randint1(6) + 6);" gives avg damage of .327, ranging from .427 to .250 Note that "dam = dam * 2 / (randint1(6) + 6);" gives something simple.

In this function, "result" messages are postponed until the end, where the "note" string is appended to the monster name, if not NULL. So, to make a spell have no effect just set "note" to NULL. You should also set "notice" to FALSE, or the player will learn what the spell does.

Note that this function determines if the player can see anything that happens by taking into account: blindness, line-of-sight, and illumination.

Hack – effects on grids which are memorized but not in view are also seen.

References cave, cave_monster(), project_monster_handler_context_s::dam, project_monster_handler_context_s::die_msg, FALSE, monster::fx, monster::fy, get_lore(), gf_force_obvious(), monster::hp, project_monster_handler_context_s::hurt_msg, project_monster_handler_context_s::l_ptr, project_monster_handler_context_s::m_ptr, MDESC_DEFAULT, MDESC_POSS, MDESC_PRO_VIS, monster::mflag, mflag_has, square::mon, monster_desc(), monster_handlers, monster_is_unusual(), player_upkeep::monster_race, project_monster_handler_context_s::obvious, PR_MONSTER, PROJECT_AWARE, project_m_apply_side_effects(), project_m_monster_attack(), project_m_n, project_m_player_attack(), project_m_x, project_m_y, PROJECT_SAFE, monster::race, player_upkeep::redraw, project_monster_handler_context_s::seen, project_monster_handler_context_s::skipped, square_isprojectable(), square_light_spot(), chunk::squares, TRUE, update_mon(), and player::upkeep.

Referenced by project().

bool project_o ( int  who,
int  r,
int  y,
int  x,
int  dam,
int  typ 
)

Called from project() to affect objects.

Called for projections with the PROJECT_ITEM flag set, which includes beam, ball and breath effects.

Parameters
whois the monster list index of the caster
ris the distance from the centre of the effect
y
xthe coordinates of the grid being handled
damis the "damage" from the effect at distance r from the centre
typis the projection (GF_) type
Returns
whether the effects were obvious

Note that this function determines if the player can see anything that happens by taking into account: blindness, line-of-sight, and illumination.

Hack – effects on objects which are memorized but not in view are also seen.

References object::artifact, become_aware(), cave, cave_monster(), project_object_handler_context_s::do_kill, FALSE, project_object_handler_context_s::ignore, object::ignore, ignore_item_ok(), object::marked, object::mimicking_m_idx, msg, msgt(), object::next, project_object_handler_context_s::note_kill, object::number, object_delete(), object_desc(), object_handlers, project_object_handler_context_s::obvious, ODESC_BASE, square_excise_object(), square_light_spot(), square_object(), TRUE, and VERB_AGREEMENT.

Referenced by project().

bool project_p ( int  who,
int  r,
int  y,
int  x,
int  dam,
int  typ 
)

Called from project() to affect the player.

Called for projections with the PROJECT_PLAY flag set, which includes bolt, beam, ball and breath effects.

Parameters
whois the monster list index of the caster
ris the distance from the centre of the effect
y
xthe coordinates of the grid being handled
damis the "damage" from the effect at distance r from the centre
typis the projection (GF_) type
Returns
whether the effects were obvious

If "r" is non-zero, then the blast was centered elsewhere; the damage is reduced in project() before being passed in here. This can happen if a monster breathes at the player and hits a wall instead.

We assume the player is aware of some effect, and always return "TRUE".

References adjust_dam(), cave, cave_monster(), disturb(), player_state::el_info, FALSE, gf_desc(), MDESC_DIED_FROM, monster::mflag, mflag_has, square::mon, monster_desc(), msg, project_player_handler_context_s::obvious, player_handlers, RANDOMISE, element_info::res_level, chunk::squares, player::state, take_hit(), player::timed, and TRUE.

Referenced by project().

int project_path ( struct loc gp,
int  range,
int  y1,
int  x1,
int  y2,
int  x2,
int  flg 
)

Determine the path taken by a projection.

The projection will always start from the grid (y1,x1), and will travel towards the grid (y2,x2), touching one grid per unit of distance along the major axis, and stopping when it enters the destination grid or a wall grid, or has travelled the maximum legal distance of "range".

Note that "distance" in this function (as in the "update_view()" code) is defined as "MAX(dy,dx) + MIN(dy,dx)/2", which means that the player actually has an "octagon of projection" not a "circle of projection".

The path grids are saved into the grid array pointed to by "gp", and there should be room for at least "range" grids in "gp". Note that due to the way in which distance is calculated, this function normally uses fewer than "range" grids for the projection path, so the result of this function should never be compared directly to "range". Note that the initial grid (y1,x1) is never saved into the grid array, not even if the initial grid is also the final grid. XXX XXX XXX

The "flg" flags can be used to modify the behavior of this function.

In particular, the "PROJECT_STOP" and "PROJECT_THRU" flags have the same semantics as they do for the "project" function, namely, that the path will stop as soon as it hits a monster, or that the path will continue through the destination grid, respectively.

The "PROJECT_JUMP" flag, which for the "project()" function means to start at a special grid (which makes no sense in this function), means that the path should be "angled" slightly if needed to avoid any wall grids, allowing the player to "target" any grid which is in "view". This flag is non-trivial and has not yet been implemented, but could perhaps make use of the "vinfo" array (above). XXX XXX XXX

This function returns the number of grids (if any) in the path. This function will return zero if and only if (y1,x1) and (y2,x2) are equal.

This algorithm is similar to, but slightly different from, the one used by "update_view_los()", and very different from the one used by "los()".

References cave, loc(), square::mon, PROJECT_STOP, PROJECT_THRU, square_isprojectable(), and chunk::squares.

Referenced by project(), projectable(), ranged_helper(), and target_set_interactive().

bool projectable ( struct chunk c,
int  y1,
int  x1,
int  y2,
int  x2,
int  flg 
)

Determine if a bolt spell cast from (y1,x1) to (y2,x2) will arrive at the final destination, assuming that no monster gets in the way, using the project_path() function to check the projection path.

Note that no grid is ever projectable() from itself.

This function is used to determine if the player can (easily) target a given grid, and if a monster can target the player.

References FALSE, angband_constants::max_range, project_path(), square_ispassable(), TRUE, loc::x, loc::y, and z_info.

Referenced by find_hiding(), make_attack_spell(), monster_list_collect(), near_permwall(), and target_able().

Variable Documentation

byte gf_to_attr[GF_MAX][BOLT_MAX]
wchar_t gf_to_char[GF_MAX][BOLT_MAX]
int project_m_n
int project_m_x
int project_m_y