2 * File: spl-transloc.cc
3 * Summary: Translocation spells.
8 #include "spl-transloc.h"
34 #include "spl-other.h"
41 #include "transform.h"
48 static bool _abyss_blocks_teleport(bool cblink
)
50 // Lugonu worshippers get their perks.
51 if (you
.religion
== GOD_LUGONU
)
54 // Controlled Blink (the spell) works quite reliably in the Abyss.
55 return (cblink
? one_chance_in(3) : !one_chance_in(3));
58 // If wizard_blink is set, all restriction are ignored (except for
59 // a monster being at the target spot), and the player gains no
61 int blink(int pow
, bool high_level_controlled_blink
, bool wizard_blink
,
64 ASSERT(!crawl_state
.game_is_arena());
68 if (crawl_state
.is_repeating_cmd())
70 crawl_state
.cant_cmd_repeat("You can't repeat controlled blinks.");
71 crawl_state
.cancel_cmd_again();
72 crawl_state
.cancel_cmd_repeat();
76 // yes, there is a logic to this ordering {dlb}:
77 if (item_blocks_teleport(true, true) && !wizard_blink
)
80 mpr(pre_msg
->c_str());
81 canned_msg(MSG_STRANGE_STASIS
);
83 else if (you
.level_type
== LEVEL_ABYSS
84 && _abyss_blocks_teleport(high_level_controlled_blink
)
88 mpr(pre_msg
->c_str());
89 mpr("The power of the Abyss keeps you in your place!");
91 else if (you
.confused() && !wizard_blink
)
94 mpr(pre_msg
->c_str());
97 else if (!allow_control_teleport(true) && !wizard_blink
)
100 mpr(pre_msg
->c_str());
101 mpr("A powerful magic interferes with your control of the blink.");
102 if (high_level_controlled_blink
)
103 return (cast_semi_controlled_blink(pow
));
108 // query for location {dlb}:
109 while (!crawl_state
.seen_hups
)
111 direction_chooser_args args
;
112 args
.restricts
= DIR_TARGET
;
113 args
.needs_path
= false;
114 args
.may_target_monster
= false;
115 args
.top_prompt
= "Blink to where?";
116 direction(beam
, args
);
118 if (!beam
.isValid
|| beam
.target
== you
.pos())
121 && !yesno("Are you sure you want to cancel this blink?",
128 return (-1); // early return {dlb}
131 monster
* beholder
= you
.get_beholder(beam
.target
);
132 if (!wizard_blink
&& beholder
)
134 mprf("You cannot blink away from %s!",
135 beholder
->name(DESC_NOCAP_THE
, true).c_str());
139 monster
* fearmonger
= you
.get_fearmonger(beam
.target
);
140 if (!wizard_blink
&& fearmonger
)
142 mprf("You cannot blink closer to %s!",
143 fearmonger
->name(DESC_NOCAP_THE
, true).c_str());
147 if (grd(beam
.target
) == DNGN_OPEN_SEA
)
150 mpr("You can't blink into the sea!");
152 else if (!check_moveto(beam
.target
, "blink"))
154 // try again (messages handled by check_moveto)
156 else if (you
.see_cell_no_trans(beam
.target
))
158 // Grid in los, no problem.
161 else if (you
.trans_wall_blocking(beam
.target
))
163 // Wizard blink can move past translucent walls.
168 mpr("You can't blink through translucent walls.");
173 mpr("You can only blink to visible locations.");
178 mpr(pre_msg
->c_str());
180 // Allow wizard blink to send player into walls, in case the
181 // user wants to alter that grid to something else.
182 if (wizard_blink
&& feat_is_solid(grd(beam
.target
)))
183 grd(beam
.target
) = DNGN_FLOOR
;
185 if (feat_is_solid(grd(beam
.target
)) || monster_at(beam
.target
))
187 mpr("Oops! Maybe something was there already.");
190 else if (you
.level_type
== LEVEL_ABYSS
&& !wizard_blink
)
192 abyss_teleport(false);
193 if (you
.pet_target
!= MHITYOU
)
194 you
.pet_target
= MHITNOT
;
198 // Leave a purple cloud.
199 place_cloud(CLOUD_TLOC_ENERGY
, you
.pos(), 1 + random2(3), &you
);
200 move_player_to_grid(beam
.target
, false, true);
202 // Controlling teleport contaminates the player. -- bwr
204 contaminate_player(1, true);
208 crawl_state
.cancel_cmd_again();
209 crawl_state
.cancel_cmd_repeat();
214 void random_blink(bool allow_partial_control
, bool override_abyss
)
216 ASSERT(!crawl_state
.game_is_arena());
220 if (item_blocks_teleport(true, true))
221 canned_msg(MSG_STRANGE_STASIS
);
222 else if (you
.level_type
== LEVEL_ABYSS
223 && !override_abyss
&& !one_chance_in(3))
225 mpr("The power of the Abyss keeps you in your place!");
227 // First try to find a random square not adjacent to the player,
228 // then one adjacent if that fails.
229 else if (!random_near_space(you
.pos(), target
)
230 && !random_near_space(you
.pos(), target
, true))
232 mpr("You feel jittery for a moment.");
235 //jmf: Add back control, but effect is cast_semi_controlled_blink(pow).
236 else if (player_control_teleport() && !you
.confused()
237 && allow_partial_control
&& allow_control_teleport())
239 mpr("You may select the general direction of your translocation.");
240 cast_semi_controlled_blink(100);
245 canned_msg(MSG_YOU_BLINK
);
246 coord_def origin
= you
.pos();
247 move_player_to_grid(target
, false, true);
249 // Leave a purple cloud.
250 place_cloud(CLOUD_TLOC_ENERGY
, origin
, 1 + random2(3), &you
);
252 if (you
.level_type
== LEVEL_ABYSS
)
254 abyss_teleport(false);
255 if (you
.pet_target
!= MHITYOU
)
256 you
.pet_target
= MHITNOT
;
261 // This function returns true if the player can use controlled teleport
263 bool allow_control_teleport(bool quiet
)
265 bool retval
= !(testbits(env
.level_flags
, LFLAG_NO_TELE_CONTROL
)
266 || testbits(get_branch_flags(), BFLAG_NO_TELE_CONTROL
));
268 // Tell the player why if they have teleport control.
269 if (!quiet
&& !retval
&& player_control_teleport())
270 mpr("A powerful magic prevents control of your teleportation.");
275 void you_teleport(void)
277 // [Cha] here we block teleportation, which will save the player from
278 // death from read-id'ing scrolls (in sprint)
279 if (crawl_state
.game_is_sprint() || item_blocks_teleport(true, true))
280 canned_msg(MSG_STRANGE_STASIS
);
281 else if (you
.duration
[DUR_TELEPORT
])
283 mpr("You feel strangely stable.");
284 you
.duration
[DUR_TELEPORT
] = 0;
288 mpr("You feel strangely unstable.");
290 int teleport_delay
= 3 + random2(3);
292 if (you
.level_type
== LEVEL_ABYSS
&& !one_chance_in(5))
294 mpr("You have a feeling this translocation may take a while to kick in...");
295 teleport_delay
+= 5 + random2(10);
298 you
.set_duration(DUR_TELEPORT
, teleport_delay
);
302 // Should return true if we don't want anyone to teleport here.
303 static bool _cell_vetoes_teleport (const coord_def cell
, bool check_monsters
= true)
305 // Monsters always veto teleport.
306 if (monster_at(cell
) && check_monsters
)
309 // As do all clouds; this may change.
310 if (env
.cgrid(cell
) != EMPTY_CLOUD
)
313 if (cell_is_solid(cell
))
316 return is_feat_dangerous(grd(cell
), true);
319 static void _handle_teleport_update (bool large_change
, bool check_ring_TC
,
320 const coord_def old_pos
)
325 for (monster_iterator mi
; mi
; ++mi
)
327 const bool see_cell
= you
.see_cell(mi
->pos());
329 if (mi
->foe
== MHITYOU
&& !see_cell
)
332 behaviour_event(*mi
, ME_EVAL
);
335 behaviour_event(*mi
, ME_EVAL
);
338 handle_interrupted_swap(true);
341 // Might identify unknown ring of teleport control.
346 if (you
.species
== SP_MERFOLK
)
348 const dungeon_feature_type new_grid
= grd(you
.pos());
349 const dungeon_feature_type old_grid
= grd(old_pos
);
350 if (feat_is_water(old_grid
) && !feat_is_water(new_grid
)
351 || !feat_is_water(old_grid
) && feat_is_water(new_grid
))
359 static bool _teleport_player(bool allow_control
, bool new_abyss_area
,
362 bool is_controlled
= (allow_control
&& !you
.confused()
363 && player_control_teleport()
364 && allow_control_teleport()
367 // All wizard teleports are automatically controlled.
369 is_controlled
= true;
372 && ((!new_abyss_area
&& crawl_state
.game_is_sprint())
373 || item_blocks_teleport(true, true)))
375 canned_msg(MSG_STRANGE_STASIS
);
379 // After this point, we're guaranteed to teleport. Kill the appropriate
381 interrupt_activity(AI_TELEPORT
);
383 // Update what we can see at the current location as well as its stash,
384 // in case something happened in the exact turn that we teleported
385 // (like picking up/dropping an item).
387 StashTrack
.update_stash(you
.pos());
389 if (you
.level_type
== LEVEL_ABYSS
)
391 abyss_teleport(new_abyss_area
);
392 if (you
.pet_target
!= MHITYOU
)
393 you
.pet_target
= MHITNOT
;
399 const coord_def old_pos
= you
.pos();
400 bool large_change
= false;
401 bool check_ring_TC
= false;
405 check_ring_TC
= true;
407 // Only have the messages and the more prompt for non-wizard.
410 mpr("You may choose your destination (press '.' or delete to select).");
411 mpr("Expect minor deviation.");
418 bool chose
= show_map(lpos
, false, true, false);
422 #if defined(USE_UNIX_SIGNALS) && defined(SIGHUP_SAVE) && defined(USE_CURSES)
423 // If we've received a HUP signal then the user can't choose a
424 // location, so cancel the teleport.
425 if (crawl_state
.seen_hups
)
427 mpr("Controlled teleport interrupted by HUP signal, "
428 "cancelling teleport.", MSGCH_ERROR
);
430 contaminate_player(1, true);
435 dprf("Target square (%d,%d)", pos
.x
, pos
.y
);
437 if (!chose
|| pos
== you
.pos())
441 if (!yesno("Are you sure you want to cancel this teleport?",
448 contaminate_player(1, true);
453 monster
* beholder
= you
.get_beholder(pos
);
454 if (beholder
&& !wizard_tele
)
456 mprf("You cannot teleport away from %s!",
457 beholder
->name(DESC_NOCAP_THE
, true).c_str());
458 mpr("Choose another destination (press '.' or delete to select).");
463 monster
* fearmonger
= you
.get_fearmonger(pos
);
464 if (fearmonger
&& !wizard_tele
)
466 mprf("You cannot teleport closer to %s!",
467 fearmonger
->name(DESC_NOCAP_THE
, true).c_str());
468 mpr("Choose another destination (press '.' or delete to select).");
475 // Don't randomly walk wizard teleports.
478 pos
.x
+= random2(3) - 1;
479 pos
.y
+= random2(3) - 1;
481 if (one_chance_in(4))
483 pos
.x
+= random2(3) - 1;
484 pos
.y
+= random2(3) - 1;
486 dprf("Scattered target square (%d, %d)", pos
.x
, pos
.y
);
491 mpr("Nearby solid objects disrupt your rematerialisation!");
492 is_controlled
= false;
497 if (!you
.see_cell(pos
))
500 // Merfolk should be able to control-tele into deep water.
501 if (_cell_vetoes_teleport(pos
))
503 dprf("Target square (%d, %d) vetoed, now random teleport.", pos
.x
, pos
.y
);
504 is_controlled
= false;
505 large_change
= false;
507 else if (testbits(env
.pgrid(pos
), FPROP_NO_CTELE_INTO
) && !wizard_tele
)
509 is_controlled
= false;
510 large_change
= false;
511 mpr("A strong magical force throws you back!", MSGCH_WARN
);
515 // Leave a purple cloud.
516 place_cloud(CLOUD_TLOC_ENERGY
, old_pos
, 1 + random2(3), &you
);
518 // Controlling teleport contaminates the player. - bwr
519 move_player_to_grid(pos
, false, true);
521 contaminate_player(1, true);
530 // If in a labyrinth, always teleport well away from the centre.
531 // (Check done for the straight line, no pathfinding involved.)
532 bool need_distance_check
= false;
534 if (you
.level_type
== LEVEL_LABYRINTH
)
536 bool success
= false;
537 for (int xpos
= 0; xpos
< GXM
; xpos
++)
539 for (int ypos
= 0; ypos
< GYM
; ypos
++)
541 centre
= coord_def(xpos
, ypos
);
542 if (!in_bounds(centre
))
545 if (grd(centre
) == DNGN_ESCAPE_HATCH_UP
)
554 need_distance_check
= success
;
558 newpos
= random_in_bounds();
559 while (_cell_vetoes_teleport(newpos
)
560 || need_distance_check
&& (newpos
- centre
).abs() < 34*34
561 || testbits(env
.pgrid(newpos
), FPROP_NO_RTELE_INTO
));
563 if (newpos
== old_pos
)
564 mpr("Your surroundings flicker for a moment.");
565 else if (you
.see_cell(newpos
))
566 mpr("Your surroundings seem slightly different.");
569 mpr("Your surroundings suddenly seem different.");
573 // Leave a purple cloud.
574 place_cloud(CLOUD_TLOC_ENERGY
, old_pos
, 1 + random2(3), &you
);
576 move_player_to_grid(newpos
, false, true);
579 _handle_teleport_update(large_change
, check_ring_TC
, old_pos
);
580 return (!is_controlled
);
583 bool you_teleport_to(const coord_def where_to
, bool move_monsters
)
585 // Attempts to teleport the player from their current location to 'where'.
586 // Follows this line of reasoning:
587 // 1. Check the location (against _cell_vetoes_teleport), if valid,
588 // teleport the player there.
589 // 2. If not because of a monster, and move_monster, teleport that
590 // monster out of the way, then teleport the player there.
591 // 3. Otherwise, iterate over adjacent squares. If a sutiable position is
592 // found (or a monster can be moved out of the way, with move_monster)
593 // then teleport the player there.
594 // 4. If not, give up and return false.
596 bool check_ring_TC
= false;
597 const coord_def old_pos
= you
.pos();
598 coord_def where
= where_to
;
599 coord_def old_where
= where_to
;
601 // Don't bother to calculate a possible new position if it's out of bounds.
602 if (!in_bounds(where
))
605 if (_cell_vetoes_teleport(where
))
607 if (monster_at(where
) && move_monsters
&& !_cell_vetoes_teleport(where
, false))
609 monster
* mons
= monster_at(where
);
610 mons
->teleport(true);
614 for (adjacent_iterator
ai(where
); ai
; ++ai
)
616 if (!_cell_vetoes_teleport(*ai
))
623 if (monster_at(*ai
) && move_monsters
624 && !_cell_vetoes_teleport(*ai
, false))
626 monster
* mons
= monster_at(*ai
);
627 mons
->teleport(true);
633 // Give up, we can't find a suitable spot.
634 if (where
== old_where
)
639 // If we got this far, we're teleporting the player.
640 // Leave a purple cloud.
641 place_cloud(CLOUD_TLOC_ENERGY
, old_pos
, 1 + random2(3), &you
);
643 bool large_change
= you
.see_cell(where
);
645 move_player_to_grid(where
, false, true);
647 _handle_teleport_update(large_change
, check_ring_TC
, old_pos
);
651 void you_teleport_now(bool allow_control
, bool new_abyss_area
, bool wizard_tele
)
653 const bool randtele
= _teleport_player(allow_control
, new_abyss_area
,
656 // Xom is amused by uncontrolled teleports that land you in a
657 // dangerous place, unless the player is in the Abyss and
658 // teleported to escape from all the monsters chasing him/her,
659 // since in that case the new dangerous area is almost certainly
660 // *less* dangerous than the old dangerous area.
661 // Teleporting in a labyrinth is also funny, more so for non-minotaurs.
663 && (you
.level_type
== LEVEL_LABYRINTH
664 || you
.level_type
!= LEVEL_ABYSS
&& player_in_a_dangerous_place()))
666 if (you
.level_type
== LEVEL_LABYRINTH
&& you
.species
== SP_MINOTAUR
)
667 xom_is_stimulated(128);
669 xom_is_stimulated(255);
673 bool cast_portal_projectile(int pow
)
676 int item
= get_ammo_to_shoot(-1, target
, true);
680 if (cell_is_solid(target
.target
))
682 mpr("You can't shoot at gazebos.");
686 // Can't use portal through walls. (That'd be just too cheap!)
687 if (you
.trans_wall_blocking(target
.target
))
689 mpr("A translucent wall is in the way.");
693 if (!check_warning_inscriptions(you
.inv
[item
], OPER_FIRE
))
697 throw_it(beam
, item
, true, random2(pow
/4), &target
);
702 bool cast_apportation(int pow
, bolt
& beam
)
704 const coord_def where
= beam
.target
;
706 if (you
.trans_wall_blocking(where
))
708 mpr("Something is in the way.");
712 // Letting mostly-melee characters spam apport after every Shoals
713 // fight seems like it has too much grinding potential. We could
714 // weaken this for high power.
715 if (grd(where
) == DNGN_DEEP_WATER
|| grd(where
) == DNGN_LAVA
)
717 mpr("The density of the terrain blocks your spell.");
721 // Let's look at the top item in that square...
722 // And don't allow apporting from shop inventories.
723 const int item_idx
= igrd(where
);
724 if (item_idx
== NON_ITEM
|| !in_bounds(where
))
726 // Maybe the player *thought* there was something there (a mimic.)
727 if (monster
* m
= monster_at(where
))
729 if (mons_is_item_mimic(m
->type
) && you
.can_see(m
))
731 mprf("%s twitches.", m
->name(DESC_CAP_THE
).c_str());
732 // Nothing else gives this message, so identify the mimic.
734 return (true); // otherwise you get free mimic ID
738 mpr("There are no items there.");
742 item_def
& item
= mitm
[item_idx
];
744 // Can't apport the Orb in zotdef
745 if (crawl_state
.game_is_zotdef() && item_is_orb(item
))
747 mpr("You cannot apport the sacred Orb!");
751 // Protect the player from destroying the item.
752 if (feat_destroys_item(grd(you
.pos()), item
))
754 mpr("That would be silly while over this terrain!");
759 const int unit_mass
= item_mass(item
);
760 const int max_mass
= pow
* 30 + random2(pow
* 20);
762 int max_units
= item
.quantity
;
764 max_units
= max_mass
/ unit_mass
;
768 if (item_is_orb(item
))
770 orb_pickup_noise(where
, 30);
775 mpr("The mass is resisting your pull.");
780 // We need to modify the item *before* we move it, because
781 // move_top_item() might change the location, or merge
782 // with something at our position.
783 mprf("Yoink! You pull the item%s towards yourself.",
784 (item
.quantity
> 1) ? "s" : "");
786 if (item_is_orb(item
))
788 fake_noisy(30, where
);
790 // There's also a 1-in-6 flat chance of apport failing.
791 if (one_chance_in(6))
793 orb_pickup_noise(where
, 30, "The orb shrieks and becomes a dead weight against your magic!",
794 "The orb lets out a furious burst of light and becomes a dead weight against your magic!");
797 else // Otherwise it's just a noisy little shiny thing
799 orb_pickup_noise(where
, 30, "The orb shrieks as your magic touches it!",
800 "The orb lets out a furious burst of light as your magic touches it!");
804 if (max_units
< item
.quantity
)
806 item
.quantity
= max_units
;
807 mpr("You feel that some mass got lost in the cosmic void.");
810 // If we apport a net, free the monster under it.
811 if (item
.base_type
== OBJ_MISSILES
812 && item
.sub_type
== MI_THROWING_NET
813 && item_is_stationary(item
))
815 remove_item_stationary(item
);
816 if (monster
* mons
= monster_at(where
))
817 mons
->del_ench(ENCH_HELD
, true);
820 if (item_is_orb(item
))
822 // The orb drags its heels.
823 beam
.is_tracer
= true;
824 beam
.aimed_at_spot
= true;
827 // Pop the orb's location off the end
828 beam
.path_taken
.pop_back();
830 // The actual number of squares it needs to traverse to get to you.
831 unsigned int dist
= beam
.path_taken
.size();
833 // The maximum number of squares the orb will actually move, always
834 // at least one square.
835 unsigned int max_dist
= std::max((pow
/ 10) - 1, 1);
837 dprf("Orb apport dist=%d, max_dist=%d", dist
, max_dist
);
839 if (max_dist
<= dist
)
841 coord_def new_spot
= beam
.path_taken
[beam
.path_taken
.size()-max_dist
];
843 dprf("Orb apport: new spot is %d/%d", new_spot
.x
, new_spot
.y
);
845 if (feat_virtually_destroys_item(grd(new_spot
), item
))
850 move_top_item(where
, new_spot
);
851 origin_set(new_spot
);
855 // if power is high enough it'll just come straight to you
858 // Actually move the item.
859 move_top_item(where
, you
.pos());
860 // Mark the item as found now.
861 origin_set(you
.pos());
866 static int _quadrant_blink(coord_def where
, int pow
, int, actor
*)
868 if (where
== you
.pos())
871 if (you
.level_type
== LEVEL_ABYSS
)
873 abyss_teleport(false);
874 if (you
.pet_target
!= MHITYOU
)
875 you
.pet_target
= MHITNOT
;
882 const int dist
= random2(6) + 2; // 2-7
884 // This is where you would *like* to go.
885 const coord_def base
= you
.pos() + (where
- you
.pos()) * dist
;
887 // This can take a while if pow is high and there's lots of translucent
891 for (int i
= 0; i
< (pow
*pow
) / 500 + 1; ++i
)
893 // Find a space near our base point...
894 // First try to find a random square not adjacent to the basepoint,
895 // then one adjacent if that fails.
896 if (!random_near_space(base
, target
)
897 && !random_near_space(base
, target
, true))
902 // ... which is close enough, but also far enough from us.
903 if (distance(base
, target
) > 10 || distance(you
.pos(), target
) < 8)
906 if (!you
.see_cell_no_trans(target
))
919 coord_def origin
= you
.pos();
920 move_player_to_grid(target
, false, true);
922 // Leave a purple cloud.
923 place_cloud(CLOUD_TLOC_ENERGY
, origin
, 1 + random2(3), &you
);
928 int cast_semi_controlled_blink(int pow
)
930 int result
= apply_one_neighbouring_square(_quadrant_blink
, pow
);
932 // Controlled blink causes glowing.
934 contaminate_player(1, true);
939 bool can_cast_golubrias_passage()
941 return find_golubria_on_level().size() < 2;
944 bool cast_golubrias_passage(const coord_def
& where
)
946 // randomize position a bit to make it not as useful to use on monsters
947 // chasing you, as well as to not give away hidden trap positions
949 coord_def randomized_where
= where
;
953 randomized_where
= where
;
954 randomized_where
.x
+= random_range(-2, 2);
955 randomized_where
.y
+= random_range(-2, 2);
956 } while((!in_bounds(randomized_where
) ||
957 grd(randomized_where
) != DNGN_FLOOR
||
958 monster_at(randomized_where
) ||
959 !you
.see_cell(randomized_where
) ||
960 you
.trans_wall_blocking(randomized_where
) ||
961 randomized_where
== you
.pos()) &&
966 if (you
.trans_wall_blocking(randomized_where
))
967 mpr("You cannot create a passage on the other side of the transparent wall.");
969 // XXX: bleh, dumb message
970 mpr("Creating a passage of Golubria requires sufficient empty space.");
974 if (!allow_control_teleport(true) ||
975 testbits(env
.pgrid(randomized_where
), FPROP_NO_CTELE_INTO
))
978 mpr("A powerful magic interferes with the creation of the passage.");
979 place_cloud(CLOUD_TLOC_ENERGY
, randomized_where
, 3 + random2(3), &you
);
983 place_specific_trap(randomized_where
, TRAP_GOLUBRIA
);
985 trap_def
*trap
= find_trap(randomized_where
);
988 mpr("Something buggy happened.");