-/* NetHack 3.6 polyself.c $NHDT-Date: 1520797126 2018/03/11 19:38:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.117 $ */
+/* NetHack 3.6 polyself.c $NHDT-Date: 1556497911 2019/04/29 00:31:51 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.132 $ */
/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
/* NetHack may be freely redistributed. See license for details. */
STATIC_DCL void FDECL(polyman, (const char *, const char *));
STATIC_DCL void NDECL(break_armor);
STATIC_DCL void FDECL(drop_weapon, (int));
-STATIC_DCL void NDECL(uunstick);
STATIC_DCL int FDECL(armor_to_dragon, (int));
STATIC_DCL void NDECL(newman);
STATIC_DCL void NDECL(polysense);
set_uasmon()
{
struct permonst *mdat = &mons[u.umonnum];
- int new_speed, old_speed = youmonst.data ? youmonst.data->mmove : 0;
- set_mon_data(&youmonst, mdat, 0);
+ set_mon_data(&youmonst, mdat);
#define PROPSET(PropIndx, ON) \
do { \
PROPSET(HALLUC_RES, dmgtype(mdat, AD_HALU));
PROPSET(SEE_INVIS, perceives(mdat));
PROPSET(TELEPAT, telepathic(mdat));
- PROPSET(INFRAVISION, infravision(mdat));
+ /* note that Infravision uses mons[race] rather than usual mons[role] */
+ PROPSET(INFRAVISION, infravision(Upolyd ? mdat : &mons[urace.malenum]));
PROPSET(INVIS, pm_invisible(mdat));
PROPSET(TELEPORT, can_teleport(mdat));
PROPSET(TELEPORT_CONTROL, control_teleport(mdat));
PROPSET(LEVITATION, is_floater(mdat));
- PROPSET(FLYING, is_flyer(mdat));
+ /* floating eye is the only 'floater'; it is also flagged as a 'flyer';
+ suppress flying for it so that enlightenment doesn't confusingly
+ show latent flight capability always blocked by levitation */
+ PROPSET(FLYING, (is_flyer(mdat) && !is_floater(mdat)));
PROPSET(SWIMMING, is_swimmer(mdat));
/* [don't touch MAGICAL_BREATHING here; both Amphibious and Breathless
key off of it but include different monster forms...] */
float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */
polysense();
- if (youmonst.movement) {
- new_speed = mdat->mmove;
- /* prorate unused movement if new form is slower so that
- it doesn't get extra moves leftover from previous form;
- if new form is faster, leave unused movement as is */
- if (new_speed < old_speed)
- youmonst.movement = new_speed * youmonst.movement / old_speed;
- }
-
#ifdef STATUS_HILITES
- status_initialize(REASSESS_ONLY);
+ if (VIA_WINDOWPORT())
+ status_initialize(REASSESS_ONLY);
#endif
}
void
float_vs_flight()
{
- /* floating overrides flight; normally float_up() and float_down()
- handle this, but sometimes they're skipped */
- if (HLevitation || ELevitation)
+ boolean stuck_in_floor = (u.utrap && u.utraptype != TT_PIT);
+
+ /* floating overrides flight; so does being trapped in the floor */
+ if ((HLevitation || ELevitation)
+ || ((HFlying || EFlying) && stuck_in_floor))
BFlying |= I_SPECIAL;
else
BFlying &= ~I_SPECIAL;
+ /* being trapped on the ground (bear trap, web, molten lava survived
+ with fire resistance, former lava solidified via cold, tethered
+ to a buried iron ball) overrides floating--the floor is reachable */
+ if ((HLevitation || ELevitation) && stuck_in_floor)
+ BLevitation |= I_SPECIAL;
+ else
+ BLevitation &= ~I_SPECIAL;
context.botl = TRUE;
}
const char *fmt, *arg;
{
boolean sticky = (sticks(youmonst.data) && u.ustuck && !u.uswallow),
- was_mimicking = (youmonst.m_ap_type == M_AP_OBJECT);
+ was_mimicking = (U_AP_TYPE == M_AP_OBJECT);
boolean was_blind = !!Blind;
if (Upolyd) {
if (u.twoweap && !could_twoweap(youmonst.data))
untwoweapon();
- if (u.utraptype == TT_PIT && u.utrap) {
- u.utrap = rn1(6, 2); /* time to escape resets */
+ if (u.utrap && u.utraptype == TT_PIT) {
+ set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */
}
if (was_blind && !Blind) { /* reverting from eyeless */
Blinded = 1L;
}
/* if stuck mimicking gold, stop immediately */
- if (multi < 0 && youmonst.m_ap_type == M_AP_OBJECT
+ if (multi < 0 && U_AP_TYPE == M_AP_OBJECT
&& youmonst.data->mlet != S_MIMIC)
unmul("");
/* if becoming a non-mimic, stop mimicking anything */
drop_weapon(1);
(void) hideunder(&youmonst);
- if (u.utraptype == TT_PIT && u.utrap) {
- u.utrap = rn1(6, 2); /* time to escape resets */
+ if (u.utrap && u.utraptype == TT_PIT) {
+ set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */
}
if (was_blind && !Blind) { /* previous form was eyeless */
Blinded = 1L;
}
newsym(u.ux, u.uy); /* Change symbol */
+ /* [note: this 'sticky' handling is only sufficient for changing from
+ grabber to engulfer or vice versa because engulfing by poly'd hero
+ always ends immediately so won't be in effect during a polymorph] */
if (!sticky && !u.uswallow && u.ustuck && sticks(youmonst.data))
u.ustuck = 0;
else if (sticky && !sticks(youmonst.data))
uunstick();
+
if (u.usteed) {
if (touch_petrifies(u.usteed->data) && !Stone_resistance && rnl(3)) {
#if 0 /*JP:T*/
*/
pline(use_thec, monsterc, "\8ep\82ð\95Ï\82¦\82é");
- if (lays_eggs(youmonst.data) && flags.female)
-/*JP
- pline(use_thec, "sit", "lay an egg");
-*/
+ if (lays_eggs(youmonst.data) && flags.female &&
+ !(youmonst.data == &mons[PM_GIANT_EEL]
+ || youmonst.data == &mons[PM_ELECTRIC_EEL]))
+#if 0 /*JP*/
+ pline(use_thec, "sit",
+ eggs_in_water(youmonst.data) ?
+ "spawn in the water" : "lay an egg");
+#else /* \93ú\96{\8cê\82Å\82Í\90\85\92\86\82Å\82à\81u\97\91\82ð\8eY\82Þ\81v\82Å\96â\91è\82È\82¢ */
pline(use_thec, "sit", "\97\91\82ð\8eY\82Þ");
+#endif
}
/* you now know what an egg of your type looks like */
spoteffects(TRUE);
if (Passes_walls && u.utrap
&& (u.utraptype == TT_INFLOOR || u.utraptype == TT_BURIEDBALL)) {
- u.utrap = 0;
- if (u.utraptype == TT_INFLOOR)
+ if (u.utraptype == TT_INFLOOR) {
/*JP
pline_The("rock seems to no longer trap you.");
*/
pline("\8aâ\82É\95Â\82¶\8d\9e\82ß\82ç\82ê\82é\82±\82Æ\82Í\82È\82¢\82¾\82ë\82¤\81D");
- else {
+ } else {
/*JP
pline_The("buried ball is no longer bound to you.");
*/
pline_The("\96\84\82Ü\82Á\82½\8b\85\82ª\8e×\96\82\82É\82È\82é\82±\82Æ\82Í\82È\82¢\82¾\82ë\82¤\81D");
buried_ball_to_freedom();
}
+ reset_utrap(TRUE);
} else if (likes_lava(youmonst.data) && u.utrap
&& u.utraptype == TT_LAVA) {
- u.utrap = 0;
/*JP
pline_The("%s now feels soothing.", hliquid("lava"));
*/
pline_The("%s\82ª\90¸\90_\82ð\97\8e\82¿\82Â\82©\82¹\82Ä\82\82ê\82é\81D", hliquid("\97n\8aâ"));
+ reset_utrap(TRUE);
}
if (amorphous(youmonst.data) || is_whirly(youmonst.data)
|| unsolid(youmonst.data)) {
u.utraptype == TT_WEB ? "\82\82à\82Ì\91\83" : "\8cF\82Ìã©");
#endif
/* probably should burn webs too if PM_FIRE_ELEMENTAL */
- u.utrap = 0;
+ reset_utrap(TRUE);
}
if (webmaker(youmonst.data) && u.utrap && u.utraptype == TT_WEB) {
/*JP
You("orient yourself on the web.");
*/
You("\82\82à\82Ì\91\83\82É\93K\89\9e\82µ\82½\81D");
- u.utrap = 0;
+ reset_utrap(TRUE);
}
check_strangling(TRUE); /* maybe start strangling */
void
rehumanize()
{
+ boolean was_flying = (Flying != 0);
+
/* You can't revert back while unchanging */
if (Unchanging) {
if (u.mh < 1) {
context.botl = 1;
vision_full_recalc = 1;
(void) encumber_msg();
-
+ if (was_flying && !Flying && u.usteed)
+ You("and %s return gently to the %s.",
+ mon_nam(u.usteed), surface(u.ux, u.uy));
retouch_equipment(2);
if (!uarmg)
selftouch(no_longer_petrify_resistant);
break;
default:
impossible("bad attack type in dospit");
- /* fall through */
+ /*FALLTHRU*/
case AD_ACID:
otmp = mksobj(ACID_VENOM, TRUE, FALSE);
break;
You_cant("see where to gaze at %s.", Monnam(mtmp));
*/
You("%s\82Í\8c©\82¦\82È\82¢\82Ì\82Å\81C\82É\82ç\82ß\82È\82¢", Monnam(mtmp));
- } else if (mtmp->m_ap_type == M_AP_FURNITURE
- || mtmp->m_ap_type == M_AP_OBJECT) {
+ } else if (M_AP_TYPE(mtmp) == M_AP_FURNITURE
+ || M_AP_TYPE(mtmp) == M_AP_OBJECT) {
looked--;
continue;
} else if (flags.safe_dog && mtmp->mtame && !Confusion) {
(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
if (dmg)
mtmp->mhp -= dmg;
- if (mtmp->mhp <= 0)
+ if (DEADMONSTER(mtmp))
killed(mtmp);
}
/* For consistency with passive() in uhitm.c, this only
: "\89ö\95¨\82ð\82Â\82©\82ñ\82Å\82¢\82é");
#endif
if (u.uundetected
- || (ismimic && youmonst.m_ap_type != M_AP_NOTHING)) {
+ || (ismimic && U_AP_TYPE != M_AP_NOTHING)) {
u.uundetected = 0;
youmonst.m_ap_type = M_AP_NOTHING;
newsym(u.ux, u.uy);
* else make youhiding() give smarter messages at such spots.
*/
- if (u.uundetected || (ismimic && youmonst.m_ap_type != M_AP_NOTHING)) {
+ if (u.uundetected || (ismimic && U_AP_TYPE != M_AP_NOTHING)) {
youhiding(FALSE, 1); /* "you are already hiding" */
return 0;
}
: telepathic(mtmp->data) ? "\90ö\8dÝ\93I\90¸\90_\82É\93ü" : "\90[\91w\88Ó\8e¯\82É\90ö");
#endif
mtmp->mhp -= rnd(15);
- if (mtmp->mhp <= 0)
+ if (DEADMONSTER(mtmp))
killed(mtmp);
}
}
return 1;
}
-STATIC_OVL void
+void
uunstick()
{
+ if (!u.ustuck) {
+ impossible("uunstick: no ustuck?");
+ return;
+ }
/*JP
pline("%s is no longer in your clutches.", Monnam(u.ustuck));
*/