Difference between revisions of "Ring of polymorph control"

From NetHackWiki
Jump to navigation Jump to search
(Convert to monsymlink. Add comment about dwarves, gnomes.)
(Limitations of controlled polymorph)
Line 24: Line 24:
  
 
Polymorph into your own species is permitted in spite of the above list.
 
Polymorph into your own species is permitted in spite of the above list.
 +
 +
1.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
 +
2.   
 +
3.    #include "hack.h"
 +
4.    #ifndef NOWORM
 +
5.    #include "def.wseg.h"
 +
6.   
 +
7.    struct wseg *wsegs[32]; /* linked list, tail first */
 +
8.    struct wseg *wheads[32];
 +
9.    long wgrowtime[32];
 +
10. 
 +
11.  getwn(mtmp) struct monst *mtmp; {
 +
12.  register tmp;
 +
13.  for(tmp=1; tmp<32; tmp++) if(!wsegs[tmp]) {
 +
14.  mtmp->wormno = tmp;
 +
15.  return(1);
 +
16.  }
 +
17.    return(0); /* level infested with worms */
 +
18.  }
 +
19. 
 +
20.  /* called to initialize a worm unless cut in half */
 +
21.  initworm(mtmp) struct monst *mtmp; {
 +
22.  register struct wseg *wtmp;
 +
23.  register tmp = mtmp->wormno;
 +
24.  if(!tmp) return;
 +
25.  wheads[tmp] = wsegs[tmp] = wtmp = newseg();
 +
26.  wgrowtime[tmp] = 0;
 +
27.  wtmp->wx = mtmp->mx;
 +
28.  wtmp->wy = mtmp->my;
 +
29.  /* wtmp->wdispl = 0;*/
 +
30.  wtmp->nseg = 0;
 +
31.  }
 +
32. 
 +
33.  worm_move(mtmp) struct monst *mtmp; {
 +
34.  register struct wseg *wtmp, *whd;
 +
35.  register tmp = mtmp->wormno;
 +
36.  wtmp = newseg();
 +
37.  wtmp->wx = mtmp->mx;
 +
38.  wtmp->wy = mtmp->my;
 +
39.  wtmp->nseg = 0;
 +
40.  /* wtmp->wdispl = 0;*/
 +
41.  (whd = wheads[tmp])->nseg = wtmp;
 +
42.  wheads[tmp] = wtmp;
 +
43.  if(cansee(whd->wx,whd->wy)){
 +
44.  unpmon(mtmp);
 +
45.  atl(whd->wx, whd->wy, '~');
 +
46.  whd->wdispl = 1;
 +
47.  } else whd->wdispl = 0;
 +
48.  if(wgrowtime[tmp] <= moves) {
 +
49.  if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5);
 +
50.  else wgrowtime[tmp] += 2+rnd(15);
 +
51.  mtmp->orig_hp++;
 +
52.  mtmp->mhp++;
 +
53.  return;
 +
54.  }
 +
55.  whd = wsegs[tmp];
 +
56.  wsegs[tmp] = whd->nseg;
 +
57.  remseg(whd);
 +
58.  }
 +
59. 
 +
60.  worm_nomove(mtmp) register struct monst *mtmp; {
 +
61.  register tmp;
 +
62.  register struct wseg *wtmp;
 +
63.  tmp = mtmp->wormno;
 +
64.  wtmp = wsegs[tmp];
 +
65.  if(wtmp == wheads[tmp]) return;
 +
66.  if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?");
 +
67.  wsegs[tmp] = wtmp->nseg;
 +
68.  remseg(wtmp);
 +
69.  mtmp->mhp--; /* orig_hp not changed ! */
 +
70.  }
 +
71. 
 +
72.  wormdead(mtmp) register struct monst *mtmp; {
 +
73.  register tmp = mtmp->wormno;
 +
74.  register struct wseg *wtmp, *wtmp2;
 +
75.  if(!tmp) return;
 +
76.  mtmp->wormno = 0;
 +
77.  for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
 +
78.  wtmp2 = wtmp->nseg;
 +
79.  remseg(wtmp);
 +
80.  }
 +
81.    wsegs[tmp] = 0;
 +
