Blindfold removal fix
[slashemextended.git] / src / dokick.c
bloba354ff6520c64c15bb95ffad38bb4cda57fd9ae0
1 /* SCCS Id: @(#)dokick.c 3.4 2003/12/04 */
2 /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "hack.h"
6 #include "eshk.h"
8 #define is_bigfoot(x) ((x) == &mons[PM_SASQUATCH])
9 #define martial() (martial_bonus() || is_bigfoot(youmonst.data) || \
10 (uarmf && uarmf->otyp == KICKING_BOOTS) || (uarmf && uarmf->otyp == COMBAT_WEDGES) || (uarmf && uarmf->otyp == STOMPING_BOOTS) )
12 static NEARDATA struct rm *maploc;
13 static NEARDATA const char *gate_str;
15 extern boolean notonhead; /* for long worms */
17 STATIC_DCL void kickdmg(struct monst *, BOOLEAN_P);
18 STATIC_DCL int kick_object(XCHAR_P, XCHAR_P);
19 STATIC_DCL char *kickstr(char *);
20 STATIC_DCL void otransit_msg(struct obj *, BOOLEAN_P, long);
21 STATIC_DCL void drop_to(coord *,SCHAR_P);
23 static NEARDATA struct obj *kickobj;
25 static const char kick_passes_thru[] = "kick passes harmlessly through";
27 STATIC_OVL void
28 kickdmg(mon, clumsy)
29 register struct monst *mon;
30 register boolean clumsy;
32 register int mdx, mdy;
33 int dmg = ( ACURRSTR + ACURR(A_DEX) + ACURR(A_CON) ) / 15;
34 int kick_skill = P_NONE;
35 int blessed_foot_damage = 0;
36 boolean trapkilled = FALSE;
38 if (uarmf && uarmf->oartifact == ART_LARISSA_S_ANGER) dmg += 5;
39 if (uarmf && uarmf->oartifact == ART_FIGHTBOOST) dmg += 5;
40 if (uarmf && uarmf->oartifact == ART_JUEN_S_WEAKNESS) dmg += 5;
41 if (uarmf && uarmf->oartifact == ART_JUMP_KICK_ACTION) dmg += 5;
42 if (uarmf && uarmf->oartifact == ART_SHIN_KICKING_GAME) dmg += 5;
43 if (uarmf && uarmf->oartifact == ART_AIRSHIP_DANCING) dmg += 2;
44 if (uarmf && uarmf->oartifact == ART_WILD_SEX_GAME) dmg += 2;
45 if (uarmf && uarmf->oartifact == ART_LITTLE_BITCH_IS_RUCTIOUS) dmg += 3;
46 if (uarmf && uarmf->oartifact == ART_NE_PROSTO_KRASIVO) dmg += 3;
47 if (uarmf && uarmf->oartifact == ART_SILVESTERBLAM) dmg += 3;
48 if (uarmf && uarmf->oartifact == ART_FULL_PROGRAM) dmg += 1;
49 if (uarmf && uarmf->oartifact == ART_AS_STRONG_AS_BOOTS) dmg += 5;
50 if (uarmf && uarmf->oartifact == ART_LEXI_S_POWERKICK) dmg += 5;
51 if (uarmf && uarmf->oartifact == ART_ARTHUR_S_HIGH_HEELED_PLATF) dmg += 2;
52 if (uarmf && uarmf->oartifact == ART_KATHARINA_S_LOVELINESS) dmg += 10;
53 if (uarmf && uarmf->oartifact == ART_FIGHT_WITH_PLATFORM_INA) dmg += 10;
54 if (uarmf && uarmf->oartifact == ART_EXCITING_SPFLOTCH) dmg += 2;
55 if (uarmf && itemhasappearance(uarmf, APP_SUPERHARD_SANDALS)) dmg += 5;
56 if (uwep && uwep->oartifact == ART_BLU_TOE) dmg += 5;
57 if (flags.female && uwep && uwep->oartifact == ART_KICKSIN_GIRL) dmg += 5;
58 if (uarmf && uarmf->oartifact == ART_FIND_THE_COMBAT_STANCE) dmg += 10;
59 if (uarmf && uarmf->oartifact == ART_THICK_PLATFORM_CRAZE) dmg += 5;
60 if (uwep && uwep->oartifact == ART_EVA_S_COLORCHANGE) dmg += 3;
61 if (uwep && uwep->oartifact == ART_FEETSERN) dmg += 5;
62 if (uarm && uarm->oartifact == ART_JEANETTA_S_REVENGE) dmg += 5;
63 if (uarmu && uarmu->oartifact == ART_FRIEDERIKE_S_BUNDLING) dmg += 5;
64 if (uarmf && uarmf->otyp == SHOCK_ISOLATED_HEELS) {
65 dmg += 2;
66 if (verysmall(mon->data)) dmg += 5;
69 if (u.ulevel >= 30) dmg += rnd(4);
70 else if (u.ulevel >= 24) dmg += rnd(3);
71 else if (u.ulevel >= 16) dmg += rnd(2);
72 else if (u.ulevel >= 8) dmg += 1;
74 if (u.martialstyle == MARTIALSTYLE_TAEKWONDO) {
75 dmg += (1 + (GushLevel / 3));
78 if (uwep && uwep->oartifact == ART_SYSETTE_S_THIEVINGNESS) {
79 dmg += 7;
80 if (PlayerInBlockHeels) dmg += 8;
83 if (uarmf && uarmf->oartifact == ART_FANNY_S_BROOK_THAT_YOU_MIS) dmg += (flags.female ? 7 : 2);
85 if (uarmf && uarmf->oartifact == ART_ARVOGENIA_S_BIKER_HEELS && u.usteed) dmg += 5;
87 if (Race_if(PM_TAYIIN)) dmg += 2;
89 if (uarmf && uarmf->oartifact == ART_SCRATCH_THE_SHRED && mon->mhp < (mon->mhpmax / 10) ) {
90 You("scratch the last shred away.");
91 dmg += 10000;
94 if (uarmf && itemhasappearance(uarmf, APP_ALLIGATOR_PUMPS) && !rn2(1000) && !(mon->data->geno & G_UNIQ) && !bigmonst(mon->data) ) {
95 pline("*gulp*");
96 dmg += 10000;
99 if (uarmf && uarmf->oartifact == ART_SAY_THE_WRONG_LINE && humanoid(mon->data) && !(mon->female) ) {
100 dmg += 2;
101 if (!rn2(100)) {
102 pline("Oh no, you said the wrong line, namely the one that allows %s to pee into your boots!", mon_nam(mon));
103 curse(uarmf);
104 if (uarmf->spe > -20) uarmf->spe--;
105 pline("Due to %s's evil penis, your boots are defiled now...", mon_nam(mon));
106 return;
110 if (uarmf && uarmf->otyp == KICKING_BOOTS)
111 dmg += 5;
112 if (uarmf && uarmf->otyp == COMBAT_WEDGES)
113 dmg += 5;
114 if (uarmf && uarmf->otyp == STOMPING_BOOTS)
115 dmg += 7;
116 if (RngeKicking) dmg += 5;
118 if (!(PlayerCannotUseSkills)) {
120 if (uarmf && (uarmf->otyp == KICKING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED) dmg += 2;
121 if (uarmf && (uarmf->otyp == KICKING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 3;
122 if (uarmf && (uarmf->otyp == KICKING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 5;
123 if (uarmf && (uarmf->otyp == KICKING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 6;
124 if (uarmf && (uarmf->otyp == KICKING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 8;
126 if (uarmf && (uarmf->otyp == COMBAT_WEDGES) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED) dmg += 2;
127 if (uarmf && (uarmf->otyp == COMBAT_WEDGES) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 3;
128 if (uarmf && (uarmf->otyp == COMBAT_WEDGES) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 5;
129 if (uarmf && (uarmf->otyp == COMBAT_WEDGES) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 6;
130 if (uarmf && (uarmf->otyp == COMBAT_WEDGES) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 8;
132 if (uarmf && (uarmf->otyp == STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED) dmg += 2;
133 if (uarmf && (uarmf->otyp == STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 4;
134 if (uarmf && (uarmf->otyp == STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 6;
135 if (uarmf && (uarmf->otyp == STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 8;
136 if (uarmf && (uarmf->otyp == STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 10;
140 if (uarmf && uarmf->otyp == WEDGE_SANDALS && Race_if(PM_NAVI) )
141 dmg += 5;
143 if (!(PlayerCannotUseSkills)) {
145 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && Race_if(PM_NAVI) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED) dmg += 1;
146 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && Race_if(PM_NAVI) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 2;
147 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && Race_if(PM_NAVI) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 3;
148 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && Race_if(PM_NAVI) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 4;
149 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && Race_if(PM_NAVI) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 5;
153 if (uarmf && uarmf->otyp == WEDGE_SANDALS)
154 dmg += 2;
156 if (!(PlayerCannotUseSkills)) {
158 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED && rn2(2)) dmg += 1;
159 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 1;
160 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 2;
161 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 3;
162 if (uarmf && (uarmf->otyp == WEDGE_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 4;
166 if (uarmf && uarmf->otyp == STAIRWELL_STOMPING_BOOTS)
167 dmg += 2;
169 if (!(PlayerCannotUseSkills)) {
171 if (uarmf && (uarmf->otyp == STAIRWELL_STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED) dmg += 1;
172 if (uarmf && (uarmf->otyp == STAIRWELL_STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 2;
173 if (uarmf && (uarmf->otyp == STAIRWELL_STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 3;
174 if (uarmf && (uarmf->otyp == STAIRWELL_STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 4;
175 if (uarmf && (uarmf->otyp == STAIRWELL_STOMPING_BOOTS) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 5;
179 if (uarmf && uarmf->otyp == STILETTO_SANDALS)
180 dmg += 2;
182 if (!(PlayerCannotUseSkills)) {
184 if (uarmf && (uarmf->otyp == STILETTO_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED) dmg += 1;
185 if (uarmf && (uarmf->otyp == STILETTO_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 2;
186 if (uarmf && (uarmf->otyp == STILETTO_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 4;
187 if (uarmf && (uarmf->otyp == STILETTO_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 5;
188 if (uarmf && (uarmf->otyp == STILETTO_SANDALS) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 7;
192 if (uarmf && uarmf->otyp == COMBAT_STILETTOS)
193 dmg += 3;
195 if (!(PlayerCannotUseSkills)) {
197 if (uarmf && (uarmf->otyp == COMBAT_STILETTOS) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED) dmg += 2;
198 if (uarmf && (uarmf->otyp == COMBAT_STILETTOS) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 4;
199 if (uarmf && (uarmf->otyp == COMBAT_STILETTOS) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 6;
200 if (uarmf && (uarmf->otyp == COMBAT_STILETTOS) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 8;
201 if (uarmf && (uarmf->otyp == COMBAT_STILETTOS) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 10;
205 if (uarmf && uarmf->otyp == LEATHER_PEEP_TOES)
206 dmg += 2;
208 if (!(PlayerCannotUseSkills)) {
210 if (uarmf && (uarmf->otyp == LEATHER_PEEP_TOES) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED) dmg += 1;
211 if (uarmf && (uarmf->otyp == LEATHER_PEEP_TOES) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 3;
212 if (uarmf && (uarmf->otyp == LEATHER_PEEP_TOES) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 5;
213 if (uarmf && (uarmf->otyp == LEATHER_PEEP_TOES) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 7;
214 if (uarmf && (uarmf->otyp == LEATHER_PEEP_TOES) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 9;
218 if (uarmf && uarmf->otyp == HIPPIE_HEELS)
219 dmg += 4;
221 if (!(PlayerCannotUseSkills)) {
223 if (uarmf && (uarmf->otyp == HIPPIE_HEELS) && P_SKILL(P_MARTIAL_ARTS) == P_SKILLED) dmg += 3;
224 if (uarmf && (uarmf->otyp == HIPPIE_HEELS) && P_SKILL(P_MARTIAL_ARTS) == P_EXPERT) dmg += 5;
225 if (uarmf && (uarmf->otyp == HIPPIE_HEELS) && P_SKILL(P_MARTIAL_ARTS) == P_MASTER) dmg += 8;
226 if (uarmf && (uarmf->otyp == HIPPIE_HEELS) && P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER) dmg += 10;
227 if (uarmf && (uarmf->otyp == HIPPIE_HEELS) && P_SKILL(P_MARTIAL_ARTS) == P_SUPREME_MASTER) dmg += 13;
231 if (!PlayerCannotUseSkills && uarmf && uarmf->oartifact == ART_MEASURER_TIP) {
232 switch (P_SKILL(P_KNIFE)) {
234 case P_BASIC: dmg += rnd(3); break;
235 case P_SKILLED: dmg += rnd(6); break;
236 case P_EXPERT: dmg += rnd(9); break;
237 case P_MASTER: dmg += rnd(12); break;
238 case P_GRAND_MASTER: dmg += rnd(15); break;
239 case P_SUPREME_MASTER: dmg += rnd(18); break;
240 default: dmg += 0; break;
246 if ((!(PlayerCannotUseSkills)) && PlayerInHighHeels) {
248 switch (P_SKILL(P_HIGH_HEELS)) {
250 case P_BASIC: dmg += 1; break;
251 case P_SKILLED: dmg += 2; break;
252 case P_EXPERT: dmg += 3; break;
253 case P_MASTER: dmg += 4; break;
254 case P_GRAND_MASTER: dmg += 5; break;
255 case P_SUPREME_MASTER: dmg += 6; break;
256 default: dmg += 0; break;
262 if (uarmf && uarmf->oartifact == ART_SLAM_INTO && humanoid(mon->data) && !is_neuter(mon->data) && !(mon->female)) {
263 dmg += 8;
264 if (!resist(mon, TOOL_CLASS, 0, NOTELL)) {
265 pline("That kick really knocked the wind out of %s.", mon_nam(mon));
266 mon_adjust_speed(mon, -1, (struct obj *)0);
267 mon->mstun = TRUE;
268 monflee(mon, rnd(10), FALSE, FALSE);
269 mon->healblock += rnd(10);
270 if (!rn2(10)) cancelmonsterlite(mon);
274 if (uarmf && uarmf->oartifact == ART_SINGHETA && mon->mcanmove) {
275 if (!resist(mon, ARMOR_CLASS, 0, NOTELL)) {
276 mon->mcanmove = 0;
277 mon->mfrozen = 2;
278 mon->mstrategy &= ~STRAT_WAITFORU;
279 pline("%s can't fight back!", Monnam(mon));
283 if (uarmf && uarmf->otyp == EGGKICK_SHOES && humanoid(mon->data) && !(mon->female) && !is_neuter(mon->data) ) {
284 dmg += 5;
287 if (Race_if(PM_DUTHOL) && PlayerInBlockHeels) dmg += 2;
289 if (uwep && uwep->oartifact == ART_PEEPLUE) dmg += 2;
291 if (uwep && uwep->oartifact == ART_ON_CLOUD_SEVEN) dmg += 2;
293 if (uarmf && uarmf->oartifact == ART_EROTICLAMP && u.ustuck && !u.uswallow && !sticks(youmonst.data)) dmg += 2;
295 if (uarmf && uarmf->otyp == FEMININE_PUMPS && uarmf->spe >= 1 && !rn2(2))
296 dmg += uarmf->spe;
298 if (!(PlayerCannotUseSkills)) {
300 if (uarmf && uarmf->otyp == FEMININE_PUMPS && uarmf->spe >= 1 && !rn2(3) && P_SKILL(P_MARTIAL_ARTS) >= P_SKILLED) dmg += uarmf->spe;
301 if (uarmf && uarmf->otyp == FEMININE_PUMPS && uarmf->spe >= 1 && !rn2(5) && P_SKILL(P_MARTIAL_ARTS) >= P_EXPERT) dmg += uarmf->spe;
302 if (uarmf && uarmf->otyp == FEMININE_PUMPS && uarmf->spe >= 1 && !rn2(7) && P_SKILL(P_MARTIAL_ARTS) >= P_MASTER) dmg += uarmf->spe;
303 if (uarmf && uarmf->otyp == FEMININE_PUMPS && uarmf->spe >= 1 && !rn2(10) && P_SKILL(P_MARTIAL_ARTS) >= P_GRAND_MASTER) dmg += uarmf->spe;
304 if (uarmf && uarmf->otyp == FEMININE_PUMPS && uarmf->spe >= 1 && !rn2(12) && P_SKILL(P_MARTIAL_ARTS) >= P_SUPREME_MASTER) dmg += uarmf->spe;
308 if (uarmf && !rn2(3) && itemhasappearance(uarmf, APP_PLOF_HEELS) ) {
309 pline("*plof*");
310 dmg += rnd(15);
313 if (uarmf && itemhasappearance(uarmf, APP_BAYONET_HEELS) && !PlayerCannotUseSkills && P_SKILL(P_SHORT_SWORD) >= P_BASIC) {
314 switch (P_SKILL(P_SHORT_SWORD)) {
315 case P_BASIC: dmg += 1; break;
316 case P_SKILLED: dmg += 2; break;
317 case P_EXPERT: dmg += 3; break;
318 case P_MASTER: dmg += 4; break;
319 case P_GRAND_MASTER: dmg += 5; break;
320 case P_SUPREME_MASTER: dmg += 6; break;
324 if (uarmf && itemhasappearance(uarmf, APP_BATTLE_BOOTS)) dmg += 5;
325 if (uarmf && itemhasappearance(uarmf, APP_PLATFORM_SNEAKERS)) dmg += 2;
326 if (uarmf && uarmf->oartifact == ART_EVELINE_S_LOVELIES) dmg += 5;
327 if (uarmf && uarmf->oartifact == ART_MANDY_S_ROUGH_BEAUTY) dmg += 10;
328 if (uarmf && uarmf->oartifact == ART_KYLIE_LUM_S_SNAKESKIN_BOOT) dmg += 10;
329 if (uarmc && uarmc->oartifact == ART_CONNY_S_COMBAT_COAT) dmg += 5;
330 if (uarmh && uarmh->oartifact == ART_CLAUDIA_S_SEXY_SCENT) dmg += 10;
332 if (uarmf && itemhasappearance(uarmf, APP_STEEL_TOED_BOOTS) ) dmg++;
334 if (uarmf && uarmf->oartifact == ART_HEADCRUNCH && has_head(mon->data) ) dmg += 10;
336 if (PlayerInStilettoHeels && uarmf && uarmf->oartifact == ART_VORPAL_HEELS && !rn2(20)) {
337 if (has_head(mon->data) && !noncorporeal(mon->data) && !amorphous(mon->data) ) {
338 if (mon->data->geno & G_UNIQ) {
339 dmg += (GushLevel * 2);
340 You("critically kick %s!", mon_nam(mon));
341 } else {
342 Your("stiletto heels cut off %s's %s!", mon_nam(mon), mbodypart(mon, HEAD));
343 dmg += 10000;
348 if (uarmf && uarmf->oartifact == ART_ELIANE_S_COMBAT_SNEAKERS && !(mon->data->geno & G_UNIQ) && !rn2(20)) {
349 Your("sneakers instantly bludgeon %s.", mon_nam(mon));
350 dmg += 10000; /* instant death */
353 if (uarmf && itemhasappearance(uarmf, APP_VELCRO_SANDALS)) dmg += rnd(10);
355 if (uarmf && uarmf->oartifact == ART_SOFT_KARATE_KICK && !P_RESTRICTED(P_MARTIAL_ARTS)) {
356 switch (P_SKILL(P_MARTIAL_ARTS)) {
357 case P_UNSKILLED: dmg += 8; break;
358 case P_BASIC: dmg += 6; break;
359 case P_SKILLED: dmg += 4; break;
360 case P_EXPERT: dmg += 2; break;
364 if (uarmf && uarmf->oartifact == ART_HUGGING__GROPING_AND_STROK) dmg += 5;
365 if (uarmf && uarmf->oartifact == ART_ELENETTES) dmg += 2;
366 if (uarmh && uarmh->oartifact == ART_STROKING_COMBAT) dmg += 2;
368 if (uarmf && itemhasappearance(uarmf, APP_WEAPON_LIGHT_BOOTS)) {
369 dmg += u.ulevel;
370 if (uarmf && uarmf->oartifact == ART_SHARP_EDGED_AND_DANGEROUS) {
372 if (!u.ualign.sins || (u.ualign.sins && !rn2(u.ualign.sins))) {
373 increasesincounter(1);
374 u.alignlim--;
375 pline("Using such a dangerous pair of boots without permission is very sinful.");
377 } else {
378 increasesincounter(1);
379 u.alignlim--;
380 pline("Using such a dangerous pair of boots without permission is very sinful.");
384 if (uarmc && uarmc->oartifact == ART_INA_S_SORROW && u.uhunger < 0) dmg += 10;
386 if (uarmf && uarmf->oartifact == ART_MADELEINE_S_GIRL_FOOTSTEPS) adjalign(1);
388 /* quarterback is expert at kicking --Amy */
389 if (Role_if(PM_QUARTERBACK) && dmg > 0) dmg += rnd(dmg);
391 if (uarmf && itemhasappearance(uarmf, APP_YELLOW_SNEAKERS)) dmg *= 2;
393 if (uarmf && itemhasappearance(uarmf, APP_CALF_LEATHER_SANDALS)) clumsy = FALSE;
394 if (u.martialstyle == MARTIALSTYLE_KUNGFU && !rn2(3)) clumsy = FALSE;
396 if (uarmf && uarmf->oartifact == ART_MAILIE_S_CHALLENGE) clumsy = FALSE;
397 if (uwep && uwep->oartifact == ART_INSECTMASHER) clumsy = FALSE;
398 if (uwep && uwep->oartifact == ART_BLU_TOE) clumsy = FALSE;
399 if (uarmf && uarmf->oartifact == ART_FRONT_TARGET) clumsy = FALSE;
400 if (uarmf && uarmf->oartifact == ART_ELENETTES) clumsy = FALSE;
401 if (uarmf && uarmf->oartifact == ART_EVIL_HAIRTEAR) clumsy = FALSE;
402 if (uarmf && uarmf->oartifact == ART_JOHN_S_REDBLOCK) clumsy = FALSE;
404 /* excessive wt affects dex, so it affects dmg */
405 if (clumsy) dmg /= 2;
407 /* kicking a dragon or an elephant will not harm it */
408 if (thick_skinned(mon->data) && dmg && !(uarmf && uarmf->oartifact == ART_HUGGING__GROPING_AND_STROK) ) dmg = 1;
409 if ((uarmf && itemhasappearance(uarmf, APP_CALF_LEATHER_SANDALS)) && dmg) dmg = 1;
411 /* high heels are the elder priest's kryptonite; he's thick-skinned so this must come after the above line */
412 if (PlayerInHighHeels && (mon->data == &mons[PM_DNETHACK_ELDER_PRIEST_TM_])) {
414 dmg += 50;
415 pline("Your high heels severely wound the elder priest's tentacles!");
419 if (mon->data == &mons[PM_PLOF_ANJE]) {
420 dmg += rnd(10);
421 pline("*plof*");
424 if (uarmf && uarmf->oartifact == ART_SEXY_PUMPS_OF_RAGNAROK) {
426 ragnarok(FALSE);
427 if (evilfriday && u.ulevel > 1) evilragnarok(FALSE,u.ulevel);
430 if (u.femcombostrike && PlayerInConeHeels) {
431 dmg += u.femcombostrike;
432 pline("You scratch %s for %d extra damage!", mon_nam(mon), u.femcombostrike);
434 if (tech_inuse(T_FEMALE_COMBO) && PlayerInConeHeels) {
435 u.femcombostrike += 2;
436 u.femcomboactive = TRUE;
439 if (uarmh && uarmh->oartifact == ART_NYPHERISBANE && (mon->data->mlet == S_SNAKE || mon->data->mlet == S_NAGA) ) {
440 You("totally stomp that stupid snake.");
441 dmg += 100;
444 if (uarmf && uarmf->oartifact == ART_LENG_S_KRYPTONITE && (mon->data == &mons[PM_DNETHACK_ELDER_PRIEST_TM_])) {
446 dmg += 50;
447 pline("SPLAT! The elder priest's tentacles are crushed underneath your very lovely high heels!");
448 /* unfortunately he has enough HP that he can still survive even though he already took 50 due to the heels */
452 if (PlayerInHighHeels && attacktype(mon->data, AT_TENT)) {
453 dmg += 2;
454 if (uarmf && uarmf->spe > 0) dmg += uarmf->spe;
456 if (mon->data != &mons[PM_DNETHACK_ELDER_PRIEST_TM_]) pline("Your high heels hurt %s's tentacles!", mon_nam(mon));
460 /* attacking a shade is useless */
461 if ( (is_shade(mon->data) || mon->egotype_shader) && !(uwep && uwep->oartifact == ART_AP_) && !(uarmf && (objects[uarmf->otyp].oc_material == MT_SILVER || objects[uarmf->otyp].oc_material == MT_ARCANIUM)) )
462 dmg = 0;
464 if ((is_undead(mon->data) || is_demon(mon->data)) && uarmf &&
465 uarmf->blessed)
466 blessed_foot_damage = 1;
468 if ( (is_shade(mon->data) || mon->egotype_shader) && !(uwep && uwep->oartifact == ART_AP_) && !(uarmf && (objects[uarmf->otyp].oc_material == MT_SILVER || objects[uarmf->otyp].oc_material == MT_ARCANIUM)) && !blessed_foot_damage) {
469 pline_The("%s.", kick_passes_thru);
470 /* doesn't exercise skill or abuse alignment or frighten pet,
471 and shades have no passive counterattack */
472 return;
475 if(mon->m_ap_type) seemimic(mon);
477 check_caitiff(mon);
479 /* squeeze some guilt feelings... */
480 if(mon->mtame) {
481 abuse_dog(mon);
482 if (mon->mtame)
483 monflee(mon, (dmg ? rnd(dmg) : 1), FALSE, FALSE);
484 else
485 mon->mflee = 0;
488 u.cnd_kickmonstercount++;
490 if (dmg > 0) {
491 /* convert potential damage to actual damage */
492 dmg = rnd(dmg);
493 if (martial()) {
495 int dexdamage = ACURR(A_DEX) / 2;
496 if (dexdamage < 0) dexdamage = 0;
498 if (dmg > /*1*/0) kick_skill = P_MARTIAL_ARTS; /* fix by Amy */
499 dmg += rn2(dexdamage + 1);
501 /* artifact hit effect (hammerfeet) implemented by stealing code from dnethack --Amy */
502 if(uarmf && uarmf->oartifact) {
503 if (artifact_hit(&youmonst, mon, uarmf, &dmg, rnd(20)) ) {
504 if(mon->mhp <= 0) /* artifact killed monster */
505 return;
509 dmg += weapon_dam_bonus((struct obj *)0);
510 /* marital arts skill is supposed to improve this!!! --Amy */
511 if (P_SKILL(P_MARTIAL_ARTS) > 0) dmg += (rnd(P_SKILL(P_MARTIAL_ARTS)) * rno(2));
512 } else {
514 if(uarmf && uarmf->oartifact) {
515 if (artifact_hit(&youmonst, mon, uarmf, &dmg, rnd(20)) ) {
516 if(mon->mhp <= 0) /* artifact killed monster */
517 return;
521 if (dmg > 0) kick_skill = P_MARTIAL_ARTS; /* so that acu can unlock it if he wants to */
523 /* a good kick exercises your dex */
524 exercise(A_DEX, TRUE);
526 if (blessed_foot_damage) dmg += rnd(4);
527 if (uarmf) dmg += uarmf->spe;
529 if (increase_damage_bonus_value() > 1) dmg += rnd(increase_damage_bonus_value());
530 else dmg += increase_damage_bonus_value(); /* add ring(s) of increase damage */
532 dmg += (Drunken_boxing && Confusion);
533 dmg += (StrongDrunken_boxing && Confusion);
534 if (RngeBloodlust) dmg += 1;
535 if (uarms && uarms->oartifact == ART_TEH_BASH_R) dmg += 2;
537 if (Race_if(PM_RODNEYAN)) dmg += (1 + (GushLevel / 3) );
539 if (Race_if(PM_PLAYER_SKELETON) && dmg > 1) {
540 dmg /= 5;
541 if (dmg < 1) dmg = 1;
544 if (uarmf && uarmf->oartifact == ART_ELIANE_S_SHIN_SMASH) dmg *= 2;
545 if (u.martialstyle == MARTIALSTYLE_KUNGFU) {
546 dmg *= 11;
547 dmg /= 10;
550 /*if (dmg > 127) dmg = 127;*/ /* sanity check... but not actually needed --Amy */
552 if (uarmf && uarmf->oartifact == ART_ELENA_S_CHALLENGE && !is_neuter(mon->data) && !(mon->female) && humanoid(mon->data) && !rn2(100) && !resist(mon, TOOL_CLASS, 0, NOTELL) ) {
553 pline("%s gets all submissive from being kicked by your beautiful high-heeled combat boots!", Monnam(mon));
554 (void) tamedog(mon, (struct obj *) 0, FALSE);
555 return;
558 if (uarmf && uarmf->oartifact == ART_BARBED_HOOK_ZIPPER && !mon->mfrenzied && !rn2(100) && !resist(mon, TOOL_CLASS, 0, NOTELL) ) {
559 pline("%s seems calmer.", Monnam(mon));
560 mon->mpeaceful = TRUE;
561 return;
564 if (dmg > 0) {
565 mon->mhp -= dmg;
566 #ifdef SHOW_DMG
567 showdmg(dmg);
568 #endif
570 if (mon->mhp > 0 && (martial() || (uarmf && itemhasappearance(uarmf, APP_BUFFALO_BOOTS)) || (uarmf && itemhasappearance(uarmf, APP_WHITE_BUFFALO_BOOTS)) ) && !bigmonst(mon->data) && !rn2(u.martialstyle == MARTIALSTYLE_TAEKWONDO ? 2 : 3) &&
571 mon->mcanmove && mon != u.ustuck && !mon->mtrapped) {
572 /* see if the monster has a place to move into */
573 mdx = mon->mx + u.dx;
574 mdy = mon->my + u.dy;
575 if(goodpos(mdx, mdy, mon, 0)) {
576 pline("%s reels from the blow.", Monnam(mon));
577 if (m_in_out_region(mon, mdx, mdy)) {
578 remove_monster(mon->mx, mon->my);
579 newsym(mon->mx, mon->my);
580 place_monster(mon, mdx, mdy);
581 newsym(mon->mx, mon->my);
582 set_apparxy(mon);
583 if (mintrap(mon) == 2) trapkilled = TRUE;
586 } else if (mon->mhp > 0 && mon != u.ustuck && !mon->mtrapped && rn2(10) && uarmf && itemhasappearance(uarmf, APP_DOCTOR_CLAW_BOOTS) ) {
588 switch (rnd(4)) {
589 case 1:
590 verbalize("Aaa-err!"); break;
591 case 2:
592 verbalize("Waa-aii!"); break;
593 case 3:
594 verbalize("Haa-waii!"); break;
595 case 4:
596 verbalize("Kamehameha!"); break;
599 /* see if the monster has a place to move into */
600 mdx = mon->mx + u.dx;
601 mdy = mon->my + u.dy;
602 if(goodpos(mdx, mdy, mon, 0)) {
603 pline("%s reels from the blow.", Monnam(mon));
604 if (m_in_out_region(mon, mdx, mdy)) {
605 remove_monster(mon->mx, mon->my);
606 newsym(mon->mx, mon->my);
607 place_monster(mon, mdx, mdy);
608 newsym(mon->mx, mon->my);
609 set_apparxy(mon);
610 if (mintrap(mon) == 2) trapkilled = TRUE;
615 if (uarmf && uarmf->oartifact == ART_RONJA_S_FEMALE_PUSHING && !rn2(10)) {
616 /* see if the monster has a place to move into */
617 mdx = mon->mx + u.dx;
618 mdy = mon->my + u.dy;
619 if(goodpos(mdx, mdy, mon, 0)) {
620 pline("%s is pushed back by your fleecy block heels.", Monnam(mon));
621 if (m_in_out_region(mon, mdx, mdy)) {
622 remove_monster(mon->mx, mon->my);
623 newsym(mon->mx, mon->my);
624 place_monster(mon, mdx, mdy);
625 newsym(mon->mx, mon->my);
626 set_apparxy(mon);
627 if (mintrap(mon) == 2) trapkilled = TRUE;
633 if (uarmf && (itemhasappearance(uarmf, APP_PLATFORM_BOOTS) || itemhasappearance(uarmf, APP_PLATEAU_BOOTS)) && !rn2(3) ) {
634 if (!mon->mstun) {
635 if (rn2(3)) pline("%s is stunned by your strong kick!", Monnam(mon));
636 else if (rn2(10)) pline("You stomp %s's %s!", mon_nam(mon), makeplural(mbodypart(mon,TOE)) );
637 else pline("You stomp %s's %s with your lovely boots!", mon_nam(mon), makeplural(mbodypart(mon,TOE)) );
639 mon->mstun = TRUE;
642 if (uarmf && uarmf->oartifact == ART_FINGERMASH && MON_WEP(mon) ) {
643 register struct obj *monwepon;
644 monwepon = MON_WEP(mon);
645 if (monwepon) {
646 if (!monwepon->cursed) {
647 curse(monwepon);
648 pline("%s's weapon becomes cursed!", Monnam(mon));
650 if (monwepon->spe > 0) {
651 monwepon->spe = 0;
652 pline("%s's weapon loses all of its enchantment!", Monnam(mon));
658 if (!rn2(10) && MON_WEP(mon) && uarmf && itemhasappearance(uarmf, APP_GENTLE_SNEAKERS) ) {
659 register struct obj *monwepon;
660 monwepon = MON_WEP(mon);
661 if (monwepon) {
662 obj_extract_self(monwepon);
663 possibly_unwield(mon, FALSE);
664 setmnotwielded(mon, monwepon);
668 if (monwepon && monwepon->mstartinventB && !(monwepon->oartifact) && !(monwepon->fakeartifact && timebasedlowerchance()) && (!rn2(4) || (rn2(100) < u.equipmentremovechance) || !timebasedlowerchance() ) ) {
669 You("vaporize %s %s!", s_suffix(mon_nam(mon)), xname(monwepon));
670 delobj(monwepon);
671 } else if (monwepon && monwepon->mstartinventC && !(monwepon->oartifact) && !(monwepon->fakeartifact && !rn2(10)) && rn2(10) ) {
672 You("vaporize %s %s!", s_suffix(mon_nam(mon)), xname(monwepon));
673 delobj(monwepon);
674 } else if (monwepon && monwepon->mstartinventE && !(monwepon->oartifact) && !(monwepon->fakeartifact && !rn2(20)) && rn2(20) ) {
675 You("vaporize %s %s!", s_suffix(mon_nam(mon)), xname(monwepon));
676 delobj(monwepon);
677 } else if (monwepon && monwepon->mstartinventD && !(monwepon->oartifact) && !(monwepon->fakeartifact && !rn2(4)) && rn2(4) ) {
678 You("vaporize %s %s!", s_suffix(mon_nam(mon)), xname(monwepon));
679 delobj(monwepon);
680 } else if (monwepon && monwepon->mstartinventX) {
681 You("vaporize %s %s!", s_suffix(mon_nam(mon)), xname(monwepon));
682 delobj(monwepon);
683 } else {
684 You("knock %s %s to the %s!", s_suffix(mon_nam(mon)), xname(monwepon), surface(u.ux, u.uy));
685 if (monwepon->otyp == CRYSKNIFE && (!monwepon->oerodeproof || !rn2(10))) {
686 monwepon->otyp = WORM_TOOTH;
687 monwepon->oerodeproof = 0;
689 place_object(monwepon, u.ux, u.uy);
690 stackobj(monwepon);
695 if (RngeToestomping && !rn2(5) && !mon->mstun) {
696 pline("You stomp %s's %s!", mon_nam(mon), makeplural(mbodypart(mon,TOE)) );
697 mon->mstun = TRUE;
701 if (RngeCoquetry && !rn2(5) && !mon->mconf) {
702 pline("Your coquetry demoralizes %s!", mon_nam(mon) );
703 mon->mconf = TRUE;
706 if (uarmf && itemhasappearance(uarmf, APP_VELCRO_BOOTS) ) {
707 if (!mon->mstun) {
708 pline("Your velcro boots joyously scratch along %s's %s, drawing lots of %s!", mon_nam(mon), makeplural(mbodypart(mon,LEG)), mbodypart(mon,BLOOD) );
710 mon->mstun = TRUE;
714 if (uarmf && uarmf->oartifact == ART_STEFANJE_S_PROBLEM && mon->mhpmax > 1) {
715 pline("Your 'Stefanje' sandals stomp %s with their lovely heels.", mon_nam(mon));
716 mon->mhpmax--;
717 if (mon->mhp > mon->mhpmax) mon->mhp--;
720 if (uarmf && uarmf->oartifact == ART_LOVELY_GIRL_PLATEAUS) {
722 if (!mon->mstun || !mon->mconf) {
723 pline("Wham! Your lovely plateau soles fully kick %s in the ass.", mon_nam(mon) );
724 mon->mstun = mon->mconf = TRUE;
729 if (uarmf && uarmf->oartifact == ART_TANJA_S_MARTIAL_PROWESS && mon->mcanmove && !PlayerCannotUseSkills) {
730 int parlyzchance = 0;
732 switch (P_SKILL(P_MARTIAL_ARTS)) {
733 case P_BASIC: parlyzchance = 1; break;
734 case P_SKILLED: parlyzchance = 2; break;
735 case P_EXPERT: parlyzchance = 3; break;
736 case P_MASTER: parlyzchance = 4; break;
737 case P_GRAND_MASTER: parlyzchance = 5; break;
738 case P_SUPREME_MASTER: parlyzchance = 6; break;
741 if (parlyzchance > rn2(100)) {
742 mon->mcanmove = 0;
743 mon->mfrozen = parlyzchance + 1;
744 mon->mstrategy &= ~STRAT_WAITFORU;
745 You("kick %s so powerfully that %s can't fight back for a bit.", mon_nam(mon), mhe(mon));
750 if ((uarmf && itemhasappearance(uarmf, APP_VELCRO_SANDALS)) && !rn2(3) && mon->mcanmove) {
751 pline("Your velcro lashes severely hurt %s.", mon_nam(mon) );
752 mon->mstun = TRUE;
753 mon->mcanmove = 0;
754 mon->mfrozen = rnd(10);
755 mon->mstrategy &= ~STRAT_WAITFORU;
759 if (uarmf && uarmf->otyp == EGGKICK_SHOES && mon->mcanmove && humanoid(mon->data) && !(mon->female) && !is_neuter(mon->data) && !rn2(20) ) {
760 pline("Score! %s's nuts got squeezed very painfully by your kick!", Monnam(mon));
761 mon->mcanmove = 0;
762 mon->mfrozen = rnd(10);
763 mon->mstrategy &= ~STRAT_WAITFORU;
766 if (uarmf && uarmf->oartifact == ART_FINAL_CHALLENGE && !rn2(5) && !(mon->female) && !is_neuter(mon->data) && mon->mcanmove) {
767 pline("Your sexy block heels fully kick %s in the nuts.", mon_nam(mon));
768 mon->mcanmove = 0;
769 mon->mfrozen = rnd(5);
770 mon->mstrategy &= ~STRAT_WAITFORU;
774 if (uarmh && uarmh->oartifact == ART_CLAUDIA_S_SEXY_SCENT && !rn2(4)) {
775 pline("%s is paralyzed by your powerful kick!", Monnam(mon));
776 mon->mcanmove = 0;
777 mon->mfrozen = rnd(10);
778 mon->mstrategy &= ~STRAT_WAITFORU;
782 if (uarmf && uarmf->oartifact == ART_DO_NOT_PEE && !rn2(5) && !(mon->female) && !is_neuter(mon->data) && !uarmf->oeroded && !uarmf->oeroded2) {
783 pline("%s is paralyzed by your powerful kick!", Monnam(mon));
784 mon->mcanmove = 0;
785 if (!mon->mfrozen) mon->mfrozen = rnd(10);
786 else if (mon->mfrozen < 127) mon->mfrozen++;
787 mon->mstrategy &= ~STRAT_WAITFORU;
790 if (uarmf && uarmf->oartifact == ART_AS_STRONG_AS_BOOTS && !rn2(10) && mon->mcanmove) {
791 pline("%s is paralyzed by your powerful kick!", Monnam(mon));
792 mon->mcanmove = 0;
793 mon->mfrozen = rnd(5);
794 mon->mstrategy &= ~STRAT_WAITFORU;
797 if (uarmf && itemhasappearance(uarmf, APP_SISTER_SHOES)) {
798 mon->bleedout += rnd(5);
799 pline("Your very pretty block heels scratch %sy wounds on %s's %s!", mbodypart(mon, BLOOD), mon_nam(mon), makeplural(mbodypart(mon, LEG)) );
802 if (uarmf && uarmf->oartifact == ART_KRISTIN_S_CHEAP_EDGE) {
803 mon->bleedout += rnd(4);
804 pline("Your very pretty block heels scratch %sy wounds on %s's %s!", mbodypart(mon, BLOOD), mon_nam(mon), makeplural(mbodypart(mon, LEG)) );
807 if (uwep && uwep->oartifact == ART_TONA_S_GAMES && (PlayerInConeHeels || PlayerInStilettoHeels) ) {
808 mon->bleedout += rnd(10);
809 pline("Your razor-sharp high heels scratch up and down %s's %s, drawing %s!", mon_nam(mon), makeplural(mbodypart(mon, LEG)), mbodypart(mon, BLOOD) );
812 if (uarmf && itemhasappearance(uarmf, APP_BLADED_DISKS)) {
813 mon->bleedout += rnd(5);
814 pline("Your metal blades slit %s, drawing a lot of %s!", mon_nam(mon), mbodypart(mon, BLOOD) );
816 if (uarmf && uarmf->oartifact == ART_HEME_FLOW) {
817 mon->bleedout += rnd(10);
820 if (uarmf && uarmf->oartifact == ART_DORA_S_SCRATCHY_HEELS) {
821 mon->bleedout += rnd(10);
822 pline("Your very pretty block heels scratch %sy wounds on %s's %s!", mbodypart(mon, BLOOD), mon_nam(mon), makeplural(mbodypart(mon, LEG)) );
825 if (uarmf && uarmf->oartifact == ART_FULL_PROGRAM) {
826 mon->bleedout += 3;
829 if (uarmf && uarmf->oartifact == ART_SHARP_EDGED_AND_DANGEROUS) {
830 mon->bleedout += 10;
833 if (uarmf && uarmf->oartifact == ART_SCRATCHE_HUSSY) {
834 mon->bleedout += rnd(10);
835 pline("Your very pretty block heels scratch %sy wounds on %s's %s!", mbodypart(mon, BLOOD), mon_nam(mon), makeplural(mbodypart(mon, LEG)) );
838 if (uarmc && uarmc->oartifact == ART_CONNY_S_COMBAT_COAT && !rn2(10) && mon->mcanmove ) {
840 pline("You place an incredibly strong kick at %s's body, who staggers and can't fight back for now.", mon_nam(mon) );
841 mon->mstun = TRUE;
842 mon->mcanmove = 0;
843 mon->mfrozen = rnd(10);
844 mon->mstrategy &= ~STRAT_WAITFORU;
848 if (FemtrapActiveNatalje) {
849 pline("Your sexy high heels stomp %s's %s.", mon_nam(mon), makeplural(mbodypart(mon, TOE)) );
850 mon->mcanmove = 0;
851 mon->mfrozen += 1;
852 mon->mstrategy &= ~STRAT_WAITFORU;
856 if (uarmf && uarmf->oartifact == ART_ELIANE_S_SHIN_SMASH && mon->mcanmove) {
858 pline("You smash %s's shins with a powerful kick.", mon_nam(mon) );
859 mon->mcanmove = 0;
860 mon->mfrozen = rnd(10);
861 mon->mstrategy &= ~STRAT_WAITFORU;
865 if (uarmf && uarmf->oartifact == ART_KYLIE_LUM_S_SNAKESKIN_BOOT && !rn2(4) && mon->mcanmove ) {
867 pline("Your very elegant snakeskin boots stop %s in its tracks.", mon_nam(mon) );
868 if (FunnyHallu) pline("You wonder if the PETA activists saw that.");
869 mon->mcanmove = 0;
870 mon->mfrozen = rnd(10);
871 mon->mstrategy &= ~STRAT_WAITFORU;
875 if (PlayerInStilettoHeels && (humanoid(mon->data) || is_animal(mon->data)) && !(mon->female) && !is_neuter(mon->data) && tech_inuse(T_ASIAN_KICK)) {
877 pline("As you drive the stiletto heel up against %s's nuts, his %s gets a shocked expression. You kicked his nuts in such a way that they're forced out of their original position, and several internal blood vessels are lacerated in the process. He falls over unconscious and most certainly won't get up for a long while!", mon_nam(mon), mbodypart(mon, FACE) );
878 mon->mcanmove = 0;
879 mon->mfrozen += rnz(100);
880 mon->mstrategy &= ~STRAT_WAITFORU;
882 stopsingletechnique(T_ASIAN_KICK);
886 if (PlayerInStilettoHeels && has_head(mon->data) && !(mon->data->geno & G_UNIQ) && !mon->mcanmove && tech_inuse(T_SKULL_CRUSH)) {
888 stopsingletechnique(T_SKULL_CRUSH);
889 mon->mhp = -1; /* instadeath */
890 Your("stiletto heels penetrate %s's skull, splitting it in two.", mon_nam(mon));
894 if (PlayerInConeHeels && tech_inuse(T_LEGSCRATCH_ATTACK)) {
896 pline("Your tender cone heels scratch up and down %s's %s!", mon_nam(mon), makeplural(mbodypart(mon,LEG)) );
897 if (resist(mon, TOOL_CLASS, 0, NOTELL)) {
898 pline("But %s shows no indication that your attack did anything...", mon_nam(mon) );
899 } else if (mon->permspeed != MSLOW) {
900 mon_adjust_speed(mon, -1, (struct obj *)0);
901 pline("Your heel scrapes off a bit of skin from %s's %s.", mon_nam(mon), makeplural(mbodypart(mon,LEG)) );
903 } else {
904 pline("Your heel just doesn't stop scratching over %s's %s, and %s is squirting everywhere!", mon_nam(mon), makeplural(mbodypart(mon,LEG)), mbodypart(mon, BLOOD) );
905 mon->mhp -= dmg;
911 if (PlayerInWedgeHeels && tech_inuse(T_GROUND_STOMP) && !(mon->mcanmove)) {
913 pline("Your wedge heels stomp %s's defenseless body.", mon_nam(mon) );
914 mon->mhp -= rnd(10);
915 mon->mfrozen += 2;
916 mon->mcanmove = 0;
917 mon->mstrategy &= ~STRAT_WAITFORU;
921 if (PlayerInBlockHeels && tech_inuse(T_ATHLETIC_COMBAT) && !mon->msleeping) {
923 pline("Your block heels aim a high kick at %s.", mon_nam(mon) );
925 if (!resist(mon, TOOL_CLASS, 0, NOTELL)) {
927 sleep_monst(mon, rnd(10), -1);
928 if (resists_sleep(mon) && !rn2(10) && mon->mcanmove) {
929 mon->mcanmove = 0;
930 mon->mfrozen = rnd(10);
932 if (mon->msleeping || !(mon->mcanmove))
933 pline("%s is amazed by your athletic combat and can't fight back!", Monnam(mon));
934 slept_monst(mon);
940 if (uarmf && itemhasappearance(uarmf, APP_PORCELAIN_SANDALS)) {
941 uarmf->spe--;
942 if (uarmf->spe < -10) {
943 pline("Suddenly, your porcelain sandals break into a thousand fragments.");
944 useup(uarmf);
945 nomul(0, 0, FALSE);
946 return;
950 if (uarmf && uarmf->oartifact == ART_WUMSHIN && rn2(4) && mon->mcanmove) {
952 pline("Wumm! You kick %s in the shins with your bum bum boots.", mon_nam(mon));
953 mon->mcanmove = 0;
954 mon->mfrozen = 1;
955 mon->mstrategy &= ~STRAT_WAITFORU;
959 if (uarmf && uarmf->oartifact == ART_VERA_S_FREEZER) {
960 pline("Your very lovely female 'Vera' sneakers clamp %s's %s!", mon_nam(mon), makeplural(mbodypart(mon,TOE)) );
961 if (!resist(mon, RING_CLASS, 0, NOTELL)) {
962 mon_adjust_speed(mon, -1, (struct obj *)0 );
963 m_dowear(mon, FALSE); /* might want speed boots */
967 if (uarmf && uarmf->oartifact == ART_VERA_S_ICECUBE_SMASH && (!resists_cold(mon) || player_will_pierce_resistance()) ) {
968 pline("Your very lovely female 'Vera' sneakers clamp %s's %s!", mon_nam(mon), makeplural(mbodypart(mon,TOE)) );
969 if (!resist(mon, RING_CLASS, 0, NOTELL)) {
970 mon_adjust_speed(mon, -1, (struct obj *)0 );
971 m_dowear(mon, FALSE); /* might want speed boots */
975 if (uarmf && uarmf->oartifact == ART_SHIT_KICKERS) {
976 if (!resist(mon, WEAPON_CLASS, 0, NOTELL) && !mon->mconf) {
977 mon->mconf = TRUE;
978 pline("You kick the shit out of %s!", mon_nam(mon));
980 if (!resist(mon, WEAPON_CLASS, 0, NOTELL) && !mon->mstun) {
981 mon->mstun = TRUE;
982 pline("You absolutely kick %s in the ass!", mon_nam(mon));
986 if (uarmf && uarmf->oartifact == ART_KATRIN_S_PARALYSIS && !sticks(mon->data)) {
987 setustuck(mon); /* it's now stuck to you */
988 if (rn2(2)) pline("You hold %s in place by stepping on its %s.", mon_nam(mon), makeplural(mbodypart(mon,TOE)));
989 else pline("The chewing gum clinging to your dancing shoe soles sticks to %s's %s!", mon_nam(mon), makeplural(mbodypart(mon,FOOT)));
990 /* supposed to give both messages to be more logical, but players dislike message spam... --Amy */
993 if (mon->mhp > 0 && !rn2(100) && uarmf && uarmf->oartifact == ART_SHIN_KICK_OF_LOVE) {
994 if (!mon->mpeaceful && !mon->mfrenzied && !resist(mon, RING_CLASS, 0, NOTELL)) {
995 mon->mpeaceful = 1;
996 pline("%s loves your beautiful sandals and no longer wants to harm you!", Monnam(mon) );
1001 (void) passive(mon, TRUE, mon->mhp > 0, AT_KICK, FALSE);
1002 if (mon->mhp <= 0 && !trapkilled) killed(mon);
1004 /* may bring up a dialog, so put this after all messages */
1005 if (kick_skill != P_NONE) { /* exercise proficiency */
1006 use_skill(kick_skill, 1);
1009 if (PlayerInColumnarHeels && !rn2((flags.female) ? 200 : 50) ) {
1010 u.columnarskill++;
1011 if (u.columnarskill == 20) You("are now more skilled in type 5: columnar heels.");
1012 if (u.columnarskill == 160) You("are now more skilled in type 5: columnar heels.");
1013 if (u.columnarskill == 540) You("are now more skilled in type 5: columnar heels.");
1014 if (u.columnarskill == 1280) You("are now more skilled in type 5: columnar heels.");
1015 if (u.columnarskill == 2500) You("are now more skilled in type 5: columnar heels.");
1016 if (u.columnarskill == 4320) You("are now most skilled in type 5: columnar heels.");
1018 if (PlayerInStilettoHeels && !rn2((flags.female || Role_if(PM_TRANSVESTITE) || Role_if(PM_TRANSSYLVANIAN)) ? 30 : 100) ) use_skill(P_STILETTO_HEELS, 1);
1019 if (PlayerInConeHeels && !rn2((flags.female || Role_if(PM_TRANSVESTITE) || Role_if(PM_TRANSSYLVANIAN)) ? 20 : 50) ) use_skill(P_CONE_HEELS, 1);
1020 if (PlayerInBlockHeels && !rn2(10) ) use_skill(P_BLOCK_HEELS, 1);
1021 if (PlayerInWedgeHeels && !rn2(10) ) use_skill(P_WEDGE_HEELS, 1);
1023 if (uarmf && uarmf->oartifact == ART_MEASURER_TIP && (dmg > 0)) {
1024 use_skill(P_KNIFE, 1);
1027 if (uarmf && itemhasappearance(uarmf, APP_BAYONET_HEELS) && (dmg > 0) ) {
1028 use_skill(P_SHORT_SWORD, 1);
1032 void
1033 kick_monster(x, y)
1034 register xchar x, y;
1036 register boolean clumsy = FALSE;
1037 register struct monst *mon = m_at(x, y);
1038 register int i, j, canhitmon, objenchant;
1040 bhitpos.x = x;
1041 bhitpos.y = y;
1042 if (!attack_checks(mon, TRUE)) return;
1043 setmangry(mon);
1045 /* Kick attacks by kicking monsters are normal attacks, not special.
1046 * This is almost always worthless, since you can either take one turn
1047 * and do all your kicks, or else take one turn and attack the monster
1048 * normally, getting all your attacks _including_ all your kicks.
1049 * If you have >1 kick attack, you get all of them.
1051 if (Upolyd && attacktype(youmonst.data, AT_KICK)) {
1052 struct attack *uattk;
1053 int sum;
1054 schar tmp = find_roll_to_hit(mon);
1055 schar roll = 0;
1057 for (i = 0; i < NATTK; i++) {
1058 /* first of two kicks might have provoked counterattack
1059 that has incapacitated the hero (ie, floating eye) */
1060 if (multi < 0) break;
1062 uattk = &youmonst.data->mattk[i];
1063 /* we only care about kicking attacks here */
1064 if (uattk->aatyp != AT_KICK) continue;
1066 if ( (is_shade(mon->data) || mon->egotype_shader) && !(uwep && uwep->oartifact == ART_AP_) && !(uarmf && (objects[uarmf->otyp].oc_material == MT_SILVER || objects[uarmf->otyp].oc_material == MT_ARCANIUM)) && (!uarmf || !uarmf->blessed)) {
1067 /* doesn't matter whether it would have hit or missed,
1068 and shades have no passive counterattack */
1069 Your("%s %s.", kick_passes_thru, mon_nam(mon));
1070 break; /* skip any additional kicks */
1071 } else if (tmp > (roll = rnd(20))) {
1072 You("kick %s.", mon_nam(mon));
1073 wakeup(mon);
1074 sum = damageum(mon, uattk);
1075 (void)passive(mon, (boolean)(sum > 0), (sum != 2), AT_KICK, FALSE);
1076 if (sum == 2)
1077 break; /* Defender died */
1078 } else {
1079 missum(mon, tmp, roll, uattk);
1080 (void)passive(mon, 0, 1, AT_KICK, FALSE);
1083 return;
1086 if(Levitation && !rn2(3) && verysmall(mon->data) && (!mon->egotype_flying) &&
1087 !is_flyer(mon->data)) {
1088 pline(FunnyHallu ? "Your legs seem to have a mind of their own!" : "Floating in the air, you miss wildly!");
1089 exercise(A_DEX, FALSE);
1090 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
1091 return;
1094 /*STEPHEN WHITE'S NEW CODE */
1095 canhitmon = 0;
1096 if (need_one(mon)) canhitmon = 1;
1097 if (need_two(mon)) canhitmon = 2;
1098 if (need_three(mon)) canhitmon = 3;
1099 if (need_four(mon)) canhitmon = 4;
1100 if (uarmf && uarmf->oartifact == ART_KILLCAP) canhitmon = 0;
1101 if (uwep && uwep->oartifact == ART_AP_) canhitmon = 0;
1103 if (Role_if(PM_MONK) && !Upolyd) {
1104 if (!uwep && !uarm && !uarms) objenchant = GushLevel / 4;
1105 else if (!uwep) objenchant = GushLevel / 12;
1106 else objenchant = 0;
1107 if (objenchant < 0) objenchant = 0;
1108 if (uarmf && (uarmf->spe > 0)) objenchant += uarmf->spe;
1109 } else if (uarmf)
1110 objenchant = uarmf->spe;
1111 else objenchant = 0;
1113 if ((objenchant < canhitmon) && ((canhitmon > 0) || (uarmf && uarmf->oartifact == ART_BUGBOOTS_OF_ERRORNESS) ) && !Upolyd && (issoviet || !rn2(isfriday ? 2 : 3) ) ) {
1114 if (!issoviet) Your("attack doesn't seem to harm %s.",
1115 mon_nam(mon));
1116 else pline("Etot monstr ne mozhet byt' povrezhden, potomu chto Sovetskiy khochet nesmotrya vas.");
1117 (void) passive(mon, FALSE, 1, TRUE, FALSE);
1118 return;
1121 if (mon->egotype_flickerer) {
1122 pline("%s flickers and is impervious to melee and missile attacks!", Monnam(mon));
1123 if (!rn2(30)) pline("Reminder: you must use something else in order to damage this monster!");
1124 else if (!rn2(30)) pline("You read that right: your attacks are doing no damage at all!");
1125 else if (!rn2(30)) pline("Hint: try offensive wands or spells.");
1127 (void) passive(mon, FALSE, 1, TRUE, FALSE);
1128 return;
1131 if (mon->data == &mons[PM_DTTN_ERROR] && rn2(10)) {
1133 pline("%s absorbed the attack and took no damage!", Monnam(mon));
1134 (void) passive(mon, FALSE, 1, TRUE, FALSE);
1135 return;
1138 if (mon->data == &mons[PM_LITTLE_POISON_IVY] || mon->data == &mons[PM_SUPERDEEP_TYPE] || mon->data == &mons[PM_AGULA] || mon->data == &mons[PM_FLUIDATOR_IVE] || mon->data == &mons[PM_CRITICALLY_INJURED_PERCENTS] || mon->data == &mons[PM_AMBER_FEMMY] || mon->data == &mons[PM_MISTER_GRIBBS] || mon->data == &mons[PM_IMMUNITY_VIRUS] || mon->data == &mons[PM_UNGENOCIDABLE_VAMPSHIFTER] || mon->data == &mons[PM_TERRIFYING_POISON_IVY] || mon->data == &mons[PM_GIRL_WITH_THE_MOST_BEAUTIFUL_SHOES_IN_THE_WORLD] || mon->data == &mons[PM_IMMOVABLE_OBSTACLE] || mon->data == &mons[PM_INVINCIBLE_HAEN] || mon->data == &mons[PM_CHAREY] || mon->data == &mons[PM_INVENTOR_OF_THE_SISTER_COMBAT_BOOTS] || mon->data == &mons[PM_SWEET_ASIAN_POISON_IVY] || mon->data == &mons[PM_FIRST_DUNVEGAN] || mon->data == &mons[PM_ARABELLA_SHOE] || mon->data == &mons[PM_ANASTASIA_SHOE] || mon->data == &mons[PM_HENRIETTA_SHOE] || mon->data == &mons[PM_KATRIN_SHOE] || mon->data == &mons[PM_JANA_SHOE] || mon->data == &mons[PM_PERCENTI_HAS_LOST___] || mon->data == &mons[PM_PERCENTI_IS_IMMUNE_TO_THE_ATTACK_]) {
1140 pline("%s is IMMUNE to the attack!", Monnam(mon));
1141 if (FunnyHallu) You("curse at Konami for designing it like that.");
1142 if (!rn2(30)) pline("Reminder: you must use something else in order to damage this monster!");
1143 else if (!rn2(30)) pline("You read that right: your attacks are doing no damage at all!");
1144 else if (!rn2(30)) pline("Hint: try offensive wands or spells.");
1146 (void) passive(mon, FALSE, 1, TRUE, FALSE);
1147 return;
1150 i = -inv_weight();
1151 j = weight_cap();
1153 if (uarmf && itemhasappearance(uarmf, APP_COMBAT_BOOTS) ) i += 6000;
1155 if (uarmf && uarmf->oartifact == ART_KYLIE_LUM_S_SNAKESKIN_BOOT) i += 6000;
1157 if((i < (j*3)/10) && !(uarmf && uarmf->oartifact == ART_MAILIE_S_CHALLENGE) && !(uwep && uwep->oartifact == ART_INSECTMASHER) && !(uwep && uwep->oartifact == ART_BLU_TOE) && !(uarmf && uarmf->oartifact == ART_FRONT_TARGET) && !(uarmf && uarmf->oartifact == ART_ELENETTES) && !(uarmf && uarmf->oartifact == ART_JOHN_S_REDBLOCK) && !(uarmf && uarmf->oartifact == ART_EVIL_HAIRTEAR) && !(uarmf && itemhasappearance(uarmf, APP_CALF_LEATHER_SANDALS)) ) {
1158 if((!rn2((i < j/10) ? 2 : (i < j/5) ? 3 : 4)) || (isfriday && !rn2(5))) {
1159 if(martial() && !rn2(isfriday ? 10 : 2)) goto doit;
1160 Your("clumsy kick does no damage.");
1161 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
1162 return;
1164 if(i < j/10) clumsy = TRUE;
1165 else if(!rn2((i < j/5) ? 2 : 3)) clumsy = TRUE;
1168 if (Fumbling) clumsy = TRUE;
1170 else if (uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25))
1171 clumsy = TRUE;
1173 if (uarmf && itemhasappearance(uarmf, APP_COMBAT_BOOTS) ) clumsy = FALSE;
1175 if (uarmf && uarmf->oartifact == ART_MAILIE_S_CHALLENGE) clumsy = FALSE;
1176 if (uwep && uwep->oartifact == ART_INSECTMASHER) clumsy = FALSE;
1177 if (uarmf && uarmf->oartifact == ART_FRONT_TARGET) clumsy = FALSE;
1178 if (uarmf && uarmf->oartifact == ART_ELENETTES) clumsy = FALSE;
1179 if (uarmf && uarmf->oartifact == ART_EVIL_HAIRTEAR) clumsy = FALSE;
1180 if (uarmf && uarmf->oartifact == ART_JOHN_S_REDBLOCK) clumsy = FALSE;
1181 if (uwep && uwep->oartifact == ART_BLU_TOE) clumsy = FALSE;
1183 if (uarmf && itemhasappearance(uarmf, APP_CALF_LEATHER_SANDALS)) clumsy = FALSE;
1184 if (u.martialstyle == MARTIALSTYLE_KUNGFU && !rn2(3)) clumsy = FALSE;
1186 if (uarmf && uarmf->oartifact == ART_KYLIE_LUM_S_SNAKESKIN_BOOT) clumsy = FALSE;
1187 if (uarmf && uarmf->oartifact == ART_JUMP_KICK_ACTION) clumsy = FALSE;
1189 if (isfriday && !rn2(10)) clumsy = TRUE;
1191 doit:
1192 You("kick %s.", mon_nam(mon));
1193 wakeup(mon);
1194 if(!rn2(clumsy ? 3 : 4) && (u.martialstyle != MARTIALSTYLE_KUNGFU || rn2(4)) && (clumsy || !bigmonst(mon->data)) &&
1195 mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data) &&
1196 mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove &&
1197 !mon->mstun && !mon->mconf && !mon->msleeping &&
1198 mon->data->mmove >= 12) {
1199 if(!nohands(mon->data) && !rn2(martial() ? 5 : 3)) {
1200 pline("%s blocks your %skick.", Monnam(mon),
1201 clumsy ? "clumsy " : "");
1202 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
1203 return;
1204 } else {
1205 mnexto(mon);
1206 if(mon->mx != x || mon->my != y) {
1207 if(memory_is_invisible(x, y)) {
1208 unmap_object(x, y);
1209 newsym(x, y);
1211 pline("%s %s, %s evading your %skick.", Monnam(mon),
1212 (can_teleport(mon->data) ? "teleports" :
1213 is_floater(mon->data) ? "floats" :
1214 is_flyer(mon->data) ? "swoops" :
1215 (nolimbs(mon->data) || slithy(mon->data)) ?
1216 "slides" : "jumps"),
1217 clumsy ? "easily" : "nimbly",
1218 clumsy ? "clumsy " : "");
1219 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
1220 return;
1225 if (uarmf && itemhasappearance(uarmf, APP_A_HEELS) && !rn2(10)) {
1226 pline("%s simply evades your clunky stiletto heels!", Monnam(mon));
1227 return;
1230 kickdmg(mon, clumsy);
1232 if (uarmf && uarmf->oartifact == ART_JANA_S_MUD_OBSESSION && !rn2(20)) {
1233 buzz(27, 6, u.ux,u.uy,u.dx,u.dy); /* 27 = acid blast */
1236 if (uarmf && uarmf->otyp == SLEEP_INDUCTION_BOOTS && !rn2(10))
1237 buzz(23, 4, u.ux,u.uy,u.dx,u.dy); /* 23 = sleep ray */
1239 return;
1243 * Return TRUE if caught (the gold taken care of), FALSE otherwise.
1244 * The gold object is *not* attached to the fobj chain!
1246 boolean
1247 ghitm(mtmp, gold)
1248 register struct monst *mtmp;
1249 register struct obj *gold;
1251 boolean msg_given = FALSE;
1252 boolean willdelete = FALSE;
1254 if(!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest
1255 && !is_mercenary(mtmp->data)) {
1256 wakeup(mtmp);
1257 } else if (!mtmp->mcanmove) {
1258 /* too light to do real damage */
1259 if (canseemon(mtmp)) {
1260 pline_The("%s harmlessly %s %s.", xname(gold),
1261 otense(gold, "hit"), mon_nam(mtmp));
1262 msg_given = TRUE;
1264 } else {
1265 #ifdef GOLDOBJ
1266 long value = gold->quan * objects[gold->otyp].oc_cost;
1267 #endif
1268 mtmp->msleeping = 0;
1269 mtmp->meating = 0;
1270 if(!rn2(4)) setmangry(mtmp); /* not always pleasing */
1272 /* greedy monsters catch gold */
1273 if (cansee(mtmp->mx, mtmp->my))
1274 pline("%s catches the gold.", Monnam(mtmp));
1275 #ifndef GOLDOBJ
1276 if (mtmp->isshk && rn2(2)) mtmp->mgold += gold->quan;
1277 else willdelete = TRUE;
1278 #endif
1279 if (mtmp->isshk) {
1280 long robbed = ESHK(mtmp)->robbed;
1282 if (robbed) {
1283 #ifndef GOLDOBJ
1284 robbed -= gold->quan;
1285 #else
1286 robbed -= value;
1287 #endif
1288 if (robbed < 0) robbed = 0;
1289 pline_The("amount %scovers %s recent losses.",
1290 !robbed ? "" : "partially ",
1291 mhis(mtmp));
1292 ESHK(mtmp)->robbed = robbed;
1293 if(!robbed)
1294 make_happy_shk(mtmp, FALSE);
1295 } else {
1296 if(mtmp->mpeaceful && rn2(2) ) { /* randomly cheat the player --Amy */
1297 #ifndef GOLDOBJ
1298 ESHK(mtmp)->credit += gold->quan;
1299 #else
1300 ESHK(mtmp)->credit += value;
1301 #endif
1302 You("have %ld %s in credit.",
1303 ESHK(mtmp)->credit,
1304 currency(ESHK(mtmp)->credit));
1305 } else if (mtmp->mpeaceful) {
1306 verbalize("I'll take that. Hahaha!");
1307 } else verbalize("Thanks, scum!");
1309 } else if (mtmp->ispriest) {
1310 if (mtmp->mpeaceful)
1311 verbalize("Thank you for your contribution.");
1312 else verbalize("Thanks, scum!");
1313 } else if (is_mercenary(mtmp->data)) {
1314 long goldreqd = 0L;
1316 if (rn2(3)) {
1317 if (mtmp->data == &mons[PM_SOLDIER])
1318 goldreqd = 100L;
1319 else if (mtmp->data == &mons[PM_TEUTON_SOLDIER])
1320 goldreqd = 100L;
1321 else if (mtmp->data == &mons[PM_FRANKISH_SOLDIER])
1322 goldreqd = 100L;
1323 else if (mtmp->data == &mons[PM_VIDEO_SOLDIER])
1324 goldreqd = 100L;
1325 else if (mtmp->data == &mons[PM_BRITISH_SOLDIER])
1326 goldreqd = 100L;
1327 else if (mtmp->data == &mons[PM_AMERICAN_SOLDIER])
1328 goldreqd = 100L;
1329 else if (mtmp->data == &mons[PM_COPPER_SOLDIER])
1330 goldreqd = 100L;
1331 else if (mtmp->data == &mons[PM_ARAB_SOLDIER])
1332 goldreqd = 100L;
1333 else if (mtmp->data == &mons[PM_ASIAN_SOLDIER])
1334 goldreqd = 100L;
1335 else if (mtmp->data == &mons[PM_MEDIEVAL_SOLDIER])
1336 goldreqd = 100L;
1337 else if (mtmp->data == &mons[PM_PAD_SOLDIER])
1338 goldreqd = 100L;
1339 else if (mtmp->data == &mons[PM_GAUCHE_SOLDIER])
1340 goldreqd = 100L;
1341 else if (mtmp->data == &mons[PM_SEAFARING_SOLDIER])
1342 goldreqd = 100L;
1343 else if (mtmp->data == &mons[PM_BYZANTINE_SOLDIER])
1344 goldreqd = 100L;
1345 else if (mtmp->data == &mons[PM_CELTIC_SOLDIER])
1346 goldreqd = 100L;
1347 else if (mtmp->data == &mons[PM_VANILLA_SOLDIER])
1348 goldreqd = 100L;
1349 else if (mtmp->data == &mons[PM_VIKING_SOLDIER])
1350 goldreqd = 100L;
1351 else if (mtmp->data == &mons[PM_VANGUARD_TROOPER])
1352 goldreqd = 100L;
1353 else if (mtmp->data == &mons[PM_INFANTRY_RECRUIT])
1354 goldreqd = 100L;
1355 else if (mtmp->data == &mons[PM_LEGIONARY_GRUNT])
1356 goldreqd = 100L;
1357 else if (mtmp->data == &mons[PM_MILITANT_TROOPER])
1358 goldreqd = 100L;
1359 else if (mtmp->data == &mons[PM_RIFLEMAN_PRIVATE])
1360 goldreqd = 100L;
1361 else if (mtmp->data == &mons[PM_FOOTMAN_CONSCRIPT])
1362 goldreqd = 100L;
1363 else if (mtmp->data == &mons[PM_GUARDSMAN_TRAINEE])
1364 goldreqd = 100L;
1365 else if (mtmp->data == &mons[PM_FUSILIER_ROOKIE])
1366 goldreqd = 100L;
1367 else if (mtmp->data == &mons[PM_SPEARMAN_RECRUIT])
1368 goldreqd = 100L;
1369 else if (mtmp->data == &mons[PM_ARCHER_CADET])
1370 goldreqd = 100L;
1371 else if (mtmp->data == &mons[PM_KUNG_FU_JESTER])
1372 goldreqd = 100L;
1373 else if (mtmp->data == &mons[PM_SWAMP_SOLDIER])
1374 goldreqd = 100L;
1375 else if (mtmp->data == &mons[PM_JAVA_SOLDIER])
1376 goldreqd = 100L;
1377 else if (mtmp->data == &mons[PM_IBERIAN_SOLDIER])
1378 goldreqd = 100L;
1379 else if (mtmp->data == &mons[PM_ROHIRRIM_SOLDIER])
1380 goldreqd = 100L;
1381 else if (mtmp->data == &mons[PM_EXTRATERRESTRIAL_SERGEANT])
1382 goldreqd = 250L;
1383 else if (mtmp->data == &mons[PM_MINOAN_SERGEANT])
1384 goldreqd = 250L;
1385 else if (mtmp->data == &mons[PM_SHADOW_COMMANDO])
1386 goldreqd = 250L;
1387 else if (mtmp->data == &mons[PM_ASS_RIMMING_RAMMER])
1388 goldreqd = 250L;
1389 else if (mtmp->data == &mons[PM_HUN_SERGEANT])
1390 goldreqd = 250L;
1391 else if (mtmp->data == &mons[PM_MONGOL_SERGEANT])
1392 goldreqd = 250L;
1393 else if (mtmp->data == &mons[PM_ORANGE_SERGEANT])
1394 goldreqd = 250L;
1395 else if (mtmp->data == &mons[PM_TWOWEAP_SERGEANT])
1396 goldreqd = 250L;
1397 else if (mtmp->data == &mons[PM_PERSIAN_SERGEANT])
1398 goldreqd = 250L;
1399 else if (mtmp->data == &mons[PM_SERGEANT])
1400 goldreqd = 250L;
1401 else if (mtmp->data == &mons[PM_LIEUTENANT])
1402 goldreqd = 500L;
1403 else if (mtmp->data == &mons[PM_YAMATO_LIEUTENANT])
1404 goldreqd = 500L;
1405 else if (mtmp->data == &mons[PM_CARTHAGE_LIEUTENANT])
1406 goldreqd = 500L;
1407 else if (mtmp->data == &mons[PM_ROMAN_LIEUTENANT])
1408 goldreqd = 500L;
1409 else if (mtmp->data == &mons[PM_ELITE_SENTINEL])
1410 goldreqd = 500L;
1411 else if (mtmp->data == &mons[PM_CAPTAIN])
1412 goldreqd = 750L;
1413 else if (mtmp->data == &mons[PM_IRONCLAD_WARRIOR])
1414 goldreqd = 750L;
1415 else if (mtmp->data == &mons[PM_GOTHIC_CAPTAIN])
1416 goldreqd = 750L;
1417 else if (mtmp->data == &mons[PM_URBAN_CAMO_CAPTAIN])
1418 goldreqd = 750L;
1419 else if (mtmp->data == &mons[PM_GENERAL])
1420 goldreqd = 1000L;
1421 else if (mtmp->data == &mons[PM_PRISON_GUARD])
1422 goldreqd = 200L;
1423 else if (mtmp->data == &mons[PM_STORMBREAKER_INFANTRY])
1424 goldreqd = 1000L;
1425 else if (mtmp->data == &mons[PM_VENOMOUS_OPERATIVE])
1426 goldreqd = 1000L;
1427 else if (mtmp->data == &mons[PM_CHAOS_REAVER])
1428 goldreqd = 1000L;
1429 else if (mtmp->data == &mons[PM_NOVA_SHOCK_TROOPER])
1430 goldreqd = 1000L;
1431 else if (mtmp->data == &mons[PM_LUNAR_WARDEN])
1432 goldreqd = 1000L;
1433 else if (mtmp->data == &mons[PM_DREADNOUGHT_MARINE])
1434 goldreqd = 1000L;
1435 else if (mtmp->data == &mons[PM_ARCTIC_BLADESTORM])
1436 goldreqd = 1000L;
1437 else if (mtmp->data == &mons[PM_RADIANT_GUARDIAN])
1438 goldreqd = 1000L;
1439 else if (mtmp->data == &mons[PM_EMBERSTRIKE_GUNNER])
1440 goldreqd = 1000L;
1441 else if (mtmp->data == &mons[PM_THUNDERCLAP_TROOPER])
1442 goldreqd = 1000L;
1443 else if (mtmp->data == &mons[PM_CELESTIAL_PARAGON])
1444 goldreqd = 1000L;
1445 else if (mtmp->data == &mons[PM_SOULFIRE_SENTINEL])
1446 goldreqd = 1000L;
1447 else if (mtmp->data == &mons[PM_SPECTRAL_ENFORCER])
1448 goldreqd = 1000L;
1449 else if (mtmp->data == &mons[PM_ABYSSAL_LEGIONNAIRE])
1450 goldreqd = 1000L;
1451 else if (mtmp->data == &mons[PM_CYBERNETIC_VANGUARD])
1452 goldreqd = 1000L;
1453 else if (mtmp->data == &mons[PM_ASTRAL_BLADEMASTER])
1454 goldreqd = 1000L;
1456 if (goldreqd && !mtmp->mfrenzied) {
1457 #ifndef GOLDOBJ
1458 if (gold->quan > goldreqd +
1459 (u.ugold + u.ulevel*rn2(5))/ACURR(A_CHA))
1460 #else
1461 if (value > goldreqd +
1462 (money_cnt(invent) + u.ulevel*rn2(5))/ACURR(A_CHA))
1463 #endif
1464 mtmp->mpeaceful = TRUE;
1466 /* Amy: politicians have a chance of taming soldiers with a bribe; the tamedog code handles the actual success rate */
1468 if (uarmc && uarmc->oartifact == ART_FIELD_MARS_RESOUNDS) {
1469 (void) tamedog(mtmp, (struct obj *) 0, TRUE); /* guaranteed because powerful artifact --Amy */
1470 } else if (Role_if(PM_POLITICIAN)) {
1471 (void) tamedog(mtmp, (struct obj *) 0, FALSE);
1475 if (mtmp->mpeaceful)
1476 verbalize("That should do. Now beat it!");
1477 else verbalize("That's not enough, coward!");
1481 #ifndef GOLDOBJ
1482 dealloc_obj(gold);
1483 #else
1484 add_to_minv(mtmp, gold);
1485 #endif
1486 return TRUE;
1489 if (!msg_given) miss(xname(gold), mtmp);
1490 return FALSE;
1493 /* container is kicked, dropped, thrown or otherwise impacted by player.
1494 * Assumes container is on floor. Checks contents for possible damage. */
1495 void
1496 container_impact_dmg(obj)
1497 struct obj *obj;
1499 struct monst *shkp;
1500 struct obj *otmp, *otmp2;
1501 long loss = 0L;
1502 boolean costly, insider;
1503 xchar x = obj->ox, y = obj->oy;
1505 /* only consider normal containers */
1506 if (!Is_container(obj) || Is_mbag(obj)) return;
1508 costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) &&
1509 costly_spot(x, y));
1510 insider = (*u.ushops && inside_shop(u.ux, u.uy) &&
1511 *in_rooms(x, y, SHOPBASE) == *u.ushops);
1513 for (otmp = obj->cobj; otmp; otmp = otmp2) {
1514 const char *result = (char *)0;
1516 otmp2 = otmp->nobj;
1518 /* Amy edit: way too harsh to constantly break all those potions. it's also dumb that this function is called
1519 * both by kicking the container (you have to be stupid enough to do that on purpose) and also by dropping it
1520 * down a staircase or while levitating (can happen by accident)... I'd like to make it so that kicking it has
1521 * way more of a chance that the items break, but oh well */
1523 if ((objects[otmp->otyp].oc_material == MT_GLASS || objects[otmp->otyp].oc_material == MT_OBSIDIAN || is_vitric(otmp)) &&
1524 otmp->oclass != GEM_CLASS && !rn2(otmp->oerodeproof ? 100 : 20) && !obj_resists(otmp, 33, 100) && !stack_too_big(otmp)) {
1525 result = "shatter";
1526 } else if (otmp->otyp == EGG && !rn2(otmp->oerodeproof ? 100 : 20) && !stack_too_big(otmp)) {
1527 result = "cracking";
1528 } else if (evilfriday && !rn2(otmp->oerodeproof ? 10 : 2) && !obj_resists(otmp, 50, 100) && !stack_too_big(otmp)) {
1529 result = "breaking sound, followed by evil laughter";
1531 if (result) {
1532 if (otmp->otyp == MIRROR) change_luck(-2);
1534 /* eggs laid by you. penalty is -1 per egg, max 5,
1535 * but it's always exactly 1 that breaks */
1536 if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM)
1537 change_luck(-1);
1538 You_hear("a muffled %s.", result);
1539 if (costly)
1540 loss += stolen_value(otmp, x, y,
1541 (boolean)shkp->mpeaceful, TRUE, TRUE);
1542 if (otmp->quan > 1L)
1543 useup(otmp);
1544 else {
1545 obj_extract_self(otmp);
1546 obfree(otmp, (struct obj *) 0);
1550 if (costly && loss) {
1551 if (!insider) {
1552 You("caused %ld %s worth of damage!", loss, currency(loss));
1553 make_angry_shk(shkp, x, y);
1554 } else {
1555 You("owe %s %ld %s for objects destroyed.",
1556 mon_nam(shkp), loss, currency(loss));
1561 STATIC_OVL int
1562 kick_object(x, y)
1563 xchar x, y;
1565 int range;
1566 register struct monst *mon, *shkp;
1567 struct trap *trap;
1568 char bhitroom;
1569 boolean costly, isgold, slide = FALSE;
1571 /* if a pile, the "top" object gets kicked */
1572 kickobj = level.objects[x][y];
1574 /* kickobj should always be set due to conditions of call */
1575 if(!kickobj || kickobj->otyp == BOULDER
1576 || kickobj == uball || kickobj == uchain)
1577 return(0);
1579 if ((trap = t_at(x,y)) != 0 &&
1580 (((trap->ttyp == PIT || trap->ttyp == SHIT_PIT || trap->ttyp == MANA_PIT || trap->ttyp == ANOXIC_PIT || trap->ttyp == HYPOXIC_PIT || trap->ttyp == ACID_PIT ||
1581 trap->ttyp == SPIKED_PIT || trap->ttyp == GIANT_CHASM) && !Passes_walls) ||
1582 trap->ttyp == WEB)) {
1583 if (!trap->tseen && !trap->hiddentrap) find_trap(trap);
1584 You_cant("kick %s that's in a %s!", something,
1585 FunnyHallu ? "tizzy" :
1586 (trap->ttyp == WEB) ? "web" : "pit");
1587 return 1;
1590 if(Fumbling && !rn2(3)) {
1591 Your("clumsy kick missed.");
1592 return(1);
1595 if(kickobj->otyp == PETRIFYIUM_BAR && (!Stone_resistance || (!IntStone_resistance && !rn2(20)) ) && !uarmf) {
1596 pline("Kicking a petrifying weapon is a bad idea.");
1597 if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) {
1599 if (!Stoned) {
1601 if (Hallucination && rn2(10)) pline("Good thing you are already stoned.");
1602 else {
1603 Stoned = Race_if(PM_EROSATOR) ? 3 : 7;
1604 u.cnd_stoningcount++;
1605 delayed_killer = "kicking a petrifyium bar";
1612 if(kickobj->otyp == PETRIFYIUM_BRA && (!Stone_resistance || (!IntStone_resistance && !rn2(20)) ) && !uarmf) {
1613 pline("Kicking a petrifying bra is a bad idea.");
1614 if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) {
1616 if (!Stoned) {
1618 if (Hallucination && rn2(10)) pline("Good thing you are already stoned.");
1619 else {
1620 Stoned = Race_if(PM_EROSATOR) ? 3 : 7;
1621 u.cnd_stoningcount++;
1622 delayed_killer = "kicking a petrifyium bra";
1629 if(kickobj->otyp == CORPSE && touch_petrifies(&mons[kickobj->corpsenm])
1630 && (!Stone_resistance || (!IntStone_resistance && !rn2(20)) ) && !uarmf) {
1631 static char kbuf[BUFSZ];
1633 You("kick the %s with your bare %s.",
1634 corpse_xname(kickobj, TRUE), makeplural(body_part(FOOT)));
1635 if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) {
1637 /*You("turn to stone...");
1638 killer_format = KILLED_BY;
1639 sprintf(kbuf, "kicking a monster corpse (%s) without boots",
1640 an(killer_cxname(kickobj, TRUE)));
1641 killer = kbuf;
1642 done(STONING); */
1643 if (!Stoned) {
1645 if (Hallucination && rn2(10)) pline("Good thing you are already stoned.");
1646 else {
1647 Stoned = Race_if(PM_EROSATOR) ? 3 : 7;
1648 u.cnd_stoningcount++;
1649 delayed_killer = killer_cxname(kickobj,TRUE);
1656 /* range < 2 means the object will not move. */
1657 /* maybe dexterity should also figure here. */
1658 /* MAR - if there are multiple objects, range is calculated */
1659 /* from a single object (not entire stack!) */
1661 if (kickobj->quan > 1L && (kickobj->oclass != COIN_CLASS)) /*MAR*/
1662 range = (int)((ACURRSTR)/2 - kickobj->owt/kickobj->quan/40);
1663 else range = (int)((ACURRSTR)/2 - kickobj->owt/40);
1665 if(martial()) range += rnd(3);
1667 if (is_waterypool(x, y) || is_watertunnel(x,y)) {
1668 /* you're in the water too; significantly reduce range */
1669 range = range / 3 + 1; /* {1,2}=>1, {3,4,5}=>2, {6,7,8}=>3 */
1670 } else {
1671 if (is_ice(x, y)) range += rnd(3), slide = TRUE;
1672 if (kickobj->greased) range += rnd(3), slide = TRUE;
1675 /* Mjollnir is magically too heavy to kick */
1676 if(kickobj->oartifact == ART_MJOLLNIR) range = 1;
1677 if(kickobj->oartifact == ART_OTHER_MJOLLNIR) range = 1;
1678 if (kickobj->dynamitekaboom) range = 1;
1680 /* see if the object has a place to move into */
1681 if(!ZAP_POS(levl[x+u.dx][y+u.dy].typ) || closed_door(x+u.dx, y+u.dy))
1682 range = 1;
1684 costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) &&
1685 costly_spot(x, y));
1686 isgold = (kickobj->oclass == COIN_CLASS);
1688 if (IS_ROCK(levl[x][y].typ) || closed_door(x, y)) {
1689 if ((!martial() && rn2(20) > ACURR(A_DEX)) ||
1690 IS_ROCK(levl[u.ux][u.uy].typ) || closed_door(u.ux, u.uy)) {
1691 if (Blind)
1692 pline("It doesn't come loose.");
1693 else
1694 pline("%s %sn't come loose.",
1695 The(distant_name(kickobj, xname)),
1696 otense(kickobj, "do"));
1697 return (!rn2(3) || martial());
1699 if (Blind)
1700 pline("It comes loose.");
1701 else
1702 pline("%s %s loose.",
1703 The(distant_name(kickobj, xname)),
1704 otense(kickobj, "come"));
1705 if (kickobj && is_metallic(kickobj)) wake_nearby(); /* metallic objects make noise --Amy */
1706 obj_extract_self(kickobj);
1707 newsym(x, y);
1708 if (costly && (!costly_spot(u.ux, u.uy) ||
1709 !index(u.urooms, *in_rooms(x, y, SHOPBASE))))
1710 addtobill(kickobj, FALSE, FALSE, FALSE);
1711 if (!flooreffects(kickobj, u.ux, u.uy, "fall")) {
1712 place_object(kickobj, u.ux, u.uy);
1713 stackobj(kickobj);
1714 newsym(u.ux, u.uy);
1716 return 1;
1719 /* a box gets a chance of breaking open here */
1720 if(Is_box(kickobj)) {
1721 boolean otrp = kickobj->otrapped;
1722 wake_nearby(); /* box always makes noise, presumably because of the metallic lock */
1723 if(range < 2) pline("THUD!");
1725 container_impact_dmg(kickobj);
1727 if (kickobj->olocked) {
1728 if (!rn2(5) || (martial() && !rn2(2))) {
1729 You("break open the lock!");
1730 u.cnd_kicklockcount++;
1731 kickobj->olocked = 0;
1732 kickobj->obroken = 1;
1733 if (otrp) (void) chest_trap(kickobj, LEG, FALSE);
1734 return(1);
1736 } else {
1737 if (!rn2(3) || (martial() && !rn2(2))) {
1738 pline_The("lid slams open, then falls shut.");
1739 if (otrp) (void) chest_trap(kickobj, LEG, FALSE);
1740 return(1);
1743 if(range < 2) return(1);
1744 /* else let it fall through to the next cases... */
1747 if (kickobj && is_metallic(kickobj)) wake_nearby(); /* metallic objects make noise --Amy */
1749 /* fragile objects should not be kicked */
1750 if (hero_breaks(kickobj, kickobj->ox, kickobj->oy, FALSE)) return 1;
1752 /* too heavy to move. range is calculated as potential distance from
1753 * player, so range == 2 means the object may move up to one square
1754 * from its current position
1756 if(range < 2 || (isgold && kickobj->quan > 300L)) {
1757 if(!Is_box(kickobj)) {
1758 pline("Thump!");
1759 if (kickobj->oartifact == ART_DONALD_THUMP_) badeffect();
1761 return(!rn2(3) || martial());
1764 if (uarmf && uarmf->oartifact == ART_NEANDERTHAL_SOCCER_CLUB) {
1765 exercise(A_STR, TRUE);
1766 exercise(A_DEX, TRUE);
1769 if (kickobj->quan > 1L && !isgold) kickobj = splitobj(kickobj, 1L);
1771 if (slide && !Blind)
1772 pline("Whee! %s %s across the %s.", Doname2(kickobj),
1773 otense(kickobj, "slide"), surface(x,y));
1775 obj_extract_self(kickobj);
1776 (void) snuff_candle(kickobj);
1777 newsym(x, y);
1778 mon = bhit(u.dx, u.dy, range, KICKED_WEAPON,
1779 (int (*)(MONST_P,OBJ_P))0,
1780 (int (*)(OBJ_P,OBJ_P))0,
1781 &kickobj, TRUE);
1782 if (!kickobj)
1783 return 1; /* object broken (and charged for if costly) */
1784 if(mon) {
1785 if (mon->isshk &&
1786 kickobj->where == OBJ_MINVENT && kickobj->ocarry == mon)
1787 return 1; /* alert shk caught it */
1788 notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
1789 if(isgold ? ghitm(mon, kickobj) : /* caught? */
1790 thitmonst(mon, kickobj, 3, FALSE)) /* hit && used up? */
1791 return(1);
1794 /* the object might have fallen down a hole */
1795 if (kickobj->where == OBJ_MIGRATING) {
1796 if (costly) {
1797 if(isgold)
1798 costly_gold(x, y, kickobj->quan);
1799 else (void)stolen_value(kickobj, x, y,
1800 (boolean)shkp->mpeaceful, FALSE, FALSE);
1802 return 1;
1805 bhitroom = *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE);
1806 if (costly && (!costly_spot(bhitpos.x, bhitpos.y) ||
1807 *in_rooms(x, y, SHOPBASE) != bhitroom)) {
1808 if(isgold)
1809 costly_gold(x, y, kickobj->quan);
1810 else (void)stolen_value(kickobj, x, y,
1811 (boolean)shkp->mpeaceful, FALSE, FALSE);
1814 if(flooreffects(kickobj,bhitpos.x,bhitpos.y,"fall")) return(1);
1815 place_object(kickobj, bhitpos.x, bhitpos.y);
1816 stackobj(kickobj);
1817 newsym(kickobj->ox, kickobj->oy);
1818 return(1);
1821 STATIC_OVL char *
1822 kickstr(buf)
1823 char *buf;
1825 const char *what;
1827 if (kickobj) what = distant_name(kickobj,doname);
1828 else if (IS_DOOR(maploc->typ)) what = "a door";
1829 else if (IS_TREE(maploc->typ)) what = "a tree";
1830 else if (IS_GRAVEWALL(maploc->typ)) what = "a grave wall";
1831 else if (IS_TUNNELWALL(maploc->typ)) what = "a tunnel";
1832 else if (IS_FARMLAND(maploc->typ)) what = "a farmland";
1833 else if (IS_MOUNTAIN(maploc->typ)) what = "a mountain";
1834 else if (IS_WATERTUNNEL(maploc->typ)) what = "a water tunnel";
1835 else if (IS_STWALL(maploc->typ)) what = "a wall";
1836 else if (IS_ROCK(maploc->typ)) what = "a rock";
1837 else if (IS_THRONE(maploc->typ)) what = "a throne";
1838 else if (IS_FOUNTAIN(maploc->typ)) what = "a fountain";
1839 else if (IS_GRAVE(maploc->typ)) what = "a headstone";
1840 else if (IS_SINK(maploc->typ)) what = "a sink";
1841 else if (IS_TOILET(maploc->typ)) what = "a toilet";
1842 else if (IS_ALTAR(maploc->typ)) what = "an altar";
1843 else if (IS_DRAWBRIDGE(maploc->typ)) what = "a drawbridge";
1844 else if (maploc->typ == STAIRS) what = "the stairs";
1845 else if (maploc->typ == LADDER) what = "a ladder";
1846 else if (maploc->typ == IRONBARS) what = "an iron bar";
1847 else what = "something weird";
1848 return strcat(strcpy(buf, "kicking "), what);
1852 dokick()
1854 int x, y;
1855 int avrg_attrib;
1856 register struct monst *mtmp;
1857 boolean no_kick = FALSE;
1858 char buf[BUFSZ];
1859 register struct obj *quivtmp;
1860 struct trap *trap;
1862 if (trap = t_at(u.ux, u.uy)) {
1863 if (trap->ttyp == VIVISECTION_TRAP) {
1864 You("are in vivisection, and therefore unable to kick!");
1865 return 0;
1869 if (!Race_if(PM_TRANSFORMER) && (nolimbs(youmonst.data) || slithy(youmonst.data))) {
1870 You("have no legs to kick with.");
1871 if (yn("Try a full-body tackle instead?") == 'y') {
1872 if (rn2(3) && !polyskillchance()) {
1873 set_wounded_legs(LEFT_SIDE, HWounded_legs + rnd(60-ACURR(A_DEX)));
1874 pline("Argh! That didn't work!");
1875 if (!rn2(20)) badeffect();
1876 return 1;
1879 else {no_kick = TRUE;}
1880 } else if (verysmall(youmonst.data) && !Race_if(PM_TRANSFORMER) ) {
1881 You("are too small to do any kicking.");
1882 if (yn("Try it anyway?") == 'y') {
1883 if (rn2(3) && !polyskillchance()) {
1884 set_wounded_legs(LEFT_SIDE, HWounded_legs + rnd(60-ACURR(A_DEX)));
1885 pline("You hurt your muscles!");
1886 if (!rn2(20)) badeffect();
1887 return 1;
1890 else {no_kick = TRUE;}
1892 /* end checks that let you try anyway */
1894 if (u.usteed) {
1895 if (yn_function("Kick your steed?", ynchars, 'n') == 'y') {
1896 You("kick %s.", mon_nam(u.usteed));
1897 kick_steed();
1898 return 1;
1899 }/* else {
1900 return 0;
1902 /* your legs are not fucking welded to the horse, so you should be able to kick monsters too!!! --Amy */
1903 } else if (Wounded_legs) {
1904 /* note: jump() has similar code */
1905 Your("%s is in no shape for kicking.", body_part(LEG));
1906 no_kick = TRUE;
1907 } else if (near_capacity() > SLT_ENCUMBER) {
1908 Your("load is too heavy to balance yourself for a kick.");
1909 no_kick = TRUE;
1910 } else if (youmonst.data->mlet == S_LIZARD) {
1911 Your("legs cannot kick effectively.");
1912 no_kick = TRUE;
1913 } else if (u.uinwater && !rn2(2)) {
1914 Your("slow motion kick doesn't hit anything.");
1915 no_kick = TRUE;
1916 } else if (u.utrap) {
1917 switch (u.utraptype) {
1918 case TT_PIT:
1919 pline("There's not enough room to kick down here.");
1920 break;
1921 case TT_WEB:
1922 case TT_GLUE:
1923 case TT_BEARTRAP:
1924 You_cant("move your %s!", body_part(LEG));
1925 break;
1926 default:
1927 break;
1929 no_kick = TRUE;
1932 if (no_kick) {
1933 /* ignore direction typed before player notices kick failed */
1934 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1935 return 0;
1938 if(!getdir((char *)0)) return(0);
1939 if(!u.dx && !u.dy) return(0);
1941 x = u.ux + u.dx;
1942 y = u.uy + u.dy;
1944 if(!isok(x, y)) { /* gotta fix that unneccessary segfault for once and for all! --Amy */
1946 pline(FunnyHallu ? "You get a great rebound effect!" : "Your kick hits an invisible barrier.");
1947 return(1);
1950 /* KMH -- Kicking boots always succeed */
1951 if (uarmf && ((uarmf->otyp == KICKING_BOOTS) || (uarmf->otyp == COMBAT_WEDGES) || (uarmf->otyp == STOMPING_BOOTS)) )
1952 avrg_attrib = 99;
1953 else
1954 avrg_attrib = (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3;
1956 if(u.uswallow) {
1957 switch(rn2(3)) {
1958 case 0: You_cant("move your %s!", body_part(LEG));
1959 break;
1960 case 1: if (is_animal(u.ustuck->data)) {
1961 pline("%s burps loudly.", Monnam(u.ustuck));
1962 break;
1964 default: Your("feeble kick has no effect."); break;
1966 return(1);
1968 if (Levitation) {
1969 int xx, yy;
1971 xx = u.ux - u.dx;
1972 yy = u.uy - u.dy;
1973 /* doors can be opened while levitating, so they must be
1974 * reachable for bracing purposes
1975 * Possible extension: allow bracing against stuff on the side?
1977 if (isok(xx,yy) && !IS_ROCK(levl[xx][yy].typ) &&
1978 !IS_DOOR(levl[xx][yy].typ) &&
1979 (!Is_airlevel(&u.uz) || !OBJ_AT(xx,yy))) {
1980 You("have nothing to brace yourself against.");
1981 return(0);
1985 if (uarmf && itemhasappearance(uarmf, APP_PISTOL_BOOTS) && uquiver && (objects[uquiver->otyp].w_ammotyp == WP_BULLET_PISTOL) ) {
1986 if (uquiver->quan > 1L) {
1987 quivtmp = splitobj(uquiver, 1L);
1988 } else {
1989 quivtmp = uquiver;
1990 if (quivtmp->owornmask)
1991 remove_worn_item(quivtmp, FALSE);
1993 freeinv(quivtmp);
1994 if (quivtmp && uarmf && uarmf->oartifact == ART_ANACONDA_HEELS) quivtmp->spe += 12;
1995 throwit(quivtmp, 0L, FALSE, 666);
1998 /* make noise only if the boots are metallic --Amy */
1999 if (uarmf && is_metallic(uarmf)) wake_nearby();
2000 u_wipe_engr(2);
2002 maploc = &levl[x][y];
2004 /* The next five tests should stay in */
2005 /* their present order: monsters, pools, */
2006 /* objects, non-doors, doors. */
2008 if(MON_AT(x, y)) {
2009 struct permonst *mdat;
2011 mtmp = m_at(x, y);
2012 mdat = mtmp->data;
2013 if (!mtmp->mpeaceful || !canspotmon(mtmp))
2014 flags.forcefight = TRUE; /* attack even if invisible */
2015 kick_monster(x, y);
2016 flags.forcefight = FALSE;
2017 /* see comment in attack_checks() */
2018 if (!DEADMONSTER(mtmp) &&
2019 !canspotmon(mtmp) &&
2020 /* check x and y; a monster that evades your kick by
2021 jumping to an unseen square doesn't leave an I behind */
2022 mtmp->mx == x && mtmp->my == y &&
2023 !memory_is_invisible(x, y) && !(mtmp->data->msound == MS_DEEPSTATE) && !(mtmp->egotype_deepstatemember) &&
2024 !(u.uswallow && mtmp == u.ustuck))
2025 map_invisible(x, y);
2026 if((Is_airlevel(&u.uz) || Levitation) && flags.move) {
2027 int range;
2029 range = ((int)youmonst.data->cwt + (weight_cap() + inv_weight()));
2030 if (range < 1) range = 1; /* divide by zero avoidance */
2031 range = (3*(int)mdat->cwt) / range;
2033 if(range < 1) range = 1;
2034 hurtle(-u.dx, -u.dy, range, TRUE);
2036 return(1);
2038 if (memory_is_invisible(x, y)) {
2039 unmap_object(x, y);
2040 newsym(x, y);
2042 if (is_waterypool(x, y) ^ !!u.uinwater) {
2043 /* objects normally can't be removed from water by kicking */
2044 You("splash some water around.");
2045 return 1;
2048 kickobj = (struct obj *)0;
2049 if (OBJ_AT(x, y) &&
2050 (!Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
2051 || sobj_at(BOULDER,x,y))) {
2052 if(kick_object(x, y)) {
2053 if(Is_airlevel(&u.uz))
2054 hurtle(-u.dx, -u.dy, 1, TRUE); /* assume it's light */
2055 return(1);
2057 goto ouch;
2060 if(!IS_DOOR(maploc->typ)) {
2061 if(maploc->typ == SDOOR) {
2062 if(!Levitation && ((rn2(25) < avrg_attrib ) || !rn2(5) ) ) {
2063 cvt_sdoor_to_door(maploc); /* ->typ = DOOR */
2064 pline("Crash! %s a secret door!",
2065 /* don't "kick open" when it's locked
2066 unless it also happens to be trapped */
2067 (maploc->doormask & (D_LOCKED|D_TRAPPED)) == D_LOCKED ?
2068 "Your kick uncovers" : "You kick open");
2069 wake_nearby();
2070 exercise(A_DEX, TRUE);
2071 if(maploc->doormask & D_TRAPPED) {
2072 maploc->doormask = D_NODOOR;
2073 b_trapped("door", FOOT);
2074 } else if (maploc->doormask != D_NODOOR &&
2075 !(maploc->doormask & D_LOCKED))
2076 maploc->doormask = D_ISOPEN;
2077 if (Blind)
2078 feel_location(x,y); /* we know it's gone */
2079 else
2080 newsym(x,y);
2081 if (maploc->doormask == D_ISOPEN ||
2082 maploc->doormask == D_NODOOR)
2083 unblock_point(x,y); /* vision */
2084 return(1);
2085 } else goto ouch;
2087 if(maploc->typ == SCORR) {
2088 if(!Levitation && ((rn2(25) < avrg_attrib ) || !rn2(5) ) ) {
2089 pline("Crash! You kick open a secret passage!");
2090 wake_nearby();
2091 exercise(A_DEX, TRUE);
2092 maploc->typ = CORR;
2093 if (Blind)
2094 feel_location(x,y); /* we know it's gone */
2095 else
2096 newsym(x,y);
2097 unblock_point(x,y); /* vision */
2098 return(1);
2099 } else goto ouch;
2101 if(IS_THRONE(maploc->typ)) {
2102 register int i;
2103 if(Levitation) goto dumb;
2104 if((Luck < 0 || maploc->doormask) && !rn2(3)) {
2105 maploc->typ = ROOM;
2106 maploc->doormask = 0; /* don't leave loose ends.. */
2107 (void) mkgold((long)rnd(200), x, y);
2108 if (Blind)
2109 pline("CRASH! You destroy it.");
2110 else {
2111 pline("CRASH! You destroy the throne.");
2112 newsym(x, y);
2114 wake_nearby();
2115 exercise(A_DEX, TRUE);
2116 return(1);
2117 } else if(Luck > 0 && !rn2(3) && !maploc->looted) {
2118 (void) mkgold((long) rn1(201, 300), x, y);
2119 i = Luck + 1;
2120 if(i > 6) i = 6;
2121 while(i--)
2122 (void) mksobj_at(rnd_class(DILITHIUM_CRYSTAL,
2123 LUCKSTONE-1), x, y, TRUE, TRUE, FALSE);
2125 if (Blind)
2126 You("kick %s loose!", something);
2127 else {
2128 You("kick loose some ornamental coins and gems!");
2129 newsym(x, y);
2131 /* prevent endless milking */
2132 maploc->looted = T_LOOTED;
2133 return(1);
2134 } else if (!rn2(4)) {
2135 if(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) {
2136 fall_through(FALSE);
2137 return(1);
2138 } else goto ouch;
2140 goto ouch;
2142 if(IS_ALTAR(maploc->typ)) {
2143 if(Levitation) goto dumb;
2144 You("kick %s.",(Blind ? something : "the altar"));
2145 if(!rn2(3)) goto ouch;
2146 altar_wrath(x, y);
2147 exercise(A_DEX, TRUE);
2148 return(1);
2150 if(IS_FOUNTAIN(maploc->typ)) {
2151 if(Levitation) goto dumb;
2152 You("kick %s.",(Blind ? something : "the fountain"));
2153 if(!rn2(3)) goto ouch;
2154 /* make metal boots rust */
2155 if(uarmf && rn2(3))
2156 if (!rust_dmg(uarmf, "metal boots", 1, FALSE, &youmonst)) {
2157 Your("boots get wet.");
2158 /* could cause short-lived fumbling here */
2160 exercise(A_DEX, TRUE);
2161 return(1);
2163 if(IS_GRAVE(maploc->typ) || maploc->typ == IRONBARS)
2164 goto ouch;
2165 if(IS_TREE(maploc->typ)) {
2166 struct obj *treefruit;
2167 /* nothing, fruit or trouble? 75:23.5:1.5% */
2169 if (uarmf && uarmf->oartifact == ART_CLIMATE_PROTECTION_IS_ERRI) {
2170 pline("You kick the tree, causing it to crumble.");
2171 levl[x][y].typ = CORR; /* it is intentional that this does not call the tree squad --Amy */
2172 newsym(x,y);
2173 return(1);
2176 if (rn2(3)) {
2177 if ( !rn2(6))
2178 You_hear("a low buzzing."); /* a warning */
2179 if (uarmf && itemhasappearance(uarmf, APP_JUNGLE_BOOTS) ) {
2180 pline("You kick the tree. Nothing happens.");
2181 return(1);
2182 } else if (RngeJungleAction) {
2183 pline("You kick the tree. Nothing happens.");
2184 return(1);
2185 } else
2186 goto ouch;
2188 if (rn2(15) && (maploc->looted & TREE_LOOTED) ) {
2189 pline("The tree's branches are swinging, but there's no fruit on it.");
2190 return(1);
2191 } else if (rn2(15) && !(maploc->looted & TREE_LOOTED) ) {
2193 if ((!issoviet && rn2(3)) || (isfriday && !rn2(2)) ) {
2194 /* nerf by Amy, it was way too easy to accumulate tons of fruits. */
2195 pline("The tree's branches are swinging, but apparently it doesn't bear any fruits.");
2196 maploc->looted |= TREE_LOOTED;
2197 return(1);
2198 } else {
2199 treefruit = rnd_treefruit_at(x, y);
2200 if (!treefruit) {
2201 pline("The tree's branches are swinging.");
2202 return(1);
2204 long nfruit = 8L-rnl(7), nfall;
2205 if (rn2(3)) nfruit /= 2; /* With the high amount of trees in the game, this is necessary --Amy */
2206 if (!rn2(4)) nfruit /= 3;
2207 if (nfruit < 1) nfruit = 1;
2208 short frtype = treefruit->otyp;
2209 treefruit->quan = nfruit;
2210 treefruit->owt = weight(treefruit);
2211 if (is_plural(treefruit))
2212 pline("Some %s fall from the tree!", xname(treefruit));
2213 else
2214 pline("%s falls from the tree!", An(xname(treefruit)));
2215 nfall = scatter(x,y,2,MAY_HIT,treefruit);
2216 if (nfall != nfruit) {
2217 /* scatter left some in the tree, but treefruit
2218 * may not refer to the correct object */
2219 treefruit = mksobj(frtype, TRUE, FALSE, FALSE);
2220 if (treefruit) {
2221 treefruit->quan = nfruit-nfall;
2222 treefruit->owt = weight(treefruit);
2223 pline("%ld %s got caught in the branches.",
2224 nfruit-nfall, xname(treefruit));
2225 dealloc_obj(treefruit);
2228 exercise(A_DEX, TRUE);
2229 exercise(A_WIS, TRUE); /* discovered a new food source! */
2230 newsym(x, y);
2231 maploc->looted |= TREE_LOOTED;
2232 return(1);
2234 } else if (!(maploc->looted & TREE_SWARM)) {
2235 int cnt = rnl(4) + 2;
2236 int made = 0;
2237 coord mm;
2238 mm.x = x; mm.y = y;
2240 if (!rn2(20)) {
2242 while (cnt--) {
2243 if (enexto(&mm, mm.x, mm.y, &mons[PM_WOOD_NYMPH]) &&
2244 makemon(mkclass(S_NYMPH,0), mm.x, mm.y, MM_ANGRY))
2245 made++;
2247 wake_nearby(); /* make sure they're awake --Amy */
2249 } else {
2251 while (cnt--) {
2252 if (enexto(&mm, mm.x, mm.y, &mons[PM_KILLER_BEE]) &&
2253 makemon(beehivemon(), mm.x, mm.y, MM_ANGRY))
2254 made++;
2258 if ( made )
2259 pline("You've attracted the tree's former occupants!");
2260 else
2261 You("smell stale honey.");
2262 maploc->looted |= TREE_SWARM;
2263 return(1);
2265 if (uarmf && itemhasappearance(uarmf, APP_JUNGLE_BOOTS) ) {
2266 pline("You kick the tree. Nothing happens.");
2267 return(1);
2268 } else if (RngeJungleAction) {
2269 pline("You kick the tree. Nothing happens.");
2270 return(1);
2271 } else
2272 goto ouch;
2274 if(IS_TOILET(maploc->typ)) {
2275 if(Levitation) goto dumb;
2276 pline("Klunk!");
2277 if (!rn2(5)) wake_nearby();
2278 if (!rn2(4)) breaktoilet(x,y);
2279 return(1);
2281 if(IS_GRAVE(maploc->typ)) {
2282 goto ouch;
2284 if(IS_SINK(maploc->typ)) {
2285 int gend = poly_gender();
2286 int washerndx = (gend == 1 || (gend == 2 && rn2(2))) ?
2287 PM_INCUBUS : PM_SUCCUBUS;
2288 boolean specwasher = rn2(2) ? 0 : 1;
2289 boolean specpudding = rn2(2) ? 0 : 1;
2291 if(Levitation) goto dumb;
2293 u.cnd_sinkamount++;
2295 if (!rn2(5)) { /* punish the sucker who keeps kicking sinks :P --Amy */
2296 pline_The("pipes break! Water spurts out!");
2297 level.flags.nsinks--;
2298 levl[x][y].typ = FOUNTAIN;
2299 level.flags.nfountains++;
2300 newsym(x,y);
2301 return(1);
2302 } else if (rn2(5)) {
2303 if(flags.soundok)
2304 pline("Klunk! The pipes vibrate noisily.");
2305 else pline("Klunk!");
2306 if (!rn2(5)) wake_nearby();
2307 exercise(A_DEX, TRUE);
2308 return(1);
2309 } else if(!(maploc->looted & S_LPUDDING) && !rn2(3) && !((specpudding == 1) && (mvitals[PM_BLACK_PUDDING].mvflags & G_GONE))) {
2310 if (Blind)
2311 You_hear("a gushing sound.");
2312 else
2313 pline("A %s ooze gushes up from the drain!", specpudding == 1 ? hcolor(NH_BLACK) : "strange");
2314 (void) makemon((specpudding == 1) ? &mons[PM_BLACK_PUDDING] : mkclass(S_PUDDING, 0), x, y, NO_MM_FLAGS);
2315 exercise(A_DEX, TRUE);
2316 newsym(x,y);
2317 maploc->looted |= S_LPUDDING;
2318 return(1);
2319 } else if(!(maploc->looted & S_LDWASHER) && !rn2(3) && !((specwasher == 1) && (mvitals[washerndx].mvflags & G_GONE))) {
2320 /* can't resist... */
2321 pline("%s returns!", (Blind ? Something : "The dish washer"));
2322 if (makemon((specwasher == 1) ? &mons[washerndx] : specialtensmon(226), x, y, NO_MM_FLAGS)) newsym(x,y); /* AD_SSEX */
2323 maploc->looted |= S_LDWASHER;
2324 exercise(A_DEX, TRUE);
2325 return(1);
2326 } else if(!rn2(3)) {
2327 pline("Flupp! %s.", (Blind ? "You hear a sloshing sound" : "Muddy waste pops up from the drain"));
2328 if(!(maploc->looted & S_LRING)) { /* once per sink */
2330 if (rn2(5)) { /* nerf nerf NEEEEEERF! :D --Amy */
2331 pline("But it contains nothing useful.");
2332 maploc->looted |= S_LRING;
2333 } else {
2335 if (!Blind)
2336 You("see a ring shining in its midst.");
2337 (void) mkobj_at(RING_CLASS, x, y, TRUE, FALSE);
2338 newsym(x, y);
2339 exercise(A_DEX, TRUE);
2340 exercise(A_WIS, TRUE); /* a discovery! */
2341 maploc->looted |= S_LRING;
2344 return(1);
2346 goto ouch;
2348 if (maploc->typ == STAIRS || maploc->typ == WATERTUNNEL || maploc->typ == LADDER ||
2349 IS_STWALL(maploc->typ)) {
2350 if(!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN)
2351 goto dumb;
2352 ouch:
2354 if (uamul && uamul->oartifact == ART_WALT_VERSUS_ANNA && !rn2(3) && IS_STWALL(maploc->typ) && !(levl[x][y].wall_info & W_NONDIGGABLE)) {
2355 pline("Crash! Your kick razed the wall!");
2356 wake_nearby();
2357 maploc->typ = CORR;
2358 newsym(x,y);
2359 return(1);
2362 if (Role_if(PM_QUARTERBACK)) { /* expert at kicking and thus doesn't take damage, from PRIME --Amy */
2363 pline("Thump - you kicked an obstacle.");
2364 return(1);
2367 pline(FunnyHallu ? "You stumped your little toe - ouch!" : "Ouch! That hurts!");
2368 exercise(A_DEX, FALSE);
2369 exercise(A_STR, FALSE);
2370 if (Blind) feel_location(x,y); /* we know we hit it */
2371 if (is_drawbridge_wall(x,y) >= 0) {
2372 pline_The("drawbridge is unaffected.");
2373 /* update maploc to refer to the drawbridge */
2374 (void) find_drawbridge(&x,&y);
2375 maploc = &levl[x][y];
2377 if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, HWounded_legs + 5 + rnd(5));
2378 losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr(buf),
2379 KILLED_BY);
2380 if(Is_airlevel(&u.uz) || Levitation)
2381 hurtle(-u.dx, -u.dy, rn1(2,4), TRUE); /* assume it's heavy */
2382 return(1);
2384 goto dumb;
2387 if(maploc->doormask == D_ISOPEN ||
2388 maploc->doormask == D_BROKEN ||
2389 maploc->doormask == D_NODOOR) {
2390 dumb:
2391 exercise(A_DEX, FALSE);
2392 if (martial() || (uarmf && itemhasappearance(uarmf, APP_PISTOL_BOOTS)) || ACURR(A_DEX) >= 16 || rn2(3)) {
2393 You("kick at empty space.");
2394 if (Blind) feel_location(x,y);
2395 } else {
2396 pline(FunnyHallu ? "Argh... this feels like overdoing sports!" : "Dumb move! You strain a muscle.");
2397 exercise(A_STR, FALSE);
2398 set_wounded_legs(RIGHT_SIDE, HWounded_legs + 5 + rnd(5));
2400 if ((Is_airlevel(&u.uz) || Levitation) && rn2(2)) {
2401 hurtle(-u.dx, -u.dy, 1, TRUE);
2402 return 1; /* you moved, so use up a turn */
2404 return(1); /* what the HELL??? you kicked at thin air, of course you used up a turn!!! --Amy */
2407 /* not enough leverage to kick open doors while levitating */
2408 if(Levitation) goto ouch;
2410 /* Ali - artifact doors */
2411 if (artifact_door(x, y)) goto ouch;
2413 exercise(A_DEX, TRUE);
2414 /* door is known to be CLOSED or LOCKED */
2415 if(rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) {
2416 boolean shopdoor = *in_rooms(x, y, SHOPBASE) ? TRUE : FALSE;
2417 /* break the door */
2418 u.cnd_kicklockcount++;
2419 wake_nearby();
2420 if(maploc->doormask & D_TRAPPED) {
2421 if (flags.verbose) You("kick the door.");
2422 exercise(A_STR, FALSE);
2423 maploc->doormask = D_NODOOR;
2424 b_trapped("door", FOOT);
2425 } else if(ACURR(A_STR) > 18 && !rn2(5) && !shopdoor) {
2426 pline("As you kick the door, it shatters to pieces!");
2427 exercise(A_STR, TRUE);
2428 maploc->doormask = D_NODOOR;
2429 } else {
2430 pline("As you kick the door, it crashes open!");
2431 exercise(A_STR, TRUE);
2432 maploc->doormask = D_BROKEN;
2434 if (Blind)
2435 feel_location(x,y); /* we know we broke it */
2436 else
2437 newsym(x,y);
2438 unblock_point(x,y); /* vision */
2439 if (shopdoor) {
2440 add_damage(x, y, 400L);
2441 pay_for_damage("break", FALSE);
2443 if (in_town(x, y))
2444 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2445 if (DEADMONSTER(mtmp)) continue;
2446 if((mtmp->data == &mons[PM_WATCHMAN] || mtmp->data == &mons[PM_WATCH_LIEUTENANT] ||
2447 mtmp->data == &mons[PM_WATCH_CAPTAIN] || mtmp->data == &mons[PM_WATCH_LEADER]) &&
2448 couldsee(mtmp->mx, mtmp->my) &&
2449 mtmp->mpeaceful) {
2450 if (canspotmon(mtmp))
2451 pline("%s yells:", Amonnam(mtmp));
2452 else
2453 You_hear("someone yell:");
2454 verbalize("Halt, thief! You're under arrest!");
2455 (void) angry_guards(FALSE);
2456 break;
2459 } else {
2460 if (Blind) feel_location(x,y); /* we know we hit it */
2461 exercise(A_STR, TRUE);
2462 pline("WHAMMM!!!");
2463 wake_nearby();
2464 if (in_town(x, y))
2465 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2466 if (DEADMONSTER(mtmp)) continue;
2467 if ((mtmp->data == &mons[PM_WATCHMAN] || mtmp->data == &mons[PM_WATCH_LIEUTENANT] ||
2468 mtmp->data == &mons[PM_WATCH_CAPTAIN] || mtmp->data == &mons[PM_WATCH_LEADER]) &&
2469 mtmp->mpeaceful && couldsee(mtmp->mx, mtmp->my)) {
2470 if (canspotmon(mtmp))
2471 pline("%s yells:", Amonnam(mtmp));
2472 else
2473 You_hear("someone yell:");
2474 if(levl[x][y].looted & D_WARNED) {
2475 verbalize("Halt, vandal! You're under arrest!");
2476 (void) angry_guards(FALSE);
2477 } else {
2478 int i;
2479 verbalize("Hey, stop damaging that door!");
2480 /* [ALI] Since marking a door as warned will have
2481 * the side effect of trapping the door, it must be
2482 * included in the doors[] array in order that trap
2483 * detection will find it.
2485 for(i = doorindex - 1; i >= 0; i--)
2486 if (x == doors[i].x && y == doors[i].y)
2487 break;
2488 if (i < 0)
2489 i = add_door(x, y, (struct mkroom *)0);
2490 if (i >= 0)
2491 levl[x][y].looted |= D_WARNED;
2493 break;
2497 return(1);
2500 STATIC_OVL void
2501 drop_to(cc, loc)
2502 coord *cc;
2503 schar loc;
2505 /* cover all the MIGR_xxx choices generated by down_gate() */
2506 switch (loc) {
2507 case MIGR_RANDOM: /* trap door or hole */
2508 if (Is_stronghold(&u.uz)) {
2509 cc->x = valley_level.dnum;
2510 cc->y = valley_level.dlevel;
2511 break;
2512 } else if (In_endgame(&u.uz) || Is_botlevel(&u.uz)) {
2513 cc->y = cc->x = 0;
2514 break;
2515 } /* else fall to the next cases */
2516 case MIGR_STAIRS_UP:
2517 case MIGR_LADDER_UP:
2518 cc->x = u.uz.dnum;
2519 cc->y = u.uz.dlevel + 1;
2520 break;
2521 case MIGR_SSTAIRS:
2522 cc->x = sstairs.tolev.dnum;
2523 cc->y = sstairs.tolev.dlevel;
2524 break;
2525 default:
2526 case MIGR_NOWHERE:
2527 /* y==0 means "nowhere", in which case x doesn't matter */
2528 cc->y = cc->x = 0;
2529 break;
2533 void
2534 impact_drop(missile, x, y, dlev)
2535 struct obj *missile;
2536 xchar x, y, dlev;
2538 schar toloc;
2539 register struct obj *obj, *obj2;
2540 register struct monst *shkp;
2541 long oct, dct, price, debit, robbed;
2542 boolean angry, costly, isrock;
2543 coord cc;
2545 if(!OBJ_AT(x, y)) return;
2547 toloc = down_gate(x, y);
2548 drop_to(&cc, toloc);
2549 if (!cc.y) return;
2551 if (dlev) {
2552 /* send objects next to player falling through trap door.
2553 * checked in obj_delivery().
2555 toloc = MIGR_NEAR_PLAYER;
2556 cc.y = dlev;
2559 costly = costly_spot(x, y);
2560 price = debit = robbed = 0L;
2561 angry = FALSE;
2562 shkp = (struct monst *) 0;
2563 /* if 'costly', we must keep a record of ESHK(shkp) before
2564 * it undergoes changes through the calls to stolen_value.
2565 * the angry bit must be reset, if needed, in this fn, since
2566 * stolen_value is called under the 'silent' flag to avoid
2567 * unsavory pline repetitions.
2569 if(costly) {
2570 if ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0) {
2571 debit = ESHK(shkp)->debit;
2572 robbed = ESHK(shkp)->robbed;
2573 angry = !shkp->mpeaceful;
2577 isrock = (missile && missile->otyp == ROCK);
2578 oct = dct = 0L;
2579 for(obj = level.objects[x][y]; obj; obj = obj2) {
2580 obj2 = obj->nexthere;
2581 if(obj == missile) continue;
2582 /* number of objects in the pile */
2583 oct += obj->quan;
2584 if(obj == uball || obj == uchain) continue;
2585 /* boulders can fall too, but rarely & never due to rocks */
2586 if((isrock && obj->otyp == BOULDER) ||
2587 rn2(obj->otyp == BOULDER ? 30 : 3)) continue;
2588 obj_extract_self(obj);
2590 if(costly) {
2591 price += stolen_value(obj, x, y,
2592 (costly_spot(u.ux, u.uy) &&
2593 index(u.urooms, *in_rooms(x, y, SHOPBASE))),
2594 TRUE, FALSE);
2595 /* set obj->no_charge to 0 */
2596 if (Has_contents(obj))
2597 picked_container(obj); /* does the right thing */
2598 if (obj->oclass != COIN_CLASS)
2599 obj->no_charge = 0;
2602 add_to_migration(obj);
2603 obj->ox = cc.x;
2604 obj->oy = cc.y;
2605 obj->owornmask = (long)toloc;
2607 /* number of fallen objects */
2608 dct += obj->quan;
2611 if (dct && cansee(x, y)) { /* at least one object fell */
2612 const char *what = (dct == 1L ? "object falls" : "objects fall");
2614 if (missile)
2615 pline("From the impact, %sother %s.",
2616 dct == oct ? "the " : dct == 1L ? "an" : "", what);
2617 else if (oct == dct)
2618 pline("%s adjacent %s %s.",
2619 dct == 1L ? "The" : "All the", what, gate_str);
2620 else
2621 pline("%s adjacent %s %s.",
2622 dct == 1L ? "One of the" : "Some of the",
2623 dct == 1L ? "objects falls" : what, gate_str);
2626 if(costly && shkp && price) {
2627 if(ESHK(shkp)->robbed > robbed) {
2628 You("removed %ld %s worth of goods!", price, currency(price));
2629 if(cansee(shkp->mx, shkp->my)) {
2630 if(ESHK(shkp)->customer[0] == 0)
2631 (void) strncpy(ESHK(shkp)->customer, plname, PL_NSIZ);
2632 if(angry)
2633 pline("%s is infuriated!", Monnam(shkp));
2634 else pline("\"%s, you are a thief!\"", plname);
2635 } else You_hear("a scream, \"Thief!\"");
2636 hot_pursuit(shkp);
2637 (void) angry_guards(FALSE);
2638 return;
2640 if(ESHK(shkp)->debit > debit) {
2641 long amt = (ESHK(shkp)->debit - debit);
2642 You("owe %s %ld %s for goods lost.",
2643 Monnam(shkp),
2644 amt, currency(amt));
2650 /* NOTE: ship_object assumes otmp was FREED from fobj or invent.
2651 * <x,y> is the point of drop. otmp is _not_ an <x,y> resident:
2652 * otmp is either a kicked, dropped, or thrown object.
2654 boolean
2655 ship_object(otmp, x, y, shop_floor_obj)
2656 xchar x, y;
2657 struct obj *otmp;
2658 boolean shop_floor_obj;
2660 schar toloc;
2661 xchar ox, oy;
2662 coord cc;
2663 struct obj *obj;
2664 struct trap *t;
2665 boolean nodrop, unpaid, container, impact = FALSE;
2666 long n = 0L;
2668 if (!otmp) return(FALSE);
2669 if ((toloc = down_gate(x, y)) == MIGR_NOWHERE) return(FALSE);
2670 drop_to(&cc, toloc);
2671 if (!cc.y) return(FALSE);
2673 /* objects other than attached iron ball always fall down ladder,
2674 but have a chance of staying otherwise */
2675 nodrop = (otmp == uball) || (otmp == uchain) ||
2676 (toloc != MIGR_LADDER_UP && rn2(3));
2678 container = Has_contents(otmp);
2679 unpaid = (otmp->unpaid || (container && count_unpaid(otmp->cobj)));
2681 if(OBJ_AT(x, y)) {
2682 for(obj = level.objects[x][y]; obj; obj = obj->nexthere)
2683 if(obj != otmp) n += obj->quan;
2684 if(n) impact = TRUE;
2686 /* boulders never fall through trap doors, but they might knock
2687 other things down before plugging the hole */
2688 if (otmp->otyp == BOULDER &&
2689 ((t = t_at(x, y)) != 0) &&
2690 (t->ttyp == TRAPDOOR || t->ttyp == SHAFT_TRAP || t->ttyp == CURRENT_SHAFT || t->ttyp == HOLE)) {
2691 if (impact) impact_drop(otmp, x, y, 0);
2692 return FALSE; /* let caller finish the drop */
2695 if (cansee(x, y)) otransit_msg(otmp, nodrop, n);
2697 if (nodrop) {
2698 if (impact) impact_drop(otmp, x, y, 0);
2699 return(FALSE);
2702 if(unpaid || shop_floor_obj) {
2703 if(unpaid) {
2704 subfrombill(otmp, shop_keeper(*u.ushops));
2705 (void)stolen_value(otmp, u.ux, u.uy, TRUE, FALSE, FALSE);
2706 } else {
2707 ox = otmp->ox;
2708 oy = otmp->oy;
2709 (void)stolen_value(otmp, ox, oy,
2710 (costly_spot(u.ux, u.uy) &&
2711 index(u.urooms, *in_rooms(ox, oy, SHOPBASE))),
2712 FALSE, FALSE);
2714 /* set otmp->no_charge to 0 */
2715 if(container)
2716 picked_container(otmp); /* happens to do the right thing */
2717 if(otmp->oclass != COIN_CLASS)
2718 otmp->no_charge = 0;
2721 if (otmp == uwep) setuwep((struct obj *)0, FALSE, TRUE);
2722 if (otmp == uswapwep) setuswapwep((struct obj *)0, FALSE);
2723 if (otmp == uquiver) setuqwep((struct obj *)0);
2725 /* some things break rather than ship
2726 * Amy edit: but it shouldn't happen all the damn time!! */
2727 if (!rn2(otmp->oerodeproof ? 100 : 20) && breaktest(otmp)) {
2728 const char *result;
2730 if (objects[otmp->otyp].oc_material == MT_GLASS || objects[otmp->otyp].oc_material == MT_OBSIDIAN || is_vitric(otmp) || otmp->otyp == EXPENSIVE_CAMERA )
2732 if (otmp->otyp == MIRROR)
2733 change_luck(-2);
2734 result = "crash";
2735 } else {
2736 /* penalty for breaking eggs laid by you */
2737 if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM)
2738 change_luck((schar) -min(otmp->quan, 5L));
2739 result = "splat";
2741 You_hear("a muffled %s.",result);
2742 obj_extract_self(otmp);
2743 obfree(otmp, (struct obj *) 0);
2744 return TRUE;
2747 add_to_migration(otmp);
2748 otmp->ox = cc.x;
2749 otmp->oy = cc.y;
2750 otmp->owornmask = (long)toloc;
2751 /* boulder from rolling boulder trap, no longer part of the trap */
2752 if (otmp->otyp == BOULDER) otmp->otrapped = 0;
2754 if(impact) {
2755 /* the objs impacted may be in a shop other than
2756 * the one in which the hero is located. another
2757 * check for a shk is made in impact_drop. it is, e.g.,
2758 * possible to kick/throw an object belonging to one
2759 * shop into another shop through a gap in the wall,
2760 * and cause objects belonging to the other shop to
2761 * fall down a trap door--thereby getting two shopkeepers
2762 * angry at the hero in one shot.
2764 impact_drop(otmp, x, y, 0);
2765 newsym(x,y);
2767 return(TRUE);
2770 void
2771 obj_delivery()
2773 register struct obj *otmp, *otmp2;
2774 register int nx, ny;
2775 long where;
2777 for (otmp = migrating_objs; otmp; otmp = otmp2) {
2778 otmp2 = otmp->nobj;
2779 if (otmp->ox != u.uz.dnum || otmp->oy != u.uz.dlevel) continue;
2781 obj_extract_self(otmp);
2782 where = otmp->owornmask; /* destination code */
2783 otmp->owornmask = 0L;
2785 switch ((int)where) {
2786 case MIGR_STAIRS_UP: nx = xupstair, ny = yupstair;
2787 break;
2788 case MIGR_LADDER_UP: nx = xupladder, ny = yupladder;
2789 break;
2790 case MIGR_SSTAIRS: nx = sstairs.sx, ny = sstairs.sy;
2791 break;
2792 case MIGR_NEAR_PLAYER: nx = u.ux, ny = u.uy;
2793 break;
2794 default:
2795 case MIGR_RANDOM: nx = ny = 0;
2796 break;
2798 if (nx > 0) {
2799 place_object(otmp, nx, ny);
2800 stackobj(otmp);
2801 (void)scatter(nx, ny, rnd(2), 0, otmp);
2802 } else { /* random location */
2803 /* set dummy coordinates because there's no
2804 current position for rloco() to update */
2805 otmp->ox = otmp->oy = 0;
2806 rloco(otmp);
2811 STATIC_OVL void
2812 otransit_msg(otmp, nodrop, num)
2813 register struct obj *otmp;
2814 register boolean nodrop;
2815 long num;
2817 char obuf[BUFSZ];
2819 sprintf(obuf, "%s%s",
2820 (otmp->otyp == CORPSE &&
2821 type_is_pname(&mons[otmp->corpsenm])) ? "" : "The ",
2822 cxname(otmp));
2824 if(num) { /* means: other objects are impacted */
2825 sprintf(eos(obuf), " %s %s object%s",
2826 otense(otmp, "hit"),
2827 num == 1L ? "another" : "other",
2828 num > 1L ? "s" : "");
2829 if(nodrop)
2830 sprintf(eos(obuf), ".");
2831 else
2832 sprintf(eos(obuf), " and %s %s.",
2833 otense(otmp, "fall"), gate_str);
2834 pline("%s", obuf);
2835 } else if(!nodrop)
2836 pline("%s %s %s.", obuf, otense(otmp, "fall"), gate_str);
2839 /* migration destination for objects which fall down to next level */
2840 schar
2841 down_gate(x, y)
2842 xchar x, y;
2844 struct trap *ttmp;
2846 gate_str = 0;
2847 /* this matches the player restriction in goto_level() */
2848 if (on_level(&u.uz, &qstart_level) && !ok_to_quest())
2849 return MIGR_NOWHERE;
2851 if ((xdnstair == x && ydnstair == y) ||
2852 (sstairs.sx == x && sstairs.sy == y && !sstairs.up)) {
2853 gate_str = "down the stairs";
2854 return (xdnstair == x && ydnstair == y) ?
2855 MIGR_STAIRS_UP : MIGR_SSTAIRS;
2857 if (xdnladder == x && ydnladder == y) {
2858 gate_str = "down the ladder";
2859 return MIGR_LADDER_UP;
2862 if (((ttmp = t_at(x, y)) != 0 && ttmp->tseen) &&
2863 (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == SHAFT_TRAP || ttmp->ttyp == CURRENT_SHAFT || ttmp->ttyp == HOLE)) {
2864 gate_str = (ttmp->ttyp == TRAPDOOR) ?
2865 "through the trap door" : (ttmp->ttyp == CURRENT_SHAFT) ? "through the shaft" :
2866 (ttmp->ttyp == SHAFT_TRAP) ? "through the shaft" : "through the hole";
2867 return MIGR_RANDOM;
2869 return MIGR_NOWHERE;
2872 /*dokick.c*/