1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-08-13 08:01:40 +01:00

Add armorsmith hopefully with a less buggy implementation.

This commit is contained in:
demogorgon22 2021-10-01 12:52:27 -04:00
parent 22d959303a
commit 5a0359ef15
5 changed files with 226 additions and 3 deletions

View file

@ -217,6 +217,23 @@ Anachrononaut changes
until repaired with an upgrade kit resized to fit you or
another monster.
Starts with a potion vaporizer and some potions.
Added armorsmiths
Armorsmiths are meant to address the weird gap caused by
upgrade kits for strangely sized races
Maybe you'll find one in an adventure town
Charge a price to provide various services
Armor repair
Remove damage from armor
Shrink armor
Lowers the size of an armor piece by 1 level
Grow armor
Increases the size of an armor piece by 1 level
Requires an armor piece of the same type to be
combined
Change Shape
Change the shape (barded/segmented/centaur) of a piece
of armor
Requires a corpse or figurine reference item if not using your shape
Dungeon Changes
Neutral Quest changes
Branch to spire from the spire in the outlands.
@ -295,8 +312,5 @@ Dungeon Changes
Ait Crystal - Shocking, 2x lightning damage
Earth Crystal - Flaying
Black Crystal - Sparkling, 2x magic damage
General changes
Red dragon scale based armor now grants flying.

View file

@ -65,6 +65,7 @@
#define MS_HARROW 54 /* Summon wraiths */
#define MS_APOC 55 /* Dire Revelations */
#define MS_TATTOO 56 /* Tattoos service */
#define MS_SMITH 57 /* Armorsmith service */
#define MR_FIRE 0x0001 /* 1 resists fire */

View file