82.  }
 +
83. 
 +
84.  wormhit(mtmp) register struct monst *mtmp; {
 +
85.  register tmp = mtmp->wormno;
 +
86.  register struct wseg *wtmp;
 +
87.  if(!tmp) return; /* worm without tail */
 +
88.  for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
 +
89.  (void) hitu(mtmp,1);
 +
90.  }
 +
91. 
 +
92.  wormsee(tmp) register unsigned tmp; {
 +
93.  register struct wseg *wtmp = wsegs[tmp];
 +
94.  if(!wtmp) panic("wormsee: wtmp==0");
 +
95.  for(; wtmp->nseg; wtmp = wtmp->nseg)
 +
96.  if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl){
 +
97.  newsym(wtmp->wx, wtmp->wy);
 +
98.  wtmp->wdispl = 0;
 +
99.  }
 +
100.  }
 +
101. 
 +
102.  pwseg(wtmp) register struct wseg *wtmp; {
 +
103.  if(!wtmp->wdispl){
 +
104.  atl(wtmp->wx, wtmp->wy, '~');
 +
105.  wtmp->wdispl = 1;
 +
106.  }
 +
107.  }
 +
108. 
 +
109.  cutworm(mtmp,x,y,weptyp)
 +
110.  register struct monst *mtmp;
 +
111.  register xchar x,y;
 +
112.  register uchar weptyp; /* uwep->otyp or 0 */
 +
113.  {
 +
114.  register struct wseg *wtmp, *wtmp2;
 +
115.  register struct monst *mtmp2;
 +
116.  register tmp,tmp2;
 +
117.  if(mtmp->mx == x && mtmp->my == y) return; /* hit headon */
 +
118. 
 +
119.  /* cutting goes best with axe or sword */
 +
120.  tmp = rnd(20);
 +
121.  if(weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD ||
 +
122.  weptyp == AXE) tmp += 5;
 +
123.  if(tmp < 12) return;
 +
124. 
 +
125.  /* if tail then worm just loses a tail segment */
 +
126.  tmp = mtmp->wormno;
 +
127.  wtmp = wsegs[tmp];
 +
128.  if(wtmp->wx == x && wtmp->wy == y){
 +
129.  wsegs[tmp] = wtmp->nseg;
 +
130.  remseg(wtmp);
 +
131.  return;
 +
132.  }
 +
133. 
 +
134.  /* cut the worm in two halves */
 +
135.  mtmp2 = newmonst(0);
 +
136.  *mtmp2 = *mtmp;
 +
137.  mtmp2->mxlth = mtmp2->mnamelth = 0;
 +
138. 
 +
139.  /* sometimes the tail end dies */
 +
140.  if(rn2(3) || !getwn(mtmp2)){
 +
141.  monfree(mtmp2);
 +
142.  tmp2 = 0;
 +
143.  } else {
 +
144.  tmp2 = mtmp2->wormno;
 +
145.  wsegs[tmp2] = wsegs[tmp];
 +
146.  wgrowtime[tmp2] = 0;
 +
147.  }
 +
148.  do {
 +
149.  if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){
 +
150.  if(tmp2) wheads[tmp2] = wtmp;
 +
151.  wsegs[tmp] = wtmp->nseg->nseg;
 +
152.  remseg(wtmp->nseg);
 +
153.  wtmp->nseg = 0;
 +
154.  if(tmp2){
 +
155.  pline("You cut the worm in half.");
 +
156.  mtmp2->orig_hp = mtmp2->mhp =
 +
157.  d(mtmp2->data->mlevel, 8);
 +
158.  mtmp2->mx = wtmp->wx;
 +
159.  mtmp2->my = wtmp->wy;
 +
160.  mtmp2->nmon = fmon;
 +
161.  fmon = mtmp2;
 +
162.  pmon(mtmp2);
 +
163.  } else {
 +
164.  pline("You cut off part of the worm's tail.");
 +
165.  remseg(wtmp);
 +
166.  }
 +
167.  mtmp->mhp /= 2;
 +
168.  return;
 +
169.  }
 +
170.  wtmp2 = wtmp->nseg;
 +
171.  if(!tmp2) remseg(wtmp);
 +
172.  wtmp = wtmp2;
 +
173.  } while(wtmp->nseg);
 +
