Hengband  2.2.1
関数 | 変数
spells1.c ファイル

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

#include "angband.h"
#include "core.h"
#include "util.h"
#include "cmd-pet.h"
#include "cmd-dump.h"
#include "floor.h"
#include "trap.h"
#include "autopick.h"
#include "object-curse.h"
#include "player-damage.h"
#include "player-effects.h"
#include "player-race.h"
#include "player-class.h"
#include "monster.h"
#include "monster-status.h"
#include "monster-spell.h"
#include "spells.h"
#include "spells-status.h"
#include "spells-diceroll.h"
#include "spells-summon.h"
#include "monsterrace-hook.h"
#include "melee.h"
#include "world.h"
#include "mutation.h"
#include "rooms.h"
#include "artifact.h"
#include "avatar.h"
#include "player-status.h"
#include "player-move.h"
#include "realm-hex.h"
#include "realm-song.h"
#include "object-hook.h"
#include "object-broken.h"
#include "object-flavor.h"
#include "quest.h"
#include "term.h"
#include "grid.h"
#include "feature.h"
#include "view-mainwindow.h"
#include "dungeon.h"
spells1.c の依存先関係図:

関数

static void next_mirror (player_type *creature_ptr, POSITION *next_y, POSITION *next_x, POSITION cury, POSITION curx)
 配置した鏡リストの次を取得する / Get another mirror. [詳解]
 
static bool project_f (floor_type *floor_ptr, MONSTER_IDX who, POSITION r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ)
 汎用的なビーム/ボルト/ボール系による地形効果処理 / We are called from "project()" to "damage" terrain features [詳解]
 
static bool project_o (MONSTER_IDX who, POSITION r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ)
 汎用的なビーム/ボルト/ボール系によるアイテムオブジェクトへの効果処理 / Handle a beam/bolt/ball causing damage to a monster. [詳解]
 
static bool project_m (MONSTER_IDX who, POSITION r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flg, bool see_s_msg)
 汎用的なビーム/ボルト/ボール系によるモンスターへの効果処理 / Handle a beam/bolt/ball causing damage to a monster. [詳解]
 
static bool project_p (MONSTER_IDX who, player_type *target_ptr, concptr who_name, int r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flg, int monspell)
 汎用的なビーム/ボルト/ボール系によるプレイヤーへの効果処理 / Helper function for "project()" below. [詳解]
 
POSITION dist_to_line (POSITION y, POSITION x, POSITION y1, POSITION x1, POSITION y2, POSITION x2)
 
bool in_disintegration_range (POSITION y1, POSITION x1, POSITION y2, POSITION x2)
 
void breath_shape (u16b *path_g, int dist, int *pgrids, POSITION *gx, POSITION *gy, POSITION *gm, POSITION *pgm_rad, POSITION rad, POSITION y1, POSITION x1, POSITION y2, POSITION x2, EFFECT_ID typ)
 
bool project (MONSTER_IDX who, POSITION rad, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flg, int monspell)
 汎用的なビーム/ボルト/ボール系処理のルーチン Generic "beam"/"bolt"/"ball" projection routine. [詳解]
 
bool binding_field (player_type *caster_ptr, HIT_POINT dam)
 鏡魔法「封魔結界」の効果処理 [詳解]
 
void seal_of_mirror (HIT_POINT dam)
 鏡魔法「鏡の封印」の効果処理 [詳解]
 
concptr spell_category_name (OBJECT_TYPE_VALUE tval)
 領域魔法に応じて技能の名称を返す。 [詳解]
 

変数

static int rakubadam_m
 振り落とされた際のダメージ量 [詳解]
 
static int rakubadam_p
 落馬した際のダメージ量 [詳解]
 
bool sukekaku
 
int project_length = 0
 投射の射程距離 [詳解]
 
int cap_mon
 
int cap_mspeed
 
HIT_POINT cap_hp
 
HIT_POINT cap_maxhp
 
STR_OFFSET cap_nickname
 
const magic_type technic_info [NUM_TECHNIC][32]
 歌、剣術、呪術領域情報テーブル [詳解]
 
static int project_m_n
 魔法効果範囲内にいるモンスターの数 [詳解]
 
static POSITION project_m_x
 処理中のモンスターX座標 [詳解]
 
static POSITION project_m_y
 処理中のモンスターY座標 [詳解]
 
