MCPcopy Create free account
hub / github.com/NetHack/NetHack / losexp

Function losexp

src/exper.c:206–291  ·  view source on GitHub ↗

e.g., hit by drain life attack */

Source from the content-addressed store, hash-verified

204
205/* e.g., hit by drain life attack */
206void
207losexp(
208 const char *drainer) /* cause of death, if drain should be fatal */
209{
210 int num, uhpmin, olduhpmax;
211
212 /* override life-drain resistance when handling an explicit
213 wizard mode request to reduce level; never fatal though */
214 if (drainer && !strcmp(drainer, "#levelchange"))
215 drainer = 0;
216 else if (resists_drli(&gy.youmonst))
217 return;
218
219 /* level-loss message; "Goodbye level 1." is fatal; divine anger
220 (drainer==NULL) resets a level 1 character to 0 experience points
221 without reducing level and that isn't fatal so suppress the message
222 in that situation */
223 if (u.ulevel > 1 || drainer)
224 pline("%s level %d.", Goodbye(), u.ulevel);
225
226 if (u.ulevel > 1) {
227 u.ulevel -= 1;
228 /* remove intrinsic abilities */
229 adjabil(u.ulevel + 1, u.ulevel);
230 livelog_printf(LL_MINORAC, "lost experience level %d", u.ulevel + 1);
231 SoundAchievement(0, sa2_xpleveldown, 0);
232 } else { /* u.ulevel==1 */
233 if (drainer) {
234 svk.killer.format = KILLED_BY;
235 if (svk.killer.name != drainer)
236 Strcpy(svk.killer.name, drainer);
237 done(DIED);
238 }
239 /* no drainer or lifesaved */
240 if (u.ulevel > 1)
241 /* can happen during debug fuzzing if fuzzer_savelife() uses
242 a blessed potion of restore ability to restore lost levels */
243 return;
244 u.uexp = 0;
245 livelog_printf(LL_MINORAC, "lost all experience");
246 }
247 assert(u.ulevel >= 0 && u.ulevel < MAXULEV); /* valid array index */
248
249 olduhpmax = u.uhpmax;
250 uhpmin = minuhpmax(10); /* same minimum as is used by life-saving */
251 num = (int) u.uhpinc[u.ulevel];
252 u.uhpmax -= num;
253 if (u.uhpmax < uhpmin)
254 setuhpmax(uhpmin, TRUE);
255 /* uhpmax might try to go up if it has previously been reduced by
256 strength loss or by a fire trap or by an attack by Death which
257 all use a different minimum than life-saving or experience loss;
258 we don't allow it to go up because that contradicts assumptions
259 elsewhere (such as healing wielder who drains with Stormbringer) */
260 if (u.uhpmax > olduhpmax)
261 setuhpmax(olduhpmax, TRUE);
262
263 u.uhp -= num;

Callers 9

special_throne_effectFunction · 0.85
mhitm_ad_drliFunction · 0.85
artifact_hitFunction · 0.85
angrygodsFunction · 0.85
wiz_level_changeFunction · 0.85
losestrFunction · 0.85
dofiretrapFunction · 0.85
zapyourselfFunction · 0.85
doseduceFunction · 0.85

Calls 11

resists_drliFunction · 0.85
GoodbyeFunction · 0.85
adjabilFunction · 0.85
livelog_printfFunction · 0.85
doneFunction · 0.85
minuhpmaxFunction · 0.85
setuhpmaxFunction · 0.85
newuexpFunction · 0.85
monhp_per_lvlFunction · 0.85
rehumanizeFunction · 0.85
plineFunction · 0.70

Tested by

no test coverage detected