Hengband  2.1.4
 全て データ構造 ファイル 関数 変数 型定義 マクロ定義 ページ
マクロ定義 | 関数 | 変数
spells1.c

魔法による遠隔処理の実装 / Spell projection [詳細]

#include "angband.h"
spells1.cのインクルード依存関係図

マクロ定義

#define HURT_CHANCE   16
 属性攻撃を受けた際に能力値低下を起こす確率(1/X) / 1/x chance of reducing stats (for elemental attacks) [詳細]
 

関数

static void next_mirror (int *next_y, int *next_x, int cury, int curx)
 配置した鏡リストの次を取得する / Get another mirror. [詳細]
 
static byte mh_attr (int max)
 万色表現用にランダムな色を選択する関数 / Get a legal "multi-hued" color for drawing "spells" [詳細]
 
static byte spell_color (int type)
 魔法属性に応じたエフェクトの色を返す / Return a color to use for the bolt/ball spells [詳細]
 
u16b bolt_pict (int y, int x, int ny, int nx, int typ)
 始点から終点にかけた方向毎にボルトのキャラクタを返す / Find the attr/char pair to use for a spell effect [詳細]
 
sint project_path (u16b *gp, int range, int y1, int x1, int y2, int x2, int flg)
 始点から終点への経路を返す / Determine the path taken by a projection. [詳細]
 
static bool project_f (int who, int r, int y, int x, int dam, int typ)
 汎用的なビーム/ボルト/ボール系による地形効果処理 / We are called from "project()" to "damage" terrain features [詳細]
 
static bool project_o (int who, int r, int y, int x, int dam, int typ)
 汎用的なビーム/ボルト/ボール系によるアイテムオブジェクトへの効果処理 / Handle a beam/bolt/ball causing damage to a monster. [詳細]
 
static bool project_m (int who, int r, int y, int x, int dam, int typ, int flg, bool see_s_msg)
 汎用的なビーム/ボルト/ボール系によるモンスターへの効果処理 / Handle a beam/bolt/ball causing damage to a monster. [詳細]
 
static bool project_p (int who, cptr who_name, int r, int y, int x, int dam, int typ, int flg, int monspell)
 汎用的なビーム/ボルト/ボール系によるプレイヤーへの効果処理 / Helper function for "project()" below. [詳細]
 
int dist_to_line (int y, int x, int y1, int x1, int y2, int x2)
 
bool in_disintegration_range (int y1, int x1, int y2, int x2)
 
void breath_shape (u16b *path_g, int dist, int *pgrids, byte *gx, byte *gy, byte *gm, int *pgm_rad, int rad, int y1, int x1, int y2, int x2, int typ)
 
bool project (int who, int rad, int y, int x, int dam, int typ, int flg, int monspell)
 汎用的なビーム/ボルト/ボール系処理のルーチン Generic "beam"/"bolt"/"ball" projection routine. [詳細]
 
bool binding_field (int dam)
 鏡魔法「封魔結界」の効果処理 [詳細]
 
void seal_of_mirror (int dam)
 鏡魔法「鏡の封印」の効果処理 [詳細]
 

変数

static int rakubadam_m
 振り落とされた際のダメージ量 [詳細]
 
static int rakubadam_p
 落馬した際のダメージ量 [詳細]
 
int project_length = 0
 投射の射程距離 [詳細]
 
static int project_m_n
 魔法効果範囲内にいるモンスターの数 [詳細]
 
static int project_m_x
 処理中のモンスターX座標 [詳細]
 
static int project_m_y
 処理中のモンスターY座標 [詳細]
 
static s16b monster_target_x
 モンスターの攻撃目標X座標 [詳細]
 
static s16b monster_target_y
 モンスターの攻撃目標Y座標 [詳細]
 

説明

魔法による遠隔処理の実装 / Spell projection

日付
2014/07/10
作者
Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
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.

マクロ定義

#define HURT_CHANCE   16

属性攻撃を受けた際に能力値低下を起こす確率(1/X) / 1/x chance of reducing stats (for elemental attacks)

関数

bool binding_field ( int  dam)

鏡魔法「封魔結界」の効果処理

引数
damダメージ量
戻り値
効果があったらTRUEを返す

関数の呼び出しグラフ:

呼出しグラフ:

u16b bolt_pict ( int  y,
int  x,
int  ny,
int  nx,
int  typ 
)