174.  panic("Cannot find worm segment");
 +
175.  }
 +
176. 
 +
177.  remseg(wtmp) register struct wseg *wtmp; {
 +
178.  if(wtmp->wdispl)
 +
179.  newsym(wtmp->wx, wtmp->wy);
 +
180.  free((char *) wtmp);
 +
181.  }
 +
182.  #endif NOWORM
  
 
== References ==
 
== References ==

Revision as of 23:07, 24 March 2009

=
Name polymorph control
Appearance random
Base price 300 zm
Weight 3

As its name suggests, the ring of polymorph control is a ring that grants polymorph control when worn.

If you are wearing (or have eaten) this ring and something causes you to polymorph, then you will be asked "Become what type of monster? [type the name]". You can then choose to polymorph into a monster.

Rings of polymorph control will also allow you to decline a change in form brought upon by lycanthropy.

Polymorph into your own species will cause you to "feel like a new (wo)man!" or whatever species, and cause random change to your scores. There is a chance that this will happen in spite of polymorph control, even if a different monster is chosen.

Limitations of controlled polymorph

Certain monsters are off-limits to polymorph[1]; these include:

Polymorph into your own species is permitted in spite of the above list.

1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2. 3. #include "hack.h" 4. #ifndef NOWORM 5. #include "def.wseg.h" 6. 7. struct wseg *wsegs[32]; /* linked list, tail first */ 8. struct wseg *wheads[32]; 9. long wgrowtime[32]; 10. 11. getwn(mtmp) struct monst *mtmp; { 12. register tmp; 13. for(tmp=1; tmp<32; tmp++) if(!wsegs[tmp]) { 14. mtmp->wormno = tmp; 15. return(1); 16. } 17. return(0); /* level infested with worms */ 18. } 19. 20. /* called to initialize a worm unless cut in half */ 21. initworm(mtmp) struct monst *mtmp; { 22. register struct wseg *wtmp; 23. register tmp = mtmp->wormno; 24. if(!tmp) return; 25. wheads[tmp] = wsegs[tmp] = wtmp = newseg(); 26. wgrowtime[tmp] = 0; 27. wtmp->wx = mtmp->mx; 28. wtmp->wy = mtmp->my; 29. /* wtmp->wdispl = 0;*/ 30. wtmp->nseg = 0; 31. } 32. 33. worm_move(mtmp) struct monst *mtmp; { 34. register struct wseg *wtmp, *whd; 35. register tmp = mtmp->wormno; 36. wtmp = newseg(); 37. wtmp->wx = mtmp->mx; 38. wtmp->wy = mtmp->my; 39. wtmp->nseg = 0; 40. /* wtmp->wdispl = 0;*/ 41. (whd = wheads[tmp])->nseg = wtmp; 42. wheads[tmp] = wtmp; 43. if(cansee(whd->wx,whd->wy)){ 44. unpmon(mtmp); 45. atl(whd->wx, whd->wy, '~'); 46. whd->wdispl = 1; 47. } else whd->wdispl = 0; 48. if(wgrowtime[tmp] <= moves) { 49. if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5); 50. else wgrowtime[tmp] += 2+rnd(15); 51. mtmp->orig_hp++; 52. mtmp->mhp++; 53. return; 54. } 55. whd = wsegs[tmp]; 56. wsegs[tmp] = whd->nseg; 57. remseg(whd); 58. } 59. 60. worm_nomove(mtmp) register struct monst *mtmp; { 61. register tmp; 62. register struct wseg *wtmp; 63. tmp = mtmp->wormno; 64. wtmp = wsegs[tmp]; 65. if(wtmp == wheads[tmp]) return; 66. if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?"); 67. wsegs[tmp] = wtmp->nseg; 68. remseg(wtmp); 69. mtmp->mhp--; /* orig_hp not changed ! */ 70. } 71. 72. wormdead(mtmp) register struct monst *mtmp; { 73. register tmp = mtmp->wormno; 74. register struct wseg *wtmp, *wtmp2; 75. if(!tmp) return; 76. mtmp->wormno = 0; 77. for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){ 78. wtmp2 = wtmp->nseg; 79. remseg(wtmp); 80. } 81. wsegs[tmp] = 0; 82. } 83. 84. wormhit(mtmp) register struct monst *mtmp; { 85. register tmp = mtmp->wormno; 86. register struct wseg *wtmp; 87. if(!tmp) return; /* worm without tail */ 88. for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg) 89. (void) hitu(mtmp,1); 90. } 91. 92. wormsee(tmp) register unsigned tmp; { 93. register struct wseg *wtmp = wsegs[tmp]; 94. if(!wtmp) panic("wormsee: wtmp==0"); 95. for(; wtmp->nseg; wtmp = wtmp->nseg) 96. if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl){ 97. newsym(wtmp->wx, wtmp->wy); 98. wtmp->wdispl = 0; 99. } 100. } 101. 102. pwseg(wtmp) register struct wseg *wtmp; { 103. if(!wtmp->wdispl){ 104. atl(wtmp->wx, wtmp->wy, '~'); 105. wtmp->wdispl = 1; 106. } 107. } 108. 109. cutworm(mtmp,x,y,weptyp) 110. register struct monst *mtmp; 111. register xchar x,y; 112. register uchar weptyp; /* uwep->otyp or 0 */ 113. { 114. register struct wseg *wtmp, *wtmp2; 115. register struct monst *mtmp2; 116. register tmp,tmp2; 117. if(mtmp->mx == x && mtmp->my == y) return; /* hit headon */ 118. 119. /* cutting goes best with axe or sword */ 120. tmp = rnd(20); 121. if(weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD || 122. weptyp == AXE) tmp += 5; 123. if(tmp < 12) return; 124. 125. /* if tail then worm just loses a tail segment */ 126. tmp = mtmp->wormno; 127. wtmp = wsegs[tmp]; 128. if(wtmp->wx == x && wtmp->wy == y){ 129. wsegs[tmp] = wtmp->nseg; 130. remseg(wtmp); 131. return; 132. } 133. 134. /* cut the worm in two halves */ 135. mtmp2 = newmonst(0); 136. *mtmp2 = *mtmp; 137. mtmp2->mxlth = mtmp2->mnamelth = 0; 138. 139. /* sometimes the tail end dies */ 140. if(rn2(3) || !getwn(mtmp2)){ 141. monfree(mtmp2); 142. tmp2 = 0; 143. } else { 144. tmp2 = mtmp2->wormno; 145. wsegs[tmp2] = wsegs[tmp]; 146. wgrowtime[tmp2] = 0; 147. } 148. do { 149. if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){ 150. if(tmp2) wheads[tmp2] = wtmp; 151. wsegs[tmp] = wtmp->nseg->nseg; 152. remseg(wtmp->nseg); 153. wtmp->nseg = 0; 154. if(tmp2){ 155. pline("You cut the worm in half."); 156. mtmp2->orig_hp = mtmp2->mhp = 157. d(mtmp2->data->mlevel, 8); 158. mtmp2->mx = wtmp->wx; 159. mtmp2->my = wtmp->wy; 160. mtmp2->nmon = fmon; 161. fmon = mtmp2; 162. pmon(mtmp2); 163. } else { 164. pline("You cut off part of the worm's tail."); 165. remseg(wtmp); 166. } 167. mtmp->mhp /= 2; 168. return; 169. } 170. wtmp2 = wtmp->nseg; 171. if(!tmp2) remseg(wtmp); 172. wtmp = wtmp2; 173. } while(wtmp->nseg); 174. panic("Cannot find worm segment"); 175. } 176. 177. remseg(wtmp) register struct wseg *wtmp; { 178. if(wtmp->wdispl) 179. newsym(wtmp->wx, wtmp->wy); 180. free((char *) wtmp); 181. } 182. #endif NOWORM

References

This page may need to be updated for the current version of NetHack.

It may contain text specific to NetHack 3.4.3. Information on this page may be out of date.

Editors: After reviewing this page and making necessary edits, please change the {{nethack-343}} tag to the current version's tag or {{noversion}} as appropriate.