Apply the new ground_level method.
[crawl.git] / crawl-ref / source / wiz-mon.cc
blob7829a601ffc4b7dba5b43483c183c2e7aca8843e
1 /*
2 * File: dbg-mon.cc
3 * Summary: Monster related debugging functions.
4 * Written by: Linley Henzell and Jesse Jones
5 */
7 #include "AppHdr.h"
9 #include "wiz-mon.h"
11 #include "areas.h"
12 #include "cio.h"
13 #include "colour.h"
14 #include "coord.h"
15 #include "dbg-util.h"
16 #include "delay.h"
17 #include "dungeon.h"
18 #include "env.h"
19 #include "files.h"
20 #include "ghost.h"
21 #include "goditem.h"
22 #include "invent.h"
23 #include "items.h"
24 #include "jobs.h"
25 #include "macro.h"
26 #include "map_knowledge.h"
27 #include "mapdef.h"
28 #include "message.h"
29 #include "mgen_data.h"
30 #include "mon-iter.h"
31 #include "mon-pathfind.h"
32 #include "mon-place.h"
33 #include "mon-speak.h"
34 #include "mon-stuff.h"
35 #include "mon-util.h"
36 #include "output.h"
37 #include "religion.h"
38 #include "shout.h"
39 #include "showsymb.h"
40 #include "spl-miscast.h"
41 #include "spl-util.h"
42 #include "stuff.h"
43 #include "terrain.h"
44 #include "view.h"
45 #include "viewmap.h"
47 #ifdef WIZARD
48 // Creates a specific monster by mon type number.
49 void wizard_create_spec_monster(void)
51 int mon = prompt_for_int("Which monster by number? ", true);
53 if (mon == -1 || (mon >= NUM_MONSTERS
54 && mon != RANDOM_MONSTER
55 && mon != RANDOM_DRACONIAN
56 && mon != RANDOM_BASE_DRACONIAN
57 && mon != RANDOM_NONBASE_DRACONIAN
58 && mon != WANDERING_MONSTER))
60 canned_msg(MSG_OK);
62 else
64 create_monster(
65 mgen_data::sleeper_at(
66 static_cast<monster_type>(mon), you.pos()));
70 // Creates a specific monster by name. Uses the same patterns as
71 // map definitions.
72 void wizard_create_spec_monster_name()
74 char specs[100];
75 mpr("Which monster by name? ", MSGCH_PROMPT);
76 if (cancelable_get_line_autohist(specs, sizeof specs) || !*specs)
78 canned_msg(MSG_OK);
79 return;
82 mons_list mlist;
83 std::string err = mlist.add_mons(specs);
85 if (!err.empty())
87 std::string newerr;
88 // Try for a partial match, but not if the user accidentally entered
89 // only a few letters.
90 monster_type partial = get_monster_by_name(specs);
91 if (strlen(specs) >= 3 && partial != MONS_NO_MONSTER)
93 mlist.clear();
94 newerr = mlist.add_mons(mons_type_name(partial, DESC_PLAIN));
97 if (!newerr.empty())
99 mpr(err.c_str());
100 return;
104 mons_spec mspec = mlist.get_monster(0);
105 if (mspec.mid == -1)
107 mpr("Such a monster couldn't be found.", MSGCH_DIAGNOSTICS);
108 return;
111 int type = mspec.mid;
112 if (mons_class_is_zombified(mspec.mid))
113 type = mspec.monbase;
115 coord_def place = find_newmons_square(type, you.pos());
116 if (!in_bounds(place))
118 // Try again with habitat HT_LAND.
119 // (Will be changed to the necessary terrain type in dgn_place_monster.)
120 place = find_newmons_square(MONS_NO_MONSTER, you.pos());
123 if (!in_bounds(place))
125 mpr("Found no space to place monster.", MSGCH_DIAGNOSTICS);
126 return;
129 // Wizmode users should be able to conjure up uniques even if they
130 // were already created. Yay, you can meet 3 Sigmunds at once! :p
131 if (mons_is_unique(mspec.mid) && you.unique_creatures[mspec.mid])
132 you.unique_creatures[mspec.mid] = false;
134 if (dgn_place_monster(mspec, you.absdepth0, place, true, false) == -1)
136 mpr("Unable to place monster.", MSGCH_DIAGNOSTICS);
137 return;
140 if (mspec.mid == MONS_KRAKEN)
142 unsigned short mid = mgrd(place);
144 if (mid >= MAX_MONSTERS || menv[mid].type != MONS_KRAKEN)
146 for (mid = 0; mid < MAX_MONSTERS; mid++)
148 if (menv[mid].type == MONS_KRAKEN && menv[mid].alive())
150 menv[mid].colour = element_colour(ETC_KRAKEN);
151 return;
155 if (mid >= MAX_MONSTERS)
157 mpr("Couldn't find player kraken!");
158 return;
162 // FIXME: This is a bit useless, seeing how you cannot set the
163 // ghost's stats, brand or level, among other things.
164 if (mspec.mid == MONS_PLAYER_GHOST)
166 unsigned short mid = mgrd(place);
168 if (mid >= MAX_MONSTERS || menv[mid].type != MONS_PLAYER_GHOST)
170 for (mid = 0; mid < MAX_MONSTERS; mid++)
172 if (menv[mid].type == MONS_PLAYER_GHOST
173 && menv[mid].alive())
175 break;
180 if (mid >= MAX_MONSTERS)
182 mpr("Couldn't find player ghost, probably going to crash.");
183 more();
184 return;
187 monster &mon = menv[mid];
188 ghost_demon ghost;
190 ghost.name = "John Doe";
192 char input_str[80];
193 msgwin_get_line("Make player ghost which species? (case-sensitive) ",
194 input_str, sizeof(input_str));
196 species_type sp_id = get_species_by_abbrev(input_str);
197 if (sp_id == SP_UNKNOWN)
198 sp_id = str_to_species(input_str);
199 if (sp_id == SP_UNKNOWN)
201 mpr("No such species, making it Human.");
202 sp_id = SP_HUMAN;
204 ghost.species = static_cast<species_type>(sp_id);
206 msgwin_get_line("Give player ghost which background? ",
207 input_str, sizeof(input_str));
209 int job_id = get_job_by_abbrev(input_str);
211 if (job_id == JOB_UNKNOWN)
212 job_id = get_job_by_name(input_str);
214 if (job_id == JOB_UNKNOWN)
216 mpr("No such background, making it a Fighter.");
217 job_id = JOB_FIGHTER;
219 ghost.job = static_cast<job_type>(job_id);
220 ghost.xl = 7;
222 mon.set_ghost(ghost);
224 ghosts.push_back(ghost);
228 static bool _sort_monster_list(int a, int b)
230 const monster* m1 = &menv[a];
231 const monster* m2 = &menv[b];
233 if (m1->alive() != m2->alive())
234 return m1->alive();
235 else if (!m1->alive())
236 return a < b;
238 if (m1->type == m2->type)
240 if (!m1->alive() || !m2->alive())
241 return (false);
243 return (m1->name(DESC_PLAIN, true) < m2->name(DESC_PLAIN, true));
246 const unsigned glyph1 = mons_char(m1->type);
247 const unsigned glyph2 = mons_char(m2->type);
248 if (glyph1 != glyph2)
250 return (glyph1 < glyph2);
253 return (m1->type < m2->type);
256 void debug_list_monsters()
258 std::vector<std::string> mons;
259 int nfound = 0;
261 int mon_nums[MAX_MONSTERS];
263 for (int i = 0; i < MAX_MONSTERS; ++i)
264 mon_nums[i] = i;
266 std::sort(mon_nums, mon_nums + MAX_MONSTERS, _sort_monster_list);
268 int total_exp = 0, total_adj_exp = 0, total_nonuniq_exp = 0;
270 std::string prev_name = "";
271 int count = 0;
273 for (int i = 0; i < MAX_MONSTERS; ++i)
275 const int idx = mon_nums[i];
276 if (invalid_monster_index(idx))
277 continue;
279 const monster* mi(&menv[idx]);
280 if (!mi->alive())
281 continue;
283 std::string name = mi->name(DESC_PLAIN, true);
285 if (prev_name != name && count > 0)
287 char buf[80];
288 if (count > 1)
289 snprintf(buf, sizeof(buf), "%d %s", count,
290 pluralise(prev_name).c_str());
291 else
292 snprintf(buf, sizeof(buf), "%s", prev_name.c_str());
293 mons.push_back(buf);
295 count = 0;
297 nfound++;
298 count++;
299 prev_name = name;
301 int exp = exper_value(mi);
302 total_exp += exp;
303 if (!mons_is_unique(mi->type))
304 total_nonuniq_exp += exp;
306 if ((mi->flags & (MF_WAS_NEUTRAL | MF_NO_REWARD))
307 || mi->has_ench(ENCH_ABJ))
309 continue;
311 if (mi->flags & MF_GOT_HALF_XP)
312 exp /= 2;
314 total_adj_exp += exp;
317 char buf[80];
318 if (count > 1)
319 snprintf(buf, sizeof(buf), "%d %s", count, pluralise(prev_name).c_str());
320 else
321 snprintf(buf, sizeof(buf), "%s", prev_name.c_str());
322 mons.push_back(buf);
324 mpr_comma_separated_list("Monsters: ", mons);
326 if (total_adj_exp == total_exp)
328 mprf("%d monsters, %d total exp value (%d non-uniq)",
329 nfound, total_exp, total_nonuniq_exp);
331 else
333 mprf("%d monsters, %d total exp value (%d non-uniq, %d adjusted)",
334 nfound, total_exp, total_nonuniq_exp, total_adj_exp);
338 void wizard_spawn_control()
340 mpr("(c)hange spawn rate or (s)pawn monsters? ", MSGCH_PROMPT);
341 const int c = tolower(getchm());
343 char specs[256];
344 bool done = false;
346 if (c == 'c')
348 mprf(MSGCH_PROMPT, "Set monster spawn rate to what? (now %d, lower value = higher rate) ",
349 env.spawn_random_rate);
351 if (!cancelable_get_line(specs, sizeof(specs)))
353 const int rate = atoi(specs);
354 if (rate)
356 env.spawn_random_rate = rate;
357 done = true;
361 else if (c == 's')
363 // 50 spots are reserved for non-wandering monsters.
364 int max_spawn = MAX_MONSTERS - 50;
365 for (monster_iterator mi; mi; ++mi)
366 if (mi->alive())
367 max_spawn--;
369 if (max_spawn <= 0)
371 mpr("Level already filled with monsters, get rid of some "
372 "of them first.", MSGCH_PROMPT);
373 return;
376 mprf(MSGCH_PROMPT, "Spawn how many random monsters (max %d)? ",
377 max_spawn);
379 if (!cancelable_get_line(specs, sizeof(specs)))
381 const int num = std::min(atoi(specs), max_spawn);
382 if (num > 0)
384 int curr_rate = env.spawn_random_rate;
385 // Each call to spawn_random_monsters() will spawn one with
386 // the rate at 5 or less.
387 env.spawn_random_rate = 5;
389 for (int i = 0; i < num; ++i)
390 spawn_random_monsters();
392 env.spawn_random_rate = curr_rate;
393 done = true;
398 if (!done)
399 canned_msg(MSG_OK);
402 // Prints a number of useful (for debugging, that is) stats on monsters.
403 void debug_stethoscope(int mon)
405 dist stth;
406 coord_def stethpos;
408 int i;
410 if (mon != RANDOM_MONSTER)
411 i = mon;
412 else
414 mpr("Which monster?", MSGCH_PROMPT);
416 direction(stth, direction_chooser_args());
418 if (!stth.isValid)
419 return;
421 if (stth.isTarget)
422 stethpos = stth.target;
423 else
424 stethpos = you.pos() + stth.delta;
426 if (env.cgrid(stethpos) != EMPTY_CLOUD)
428 mprf(MSGCH_DIAGNOSTICS, "cloud type: %d delay: %d",
429 env.cloud[ env.cgrid(stethpos) ].type,
430 env.cloud[ env.cgrid(stethpos) ].decay);
433 if (!monster_at(stethpos))
435 mprf(MSGCH_DIAGNOSTICS, "item grid = %d", igrd(stethpos));
436 return;
439 i = mgrd(stethpos);
442 monster& mons(menv[i]);
444 // Print type of monster.
445 mprf(MSGCH_DIAGNOSTICS, "%s (id #%d; type=%d loc=(%d,%d) align=%s)",
446 mons.name(DESC_CAP_THE, true).c_str(),
447 i, mons.type, mons.pos().x, mons.pos().y,
448 ((mons.attitude == ATT_HOSTILE) ? "hostile" :
449 (mons.attitude == ATT_FRIENDLY) ? "friendly" :
450 (mons.attitude == ATT_NEUTRAL) ? "neutral" :
451 (mons.attitude == ATT_GOOD_NEUTRAL) ? "good neutral":
452 (mons.attitude == ATT_STRICT_NEUTRAL) ? "strictly neutral"
453 : "unknown alignment"));
455 // Print stats and other info.
456 mprf(MSGCH_DIAGNOSTICS,
457 "HD=%d (%u) HP=%d/%d AC=%d(%d) EV=%d MR=%d SP=%d "
458 "energy=%d%s%s mid=%u num=%d stealth=%d flags=%04"PRIx64,
459 mons.hit_dice,
460 mons.experience,
461 mons.hit_points, mons.max_hit_points,
462 mons.ac, mons.armour_class(),
463 mons.ev,
464 mons.res_magic(),
465 mons.speed, mons.speed_increment,
466 mons.base_monster != MONS_NO_MONSTER ? " base=" : "",
467 mons.base_monster != MONS_NO_MONSTER ?
468 get_monster_data(mons.base_monster)->name : "",
469 mons.mid, mons.number, mons.stealth(), mons.flags);
471 // Print habitat and behaviour information.
472 const habitat_type hab = mons_habitat(&mons);
474 mprf(MSGCH_DIAGNOSTICS,
475 "hab=%s beh=%s(%d) foe=%s(%d) mem=%d target=(%d,%d) "
476 "firing_pos=(%d,%d) god=%s",
477 ((hab == HT_LAND) ? "land" :
478 (hab == HT_AMPHIBIOUS) ? "amphibious" :
479 (hab == HT_WATER) ? "water" :
480 (hab == HT_LAVA) ? "lava" :
481 (hab == HT_ROCK) ? "rock"
482 : "unknown"),
483 (mons.asleep() ? "sleep" :
484 mons_is_wandering(&mons) ? "wander" :
485 mons_is_seeking(&mons) ? "seek" :
486 mons_is_fleeing(&mons) ? "flee" :
487 mons_is_cornered(&mons) ? "cornered" :
488 mons_is_panicking(&mons) ? "panic" :
489 mons_is_lurking(&mons) ? "lurk"
490 : "unknown"),
491 mons.behaviour,
492 ((mons.foe == MHITYOU) ? "you" :
493 (mons.foe == MHITNOT) ? "none" :
494 (menv[mons.foe].type == MONS_NO_MONSTER) ? "unassigned monster"
495 : menv[mons.foe].name(DESC_PLAIN, true).c_str()),
496 mons.foe,
497 mons.foe_memory,
498 mons.target.x, mons.target.y,
499 mons.firing_pos.x, mons.firing_pos.y,
500 god_name(mons.god).c_str());
502 // Print resistances.
503 mprf(MSGCH_DIAGNOSTICS, "resist: fire=%d cold=%d elec=%d pois=%d neg=%d "
504 "acid=%d sticky=%s rot=%s",
505 mons.res_fire(),
506 mons.res_cold(),
507 mons.res_elec(),
508 mons.res_poison(),
509 mons.res_negative_energy(),
510 mons.res_acid(),
511 mons.res_sticky_flame() ? "yes" : "no",
512 mons.res_rotting() ? "yes" : "no");
514 mprf(MSGCH_DIAGNOSTICS, "ench: %s",
515 mons.describe_enchantments().c_str());
517 std::ostringstream spl;
518 const monster_spells &hspell_pass = mons.spells;
519 bool found_spell = false;
520 for (int k = 0; k < NUM_MONSTER_SPELL_SLOTS; ++k)
522 if (hspell_pass[k] != SPELL_NO_SPELL)
524 if (found_spell)
525 spl << ", ";
527 found_spell = true;
529 spl << k << ": ";
531 if (hspell_pass[k] >= NUM_SPELLS)
532 spl << "buggy spell";
533 else
534 spl << spell_title(hspell_pass[k]);
536 spl << " (" << static_cast<int>(hspell_pass[k]) << ")";
539 if (found_spell)
540 mprf(MSGCH_DIAGNOSTICS, "spells: %s", spl.str().c_str());
542 if (mons_is_ghost_demon(mons.type))
544 ASSERT(mons.ghost.get());
545 const ghost_demon &ghost = *mons.ghost;
546 mprf(MSGCH_DIAGNOSTICS, "Ghost damage: %d; brand: %d; att_type: %d; "
547 "att_flav: %d",
548 ghost.damage, ghost.brand, ghost.att_type, ghost.att_flav);
552 // Detects all monsters on the level, using their exact positions.
553 void wizard_detect_creatures()
555 for (monster_iterator mi; mi; ++mi)
557 env.map_knowledge(mi->pos()).set_monster(monster_info(*mi));
558 env.map_knowledge(mi->pos()).set_detected_monster(mi->type);
562 // Dismisses all monsters on the level or all monsters that match a user
563 // specified regex.
564 void wizard_dismiss_all_monsters(bool force_all)
566 char buf[80] = "";
567 if (!force_all)
569 mpr("Regex of monsters to dismiss (ENTER for all): ", MSGCH_PROMPT);
570 bool validline = !cancelable_get_line_autohist(buf, sizeof buf);
572 if (!validline)
574 canned_msg(MSG_OK);
575 return;
579 dismiss_monsters(buf);
580 // If it was turned off turn autopickup back on if all monsters went away.
581 if (!*buf)
582 autotoggle_autopickup(false);
585 void debug_make_monster_shout(monster* mon)
587 mpr("Make the monster (S)hout or (T)alk? ", MSGCH_PROMPT);
589 char type = (char) getchm(KMC_DEFAULT);
590 type = tolower(type);
592 if (type != 's' && type != 't')
594 canned_msg(MSG_OK);
595 return;
598 int num_times = prompt_for_int("How many times? ", false);
600 if (num_times <= 0)
602 canned_msg(MSG_OK);
603 return;
606 if (type == 's')
608 if (silenced(you.pos()))
609 mpr("You are silenced and likely won't hear any shouts.");
610 else if (silenced(mon->pos()))
611 mpr("The monster is silenced and likely won't give any shouts.");
613 for (int i = 0; i < num_times; ++i)
614 force_monster_shout(mon);
616 else
618 if (mon->invisible())
619 mpr("The monster is invisible and likely won't speak.");
621 if (silenced(you.pos()) && !silenced(mon->pos()))
623 mpr("You are silenced but the monster isn't; you will "
624 "probably hear/see nothing.");
626 else if (!silenced(you.pos()) && silenced(mon->pos()))
627 mpr("The monster is silenced and likely won't say anything.");
628 else if (silenced(you.pos()) && silenced(mon->pos()))
630 mpr("Both you and the monster are silenced, so you likely "
631 "won't hear anything.");
634 for (int i = 0; i< num_times; ++i)
635 mons_speaks(mon);
638 mpr("== Done ==");
641 static bool _force_suitable(const monster* mon)
643 return (mon->alive());
646 void wizard_apply_monster_blessing(monster* mon)
648 mpr("Apply blessing of (B)eogh, The (S)hining One, or (R)andomly? ",
649 MSGCH_PROMPT);
651 char type = (char) getchm(KMC_DEFAULT);
652 type = tolower(type);
654 if (type != 'b' && type != 's' && type != 'r')
656 canned_msg(MSG_OK);
657 return;
659 god_type god = GOD_NO_GOD;
660 if (type == 'b' || type == 'r' && coinflip())
661 god = GOD_BEOGH;
662 else
663 god = GOD_SHINING_ONE;
665 if (!bless_follower(mon, god, _force_suitable, true))
666 mprf("%s won't bless this monster for you!", god_name(god).c_str());
669 void wizard_give_monster_item(monster* mon)
671 mon_itemuse_type item_use = mons_itemuse(mon);
672 if (item_use < MONUSE_STARTING_EQUIPMENT)
674 mpr("That type of monster can't use any items.");
675 return;
678 int player_slot = prompt_invent_item("Give which item to monster?",
679 MT_DROP, -1);
681 if (player_slot == PROMPT_ABORT)
682 return;
684 for (int i = 0; i < NUM_EQUIP; ++i)
685 if (you.equip[i] == player_slot)
687 mpr("Can't give equipped items to a monster.");
688 return;
691 item_def &item = you.inv[player_slot];
692 mon_inv_type mon_slot = NUM_MONSTER_SLOTS;
694 switch (item.base_type)
696 case OBJ_WEAPONS:
697 case OBJ_STAVES:
698 // Let wizard specify which slot to put weapon into via
699 // inscriptions.
700 if (item.inscription.find("first") != std::string::npos
701 || item.inscription.find("primary") != std::string::npos)
703 mpr("Putting weapon into primary slot by inscription");
704 mon_slot = MSLOT_WEAPON;
705 break;
707 else if (item.inscription.find("second") != std::string::npos
708 || item.inscription.find("alt") != std::string::npos)
710 mpr("Putting weapon into alt slot by inscription");
711 mon_slot = MSLOT_ALT_WEAPON;
712 break;
715 // For monsters which can wield two weapons, prefer whichever
716 // slot is empty (if there is an empty slot).
717 if (mons_wields_two_weapons(mon))
719 if (mon->inv[MSLOT_WEAPON] == NON_ITEM)
721 mpr("Dual wielding monster, putting into empty primary slot");
722 mon_slot = MSLOT_WEAPON;
723 break;
725 else if (mon->inv[MSLOT_ALT_WEAPON] == NON_ITEM)
727 mpr("Dual wielding monster, putting into empty alt slot");
728 mon_slot = MSLOT_ALT_WEAPON;
729 break;
733 // Try to replace a ranged weapon with a ranged weapon and
734 // a non-ranged weapon with a non-ranged weapon
735 if (mon->inv[MSLOT_WEAPON] != NON_ITEM
736 && (is_range_weapon(mitm[mon->inv[MSLOT_WEAPON]])
737 == is_range_weapon(item)))
739 mpr("Replacing primary slot with similar weapon");
740 mon_slot = MSLOT_WEAPON;
741 break;
743 if (mon->inv[MSLOT_ALT_WEAPON] != NON_ITEM
744 && (is_range_weapon(mitm[mon->inv[MSLOT_ALT_WEAPON]])
745 == is_range_weapon(item)))
747 mpr("Replacing alt slot with similar weapon");
748 mon_slot = MSLOT_ALT_WEAPON;
749 break;
752 // Prefer the empty slot (if any)
753 if (mon->inv[MSLOT_WEAPON] == NON_ITEM)
755 mpr("Putting weapon into empty primary slot");
756 mon_slot = MSLOT_WEAPON;
757 break;
759 else if (mon->inv[MSLOT_ALT_WEAPON] == NON_ITEM)
761 mpr("Putting weapon into empty alt slot");
762 mon_slot = MSLOT_ALT_WEAPON;
763 break;
766 // Default to primary weapon slot
767 mpr("Defaulting to primary slot");
768 mon_slot = MSLOT_WEAPON;
769 break;
771 case OBJ_ARMOUR:
773 // May only return shield or armour slot.
774 equipment_type eq = get_armour_slot(item);
776 // Force non-shield, non-body armour to be worn anyway.
777 if (eq == EQ_NONE)
778 eq = EQ_BODY_ARMOUR;
780 mon_slot = equip_slot_to_mslot(eq);
781 break;
783 case OBJ_MISSILES:
784 mon_slot = MSLOT_MISSILE;
785 break;
786 case OBJ_WANDS:
787 mon_slot = MSLOT_WAND;
788 break;
789 case OBJ_SCROLLS:
790 mon_slot = MSLOT_SCROLL;
791 break;
792 case OBJ_POTIONS:
793 mon_slot = MSLOT_POTION;
794 break;
795 case OBJ_MISCELLANY:
796 mon_slot = MSLOT_MISCELLANY;
797 break;
798 default:
799 mpr("You can't give that type of item to a monster.");
800 return;
803 if (item_use == MONUSE_STARTING_EQUIPMENT
804 && !mons_is_unique(mon->type))
806 switch (mon_slot)
808 case MSLOT_WEAPON:
809 case MSLOT_ALT_WEAPON:
810 case MSLOT_ARMOUR:
811 case MSLOT_MISSILE:
812 break;
814 default:
815 mpr("That type of monster can only use weapons and armour.");
816 return;
820 int index = get_item_slot(10);
821 if (index == NON_ITEM)
823 mpr("Too many items on level, bailing.");
824 return;
827 // Move monster's old item to player's inventory as last step.
828 int old_eq = NON_ITEM;
829 bool unequipped = false;
830 if (mon_slot != NUM_MONSTER_SLOTS
831 && mon->inv[mon_slot] != NON_ITEM
832 && !items_stack(item, mitm[mon->inv[mon_slot]]))
834 old_eq = mon->inv[mon_slot];
835 // Alternative weapons don't get (un)wielded unless the monster
836 // can wield two weapons.
837 if (mon_slot != MSLOT_ALT_WEAPON || mons_wields_two_weapons(mon))
839 mon->unequip(*(mon->mslot_item(mon_slot)), mon_slot, 1, true);
840 unequipped = true;
842 mon->inv[mon_slot] = NON_ITEM;
845 mitm[index] = item;
847 unwind_var<int> save_speedinc(mon->speed_increment);
848 if (!mon->pickup_item(mitm[index], false, true))
850 mpr("Monster wouldn't take item.");
851 if (old_eq != NON_ITEM && mon_slot != NUM_MONSTER_SLOTS)
853 mon->inv[mon_slot] = old_eq;
854 if (unequipped)
855 mon->equip(mitm[old_eq], mon_slot, 1);
857 unlink_item(index);
858 destroy_item(item);
859 return;
862 // Item is gone from player's inventory.
863 dec_inv_item_quantity(player_slot, item.quantity);
865 if ((mon->flags & MF_HARD_RESET) && !(item.flags & ISFLAG_SUMMONED))
867 mprf(MSGCH_WARN, "WARNING: Monster has MF_HARD_RESET and all its "
868 "items will disappear when it does.");
870 else if ((item.flags & ISFLAG_SUMMONED) && !mon->is_summoned())
872 mprf(MSGCH_WARN, "WARNING: Item is summoned and will disappear when "
873 "the monster does.");
875 // Monster's old item moves to player's inventory.
876 if (old_eq != NON_ITEM)
878 mpr("Fetching monster's old item.");
879 if (mitm[old_eq].flags & ISFLAG_SUMMONED)
881 mprf(MSGCH_WARN, "WARNING: Item is summoned and shouldn't really "
882 "be anywhere but in the inventory of a summoned monster.");
884 mitm[old_eq].pos.reset();
885 mitm[old_eq].link = NON_ITEM;
886 move_item_to_player(old_eq, mitm[old_eq].quantity);
890 static void _move_player(const coord_def& where)
892 if (!you.can_pass_through_feat(grd(where)))
893 grd(where) = DNGN_FLOOR;
894 move_player_to_grid(where, false, true);
897 static void _move_monster(const coord_def& where, int mid1)
899 dist moves;
900 direction_chooser_args args;
901 args.needs_path = false;
902 args.top_prompt = "Move monster to where?";
903 direction(moves, args);
905 if (!moves.isValid || !in_bounds(moves.target))
906 return;
908 monster* mon1 = &menv[mid1];
910 const int mid2 = mgrd(moves.target);
911 monster* mon2 = monster_at(moves.target);
913 mon1->moveto(moves.target);
914 mgrd(moves.target) = mid1;
915 mon1->check_redraw(moves.target);
917 mgrd(where) = mid2;
919 if (mon2 != NULL)
921 mon2->moveto(where);
922 mon1->check_redraw(where);
926 void wizard_move_player_or_monster(const coord_def& where)
928 crawl_state.cancel_cmd_again();
929 crawl_state.cancel_cmd_repeat();
931 static bool already_moving = false;
933 if (already_moving)
935 mpr("Already doing a move command.");
936 return;
939 already_moving = true;
941 int mid = mgrd(where);
943 if (mid == NON_MONSTER)
945 if (crawl_state.arena_suspended)
947 mpr("You can't move yourself into the arena.");
948 more();
949 return;
951 _move_player(where);
953 else
954 _move_monster(where, mid);
956 already_moving = false;
959 void wizard_make_monster_summoned(monster* mon)
961 int summon_type = 0;
962 if (mon->is_summoned(NULL, &summon_type) || summon_type != 0)
964 mpr("Monster is already summoned.", MSGCH_PROMPT);
965 return;
968 int dur = prompt_for_int("What summon longevity (1 to 6)? ", true);
970 if (dur < 1 || dur > 6)
972 canned_msg(MSG_OK);
973 return;
976 mpr("[a] clone [b] animated [c] chaos [d] miscast [e] zot", MSGCH_PROMPT);
977 mpr("[f] wrath [g] aid [m] misc [s] spell",
978 MSGCH_PROMPT);
980 mpr("Which summon type? ", MSGCH_PROMPT);
982 char choice = tolower(getchm());
984 if (!(choice >= 'a' && choice <= 'g') && choice != 'm' && choice != 's')
986 canned_msg(MSG_OK);
987 return;
990 int type = 0;
992 switch (choice)
994 case 'a': type = MON_SUMM_CLONE; break;
995 case 'b': type = MON_SUMM_ANIMATE; break;
996 case 'c': type = MON_SUMM_CHAOS; break;
997 case 'd': type = MON_SUMM_MISCAST; break;
998 case 'e': type = MON_SUMM_ZOT; break;
999 case 'f': type = MON_SUMM_WRATH; break;
1000 case 'g': type = MON_SUMM_AID; break;
1001 case 'm': type = 0; break;
1003 case 's':
1005 char specs[80];
1007 msgwin_get_line("Cast which spell by name? ",
1008 specs, sizeof(specs));
1010 if (specs[0] == '\0')
1012 canned_msg(MSG_OK);
1013 return;
1016 spell_type spell = spell_by_name(specs, true);
1017 if (spell == SPELL_NO_SPELL)
1019 mpr("No such spell.", MSGCH_PROMPT);
1020 return;
1022 type = (int) spell;
1023 break;
1026 default:
1027 die("Invalid summon type choice.");
1028 break;
1031 mon->mark_summoned(dur, true, type);
1032 mpr("Monster is now summoned.");
1035 void wizard_polymorph_monster(monster* mon)
1037 monster_type old_type = mon->type;
1038 monster_type type = debug_prompt_for_monster();
1040 if (type == NUM_MONSTERS)
1042 canned_msg(MSG_OK);
1043 return;
1046 if (invalid_monster_type(type))
1048 mpr("Invalid monster type.", MSGCH_PROMPT);
1049 return;
1052 if (type == old_type)
1054 mpr("Old type and new type are the same, not polymorphing.");
1055 return;
1058 if (mons_species(type) == mons_species(old_type))
1060 mpr("Target species must be different from current species.");
1061 return;
1064 monster_polymorph(mon, type, PPT_SAME, true);
1066 if (!mon->alive())
1068 mpr("Polymorph killed monster?", MSGCH_ERROR);
1069 return;
1072 mon->check_redraw(mon->pos());
1074 if (mon->type == old_type)
1075 mpr("Polymorph failed.");
1076 else if (mon->type != type)
1077 mpr("Monster turned into something other than the desired type.");
1080 void debug_pathfind(int mid)
1082 if (mid == NON_MONSTER)
1083 return;
1085 mpr("Choose a destination!");
1086 #ifndef USE_TILE
1087 more();
1088 #endif
1089 coord_def dest;
1090 level_pos ldest;
1091 bool chose = show_map(ldest, false, true, false);
1092 dest = ldest.pos;
1093 redraw_screen();
1094 if (!chose)
1096 canned_msg(MSG_OK);
1097 return;
1100 monster& mon = menv[mid];
1101 mprf("Attempting to calculate a path from (%d, %d) to (%d, %d)...",
1102 mon.pos().x, mon.pos().y, dest.x, dest.y);
1103 monster_pathfind mp;
1104 bool success = mp.init_pathfind(&mon, dest, true, true);
1105 if (success)
1107 std::vector<coord_def> path = mp.backtrack();
1108 std::string path_str;
1109 mpr("Here's the shortest path: ");
1110 for (unsigned int i = 0; i < path.size(); ++i)
1112 snprintf(info, INFO_SIZE, "(%d, %d) ", path[i].x, path[i].y);
1113 path_str += info;
1115 mpr(path_str.c_str());
1116 mprf("-> path length: %d", path.size());
1118 mpr("");
1119 path = mp.calc_waypoints();
1120 path_str = "";
1121 mpr("");
1122 mpr("And here are the needed waypoints: ");
1123 for (unsigned int i = 0; i < path.size(); ++i)
1125 snprintf(info, INFO_SIZE, "(%d, %d) ", path[i].x, path[i].y);
1126 path_str += info;
1128 mpr(path_str.c_str());
1129 mprf("-> #waypoints: %d", path.size());
1133 static void _miscast_screen_update()
1135 viewwindow();
1137 you.redraw_status_flags =
1138 REDRAW_LINE_1_MASK | REDRAW_LINE_2_MASK | REDRAW_LINE_3_MASK;
1139 print_stats();
1141 #ifndef USE_TILE
1142 update_monster_pane();
1143 #endif
1146 void debug_miscast(int target_index)
1148 crawl_state.cancel_cmd_repeat();
1150 actor* target;
1151 if (target_index == NON_MONSTER)
1152 target = &you;
1153 else
1154 target = &menv[target_index];
1156 if (!target->alive())
1158 mpr("Can't make already dead target miscast.");
1159 return;
1162 char specs[100];
1163 mpr("Miscast which school or spell, by name? ", MSGCH_PROMPT);
1164 if (cancelable_get_line_autohist(specs, sizeof specs) || !*specs)
1166 canned_msg(MSG_OK);
1167 return;
1170 spell_type spell = spell_by_name(specs, true);
1171 spschool_flag_type school = school_by_name(specs);
1173 // Prefer exact matches for school name over partial matches for
1174 // spell name.
1175 if (school != SPTYP_NONE
1176 && (strcasecmp(specs, spelltype_short_name(school)) == 0
1177 || strcasecmp(specs, spelltype_long_name(school)) == 0))
1179 spell = SPELL_NO_SPELL;
1182 if (spell == SPELL_NO_SPELL && school == SPTYP_NONE)
1184 mpr("No matching spell or spell school.");
1185 return;
1187 else if (spell != SPELL_NO_SPELL && school != SPTYP_NONE)
1189 mprf("Ambiguous: can be spell '%s' or school '%s'.",
1190 spell_title(spell), spelltype_short_name(school));
1191 return;
1194 int disciplines = 0;
1195 if (spell != SPELL_NO_SPELL)
1197 disciplines = get_spell_disciplines(spell);
1199 if (disciplines == 0)
1201 mprf("Spell '%s' has no disciplines.", spell_title(spell));
1202 return;
1206 if (is_holy_spell(spell))
1208 mpr("Can't miscast holy spells.");
1209 return;
1212 if (spell != SPELL_NO_SPELL)
1213 mprf("Miscasting spell %s.", spell_title(spell));
1214 else
1215 mprf("Miscasting school %s.", spelltype_long_name(school));
1217 if (spell != SPELL_NO_SPELL)
1218 mpr("Enter spell_power,spell_failure: ", MSGCH_PROMPT);
1219 else
1221 mpr("Enter miscast_level or spell_power,spell_failure: ",
1222 MSGCH_PROMPT);
1225 if (cancelable_get_line_autohist(specs, sizeof specs) || !*specs)
1227 canned_msg(MSG_OK);
1228 return;
1231 int level = -1, pow = -1, fail = -1;
1233 if (strchr(specs, ','))
1235 std::vector<std::string> nums = split_string(",", specs);
1236 pow = atoi(nums[0].c_str());
1237 fail = atoi(nums[1].c_str());
1239 if (pow <= 0 || fail <= 0)
1241 canned_msg(MSG_OK);
1242 return;
1245 else
1247 if (spell != SPELL_NO_SPELL)
1249 mpr("Can only enter fixed miscast level for schools, not spells.");
1250 return;
1253 level = atoi(specs);
1254 if (level < 0)
1256 canned_msg(MSG_OK);
1257 return;
1259 else if (level > 3)
1261 mpr("Miscast level can be at most 3.");
1262 return;
1266 // Handle repeats ourselves since miscasts are likely to interrupt
1267 // command repetions, especially if the player is the target.
1268 int repeats = prompt_for_int("Number of repetitions? ", true);
1269 if (repeats < 1)
1271 canned_msg(MSG_OK);
1272 return;
1275 // Supress "nothing happens" message for monster miscasts which are
1276 // only harmless messages, since a large number of those are missing
1277 // monster messages.
1278 nothing_happens_when_type nothing = NH_DEFAULT;
1279 if (target_index != NON_MONSTER && level == 0)
1280 nothing = NH_NEVER;
1282 MiscastEffect *miscast;
1284 if (spell != SPELL_NO_SPELL)
1286 miscast = new MiscastEffect(target, target_index, spell, pow, fail,
1287 "", nothing);
1289 else
1291 if (level != -1)
1293 miscast = new MiscastEffect(target, target_index, school,
1294 level, "wizard testing miscast",
1295 nothing);
1297 else
1299 miscast = new MiscastEffect(target, target_index, school,
1300 pow, fail, "wizard testing miscast",
1301 nothing);
1304 // Merely creating the miscast object causes one miscast effect to
1305 // happen.
1306 repeats--;
1307 if (level != 0)
1308 _miscast_screen_update();
1310 while (target->alive() && repeats-- > 0)
1312 if (kbhit())
1314 mpr("Key pressed, interrupting miscast testing.");
1315 getchm();
1316 break;
1319 miscast->do_miscast();
1320 if (level != 0)
1321 _miscast_screen_update();
1324 delete miscast;
1327 void debug_ghosts()
1329 mpr("(C)reate or (L)oad bones file?", MSGCH_PROMPT);
1330 const char c = tolower(getchm());
1332 if (c == 'c')
1333 save_ghost(true);
1334 else if (c == 'l')
1335 load_ghost(false);
1336 else
1337 canned_msg(MSG_OK);
1340 #endif