diff -burN nethack-orig/include/decl.h nethack/include/decl.h --- nethack-orig/include/decl.h 2003-12-07 18:39:13.000000000 -0500 +++ nethack/include/decl.h 2010-04-14 13:13:09.752615380 -0400 @@ -190,6 +190,7 @@ E NEARDATA char catname[]; E NEARDATA char horsename[]; E char preferred_pet; +E NEARDATA char pet_monster[64]; E const char *occtxt; /* defined when occupation != NULL */ E const char *nomovemsg; E const char nul[]; diff -burN nethack-orig/src/decl.c nethack/src/decl.c --- nethack-orig/src/decl.c 2003-12-07 18:39:13.000000000 -0500 +++ nethack/src/decl.c 2010-04-14 13:13:24.208641324 -0400 @@ -202,6 +202,7 @@ NEARDATA char catname[PL_PSIZ] = DUMMY; NEARDATA char horsename[PL_PSIZ] = DUMMY; char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */ +NEARDATA char pet_monster[64] = DUMMY; /* Name of monster for pet */ /* monsters that went down/up together with @ */ NEARDATA struct monst *mydogs = (struct monst *)0; /* monsters that are moving to another dungeon level */ diff -burN nethack-orig/src/dog.c nethack/src/dog.c --- nethack-orig/src/dog.c 2003-12-07 18:39:13.000000000 -0500 +++ nethack/src/dog.c 2010-04-14 13:32:33.792622976 -0400 @@ -134,10 +134,105 @@ const char *petname; int pettype; static int petname_used = 0; + char buf[BUFSZ]; + int pet_try = 0; if (preferred_pet == 'n') return((struct monst *) 0); pettype = pet_type(); + + if (preferred_pet == 'a') + { + do + { + if (pet_try == 0) + { + getlin("What type of pet would you like?", buf); + } + else + { + getlin("Try again. What type of pet would you like?", + buf); + } + + (void) mungspaces(buf); + (void) lcase(buf); + + if (strlen(buf) == 0) + { + preferred_pet = 'r'; + break; + } + + pettype = name_to_mon(buf); + + if (pettype < LOW_PM) + { + pline("I've never heard of such monsters."); + } + else if (!polyok(&mons[pettype])) + { + pline("A pet %s is not allowed.", buf); + } + else + { + break; + } + + pet_try++; + } while(pet_try < 5); + } + + if (pet_try == 5) + { + pline("That's enough tries."); + preferred_pet = 'r'; + } + + if (preferred_pet == 'm') + { + if (strlen(pet_monster) == 0) + { + preferred_pet = 'r'; + } + + pettype = name_to_mon(pet_monster); + + if (pettype < LOW_PM) + { + pline("I've never heard of such monsters."); + preferred_pet = 'r'; + } + else if (!polyok(&mons[pettype])) + { + pline("A pet %s is not allowed.", buf); + preferred_pet = 'r'; + } + } + + if (preferred_pet == 'r') + { + do + { + pettype = rn1(SPECIAL_PM - LOW_PM, LOW_PM); + } while(!polyok(&mons[pettype])); + } + +#ifdef STEED + if (preferred_pet == 's') + { + mtmp = malloc(sizeof(struct monst)); + + do + { + pettype = rn1(SPECIAL_PM - LOW_PM, LOW_PM); + mtmp->data = &mons[pettype]; + } while((!polyok(&mons[pettype])) || (!can_saddle(mtmp))); + + free(mtmp); + } +#endif + if (pettype == PM_LITTLE_DOG) petname = dogname; else if (pettype == PM_PONY) @@ -159,14 +254,17 @@ if(!mtmp) return((struct monst *) 0); /* pets were genocided */ #ifdef STEED - /* Horses already wear a saddle */ - if (pettype == PM_PONY && !!(otmp = mksobj(SADDLE, TRUE, FALSE))) { + /* Rideable pets come with a saddle if the character has any riding + skill */ + if ((P_SKILL(P_RIDING) >= P_BASIC) && can_saddle(mtmp) && + !!(otmp = mksobj(SADDLE, TRUE, FALSE))) { if (mpickobj(mtmp, otmp)) panic("merged saddle?"); mtmp->misc_worn_check |= W_SADDLE; otmp->dknown = otmp->bknown = otmp->rknown = 1; otmp->owornmask = W_SADDLE; otmp->leashmon = mtmp->m_id; + petname = horsename; update_mon_intrinsics(mtmp, otmp, TRUE, TRUE); } #endif diff -burN nethack-orig/src/options.c nethack/src/options.c --- nethack-orig/src/options.c 2003-12-07 18:39:13.000000000 -0500 +++ nethack/src/options.c 2010-04-14 13:36:53.708621541 -0400 @@ -288,7 +288,7 @@ 15, SET_IN_FILE }, # endif #endif - { "pettype", "your preferred initial pet type", 4, DISP_IN_GAME }, + { "pettype", "your preferred initial pet type", 64, DISP_IN_GAME }, { "pickup_burden", "maximum burden picked up before prompt", 20, SET_IN_GAME }, { "pickup_types", "types of objects to pick up automatically", @@ -1036,9 +1036,12 @@ fullname = "pettype"; if (match_optname(opts, fullname, 3, TRUE)) { + (void) mungspaces(op); + (void) lcase(op); if ((op = string_for_env_opt(fullname, opts, negated)) != 0) { - if (negated) bad_negation(fullname, TRUE); - else switch (*op) { + if (strlen(op) == 1) + { + switch (*op) { case 'd': /* dog */ case 'D': preferred_pet = 'd'; @@ -1053,10 +1056,56 @@ case 'N': preferred_pet = 'n'; break; + case 'a': /* ask */ + case 'A': + preferred_pet = 'a'; + break; + case 's': /* steed */ + case 'S': + preferred_pet = 's'; + break; + case 'r': /* random */ + case 'R': + preferred_pet = 'r'; + break; default: pline("Unrecognized pet type '%s'.", op); break; } + } + else + { + if (strcmp(op, "dog") == 0) + { + preferred_pet = 'd'; + } + else if ((strcmp(op, "cat") == 0) || + (strcmp(op, "feline") == 0)) + { + preferred_pet = 'd'; + } + else if (strcmp(op, "none") == 0) + { + preferred_pet = 'n'; + } + else if (strcmp(op, "ask") == 0) + { + preferred_pet = 'a'; + } + else if (strcmp(op, "steed") == 0) + { + preferred_pet = 's'; + } + else if (strcmp(op, "random") == 0) + { + preferred_pet = 'r'; + } + else /* Specific pet specified */ + { + strncpy(pet_monster, op, 63); + preferred_pet = 'm'; /* Monster */ + } + } } else if (negated) preferred_pet = 'n'; return; } @@ -3047,6 +3096,9 @@ else if (!strcmp(optname, "pettype")) Sprintf(buf, "%s", (preferred_pet == 'c') ? "cat" : (preferred_pet == 'd') ? "dog" : + (preferred_pet == 'a') ? "ask" : + (preferred_pet == 's') ? "steed" : + (preferred_pet == 'r') ? "random" : (preferred_pet == 'n') ? "none" : "random"); else if (!strcmp(optname, "pickup_burden")) Sprintf(buf, "%s", burdentype[flags.pickup_burden] );