static POSITION monster_target_x
 モンスターの攻撃目標X座標 [詳解]
 
static POSITION 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.

関数詳解

◆ binding_field()

bool binding_field ( player_type caster_ptr,
HIT_POINT  dam 
)

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

引数
damダメージ量
戻り値
効果があったらTRUEを返す
呼び出し関係図:

◆ breath_shape()

void breath_shape ( u16b path_g,
int  dist,
int *  pgrids,
POSITION gx,
POSITION gy,
POSITION gm,
POSITION pgm_rad,
POSITION  rad,
POSITION  y1,
POSITION  x1,
POSITION  y2,
POSITION  x2,
EFFECT_ID  typ 
)
呼び出し関係図:

◆ dist_to_line()

POSITION dist_to_line ( POSITION  y,
POSITION  x,
POSITION  y1,
POSITION  x1,
POSITION  y2,
POSITION  x2 
)
呼び出し関係図:

◆ in_disintegration_range()

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

◆ next_mirror()

static void next_mirror ( player_type creature_ptr,
POSITION next_y,
POSITION next_x,
POSITION  cury,
POSITION  curx 
)
static

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

for SEEKER

引数
next_y次の鏡のy座標を返す参照ポインタ
next_x次の鏡のx座標を返す参照ポインタ
cury現在の鏡のy座標
curx現在の鏡のx座標
呼び出し関係図:
被呼び出し関係図:

◆ project()

bool project ( MONSTER_IDX  who,
POSITION  rad,
POSITION  y,
POSITION  x,
HIT_POINT  dam,
EFFECT_ID  typ,
BIT_FLAGS  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)
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.
呼び出し関係図:

◆ project_f()

static bool project_f ( floor_type floor_ptr,
MONSTER_IDX  who,
POSITION  r,
POSITION  y,
POSITION  x,
HIT_POINT  dam,
EFFECT_ID  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".
We also "see" grids which are "memorized", probably a hack
Perhaps we should affect doors?
呼び出し関係図:
被呼び出し関係図:

◆ project_m()

static bool project_m ( MONSTER_IDX  who,
POSITION  r,
POSITION  y,
POSITION  x,
HIT_POINT  dam,
EFFECT_ID  typ,
BIT_FLAGS  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.  
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.
呼び出し関係図:
被呼び出し関係図:

◆ project_o()

static bool project_o ( MONSTER_IDX  who,
POSITION  r,
POSITION  y,
POSITION  x,
HIT_POINT  dam,
EFFECT_ID  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.
We also "see" grids which are "memorized", probably a hack
We return "TRUE" if the effect of the projection is "obvious".
呼び出し関係図:
被呼び出し関係図:

◆ project_p()

static bool project_p ( MONSTER_IDX  who,
player_type target_ptr,
concptr  who_name,
int  r,
POSITION  y,
POSITION  x,
HIT_POINT  dam,
EFFECT_ID  typ,
BIT_FLAGS  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.

呼び出し関係図:
被呼び出し関係図:

◆ seal_of_mirror()

void seal_of_mirror ( HIT_POINT  dam)

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

引数
damダメージ量
戻り値
効果があったらTRUEを返す
呼び出し関係図:

◆ spell_category_name()

concptr spell_category_name ( OBJECT_TYPE_VALUE  tval)

領域魔法に応じて技能の名称を返す。

引数
tval魔法書のtval
戻り値
領域魔法の技能名称を保管した文字列ポインタ

変数詳解

◆ cap_hp

HIT_POINT cap_hp

◆ cap_maxhp

HIT_POINT cap_maxhp

◆ cap_mon

int cap_mon

◆ cap_mspeed

int cap_mspeed

◆ cap_nickname

STR_OFFSET cap_nickname

◆ monster_target_x

POSITION monster_target_x
static

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

◆ monster_target_y

POSITION monster_target_y
static

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

◆ project_length

int project_length = 0

投射の射程距離

◆ project_m_n

int project_m_n
static

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

◆ project_m_x

POSITION project_m_x
static

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

◆ project_m_y

POSITION project_m_y
static

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

◆ rakubadam_m

int rakubadam_m
static

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

◆ rakubadam_p

int rakubadam_p
static

落馬した際のダメージ量

◆ sukekaku

bool sukekaku

◆ technic_info

const magic_type technic_info[NUM_TECHNIC][32]

歌、剣術、呪術領域情報テーブル