diff options
author | Adam Borowski <kilobyte@angband.pl> | 2009-12-19 22:51:57 +0100 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2009-12-20 17:29:36 +0100 |
commit | 0cebeb433d68aea197f5ee1d2c38809b71c2e3dd (patch) | |
tree | 67cea0b5ab60075666e8ca110c9aa7035bfa0d79 | |
parent | 7e4b512c4cf3b6269ddb3748760c8cf050b60b39 (diff) | |
download | crawl-ref-0cebeb433d68aea197f5ee1d2c38809b71c2e3dd.tar.gz crawl-ref-0cebeb433d68aea197f5ee1d2c38809b71c2e3dd.zip |
Iskenderun's Orb of Destruction
-rw-r--r-- | crawl-ref/source/beam.cc | 18 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/fight.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/main.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/makefile.obj | 1 | ||||
-rw-r--r-- | crawl-ref/source/mgen_data.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-act.cc | 16 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 13 | ||||
-rw-r--r-- | crawl-ref/source/mon-project.cc | 172 | ||||
-rw-r--r-- | crawl-ref/source/mon-project.h | 17 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/spl-book.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/spl-cast.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/spl-data.h | 13 |
14 files changed, 268 insertions, 8 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index affd03ce5a..c887250051 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -1357,7 +1357,23 @@ const zap_info zap_data[] = { false, false, 0 - } + }, + + { + ZAP_IOOD, + "0", + 200, + NULL, + new tohit_calculator<AUTOMATIC_HIT>, + WHITE, + false, + BEAM_NUKE, + DCHAR_FIRED_ZAP, + true, + true, + false, + 0 + }, }; static void _zappy(zap_type z_type, int power, bolt &pbolt) diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 94d2b6328d..fe079d395f 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -1671,8 +1671,8 @@ enum monster_type // (int) menv[].type MONS_KOBOLD_DEMONOLOGIST, MONS_ORC_WIZARD, MONS_ORC_KNIGHT, // 55 - //MONS_WORM_TAIL = 56, // deprecated and now officially removed {dlb} - MONS_WYVERN = 57, // 57 + MONS_ORB_OF_DESTRUCTION, // a projectile, not a real mon + MONS_WYVERN, MONS_BIG_KOBOLD, MONS_GIANT_EYEBALL, MONS_WIGHT, // 60 @@ -2912,6 +2912,7 @@ enum spell_type SPELL_BLINK_CLOSE, SPELL_BLINK_RANGE, SPELL_BLINK_AWAY, + SPELL_IOOD, NUM_SPELLS }; @@ -3159,6 +3160,7 @@ enum zap_type ZAP_SLIME, ZAP_PORKALATOR, ZAP_SLEEP, + ZAP_IOOD, NUM_ZAPS }; diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 3c349e283c..dc1410a5a6 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -4306,7 +4306,8 @@ bool melee_attack::mons_attack_mons() bool melee_attack::mons_self_destructs() { if (attacker->id() == MONS_GIANT_SPORE - || attacker->id() == MONS_BALL_LIGHTNING) + || attacker->id() == MONS_BALL_LIGHTNING + || attacker->id() == MONS_ORB_OF_DESTRUCTION) { attacker_as_monster()->hit_points = -1; // Do the explosion right now. diff --git a/crawl-ref/source/main.cc b/crawl-ref/source/main.cc index d3feb08c00..2a68a7f624 100644 --- a/crawl-ref/source/main.cc +++ b/crawl-ref/source/main.cc @@ -4618,7 +4618,7 @@ static void _compile_time_asserts() COMPILE_CHECK(SP_VAMPIRE == 30 , c3); COMPILE_CHECK(SPELL_DEBUGGING_RAY == 103 , c4); COMPILE_CHECK(SPELL_RETURNING_AMMUNITION == 162 , c5); - COMPILE_CHECK(NUM_SPELLS == 211 , c6); + COMPILE_CHECK(NUM_SPELLS == 212 , c6); //jmf: NEW ASSERTS: we ought to do a *lot* of these COMPILE_CHECK(NUM_SPECIES < SP_UNKNOWN , c7); diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index fd38cf9783..633a9d2a54 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -112,6 +112,7 @@ mon-movetarget.o \ mon-pathfind.o \ mon-pick.o \ mon-place.o \ +mon-project.o \ mon-util.o \ mon-speak.o \ mon-stuff.o \ diff --git a/crawl-ref/source/mgen_data.h b/crawl-ref/source/mgen_data.h index 6934100ede..d2794796ec 100644 --- a/crawl-ref/source/mgen_data.h +++ b/crawl-ref/source/mgen_data.h @@ -132,7 +132,7 @@ struct mgen_data non_actor_summoner(nas), props() { ASSERT(summon_type == 0 || (abj >= 1 && abj <= 6) - || mt == MONS_BALL_LIGHTNING); + || mt == MONS_BALL_LIGHTNING || mt == MONS_ORB_OF_DESTRUCTION); } bool permit_bands() const { return (flags & MG_PERMIT_BANDS); } diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc index 16c025e217..a3a46955ce 100644 --- a/crawl-ref/source/mon-act.cc +++ b/crawl-ref/source/mon-act.cc @@ -33,6 +33,7 @@ #include "mon-cast.h" #include "mon-iter.h" #include "mon-place.h" +#include "mon-project.h" #include "mgen_data.h" #include "coord.h" #include "mon-stuff.h" @@ -1708,6 +1709,14 @@ static void _handle_monster_move(monsters *monster) } old_energy = monster->speed_increment; + if (mons_is_projectile(monster->type)) + { + if (iood_act(*monster)) + return; + monster->lose_energy(EUT_MOVE); + continue; + } + monster->shield_blocks = 0; cloud_type cl_type; @@ -3416,6 +3425,13 @@ static bool _monster_move(monsters *monster) 2 + random2(3), monster->kill_alignment(), KILL_MON_MISSILE ); } + + if (monster->type == MONS_ORB_OF_DESTRUCTION) + { + place_cloud( CLOUD_TLOC_ENERGY, monster->pos(), + 2 + random2(3), monster->kill_alignment(), + KILL_MON_MISSILE ); + } } else { diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index e9094329bd..c9f8f8d90d 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -4283,6 +4283,19 @@ static monsterentry mondata[] = { MONUSE_NOTHING, MONEAT_NOTHING, SIZE_LITTLE }, +{ + MONS_ORB_OF_DESTRUCTION, '*', WHITE, "orb of destruction", + M_INSUBSTANTIAL | M_GLOWS | M_NO_EXP_GAIN, + mrd(MR_RES_FIRE | MR_RES_HELLFIRE | MR_RES_POISON | MR_RES_COLD, 3) + | MR_RES_ELEC | MR_RES_STICKY_FLAME | MR_RES_ACID, + 0, 0, MONS_ORB_OF_DESTRUCTION, MONS_ORB_OF_DESTRUCTION, MH_NONLIVING, MAG_IMMUNE, + { AT_NO_ATK, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, + { 5, 0, 0, 50 }, + 0, 10, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, + I_PLANT, HT_LAND, FL_LEVITATE, 30, DEFAULT_ENERGY, + MONUSE_NOTHING, MONEAT_NOTHING, SIZE_LITTLE +}, + // other symbols { MONS_VAPOUR, '#', LIGHTGREY, "vapour", diff --git a/crawl-ref/source/mon-project.cc b/crawl-ref/source/mon-project.cc new file mode 100644 index 0000000000..0052055d2a --- /dev/null +++ b/crawl-ref/source/mon-project.cc @@ -0,0 +1,172 @@ +/* + * File: mon-project.cc + * Summary: Slow projectiles, done as monsters. + * Written by: Adam Borowski + */ + +#include "AppHdr.h" + +#include "mon-project.h" + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <cmath> + +#include "externs.h" + +#include "coord.h" +#include "env.h" +#include "mgen_data.h" +#include "mon-place.h" +#include "mon-stuff.h" +#include "stuff.h" +#include "terrain.h" +#include "viewchar.h" + +bool mons_is_projectile(monster_type mt) +{ + return (mt == MONS_ORB_OF_DESTRUCTION); +} + +bool cast_iood(actor *caster, int pow, bolt *beam) +{ + int mtarg = mgrd(beam->target); + + int mind = mons_place(mgen_data(MONS_ORB_OF_DESTRUCTION, + (caster->atype() == ACT_PLAYER) ? BEH_FRIENDLY : + ((monsters*)caster)->wont_attack() ? BEH_FRIENDLY : BEH_HOSTILE, + caster, + 0, + SPELL_IOOD, + coord_def(-1, -1), + (mtarg != NON_MONSTER) ? mtarg : + (you.pos() == beam->target) ? MHITYOU : MHITNOT, + 0, + GOD_NO_GOD)); + if (mind == -1) + { + canned_msg(MSG_NOTHING_HAPPENS); + return (false); + } + + monsters &mon = menv[mind]; + const coord_def pos = caster->pos(); + mon.props["iood_x"] = (float)pos.x; + mon.props["iood_y"] = (float)pos.y; + mon.props["iood_vx"] = (float)(beam->target.x - pos.x); + mon.props["iood_vy"] = (float)(beam->target.y - pos.y); + mon.props["iood_kc"].get_byte() = (caster->atype() == ACT_PLAYER) ? KC_YOU : + ((monsters*)caster)->wont_attack() ? KC_FRIENDLY : KC_OTHER; + mon.flags &= ~MF_JUST_SUMMONED; + + // Move away from the caster's square. + iood_act(mon); + mon.lose_energy(EUT_MOVE); + return (true); +} + +void _normalize(float &x, float &y) +{ + const float d = sqrt(x*x + y*y); + if (d <= 0.000001) + return; + x/=d; + y/=d; +} + +void _iood_dissipate(monsters &mon) +{ + simple_monster_message(&mon, " dissipates."); + mpr("iood: dissipating"); + monster_die(&mon, KILL_DISMISSED, NON_MONSTER); +} + +bool _iood_hit(monsters &mon, const coord_def &pos) +{ + bolt beam; + beam.name = "orb of destruction"; + beam.flavour = BEAM_NUKE; + beam.attitude = mon.attitude; + beam.thrower = (mon.props["iood_kc"].get_byte() == KC_YOU) + ? KILL_YOU_MISSILE : KILL_MON_MISSILE; + beam.colour = WHITE; + beam.type = dchar_glyph(DCHAR_FIRED_BURST); + beam.range = 1; + beam.source = pos; + beam.target = pos; + beam.hit = AUTOMATIC_HIT; + beam.damage = dice_def(3, 20); + beam.fire(); + + return (true); +} + +// returns true if the orb is gone +bool iood_act(monsters &mon) +{ + ASSERT(mons_is_projectile(mon.type)); + + float x = mon.props["iood_x"]; + float y = mon.props["iood_y"]; + float vx = mon.props["iood_vx"]; + float vy = mon.props["iood_vy"]; + + mprf("iood_act: pos (%d,%d) rpos (%f,%f) v (%f,%f)", mon.pos().x, mon.pos().y, + x, y, vx, vy); + + if (!vx && !vy) // not initialized + { + _iood_dissipate(mon); + return (true); + } + + coord_def target(-1, -1); + if (mon.foe == MHITYOU) + target = you.pos(); + else if (invalid_monster_index(mon.foe)) + ; + else if (invalid_monster_type(menv[mon.foe].type)) + { + // Our target is gone. Since picking a new one would require + // intelligence, the orb continues on a ballistic course. + mon.foe = MHITNOT; + } + else + target = menv[mon.foe].pos(); + + _normalize(vx, vy); + + x += vx; + y += vy; + + mon.props["iood_x"] = x; + mon.props["iood_y"] = y; + + coord_def pos(round(x), round(y)); + if (!in_bounds(pos)) + { + _iood_dissipate(mon); + return (true); + } + + if (pos == mon.pos()) + return (false); + + if (cell_is_solid(pos) || actor_at(pos)) + { + if (_iood_hit(mon, pos)) + { + monster_die(&mon, KILL_DISMISSED, NON_MONSTER); + return (true); + } + } + + if (!mon.move_to_pos(pos)) + { + _iood_dissipate(mon); + return (true); + } + + return (false); +} diff --git a/crawl-ref/source/mon-project.h b/crawl-ref/source/mon-project.h new file mode 100644 index 0000000000..3f17a9c755 --- /dev/null +++ b/crawl-ref/source/mon-project.h @@ -0,0 +1,17 @@ +/* + * File: mon-project.cc + * Summary: Slow projectiles, done as monsters. + * Written by: Adam Borowski + */ + +#ifndef MON_PROJECT_H +#define MON_PROJECT_H + +#include "beam.h" + +bool mons_is_projectile(monster_type mt); + +bool cast_iood(actor *caster, int pow, bolt *beam); +bool iood_act(monsters &mon); + +#endif diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 9420d1d78c..17ed88bd8e 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -2010,7 +2010,8 @@ bool mons_wields_two_weapons(const monsters *mon) bool mons_self_destructs(const monsters *m) { - return (m->type == MONS_GIANT_SPORE || m->type == MONS_BALL_LIGHTNING); + return (m->type == MONS_GIANT_SPORE || m->type == MONS_BALL_LIGHTNING + || m->type == MONS_ORB_OF_DESTRUCTION); } int mons_base_damage_brand(const monsters *m) diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc index f5f89f44b6..d5810bc106 100644 --- a/crawl-ref/source/spl-book.cc +++ b/crawl-ref/source/spl-book.cc @@ -518,12 +518,12 @@ static spell_type spellbook_template_array[][SPELLBOOK_SIZE] = // Book of Annihilations - Vehumet special {SPELL_ISKENDERUNS_MYSTIC_BLAST, SPELL_POISON_ARROW, + SPELL_IOOD, SPELL_CHAIN_LIGHTNING, SPELL_LEHUDIBS_CRYSTAL_SPEAR, SPELL_ICE_STORM, SPELL_FIRE_STORM, SPELL_NO_SPELL, - SPELL_NO_SPELL, }, // Book of Demonology - Vehumet special diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index e35944c8ce..efb8386ee0 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -37,6 +37,7 @@ #include "message.h" #include "mon-cast.h" #include "mon-place.h" +#include "mon-project.h" #include "mon-stuff.h" #include "mutation.h" #include "ouch.h" @@ -1514,6 +1515,13 @@ spret_type your_spells(spell_type spell, int powc, bool allow_fail) return (SPRET_ABORT); break; + case SPELL_IOOD: + if (!player_tracer(ZAP_IOOD, powc, beam)) + return (SPRET_ABORT); + if (!cast_iood(&you, powc, &beam)) + return (SPRET_ABORT); + break; + // Clouds and explosions. case SPELL_MEPHITIC_CLOUD: if (!stinking_cloud(powc, beam)) diff --git a/crawl-ref/source/spl-data.h b/crawl-ref/source/spl-data.h index 27f1ea2632..cd0e4336d8 100644 --- a/crawl-ref/source/spl-data.h +++ b/crawl-ref/source/spl-data.h @@ -2590,6 +2590,19 @@ }, { + SPELL_IOOD, "Iskenderun's Orb of Destruction", + SPTYP_CONJURATION, + SPFLAG_DIR_OR_TARGET, + 7, + 200, + 9, 9, + 0, + NULL, + true, + false +}, + +{ SPELL_NO_SPELL, "nonexistent spell", 0, SPFLAG_TESTING, |