@ -7089,6 +7089,13 @@ int faction;
case 4: (void) mongets(mtmp, POT_HEALING, mkobjflags);
case 5: (void) mongets(mtmp, POT_EXTRA_HEALING, mkobjflags);
}
} else if (ptr->mtyp == PM_ARMORSMITH) {
(void) mongets(mtmp, WAR_HAMMER,mkobjflags);
(void) mongets(mtmp, CHAIN_MAIL,mkobjflags);
(void) mongets(mtmp, HELMET,mkobjflags);
(void) mongets(mtmp, GLOVES,mkobjflags);
(void) mongets(mtmp, HIGH_BOOTS,mkobjflags);
(void) mongets(mtmp, CLOAK,mkobjflags);
} else if (ptr->msound == MS_PRIEST ||
quest_mon_represents_role(ptr,PM_PRIEST)
) {

View file

@ -5692,6 +5692,14 @@ struct permonst _mons2[] = {
0 /*MM*/, MT_OMNIVORE|MT_PEACEFUL|MT_COLLECT|MT_MAGIC /*MT*/, MF_MARTIAL_B /*MF*/,
MB_HUMANOID|MB_STRONG /*MB*/, MG_NOWISH|MG_NOPOLY|MG_INFRAVISIBLE /*MG*/,
MA_HUMAN /*MA*/, MV_NORMAL /*MV*/, HI_DOMESTIC),
MON("armorsmith", S_HUMAN,//18
LVL(12, 8, 50, 0), G_NOGEN, /*level raised so as to avoid being attacked by horses*/
DEF(SPE_AC(10)),
A(ATTK(AT_WEAP, AD_PHYS, 4, 4), ATTK(AT_XWEP, AD_PHYS, 4, 4)),
SIZ(WT_HUMAN, 400, MS_SMITH, MZ_HUMAN), 0, 0,
0 /*MM*/, MT_OMNIVORE|MT_PEACEFUL|MT_COLLECT|MT_MAGIC /*MT*/, MF_MARTIAL_B /*MF*/,
MB_HUMANOID|MB_STRONG /*MB*/, MG_NOWISH|MG_NOPOLY|MG_INFRAVISIBLE /*MG*/,
MA_HUMAN /*MA*/, MV_NORMAL /*MV*/, HI_DOMESTIC),
MON("guard", S_HUMAN,//14 /*Needs encyc entry*/
LVL(12, 12, 40, 10), G_NOGEN,
DEF(NAT_AC(0)),

View file

@ -54,12 +54,15 @@ static int NDECL(donursemenu);
static int NDECL(dorendermenu);
static int FDECL(dodollmenu, (struct monst *));
static int FDECL(dotatmenu, (const char *));
static int FDECL(dosmithmenu, (const char *));
static boolean FDECL(smith_offer_price, (long charge, struct monst *));
static boolean FDECL(nurse_services,(struct monst *));
static boolean FDECL(render_services,(struct monst *));
static boolean FDECL(buy_dolls,(struct monst *));
static const char tools[] = { TOOL_CLASS, 0 };
static const char models[] = { TOOL_CLASS, FOOD_CLASS, 0 };
static const char armors[] = { ARMOR_CLASS, 0 };
#endif /* OVLB */
@ -921,6 +924,153 @@ boolean chatting;
//if(original_tats != u.utats) achieve.inked_up = 1;
break;
}
case MS_SMITH:{
if(!mtmp->mpeaceful){
verbalize("Begone!");
break;
}
int seenSeals = countCloseSigns(mtmp);
int selection = dosmithmenu("Are you interested in a service?");
struct obj *obj; /* The object to smith */
struct obj *obj2; /* The object to use */
long charge;
long bodytype;
boolean made_purchase = FALSE;
switch(selection){
case 1: //shrink
if ( !(obj = getobj(armors, "have shrunk"))) break;
if(obj->owornmask){
verbalize("I can't work on armor you are wearing!");
break;
}
if (Is_dragon_scales(obj)){
verbalize("Dragon scales cannot be resized.");
}
if(obj->objsize == MZ_TINY){
verbalize("That's already as small as it gets!");
break;
}
charge = 520 * (seenSeals + 1) * (obj->oartifact?2:1);
if (smith_offer_price(charge, mtmp) == FALSE) break;
if(obj->objsize == MZ_GIGANTIC) obj->objsize = MZ_HUGE;
else obj->objsize--;
verbalize("Shrunk her down!");
made_purchase = TRUE;
break;
case 2://grow armor
if ( !(obj = getobj(armors, "have grown"))) break;
if(obj->owornmask){
verbalize("I can't work on armor you are wearing!");
break;
}
if (Is_dragon_scales(obj)){
verbalize("Dragon scales cannot be resized.");
}
if(obj->objsize == MZ_GIGANTIC){
verbalize("That's already as big as it gets!");
break;
}
if ( !(obj2 = getobj(armors, "have combined"))) break;
if(obj == obj2){
verbalize("I can't combine that with itself!");
break;
}
if(obj2->oartifact){
verbalize("That's too powerful for me to combine.");
break;
}
if(obj2->otyp != obj->otyp){
verbalize("I need an armor of the same type.");
break;
}
charge = 520 * (seenSeals + 1) * (obj->oartifact?2:1);
if (smith_offer_price(charge, mtmp) == FALSE) break;
delobj(obj2);
if(obj->objsize == MZ_HUGE) obj->objsize = MZ_GIGANTIC;
else obj->objsize++;
verbalize("Combined em!");
made_purchase = TRUE;
break;
case 3://repair armor
if ( !(obj = getobj(armors, "have repaired"))) break;
if(obj->owornmask){
verbalize("I can't work on armor you are wearing!");
break;
}
if(!(obj->oeroded || obj->oeroded2)){
verbalize("Can't do anything for that bud.");
verbalize("It isn't damaged.");
break;
}
charge = 240 * (seenSeals + 1);
if (smith_offer_price(charge, mtmp) == FALSE) break;
obj->oeroded = obj->oeroded2 = 0;
verbalize("All good now!");
made_purchase = TRUE;
break;
case 4: // reshape armor
if ( !(obj = getobj(armors, "have reshaped"))) break;
if(obj->owornmask){
verbalize("I can't work on armor you are wearing!");
break;
}
if(!(is_suit(obj) || is_shirt(obj) || is_helmet(obj) || Is_dragon_scales(obj))) {
verbalize("I can't reshape that.");
break;
}
struct permonst *ptr = youracedata;
if(yn("Resize the armor to your body shape?") != 'y'){
if ( !(obj2 = getobj(models, "have used as a model"))) break;
if(obj2->otyp != CORPSE && obj2->otyp!=FIGURINE){
verbalize("I need a corpse or figurine to use as a model.");
break;
}
ptr = &mons[obj2->corpsenm];
}
if (is_shirt(obj) || obj->otyp == ELVEN_TOGA){
//Check that the monster can actually have armor that fits it.
if(!(ptr->mflagsb&MB_BODYTYPEMASK)){
verbalize("I can't figure out how to make it fit.");
break;
}
if(obj->otyp == BODYGLOVE)
bodytype = (ptr->mflagsb&MB_BODYTYPEMASK);
else
bodytype = (ptr->mflagsb&MB_HUMANOID) ? MB_HUMANOID : (ptr->mflagsb&MB_BODYTYPEMASK);
}
else if (is_suit(obj)){
//Check that the monster can actually have armor that fits it.
if(!(ptr->mflagsb&MB_BODYTYPEMASK)){
verbalize("I can't figure out how to make it fit.");
break;
}
bodytype = (ptr->mflagsb&MB_BODYTYPEMASK);
}
else if (is_helmet(obj)){
//Check that the monster can actually have armor that fits it.
if(!has_head(ptr)){
verbalize("I can't reshape a hat to fit something without a head!");
break;
}
bodytype = (ptr->mflagsb&MB_HEADMODIMASK);
}
if(obj->bodytypeflag == bodytype){
verbalize("It's already shaped that way!");
break;
}
charge = 520 * (seenSeals + 1) * (obj->oartifact?2:1);
if (smith_offer_price(charge, mtmp) == FALSE) break;
obj->bodytypeflag = bodytype;
verbalize("Reshaped!");
made_purchase = TRUE;
break;
default:
break;
}
//if(made_purchase) achieve.used_smith = 1;
break;
}
case MS_ORACLE:
return doconsult(mtmp);
case MS_PRIEST: /*Most (all?) things with this will have ispriest set*/
@ -2527,6 +2677,49 @@ tat_to_name(int tat){
}
}
int
dosmithmenu(prompt)
const char *prompt;
{
winid tmpwin;
int n, how;
char buf[BUFSZ];
menu_item *selected;
anything any;
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any.a_void = 0; /* zero out all bits */
Sprintf(buf, "Services: ");
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_BOLD, buf, MENU_UNSELECTED);
Sprintf(buf, "Shrink Armor");
any.a_int = 1; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
's', 0, ATR_NONE, buf,
MENU_UNSELECTED);
Sprintf(buf, "Grow Armor");
any.a_int = 2; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'g', 0, ATR_NONE, buf,
MENU_UNSELECTED);
Sprintf(buf, "Repair Armor");
any.a_int = 3; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'r', 0, ATR_NONE, buf,
MENU_UNSELECTED);
Sprintf(buf, "Reshape Armor");
any.a_int = 4; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'e', 0, ATR_NONE, buf,
MENU_UNSELECTED);
end_menu(tmpwin, prompt);
how = PICK_ONE;
n = select_menu(tmpwin, how, &selected);
destroy_nhwindow(tmpwin);
return (n > 0) ? selected[0].item.a_int : 0;
}
static const short command_chain[][2] = {
{ PM_ORC, PM_ORC_CAPTAIN }, { PM_HILL_ORC, PM_ORC_CAPTAIN }, { PM_MORDOR_ORC, PM_ORC_CAPTAIN },
{ PM_ORC_CAPTAIN, PM_BOLG },