始点から終点にかけた方向毎にボルトのキャラクタを返す / Find the attr/char pair to use for a spell effect

引数
y始点Y座標
x始点X座標
ny終点Y座標
nx終点X座標
typ魔法の効果属性
戻り値
方向キャラID
It is moving (or has moved) from (x,y) to (nx,ny).
If the distance is not "one", we (may) return "*".

関数の呼び出しグラフ:

呼出しグラフ:

void breath_shape ( u16b path_g,
int  dist,
int *  pgrids,
byte gx,
byte gy,
byte gm,
int *  pgm_rad,
int  rad,
int  y1,
int  x1,
int  y2,
int  x2,
int  typ 
)

関数の呼び出しグラフ:

呼出しグラフ:

int dist_to_line ( int  y,
int  x,
int  y1,
int  x1,
int  y2,
int  x2 
)

関数の呼び出しグラフ:

呼出しグラフ:

bool in_disintegration_range ( int  y1,
int  x1,
int  y2,
int  x2 
)

呼出しグラフ:

static byte mh_attr ( int  max)
static

万色表現用にランダムな色を選択する関数 / Get a legal "multi-hued" color for drawing "spells"

引数
max色IDの最大値
戻り値
選択した色ID

呼出しグラフ:

static void next_mirror ( int *  next_y,
int *  next_x,
int  cury,
int  curx 
)
static

配置した鏡リストの次を取得する / Get another mirror.

for SEEKER

引数
next_y次の鏡のy座標を返す参照ポインタ
next_x次の鏡のx座標を返す参照ポインタ
cury現在の鏡のy座標
curx現在の鏡のx座標

関数の呼び出しグラフ:

呼出しグラフ:

bool project ( int  who,
int  rad,
int  y,
int  x,
int  dam,
int  typ,
int  flg,
int  monspell 
)

汎用的なビーム/ボルト/ボール系処理のルーチン Generic "beam"/"bolt"/"ball" projection routine.

引数
who魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
rad効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
y目標Y座標 / Target y location (or location to travel "towards")
x目標X座標 / Target x location (or location to travel "towards")
dam基本威力 / Base damage roll to apply to affected monsters (or player)
typ効果属性 / Type of damage to apply to monsters (and objects)
flg効果フラグ / Extra bit flags (see PROJECT_xxxx in "defines.h")
monspell効果元のモンスター魔法ID
戻り値
何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
Allows a monster (or player) to project a beam/bolt/ball of a given kind
towards a given location (optionally passing over the heads of interposing
monsters), and have it do a given amount of damage to the monsters (and
optionally objects) within the given radius of the final location.
A "bolt" travels from source to target and affects only the target grid.
A "beam" travels from source to target, affecting all grids passed through.
A "ball" travels from source to the target, exploding at the target, and
  affecting everything within the given radius of the target location.
