unsigned char* hex2bin(char *hex, unsigned char *bin, int iLen, int *oLen) { int bLen; int i; iLen = (iLen <= 0) ? StrLen(hex) : iLen; if(StrNCompare(hex, "0x", 2) == 0) { /* hex string has 0x prefix */ hex = hex + 2; iLen -= 2; } if(iLen%2 != 0) { /* hex string is not a multiple of 2 in length */ return NULL; } bLen = iLen / 2; MemSet(bin,0,bLen); for(i = 0; i < bLen; i++) { char hbyte = *hex++; char lbyte = *hex++; if(!is_hex(hbyte) || !is_hex(lbyte)) { /* invalid character */ return NULL; } *bin++ = (unsigned char) (hex2byte(hbyte)<<4 | hex2byte(lbyte)); } *oLen = i; return bin; }
long strtol(const char *s, char **endptr, int base) { // WARNING : only base = 10 supported long val = StrAToI(s); if (endptr) { Char str[maxStrIToALen]; StrIToA(str, val); if (StrNCompare(s, str, StrLen(str)) == 0) *endptr = (char *)s + StrLen(str); } return val; }
static void findshk(Short roomno) { monst_t *mtmp; for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon) if ((mtmp->bitflags & M_IS_SHOPKEEPER) && ESHK(mtmp)->shoproom == roomno && ESHK(mtmp)->shoplevel == dlevel) { shopkeeper = mtmp; bill = ESHK(shopkeeper)->bill; shlevel = dlevel; if (ANGRY(shopkeeper) && StrNCompare(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; /* billobjs = 0; -- this is wrong if we save in a shop */ /* (and it is harmless to have too many things in billobjs) */ return; } shopkeeper = NULL; shlevel = 0; // bill = (struct bill_x *) -1000; /* dump core when referenced */ bill = NULL; }
/* * shk_move: return 1: he moved 0: he didnt -1: let m_move do it * (what about "return 2" ??? */ Short shk_move(monst_t *shkp) { monst_t *mtmp; permonst_t *mdat = shkp->data; UChar gx,gy,omx,omy,nx,ny,nix,niy; Int8 appr,i; Short udist; Short z; Int8 shkroom,chi,chcnt,cnt; Boolean uondoor=false, satdoor, avoid=false, badinv; coord poss[9]; Short info[9]; obj_t *ib = NULL; omx = shkp->mx; omy = shkp->my; if ((udist = dist(omx,omy)) < 3) { if (ANGRY(shkp)) { hit_you(shkp, dice(mdat->damn, mdat->damd)+1); return 0; } if (ESHK(shkp)->following) { if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ)) { StrPrintF(ScratchBuffer, "Hello %s! I was looking for %s.", plname, ESHK(shkp)->customer); message(ScratchBuffer); ESHK(shkp)->following = false; return 0; } if (!ESHK(shkp)->robbed) { /* impossible? */ ESHK(shkp)->following = false; return 0; } if (moves > followmsg+4) { StrPrintF(ScratchBuffer, "Hello %s! Didn't you forget to pay?", plname); message(ScratchBuffer); followmsg = moves; } if (udist < 2) return 0; } } shkroom = inroom(omx,omy); appr = 1; gx = ESHK(shkp)->shk.x; gy = ESHK(shkp)->shk.y; satdoor = (gx == omx && gy == omy); if (ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){ gx = you.ux; gy = you.uy; if (shkroom < 0 || shkroom != inroom(you.ux,you.uy)) if (udist > 4) return -1; /* leave it to m_move */ } else if (ANGRY(shkp)) { Long saveBlind = Blind; Blind = 0; if ((shkp->mcansee_and_blinded & M_CAN_SEE) && !Invis && cansee(omx,omy)) { gx = you.ux; gy = you.uy; } Blind = saveBlind; avoid = false; } else { #define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy)) if (Invis) avoid = false; else { uondoor = (you.ux == ESHK(shkp)->shd.x && you.uy == ESHK(shkp)->shd.y); if (uondoor) { if (ESHK(shkp)->billct) { StrPrintF(ScratchBuffer, "Hello %s! Will you please pay before leaving?", plname); message(ScratchBuffer); } badinv = (carrying(PICK_AXE) || carrying(ICE_BOX)); if (satdoor && badinv) return 0; avoid = !badinv; } else { avoid = (you.uinshop && dist(gx,gy) > 8); badinv = false; } if (((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid) && GDIST(omx,omy) < 3) { if (!badinv && !online(omx,omy)) return 0; if (satdoor) appr = gx = gy = 0; } } } if (omx == gx && omy == gy) return 0; if (shkp->bitflags & M_IS_CONFUSED) { avoid = false; appr = 0; } nix = omx; niy = omy; cnt = mfindpos(shkp,poss,info,ALLOW_SSM); if (avoid && uondoor) { /* perhaps we cannot avoid him */ for (i=0; i<cnt; i++) if (!(info[i] & NOTONL)) goto notonl_ok; avoid = false; notonl_ok: ; } chi = -1; chcnt = 0; for (i = 0 ; i < cnt ; i++) { nx = poss[i].x; ny = poss[i].y; if (get_cell_type(floor_info[nx][ny]) == ROOM || shkroom != ESHK(shkp)->shoproom || ESHK(shkp)->following) { #ifdef STUPID /* cater for stupid compilers */ Short zz; #endif STUPID if (uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) { nix = nx; niy = ny; chi = i; break; } if (avoid && (info[i] & NOTONL)) continue; if ((!appr && !rund(++chcnt)) || #ifdef STUPID (appr && (zz = GDIST(nix,niy)) && zz > GDIST(nx,ny)) #else (appr && GDIST(nx,ny) < GDIST(nix,niy)) #endif STUPID ) { nix = nx; niy = ny; chi = i; } } } if (nix != omx || niy != omy) { if (info[chi] & ALLOW_M){ mtmp = mon_at(nix,niy); if (hitmm(shkp,mtmp) == 1 && rund(3) && hitmm(mtmp,shkp) == 2) return 2; return 0; } else if (info[chi] & ALLOW_U){ hit_you(shkp, dice(mdat->damn, mdat->damd)+1); return 0; } shkp->mx = nix; shkp->my = niy; pmon(shkp); if (ib) { unlink_obj(ib);//freeobj mpickobj(shkp, ib); } return 1; } return 0; }
// What does the return value indicate?? Boolean dopay() { Long ltmp; bill_t *bp; monst_t *shkp; Short pass, tmp; multi = 0; inshop(); for (shkp = fmon ; shkp ; shkp = shkp->nmon) if ((shkp->bitflags & M_IS_SHOPKEEPER) && dist(shkp->mx,shkp->my) < 3) break; if (!shkp && you.uinshop && inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom) shkp = shopkeeper; if (!shkp) { message("There is nobody here to receive your payment."); return false; } ltmp = ESHK(shkp)->robbed; if (shkp != shopkeeper && NOTANGRY(shkp)) { if (!ltmp) { StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp)); message(ScratchBuffer); } else if (!you.ugold) { message("You have no money."); } else { Long ugold = you.ugold; if (you.ugold > ltmp) { StrPrintF(ScratchBuffer, "You give %s the %ld gold pieces he asked for.", monnam(shkp), ltmp); message(ScratchBuffer); pay(ltmp, shkp); } else { StrPrintF(ScratchBuffer, "You give %s all your gold.", monnam(shkp)); message(ScratchBuffer); pay(you.ugold, shkp); } if (ugold < ltmp/2) { message("Unfortunately, he doesn't look satisfied."); } else { ESHK(shkp)->robbed = 0; ESHK(shkp)->following = false; if (ESHK(shkp)->shoplevel != dlevel) { /* For convenience's sake, let him disappear */ shkp->minvent = NULL; /* %% */ // xxx leak? shkp->mgold = 0; mondead(shkp); } } } return true; } if (!ESHK(shkp)->billct) { StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp)); message(ScratchBuffer); if (!you.ugold) { message("Moreover, you have no money."); return true; } if (ESHK(shkp)->robbed) { message("But since his shop has been robbed recently,"); StrPrintF(ScratchBuffer, "you%srepay %s's expenses.", (you.ugold < ESHK(shkp)->robbed) ? " partially " : " ", monnam(shkp)); message(ScratchBuffer); pay(min(you.ugold, ESHK(shkp)->robbed), shkp); ESHK(shkp)->robbed = 0; return true; } if (ANGRY(shkp)) { StrPrintF(ScratchBuffer, "But in order to appease %s,", amonnam(shkp, "angry")); message(ScratchBuffer); if (you.ugold >= 1000) { ltmp = 1000; message(" you give him 1000 gold pieces."); } else { ltmp = you.ugold; message(" you give him all your money."); } pay(ltmp, shkp); if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ) || rund(3)){ StrPrintF(ScratchBuffer, "%s calms down.", Monnam(shkp)); message(ScratchBuffer); shkp->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; } else { StrPrintF(ScratchBuffer, "%s is as angry as ever.", Monnam(shkp)); message(ScratchBuffer); } } return true; } if (shkp != shopkeeper) { message("BUG: dopay: not to shopkeeper?"); if (shopkeeper) setpaid(); return false; } for (pass = 0 ; pass <= 1 ; pass++) { tmp = 0; while (tmp < ESHK(shopkeeper)->billct) { bp = &bill[tmp]; if (!pass && !bp->useup) { tmp++; continue; } if (!dopayobj(bp)) return true; bill[tmp] = bill[--ESHK(shopkeeper)->billct]; } } StrPrintF(ScratchBuffer, "Thank you for shopping in %s's %s store!", shkname(shopkeeper), shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]); shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; return true; }
UInt inshop() { Short roomno = inroom(you.ux,you.uy); /* Did we just leave a shop? */ if (you.uinshop && (you.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) { if (shopkeeper) { if (ESHK(shopkeeper)->billct) { if (inroom(shopkeeper->mx, shopkeeper->my) == you.uinshop - 1) /* ab@unido */ message("Somehow you escaped the shop without paying!"); addupbill(); StrPrintF(ScratchBuffer,"You stole for a total worth of %ld zorkmids.", total); message(ScratchBuffer); ESHK(shopkeeper)->robbed += total; setpaid(); if ((rooms[ESHK(shopkeeper)->shoproom].rtype == GENERAL) == (rund(3) == 0)) ESHK(shopkeeper)->following = true; } shopkeeper = NULL; shlevel = 0; } you.uinshop = 0; } /* Did we just enter a zoo of some kind? */ if (roomno >= 0) { Short rt = rooms[roomno].rtype; monst_t *mtmp; if (rt == ZOO) { message("Welcome to David's treasure zoo!"); } else if (rt == SWAMP) { message("It looks rather muddy down here."); } else if (rt == MORGUE) { if (midnight()) message("Go away! Go away!"); else message("You get an uncanny feeling ..."); } else rt = 0; if (rt != 0) { rooms[roomno].rtype = 0; for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon) if (rt != ZOO || !rund(3)) mtmp->bitflags &= ~M_IS_ASLEEP; } } /* Did we just enter a shop? */ if (roomno >= 0 && rooms[roomno].rtype >= 8) { if (shlevel != dlevel || !shopkeeper || ESHK(shopkeeper)->shoproom != roomno) findshk(roomno); if (!shopkeeper) { rooms[roomno].rtype = 0; you.uinshop = 0; } else if (!you.uinshop) { if (!ESHK(shopkeeper)->visitct || StrNCompare(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) { /* He seems to be new here */ ESHK(shopkeeper)->visitct = 0; ESHK(shopkeeper)->following = false; StrNCopy(ESHK(shopkeeper)->customer, plname, PL_NSIZ); shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; } if (!ESHK(shopkeeper)->following) { Boolean box, pick; StrPrintF(ScratchBuffer, "Hello %s! Welcome%sto %s's %s shop!", plname, ESHK(shopkeeper)->visitct++ ? " again " : " ", shkname(shopkeeper), shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8] ); message(ScratchBuffer); box = carrying(ICE_BOX); pick = carrying(PICK_AXE); if (box || pick) { if (do_chug(shopkeeper)) { you.uinshop = 0; /* he died moving */ return 0; } StrPrintF(ScratchBuffer, "Will you please leave your %s outside?", (box && pick) ? "box and pick-axe" : box ? "box" : "pick-axe"); message(ScratchBuffer); } } you.uinshop = roomno + 1; // (0 is "not in shop") } } return you.uinshop; }
// Note: this is a litte different, it will return true // iff the action is COMPLETE, and false if there was no action OR // the action is needing to finish up (after leaving SenseForm). // So if (do_drink) the caller should exit invform _and_ tick, // otherwise the caller should just exit invform. // (exiting the invform occurs _before_ calling do_drink..) // .. Ok, I've modified this again so that it lets the caller distinguish // between "it worked" and "it worked and I popped up EngraveForm". tri_val_t do_drink(obj_t *otmp) { obj_t *objs; // monst_t *mtmp; Boolean unkn = false, nothing = false, b; Short tmp; if (!otmp) return NO_OP; tmp = oc_descr_offset[otmp->otype]; if (tmp >= 0 && (0 == StrNCompare("smoky", oc_descrs+tmp, 5)) && !rund(13)) { ghost_from_bottle(); useup(otmp); return DONE; } switch(otmp->otype) { case POT_RESTORE_STRENGTH: unkn = true; message("Wow! This makes you feel great!"); if (you.ustr < you.ustrmax) { you.ustr = you.ustrmax; flags.botl |= BOTL_STR; } break; case POT_BOOZE: unkn = true; message("Ooph! This tastes like liquid fire!"); Confusion += dice(3,8); /* the whiskey makes us feel better */ if (you.uhp < you.uhpmax) losehp(-1, "bottle of whiskey"); if (!rund(4)) { tri_val_t t; // Short coma; message("You pass out."); multi = -rnd(15); spin_multi("You awake with a headache."); // coma = rnd(15); // // do { tick(); } while (--coma > 0); // message("You awake with a headache."); // // nomovemsg = "You awake with a headache."; t = finish_do_drink(otmp, nothing, unkn); //.... I guess.... return (t==DONE ? NO_OP : t); // so that we don't take any _more_ turns } break; case POT_INVISIBILITY: if (Invis || See_invisible) nothing = true; else { if (!Blind) message("Gee! All of a sudden, you can't see yourself."); else { message("You feel rather airy."); unkn = true; } newsym(you.ux,you.uy); } Invis += rund(15)+31; break; case POT_FRUIT_JUICE: message("This tastes like fruit juice."); lesshungry(20); break; case POT_HEALING: message("You begin to feel better."); you.uhp += rnd(10); if (you.uhp > you.uhpmax) you.uhp = ++you.uhpmax; if (Blind) Blind = 1; /* you'll see again on the next move */ if (Sick) Sick = 0; flags.botl |= BOTL_HP; break; case POT_PARALYSIS: if (Levitation) message("You are motionlessly suspended."); else message("Your feet are frozen to the floor!"); nomul(-(rund(10)+25)); break; case POT_MONSTER_DETECTION: if (!fmon) { b = strange_feeling(otmp, "You feel threatened."); return ((b) ? GO_ON : DONE); } else { sense_what = SENSE_MONSTERS; sense_by_what = otmp; sense_init_screen(); FrmPopupForm(SenseForm); return GO_ON; // to postpone the tick! } break; case POT_OBJECT_DETECTION: if (!fobj) { b = strange_feeling(otmp, "You feel a pull downward."); return ((b) ? GO_ON : DONE); } else { for (objs = fobj; objs; objs = objs->nobj) if (objs->ox != you.ux || objs->oy != you.uy) { sense_what = SENSE_OBJECTS; sense_by_what = otmp; sense_init_screen(); FrmPopupForm(SenseForm); return GO_ON; // to postpone the tick! } message("You sense the presence of objects close nearby."); break; } break; case POT_SICKNESS: message("Yech! This stuff tastes like poison."); if (Poison_resistance) message("(But in fact it was biologically contaminated orange juice.)"); losestr(rund(4)+3); losehp(rnd(10), "contaminated potion"); flags.botl |= BOTL_STR; break; case POT_CONFUSION: if (!Confusion) message("Huh, What? Where am I?"); else nothing = true; Confusion += rund(7)+16; break; case POT_GAIN_STRENGTH: message("Wow do you feel strong!"); if (you.ustr >= 118) break; /* > 118 is impossible */ if (you.ustr > 17) you.ustr += rnd(118-you.ustr); else you.ustr++; if (you.ustr > you.ustrmax) you.ustrmax = you.ustr; flags.botl |= BOTL_STR; break; case POT_SPEED: if (Wounded_legs) { heal_legs(); unkn = true; break; } if (!(Fast & ~INTRINSIC)) message("You are suddenly moving much faster."); else { message("Your legs get new energy."); unkn = true; } Fast += rund(10)+100; break; case POT_BLINDNESS: if (!Blind) message("A cloud of darkness falls upon you."); else nothing = true; Blind += rund(100)+250; seeoff(false); break; case POT_GAIN_LEVEL: pluslvl(); break; case POT_EXTRA_HEALING: message("You feel much better."); you.uhp += dice(2,20)+1; if (you.uhp > you.uhpmax) you.uhp = (you.uhpmax += 2); if (Blind) Blind = 1; if (Sick) Sick = 0; flags.botl |= BOTL_HP; break; case POT_LEVITATION: if (!Levitation) float_up(); else nothing = true; Levitation += rnd(100); // you.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down; // UNNEEDED, // it has been replaced by tweaking timeout.c to call float_down directly! break; default: StrPrintF(ScratchBuffer, "What a funny potion! (%u)", otmp->otype); message(ScratchBuffer); return NO_OP; } return finish_do_drink(otmp, nothing, unkn); }