Macros | Functions | Variables
project.c File Reference

The project() function and helpers. More...

#include "angband.h"
#include "cave.h"
#include "game-event.h"
#include "game-input.h"
#include "generate.h"
#include "init.h"
#include "mon-predicate.h"
#include "mon-util.h"
#include "player-calcs.h"
#include "player-timed.h"
#include "project.h"
#include "source.h"
#include "trap.h"
#include "list-elements.h"
#include "list-projections.h"


#define ELEM(a)   #a,
#define PROJ(a)   #a,


int proj_name_to_idx (const char *name)
const char * proj_idx_to_name (int type)
int project_path (struct loc *gp, int range, struct loc grid1, struct loc grid2, int flg)

Projection paths

bool projectable (struct chunk *c, struct loc grid1, struct loc grid2, int flg)
 Determine if a bolt spell cast from grid1 to grid2 will arrive at the final destination, assuming that no monster gets in the way, using the project_path() function to check the projection path. More...
struct loc origin_get_loc (struct source origin)

The main project() function and its helpers

bool project (struct source origin, int rad, struct loc finish, int dam, int typ, int flg, int degrees_of_arc, byte diameter_of_source, const struct object *obj)
 Generic "beam"/"bolt"/"ball" projection routine. More...


struct projectionprojections
byte proj_to_attr [PROJ_MAX][BOLT_MAX]
wchar_t proj_to_char [PROJ_MAX][BOLT_MAX]
static const char * proj_name_list []

PROJ type info needed for projections More...


Detailed Description

The project() function and helpers.

Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke

This work is free software; you can redistribute it and/or modify it under the terms of either:

a) the GNU General Public License as published by the Free Software Foundation, version 2, or

b) the "Angband licence": This software may be copied and distributed for educational, research, and not for profit purposes provided that this copyright and statement are included in all such copies. Other copyrights may also apply.

Macro Definition Documentation


#define ELEM (   a)    #a,


#define PROJ (   a)    #a,

Function Documentation

◆ origin_get_loc()

struct loc origin_get_loc ( struct source  origin)

The main project() function and its helpers

Given an origin, find its coordinates and return them

If there is no origin, return (-1, -1)

References cave, cave_monster(), trap::grid, monster::grid, player::grid, and loc().

Referenced by effect_handler_EARTHQUAKE(), effect_handler_MAP_AREA(), effect_handler_PROJECT_LOS(), effect_handler_WAKE(), project(), project_monster_handler_FORCE(), and project_player_handler_FORCE().

◆ proj_idx_to_name()

const char* proj_idx_to_name ( int  type)

References PROJ_MAX, proj_name_list, and type.

Referenced by proj_display().

◆ proj_name_to_idx()

int proj_name_to_idx ( const char *  name)

◆ project()

bool project ( struct source  origin,
int  rad,
struct loc  finish,
int  dam,
int  typ,
int  flg,
int  degrees_of_arc,
byte  diameter_of_source,
const struct object obj 

Generic "beam"/"bolt"/"ball" projection routine.

-BEN-, some changes by -LM-

originOrigin of the projection
radRadius of explosion (0 = beam/bolt, 1 to 20 = ball), or maximum length of arc from the source.
yTarget location (or location to travel towards)
xTarget location (or location to travel towards)
damBase damage to apply to monsters, terrain, objects, or player
typType of projection (fire, frost, dispel demons etc.)
flgExtra bit flags that control projection behavior
degrees_of_arcHow wide an arc spell is (in degrees).
diameter_of_sourcehow wide the source diameter is.
objAn object that the projection ignores
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.


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 from 20, which allows the spell designer to fine-tune how quickly a breath loses strength outwards from the breather.

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(), ddgrid_ddd, distance(), EVENT_BOLT, EVENT_EXPLOSION, event_signal_blast(), event_signal_bolt(), get_angle_to_grid, monster::grid, handle_stuff(), health_track(), i, player::is_dead, loc(), loc_eq(), loc_sum(), los(), MAX, angband_constants::max_range, source::monster, monster_is_powerful(), monster_is_visible(), monster_race_track(), origin_get_loc(), panel_contains(), PROJECT_ARC, PROJECT_BEAM, project_f(), PROJECT_GRID, PROJECT_HIDE, PROJECT_ITEM, PROJECT_JUMP, PROJECT_KILL, project_m(), project_o(), project_p(), project_path(), PROJECT_PLAY, PROJECT_SELF, PROJECT_THRU, monster::race, monster_race::spell_power, sqinfo_off, sqinfo_on, square(), square_in_bounds(), square_ispassable(), square_isproject(), square_isprojectable(), square_isview(), square_monster(), start, player::timed, player_upkeep::update, update_stuff(), player::upkeep, source::what, source::which, loc::x, loc::y, and z_info.

Referenced by effect_handler_ARC(), effect_handler_BALL(), effect_handler_BIZARRE(), effect_handler_BREATH(), effect_handler_LASH(), effect_handler_PROJECT_LOS(), effect_handler_PROJECT_LOS_AWARE(), effect_handler_SHORT_BEAM(), effect_handler_SPHERE(), effect_handler_SPOT(), effect_handler_STAR(), effect_handler_STAR_BALL(), effect_handler_STRIKE(), effect_handler_SWARM(), effect_handler_TOUCH(), project_aimed(), and project_touch().

◆ project_path()

int project_path ( struct loc gp,
int  range,
struct loc  grid1,
struct loc  grid2,
int  flg 

Projection paths

Determine the path taken by a projection.

The projection will always start from the grid1, and will travel towards grid2, touching one grid per unit of distance along the major axis, and stopping when it enters the finish 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 grid1 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 finish 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 grid1 and grid2 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, cave_find_decoy(), loc(), loc_eq(), PROJECT_INFO, PROJECT_ROCK, PROJECT_STOP, PROJECT_THRU, square(), square_isbelievedwall(), square_isprojectable(), loc::x, and loc::y.

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

◆ projectable()

bool projectable ( struct chunk c,
struct loc  grid1,
struct loc  grid2,
int  flg 

Determine if a bolt spell cast from grid1 to grid2 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 loc_eq(), angband_constants::max_range, project_path(), PROJECT_SHORT, square_ispassable(), player::timed, and z_info.

Referenced by effect_handler_STRIKE(), get_move_find_hiding(), make_ranged_attack(), monster_can_cast(), monster_list_collect(), monster_near_permwall(), object_list_collect(), object_list_format_name(), and target_able().

Variable Documentation

◆ proj_name_list

const char* proj_name_list[]

PROJ type info needed for projections

Note that elements come first, so PROJ_ACID == ELEM_ACID, etc

Referenced by proj_idx_to_name(), and proj_name_to_idx().

◆ proj_to_attr

byte proj_to_attr[PROJ_MAX][BOLT_MAX]

◆ proj_to_char

wchar_t proj_to_char[PROJ_MAX][BOLT_MAX]

◆ projections

struct projection* projections