Traditionally, a "bolt" does not affect anything on the ground, and does
not pass over the heads of interposing monsters, much like a traditional
missile, and will "stop" abruptly at the "target" even if no monster is
positioned there, while a "ball", on the other hand, passes over the heads
of monsters between the source and target, and affects everything except
the source monster which lies within the final radius, while a "beam"
affects every monster between the source and target, except for the casting
monster (or player), and rarely affects things on the ground.
Two special flags allow us to use this function in special ways, the
"PROJECT_HIDE" flag allows us to perform "invisible" projections, while
the "PROJECT_JUMP" flag allows us to affect a specific grid, without
actually projecting from the source monster (or player).
The player will only get "experience" for monsters killed by himself
Unique monsters can only be destroyed by attacks from the player
Only 256 grids can be affected per projection, limiting the effective
"radius" of standard ball attacks to nine units (diameter nineteen).
One can project in a given "direction" by combining PROJECT_THRU with small
offsets to the initial location (see "line_spell()"), or by calculating
"virtual targets" far away from the player.
One can also use PROJECT_THRU to send a beam/bolt along an angled path,
continuing until it actually hits somethings (useful for "stone to mud").
Bolts and Beams explode INSIDE walls, so that they can destroy doors.
Balls must explode BEFORE hitting walls, or they would affect monsters
on both sides of a wall.  Some bug reports indicate that this is still
happening in 2.7.8 for Windows, though it appears to be impossible.
We "pre-calculate" the blast area only in part for efficiency.
More importantly, this lets us do "explosions" from the "inside" out.
This results in a more logical distribution of "blast" treasure.
It also produces a better (in my opinion) animation of the explosion.
It could be (but is not) used to have the treasure dropped by monsters
in the middle of the explosion fall "outwards", and then be damaged by
the blast as it spreads outwards towards the treasure drop location.
Walls and doors are included in the blast area, so that they can be
"burned" or "melted" in later versions.
This algorithm is intended to maximize simplicity, not necessarily
efficiency, since this function is not a bottleneck in the code.
We apply the blast effect from ground zero outwards, in several passes,
first affecting features, then objects, then monsters, then the player.
This allows walls to be removed before checking the object or monster
in the wall, and protects objects which are dropped by monsters killed
in the blast, and allows the player to see all affects before he is
killed or teleported away.  The semantics of this method are open to
various interpretations, but they seem to work well in practice.
We process the blast area from ground-zero outwards to allow for better
distribution of treasure dropped by monsters, and because it provides a
pleasing visual effect at low cost.
Note that the damage done by "ball" explosions decreases with distance.
This decrease is rapid, grids at radius "dist" take "1/dist" damage.
Notice the "napalm" effect of "beam" weapons.  First they "project" to
the target, and then the damage "flows" along this beam of destruction.
The damage at every grid is the same as at the "center" of a "ball"
explosion, since the "beam" grids are treated as if they ARE at the
center of a "ball" explosion.
Currently, specifying "beam" plus "ball" means that locations which are
covered by the initial "beam", and also covered by the final "ball", except
for the final grid (the epicenter of the ball), will be "hit twice", once
by the initial beam, and once by the exploding ball.  For the grid right
next to the epicenter, this results in 150% damage being done.  The center
does not have this problem, for the same reason the final grid in a "beam"
plus "bolt" does not – it is explicitly removed.  Simply removing "beam"
grids which are covered by the "ball" will NOT work, as then they will
receive LESS damage than they should.  Do not combine "beam" with "ball".
The array "gy[],gx[]" with current size "grids" is used to hold the
collected locations of all grids in the "blast area" plus "beam path".
Note the rather complex usage of the "gm[]" array.  First, gm[0] is always
zero.  Second, for N>1, gm[N] is always the index (in gy[],gx[]) of the
first blast grid (see above) with radius "N" from the blast center.  Note
that only the first gm[1] grids in the blast area thus take full damage.
Also, note that gm[rad+1] is always equal to "grids", which is the total
number of blast grids.
Note that once the projection is complete, (y2,x2) holds the final location
of bolts/beams, and the "epicenter" of balls.
Note also that "rad" specifies the "inclusive" radius of projection blast,
so that a "rad" of "one" actually covers 5 or 9 grids, depending on the
implementation of the "distance" function.  Also, a bolt can be properly
viewed as a "ball" with a "rad" of "zero".
Note that if no "target" is reached before the beam/bolt/ball travels the
maximum distance allowed (MAX_RANGE), no "blast" will be induced.  This
may be relevant even for bolts, since they have a "1x1" mini-blast.
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 all projections now "explode" at their final destination, even
if they were being projected at a more distant destination.  This means
that "ball" spells will always explode.
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.

関数の呼び出しグラフ:

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

汎用的なビーム/ボルト/ボール系による地形効果処理 / We are called from "project()" to "damage" terrain features

引数
who魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
r効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
y目標Y座標 / Target y location (or location to travel "towards")
x目標X座標 / Target x location (or location to travel "towards")
dam基本威力 / Base damage roll to apply to affected monsters (or player)
typ効果属性 / Type of damage to apply to monsters (and objects)
戻り値
何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
We are called both for "beam" effects and "ball" effects.
The "r" parameter is the "distance from ground zero".
Note that we determine if the player can "see" anything that happens
by taking into account: blindness, line-of-sight, and illumination.
We return "TRUE" if the effect of the projection is "obvious".
XXX XXX XXX We also "see" grids which are "memorized", probably a hack
XXX XXX XXX Perhaps we should affect doors?

関数の呼び出しグラフ:

呼出しグラフ:

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

汎用的なビーム/ボルト/ボール系によるモンスターへの効果処理 / Handle a beam/bolt/ball causing damage to a monster.

引数
who魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
r効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
y目標Y座標 / Target y location (or location to travel "towards")
x目標X座標 / Target x location (or location to travel "towards")
dam基本威力 / Base damage roll to apply to affected monsters (or player)
typ効果属性 / Type of damage to apply to monsters (and objects)
flg効果フラグ
see_s_msgTRUEならばメッセージを表示する
戻り値
何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
This routine takes a "source monster" (by index) which is mostly used to
determine if the player is causing the damage, and a "radius" (see below),
which is used to decrease the power of explosions with distance, and a
location, via integers which are modified by certain types of attacks
(polymorph and teleport being the obvious ones), a default damage, which
is modified as needed based on various properties, and finally a "damage
type" (see below).
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 the "damage" parameter is
divided by the radius, so monsters not at the "epicenter" will not take
as much damage (or whatever)...
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" a substance (i.e. 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.
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.
We attempt to return "TRUE" if the player saw anything "useful" happen.
"flg" was added.

呼出しグラフ:

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

汎用的なビーム/ボルト/ボール系によるアイテムオブジェクトへの効果処理 / Handle a beam/bolt/ball causing damage to a monster.

引数
who魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
r効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
y目標Y座標 / Target y location (or location to travel "towards")
x目標X座標 / Target x location (or location to travel "towards")
dam基本威力 / Base damage roll to apply to affected monsters (or player)
typ効果属性 / Type of damage to apply to monsters (and objects)
戻り値
何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
We are called from "project()" to "damage" objects
We are called both for "beam" effects and "ball" effects.
Perhaps we should only SOMETIMES damage things on the ground.
The "r" parameter is the "distance from ground zero".
Note that we determine if the player can "see" anything that happens
by taking into account: blindness, line-of-sight, and illumination.
XXX XXX XXX We also "see" grids which are "memorized", probably a hack
We return "TRUE" if the effect of the projection is "obvious".

関数の呼び出しグラフ:

呼出しグラフ:

static bool project_p ( int  who,
cptr  who_name,
int  r,
int  y,
int  x,
int  dam,
int  typ,
int  flg,
int  monspell 
)
static

汎用的なビーム/ボルト/ボール系によるプレイヤーへの効果処理 / Helper function for "project()" below.

引数
who魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
who_name効果を起こしたモンスターの名前
r効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
y目標Y座標 / Target y location (or location to travel "towards")
x目標X座標 / Target x location (or location to travel "towards")
dam基本威力 / Base damage roll to apply to affected monsters (or player)
typ効果属性 / Type of damage to apply to monsters (and objects)
flg効果フラグ
monspell効果元のモンスター魔法ID
戻り値
何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE

Handle a beam/bolt/ball causing damage to the player. This routine takes a "source monster" (by index), a "distance", a default "damage", and a "damage type". See "project_m()" above. If "rad" is non-zero, then the blast was centered elsewhere, and the damage is reduced (see "project_m()" above). This can happen if a monster breathes at the player and hits a wall instead. NOTE (Zangband): 'Bolt' attacks can be reflected back, so we need to know if this is actually a ball or a bolt spell We return "TRUE" if any "obvious" effects were observed. XXX XXX Actually, we just assume that the effects were obvious, for historical reasons.

関数の呼び出しグラフ:

呼出しグラフ:

sint project_path ( u16b gp,
int  range,
int  y1,
int  x1,
int  y2,
int  x2,
int  flg 
)

始点から終点への経路を返す / Determine the path taken by a projection.

引数
gp経路座標リストを返す参照ポインタ
range距離
y1始点Y座標
x1始点X座標
y2終点Y座標
x2終点X座標
flgフラグID
戻り値
リストの長さ
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()".

呼出しグラフ:

void seal_of_mirror ( int  dam)

鏡魔法「鏡の封印」の効果処理

引数
damダメージ量
戻り値
効果があったらTRUEを返す

関数の呼び出しグラフ:

呼出しグラフ:

static byte spell_color ( int  type)
static

魔法属性に応じたエフェクトの色を返す / Return a color to use for the bolt/ball spells

引数
type魔法属性
戻り値
対応する色ID

関数の呼び出しグラフ:

呼出しグラフ:

変数

s16b monster_target_x
static

モンスターの攻撃目標X座標

s16b monster_target_y
static

モンスターの攻撃目標Y座標

int project_length = 0

投射の射程距離

int project_m_n
static

魔法効果範囲内にいるモンスターの数

int project_m_x
static

処理中のモンスターX座標

int project_m_y
static

処理中のモンスターY座標

int rakubadam_m
static

振り落とされた際のダメージ量

int rakubadam_p
static

落馬した際のダメージ量