#include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "mud.h" /* Used in forest/woods areas */ void do_chop (CHAR_DATA *ch, char *argy) { SINGLE_OBJECT *axe; int material; bool found = TRUE; DEFINE_COMMAND( "chop", do_chop, POSITION_STANDING, 0, LOG_NORMAL, "This command is used by players to chop down trees to build stuff.") if (IS_MOB(ch)) return; if(!ch->in_room) return; if((axe = get_item_held(ch,ITEM_WEAPON)) == NULL || axe->pIndexData->made_of == 0 || !is_name("axe", axe->pIndexData->name)) { send_to_char("You must be holding a forged axe to chop down trees!\n\r", ch); return; } material = axe->pIndexData->made_of; if (ch->in_room->sector_type != SECT_FOREST && ch->in_room->sector_type != SECT_WOODS && ch->in_room->sector_type != SECT_BRUSH) { found = FALSE; } if (number_range(1,3) != 2 || !check_skill(ch, gsn_chop)) { found = FALSE; } if (ch->pcdata->online_spot->chopped > 200 && LEVEL(ch) < 100) { found = FALSE; } if (!IS_SET(ch->in_room->room_flags, ROOM_MINERALS)) { found = FALSE; } if (!found) { send_to_char("You look around for something to chop down, but find nothing worth cutting.", ch); WAIT_STATE(ch, 3*PULSE_VIOLENCE); return; } else { int vnum; SINGLE_OBJECT *log; vnum = 551 + number_range(0,UMIN(9, material+1)); send_to_char("CHOP!\n\r CHOP!\n\r CHOP!\n\r\n\n\n TIIIMMMMMBBBBEEERRRR!!!!.\n\r", ch); if ((log = create_object(get_obj_index(vnum),1)) == NULL) { char buf[100]; sprintf(buf, "There seems to be an error with vnum %d.\n\r", vnum); send_to_char(buf, ch); send_to_char("Report this to an admin please.\n\r", ch); return; } else { log = create_object(get_obj_index(vnum),1); obj_to(log, ch->in_room); if (number_range(1,7) == 3) REMOVE_BIT(ch->in_room->room_flags, ROOM_MINERALS); ch->pcdata->online_spot->chopped++; WAIT_STATE(ch, 3*PULSE_VIOLENCE); } } return; } /* Need hammer and wood to use */ void do_build (CHAR_DATA *ch, char *argy) { DEFINE_COMMAND( "build", do_build, POSITION_STANDING, 0, LOG_NORMAL, "This command is used by players to build machines to make stuff.") send_to_char("Not ready yet.\n\r", ch); return; } void do_graft (CHAR_DATA *ch, char *argy) { DEFINE_COMMAND( "graft", do_graft, POSITION_STANDING, 0, LOG_NORMAL, "This command lets you enhance gems that you have.") send_to_char("Not ready yet.\n\r", ch); return; } void do_tan (CHAR_DATA *ch, char *argy) { DEFINE_COMMAND( "tan", do_tan, POSITION_STANDING, 0, LOG_NORMAL, "This command is used by players to make clothing from animal skins.") send_to_char("Not ready yet.\n\r", ch); return; } /* When certain kinds of animals leave corpses, they can be skinned... based on the name of the animal only certain kinds of animals have valuable skins. */ void do_skin (CHAR_DATA *ch, char *argy) { SINGLE_OBJECT *knife; SINGLE_OBJECT *obj; SINGLE_OBJECT *skin; char arg1[STD_LENGTH]; int skin_type = 0; int material = 0; int i = 0; bool found = FALSE; DEFINE_COMMAND( "skin", do_skin, POSITION_STANDING, 0, LOG_NORMAL, "This command is used by players to make animal pelts out of corpses.") if (IS_MOB(ch)) return; if(!ch->in_room) return; argy = one_argy(argy, arg1); if (arg1[0] == '\0') { send_to_char ("Skin <creature name>\n\r", ch); return; } for (i = 0; str_cmp(hide_types[i].name, "end_of_list") && i < 20; i ++) { if (!str_cmp(arg1, hide_types[i].name)) { skin_type = i+1; break; } } if (skin_type == 0) { send_to_char("Exactly what kind of animal skin did you want to make?\n\r", ch); return; } for(obj = ch->in_room->contents; obj != NULL; obj = obj->next_content) { if (obj->pIndexData->item_type == ITEM_CORPSE_NPC && is_name(hide_types[i].name, obj->short_descr)) { skin = obj; found = TRUE; break; } } if (!found) { send_to_char("There is no corpse of that type here.\n\r", ch); return; } if((knife = get_item_held(ch,ITEM_WEAPON)) == NULL || (material = knife->pIndexData->made_of) == 0 || !is_name("dagger", knife->pIndexData->name) ) { send_to_char("You must be holding a forged dagger to skin corpses!\n\r", ch); obj_from(obj); free_it(obj); return; } if (!check_skill(ch, gsn_skin)) { send_to_char("You fail to skin the corpse correctly, ruining it.\n\r", ch); return; } if (skin_type > (material+1)) { send_to_char("You attempt to skin the hide, but your knife is not powerful enough!\n\rYou ruin the corpse.\n\r", ch); obj_from(obj); free_it(obj); return; } { int vnum; SINGLE_OBJECT *skin; vnum = 90700 + 20*skin_type + 12; send_to_char("You carefully remove the hide from the corpse.\n\r", ch); obj_from(obj); free_it(obj); if ((skin = create_object(get_obj_index(vnum),1)) == NULL) { char buf[100]; sprintf(buf, "There seems to be an error with vnum %d.\n\r", vnum); send_to_char(buf, ch); send_to_char("Report this to an admin please.\n\r", ch); return; } else { skin = create_object(get_obj_index(vnum),1); obj_to(skin, ch); WAIT_STATE(ch, 3*PULSE_VIOLENCE); } } return; } /* Gather materials from field/sheep/grassland/savannah */ /* You always need 5 pieces of raw materials to weave something. */ void do_weave (CHAR_DATA *ch, char *argy) { SINGLE_OBJECT *loom = NULL; SINGLE_OBJECT *obj; SINGLE_OBJECT *obj_next; int num_have = 0; int num_needed = 5; bool found = FALSE; char arg1[STD_LENGTH]; int i; int cloth_type = 0; DEFINE_COMMAND( "weave", do_weave, POSITION_STANDING, 0, LOG_NORMAL, "This command is used by players to weave cloth out of raw materials.") if (IS_MOB(ch)) return; argy = one_argy(argy, arg1); if (arg1[0] == '\0' || arg1 == "") { send_to_char ("Weave <cloth type>\n\r", ch); return; } for (i = 0; str_cmp(cloth_types[i].name, "end_of_list") && i < 20; i ++) { if (!str_cmp(arg1, cloth_types[i].name)) { cloth_type = i+1; break; } } if (cloth_type == 0) { send_to_char("Exactly what kind of cloth did you want to weave?\n\r", ch); return; } for(obj = ch->in_room->contents; obj != NULL; obj = obj->next_content) { if (obj->pIndexData->item_type == ITEM_FURNITURE && ((I_FURNITURE *) obj->more)->type == FURN_LOOM) { loom = obj; found = TRUE; break; } } if (!found) { send_to_char("You need a loom in the room in order to weave!\n\rGo build one!\n\r", ch); return; } if (((I_FURNITURE *)loom->more)->portal_flags < cloth_type) { send_to_char("Your loom is not good enough to weave this type of material!\n\r", ch); return; } num_have = 0; for(obj = ch->in_room->contents; obj != NULL; obj = obj->next_content) { if (obj->pIndexData->item_type == ITEM_RAW && ((I_RAW *) obj->more)->type == RAW_FIBER && ((I_RAW *) obj->more)->rank == cloth_type) { num_have ++; } if (num_have >= num_needed) break; } if (num_have < num_needed) { send_to_char("You need five pieces of raw materials to weave that kind of cloth!\n\r", ch); return; } if (!check_skill(ch, gsn_weave)) { int num_lost = 0; send_to_char("You attempt to weave some cloth, but manage to get it all tangled up in the loom!\n\r", ch); for(obj = ch->in_room->contents; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if (obj->pIndexData->item_type == ITEM_RAW && ((I_RAW *) obj->more)->type == RAW_FIBER && ((I_RAW *) obj->more)->rank == cloth_type) { num_lost++; obj_from(obj); free_it(obj); if (num_lost > num_needed/2) break; } } } else { int num_lost = 0; int vnum = 91200 + 20*cloth_type + 13; SINGLE_OBJECT *cloth; send_to_char("Ok, you weave some cloth.\n\r", ch); for(obj = ch->in_room->contents; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if (obj->pIndexData->item_type == ITEM_RAW && ((I_RAW *) obj->more)->type == RAW_FIBER && ((I_RAW *) obj->more)->rank == cloth_type) { num_lost++; obj_from(obj); free_it(obj); if (num_lost >= num_needed) break; } } if ((cloth = create_object(get_obj_index(vnum),1)) == NULL) { char buf[500]; sprintf(buf, "There seems to be an error with vnum %d.\n\r", vnum); send_to_char(buf, ch); send_to_char("Report this to an admin please.\n\r", ch); return; } else { obj_to(cloth, ch); send_to_char("Enjoy it.\n\r", ch); } } return; } /* Make clothing using needles and objects build with build */ void do_stitch (CHAR_DATA *ch, char *argy) { DEFINE_COMMAND( "stitch", do_stitch, POSITION_STANDING, 0, LOG_NORMAL, "This command is used by players to make clothing out of cloth.") send_to_char("Not ready yet.\n\r", ch); return; } void do_forge(CHAR_DATA * ch, char * argy) { SINGLE_OBJECT *hammer = NULL; SINGLE_OBJECT *forge = NULL; SINGLE_OBJECT *anvil = NULL; SINGLE_OBJECT *obj; SINGLE_OBJECT *obj_next; SINGLE_OBJECT *forged_object; char arg1[STD_LENGTH]; char arg2[STD_LENGTH]; char buf[200]; int material = 0; int i = 0; int num_needed = -1; int num_chose = -1; int num_have = 0; int vnum = 0; DEFINE_COMMAND( "forge", do_forge, POSITION_STANDING, 0, LOG_NORMAL, "This command is used by players to forge equipment from minerals.") argy = one_argy(argy, arg1); argy = one_argy(argy, arg2); if (arg1 == "" || arg1[0] == '\0' || arg2 == "" || arg2[0] == '\0') { send_to_char("Forge what????\n\r", ch); return; } for (i = 0; str_cmp(materials[i].name, "END"); i++) { if(!str_cmp(materials[i].name, arg1)) { material = i+1; break; } } if (material == 0) { send_to_char("Forge an item using which kind of material?\n\r", ch); return; } if (!str_cmp(arg2, "chunk")) { send_to_char("You cannot forge a chunk.\n\r", ch); return; } for (i = 0; str_cmp(forged[i].name, "end_of_list"); i++) { if (!str_cmp(forged[i].name, arg2)) { num_chose = i; num_needed = forged[i].chunk_cost; break; } } if (num_chose == -1 || num_needed == -1) { send_to_char("You try and forge something unknown. Try making some kind of armor or weapon or something.\n\r", ch); return; } if (!ch->in_room) return; if (IS_PLAYER (ch)) { if ((hammer = get_item_held(ch, ITEM_TOOL)) == NULL) { send_to_char("You must be holding a forging hammer to forge!\n\r", ch); return; } if (!IS_SET(((I_TOOL *) hammer->more)->tool_type, TOOL_FORGING)) { send_to_char("You must be holding a forging hammer to forge!\n\r", ch); return; } if ((hammer->pIndexData->made_of < material && num_chose != 17 && num_chose != 18) || hammer->pIndexData->made_of < material-1) { send_to_char("That hammer is not powerful enough to forge what you want.\n\r", ch); return; } for(obj = ch->in_room->contents; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if (obj->pIndexData->item_type == ITEM_FURNITURE && (IS_SET(((I_FURNITURE *) obj->more)->type, FURN_ANVIL))) { anvil = obj; } if (obj->pIndexData->item_type == ITEM_FURNITURE && (IS_SET(((I_FURNITURE *) obj->more)->type, FURN_FORGE))) { forge = obj; } } if (IS_PLAYER(ch) && forge == NULL) { send_to_char("There is no forge here.\n\r", ch); return; } if (anvil == NULL || (anvil->pIndexData->made_of < material && num_chose != 17 && num_chose != 18) || (anvil->pIndexData->made_of < (material -1))) { send_to_char("There is no anvil here, or it is not powerful enough.\n\r", ch); return; } } for(obj = ch->carrying; obj != NULL; obj = obj->next_content) { if (obj->pIndexData->item_type == ITEM_RAW && ((I_RAW *) obj->more)->type == RAW_MINERAL && ((I_RAW *) obj->more)->rank == material) num_have ++; if (num_have >= num_needed) break; } if (num_have < num_needed) { sprintf(buf, "You need %d chunks of %s, and you only have %d here.\n\r", num_needed, materials[material-1].name, num_have); send_to_char(buf, ch); send_to_char("You don't seem to have enough minerals in the room to forge into the item you want.\n\r", ch); return; } send_to_char("Ok, you attempt to forge an item.\n\r", ch); if (!check_skill(ch, gsn_forge)) { send_to_char("You FAIL to forge the item! Some of the minerals are ruined.\n\r", ch); for(obj = ch->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if (obj->pIndexData->item_type == ITEM_RAW && ((I_RAW *) obj->more)->type == RAW_MINERAL && ((I_RAW *) obj->more)->rank == material && number_range(1,4) == 2) { obj_from(obj); free_it(obj); } } } else { sprintf(buf, "Ok, you forge your %s %s.\n\r", arg1, arg2); send_to_char(buf, ch); vnum = 90000 + (40 * (material-1)) + num_chose; if ((forged_object = create_object(get_obj_index(vnum),1)) == NULL) { sprintf(buf, "There seems to be an error with vnum %d.\n\r", vnum); send_to_char(buf, ch); send_to_char("Report this to an admin please.\n\r", ch); return; } else { obj_to(forged_object, ch); act ("$n forges $p!", ch, forged_object, NULL, TO_ROOM); send_to_char("Enjoy it.\n\r", ch); } num_have = 0; for(obj = ch->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if (obj->pIndexData->item_type == ITEM_RAW && ((I_RAW *) obj->more)->type == RAW_MINERAL && ((I_RAW *) obj->more)->rank == material) { obj_from(obj); free_it(obj); num_have++; } if(num_have >= num_needed) break; } if (num_chose == 17) { send_to_char("The old hammer you used is now useless and it disappears.\n\r", ch); obj_from(hammer); free_it(hammer); } if (num_chose == 18) { send_to_char("The old anvil you used is now useless and it disappears.\n\r", ch); obj_from(anvil); free_it(anvil); } return; } return; } void do_brew (CHAR_DATA * ch, char * argy) { SINGLE_OBJECT *mortar; SINGLE_OBJECT *pestle; SINGLE_OBJECT *herb; SINGLE_OBJECT *herb_next; SINGLE_OBJECT *potion; bool used_it = FALSE; int potion_vnum = 0; int potion_timer = 200; int rank = 0; SPELL_DATA *spell[3]; int pot_number[3]; /* The number of this spell in the potion info struct */ char arg[3][SML_LENGTH]; /* UP to 3 spells per potion so you need up to 10 ingredients for each spell so we check the ingredients for each spell separately */ bool has_ingredient[3][10]; int i,j; DEFINE_COMMAND( "brew", do_brew, POSITION_STANDING, 0, LOG_NORMAL, "This command is used by players to brew potions from herbs.") if (IS_MOB(ch)) return; WAIT_STATE(ch, 5*PULSE_VIOLENCE); /* Check to see if the player is actually trying to brew something legit */ if (argy == "" || argy[0] == '\0') { send_to_char("Brew what?\n\r", ch); return; } for(i=0; i < 3; i++) { arg[i][0] = '\0'; pot_number[i] = -1; argy = one_argy(argy, arg[i]); if (arg[i] != "" && arg[i][0] != '\0') { if ((spell[i] = skill_lookup(arg[i], -1)) == NULL) { send_to_char("Unknown spell name.\n\r", ch); return; } for (j = 0; (pot_info[j].gsn > 0); j++) { if(spell[i]->gsn == pot_info[j].gsn) { pot_number[i] = j; break; } } if(pot_number[i] == -1) { send_to_char("You cannot brew that kind of a potion.\n\r", ch); return; } if(ch->pcdata->learned[spell[i]->gsn] < pow.max_prac_spells) { send_to_char("You do not know how to cast that spell well enough to brew it into a potion.\n\r", ch); return; } } } if (pot_number[0] == -1 && pot_number[1] == -1 && pot_number[2] == -1) { send_to_char("You need to brew something, not just brew.\n\r", ch); return; } /* Make sure the player is holding the required pestle and mortar */ if ((pestle = get_item_held(ch, ITEM_TOOL)) == NULL || !IS_SET(((I_TOOL *)pestle->more)->tool_type, TOOL_PESTLE)) { send_to_char("You need to be holding a pestle to brew something.\n\r", ch); return; } if((mortar = get_obj_carry(ch, "mortar")) == NULL || !IS_SET(((I_CONTAINER *)mortar->more)->flags, CONT_MORTAR)) { send_to_char("You must be carrying a mortar with herbs in it to brew.\n\r", ch); return; } rank = UMIN(pestle->pIndexData->made_of, mortar->pIndexData->made_of); /* Check to see if the player equipment is powerful enough for what they want to make */ for (i = 0; i < 3; i++) { if (pot_number[i] != 1 && rank < pot_info[pot_number[i]].equipment_level) { char buff[SML_LENGTH]; sprintf(buff, "You need to have a mortar and pestle made of %s to brew this potion.\n\r", materials[pot_info[pot_number[i]].equipment_level].name); send_to_char(buff, ch); return; } } /* Set up our flag matrix... if the person is brewing a specific spell which is brewable and that spell requires an ingredient in that spot then the has_ingredient is false, otherwise it is true. */ for (i = 0; i < 10; i++) { for(j = 0; j < 3; j++) { if (pot_number[j] != -1 && pot_info[pot_number[j]].ingredients[i] != 0) has_ingredient[j][i] = FALSE; else has_ingredient[j][i] = TRUE; } } /* Now search the stuff inside the mortar for herbs. For each herb, it goes through all the needed potion ingredients for the potion and as it finds the herbs, it checks them off basically. If all of the things are true at the end, then we have all the stuff we need. */ for (herb = mortar->contains; herb != NULL; herb = herb->next_content) { used_it = FALSE; for (j = 0; j < 3 && !used_it; j++) { for (i = 0; i < 10 && !used_it; i++) { if(!has_ingredient[j][i]) { if (herb->pIndexData->item_type == ITEM_RAW && ((I_RAW *)herb->more)->type == RAW_HERB && ((I_RAW *)herb->more)->rank == pot_info[pot_number[j]].ingredients[i]) { has_ingredient[j][i] = TRUE; used_it = TRUE; } } } } } /* Now check to make sure we have the ingredients */ for(j = 0; j < 3; j++) { for (i= 0; i < 10; i++) { if (!has_ingredient[j][i]) { send_to_char("You do not have the proper ingredients for this potion.\n\r", ch); return; } } } /* Ok now check to make sure the person is good enough at brewing. */ if(!check_skill(ch, gsn_brew)) { send_to_char("You did not brew the ingredients correctly. Some of the herbs are ruined.\n\r", ch); for(herb = mortar->contains; herb != NULL; herb = herb_next) { herb_next = herb->next_content; if(number_range(1,8) == 3) { obj_from(herb); free_it(herb); } } return; } for(i=0;i<3;i++) { potion_vnum += pot_info[pot_number[i]].gsn; potion_timer = UMIN(potion_timer, pot_info[pot_number[i]].timer); } /* There are 15 potions starting at 750 we can use for this. */ potion_vnum = 750 + number_range(0,14); if((potion = create_object(get_obj_index(potion_vnum),1)) == NULL) { send_to_char("This does not exist. Tell an admin.\n\r", ch); return; } { I_POTION *pot = (I_POTION *)potion->more; pot->spell_level = UMAX(10, LEVEL(ch) - 10); potion->timer = potion_timer; for (i = 0; i < 3; i++) { if (spell[i] != NULL) pot->spells[i] = spell[i]->gsn; else pot->spells[i] = 0; } } send_to_char("You mix the ingredients and \x1b[1;31m!\x1b[1;37m!\x1b[1;31mPOOF\x1b[1;37m!\x1b[1;31m!\x1b[0;37m A potion appears.\n\r", ch); obj_from(potion); obj_to(potion, ch); /* Ok now the char has the stuff, we then get rid of the herbs and mortar */ for(herb = mortar->contains; herb != NULL; herb = herb_next) { herb_next = herb->next_content; obj_from(herb); free_it(herb); } obj_from(mortar); free_it(mortar); return; } void do_mine (CHAR_DATA *ch, char *argy) { bool found = TRUE; SINGLE_OBJECT *pickaxe; DEFINE_COMMAND( "mine", do_mine, POSITION_STANDING, 0, LOG_NORMAL, "This command is used by players to mine stuff from rooms and caves.") if (IS_PLAYER (ch)) { if ((pickaxe = get_item_held(ch, ITEM_TOOL)) == NULL || !IS_SET(((I_TOOL *)pickaxe->more)->tool_type, TOOL_PICKAXE)) { send_to_char("You must be holding a pickaxe to mine!\n\r", ch); return; } if (!actually_doing) { send_to_char("You begin to chip away at the rock.\n\r", ch); NEW_POSITION(ch, POSITION_MINING); ch->pcdata->tickcounts = number_range(10,45); return; } } ch->position = POSITION_STANDING; if (ch->in_room->sector_type != SECT_MOUNTAIN && ch->in_room->sector_type != SECT_HILLS && ch->in_room->sector_type != SECT_ROCKY && ch->in_room->sector_type != SECT_CANYON && ch->in_room->sector_type < SECT_CAVE) { found = FALSE; } if (IS_PLAYER (ch) && LEVEL(ch) < MAX_LEVEL) { if (!check_skill(ch, gsn_mine) || number_range(1,3) != 2) { found = FALSE; } if (ch->pcdata->online_spot->mined > 200) { found = FALSE; } if (!IS_SET(ch->in_room->room_flags, ROOM_MINERALS)) { found = FALSE; } } if (!found) { send_to_char("You hack away at the rock for a while, but find nothing.\n\r", ch); WAIT_STATE(ch, 3*PULSE_VIOLENCE); return; } else { int i; int vnum; SINGLE_OBJECT *chunk; send_to_char("You manage to break off a chunk of mineral.\n\r", ch); for (i=0;i < 15; i++) if (number_range(1,4) == 2) break; if (i >= 14) { if (number_range(1,4) != 2) i = number_range(0,10); else i = 14; } vnum = 90000 + (40 * i) + 19; if ((chunk = create_object(get_obj_index(vnum),1)) == NULL) { char buf[100]; sprintf(buf, "There seems to be an error with vnum %d.\n\r", vnum); send_to_char(buf, ch); send_to_char("Report this to an admin please.\n\r", ch); return; } else { chunk = create_object(get_obj_index(vnum),1); obj_to(chunk, ch); if (IS_PLAYER (ch)) { if (number_range(1,7) == 3) REMOVE_BIT(ch->in_room->room_flags, ROOM_MINERALS); ch->pcdata->online_spot->mined++; WAIT_STATE(ch, 3*PULSE_VIOLENCE); } } } return; } void do_enchant (CHAR_DATA *ch, char* argy) { char arg1[STD_LENGTH]; char arg2[STD_LENGTH]; char arg3[STD_LENGTH]; char buf[STD_LENGTH]; SINGLE_OBJECT *obj; AFFECT_DATA *paf; int location; int modifier; int cost = 0; int i; bool affected_already[30]; DEFINE_COMMAND( "enchant", do_enchant, POSITION_STANDING, 0, LOG_NORMAL, "This command lets you enchant items for specific enhancements.") if (IS_MOB(ch)) return; for (i = 0; i < 30; i++) affected_already[i] = FALSE; argy = one_argy(argy, arg1); if ((obj = get_obj_inv(ch, arg1)) == NULL) { send_to_char("You don't have that object in your inventory.\n\r", ch); return; } argy = one_argy(argy, arg2); if ((location = affect_name_loc (arg2)) == -99) { send_to_char("Unknown location.\n\r", ch); return; } if (LEVEL(ch) == MAX_LEVEL) { argy = one_argy(argy, arg3); if (is_number(arg3)) modifier = atoi(arg3); if (modifier > 100 || modifier < -100) { send_to_char("Modifiers must be between -100 and 100.\n\r", ch); return; } paf = new_affect (); paf->location = location; paf->modifier = modifier; paf->type = 1; paf->duration = 0; paf->next = obj->affected; obj->affected = paf; send_to_char ("Enchantment added.\n\r", ch); return; } else { if (obj->pIndexData->item_type != ITEM_WEAPON && obj->pIndexData->item_type != ITEM_ARMOR) { send_to_char("You can only enchant armor and weapons.\n\r", ch); return; } for (paf = obj->pIndexData->affected; paf != NULL; paf = paf->next) { affected_already[paf->location] = TRUE; if ((paf->location > 0 && paf->location < 6) || paf->location == APPLY_DAMROLL) affected_already[29] = TRUE; if (paf->location == APPLY_KICK_DAMAGE && paf->modifier >=3) affected_already[29] = TRUE; } if (ch->max_hit < 800) { send_to_char("You do not have enough health to enchant.\n\r", ch); return; } if (obj->pIndexData->item_type != ITEM_WEAPON && obj->pIndexData->item_type != ITEM_ARMOR) { send_to_char("You can only enchant armor and weapons.\n\r", ch); return; } if (obj->affected) { send_to_char("You attempt to enchant an item more than once and it implodes under the force!\n\r", ch); send_to_char("The Angel of the Anti-Cheater places \x1b[1;31mThe Bloody Dagger of Infinite Pain and Unbearable Suffering\x1b[0;37m into your back! OUCH!!!! That was *NOT* pleasant!\n\r", ch); obj_from(obj); free_it(obj); ch->hit = 1; return; } if(affected_already[location]) { send_to_char("That item already has that kind of enchantment, and cannot accept any more.\n\r", ch); return; } switch (location) { case APPLY_STR: case APPLY_DAMROLL: case APPLY_INT: case APPLY_WIS: case APPLY_DEX: { if (LEVEL(ch) < 60) { send_to_char("You are too weak to enchant something this powerful!\n\r", ch); return; } modifier = 1; cost = 100000; break; } case APPLY_CON: { send_to_char("Uh, no. Nice try tho.\n\r", ch); return; } break; case APPLY_HIT: case APPLY_MOVE: case APPLY_SNEAK: case APPLY_HIDE: { modifier = 3 + LEVEL(ch)/8; cost = 50000; break; } case APPLY_AC: case APPLY_SAVING_THROW: { modifier = -1 - LEVEL(ch)/37; cost = 10000; break; } case APPLY_HITROLL: { modifier = 1 + LEVEL(ch)/29; cost = 10000; break; } case APPLY_KICK_DAMAGE: { modifier = 1 + LEVEL(ch)/25; if (!CAN_WEAR(obj, ITEM_WEAR_FEET) && !CAN_WEAR(obj, ITEM_WEAR_ANKLE) && !CAN_WEAR(obj, ITEM_WEAR_LEGS) && !CAN_WEAR (obj, ITEM_WEAR_KNEE)) { send_to_char("You cannot put kickdam on a piece of eq worn here.\n\r", ch); return; } if (CAN_WEAR(obj, ITEM_WEAR_FEET) || CAN_WEAR(obj, ITEM_WEAR_LEGS)) { modifier = 1 + LEVEL(ch)/25; } else { modifier = 1 + LEVEL(ch)/45; } break; } default: cost = 1000000; modifier = 0; break; } if (!CAN_WEAR(obj, ITEM_WEAR_LEGS) && !CAN_WEAR(obj, ITEM_WEAR_ARMS) && !CAN_WEAR(obj, ITEM_WEAR_BODY) && !CAN_WEAR(obj, ITEM_WEAR_WAIST) && !CAN_WEAR(obj, ITEM_WEAR_HEAD) && !CAN_WEAR(obj, ITEM_WEAR_FEET) && !CAN_WEAR(obj, ITEM_WEAR_SHIELD)) cost *= 2; if (affected_already[29]) cost *=2; if (ch->pcdata->bank < cost) { sprintf(buf, "You need %d coins in the bank to put this enchantment on this item.\n\r", cost); send_to_char(buf, ch); return; } if (!check_skill(ch, gsn_enchant) || number_range(1,5) != 2) { send_to_char("You fail your enchantment.\n\r", ch); ch->pcdata->bank -= cost/20; if (number_range(1,20) == 3) { send_to_char("The object is destroyed!\n\r", ch); obj_from(obj); free_it(obj); ch->hit = 1; } return; } paf = new_affect (); paf->location = location; paf->modifier = modifier; paf->type = 1; paf->duration = 0; paf->next = obj->affected; obj->affected = paf; ch->max_hit--; ch->pcdata->bank -= cost; send_to_char ("Enchantment added.\n\r", ch); return; } return; } void do_empower (CHAR_DATA *ch, char* argy) { char arg1[STD_LENGTH]; char arg2[STD_LENGTH]; SINGLE_OBJECT *obj; SPELL_DATA *spl; SPELL_DATA *empower; DEFINE_COMMAND( "empower", do_empower, POSITION_STANDING, 0, LOG_NORMAL, "This command lets you make gems and weapons cast spells when held.") if (IS_MOB(ch)) return; argy = one_argy(argy, arg1); if ((obj = get_obj_inv(ch, arg1)) == NULL) { send_to_char("You don't have that object in your inventory.\n\r", ch); return; } if (obj->pIndexData->item_type != ITEM_GEM && obj->pIndexData->item_type != ITEM_WEAPON) { send_to_char("Only gems and weapons can be empowered.\n\r", ch); return; } if ((empower = skill_lookup("empower", -1)) == NULL) { send_to_char("Empower spell does not exist!\n\r", ch); return; } argy = one_argy(argy, arg2); if (LEVEL(ch) == MAX_LEVEL && !str_cmp(arg2, "none")) { if (obj->pIndexData->item_type == ITEM_GEM) { ((I_GEM *)obj->more)->casts_spell = 0; send_to_char("Spell removed from the item.\n\r", ch); return; } if (obj->pIndexData->item_type == ITEM_WEAPON) { ((I_WEAPON *)obj->more)->casts_spell = 0; send_to_char("Spell removed from the item.\n\r", ch); return; } send_to_char("Unknown item type...how did you do that?\n\r", ch); return; } if ((spl = skill_lookup(arg2, -1)) == NULL) { send_to_char("What spell are you attempting to put onto this item?\n\r", ch); return; } if (ch->pcdata->bank < 100000) { send_to_char("You need 1000 gold in the bank to empower something.\n\r", ch); return; } if (!check_skill(ch, empower->gsn)) { send_to_char("You fail to empower this item!\n\r", ch); return; } if (ch->pcdata->learned[spl->gsn] < 95) { send_to_char("You do not know the spell you are trying to infuse into the item well enough!\n\r", ch); return; } if (LEVEL(ch) < 3*spl->spell_level/2) { send_to_char ("You are not powerful enough to empower this spell. You must be at least 1.5 times as high as the minimum level to cast the spell.\n\r", ch); return; } if (spl->spell_type != TAR_CHAR_OFFENSIVE && !IS_SET(spl->spell_bits, SPELL_HEALS_DAM | SPELL_ADD_MOVE | SPELL_REMOVES_BIT)) { send_to_char ("The only kinds of spells you may empower are offensive and healing/curative spells.\n\r", ch); return; } if (obj->pIndexData->item_type == ITEM_GEM) { if (((I_GEM *)obj->more)->casts_spell != 0) { obj_from(obj); free_it(obj); send_to_char("You try to empower the gem again and it goes *poof*.\n\r", ch); return; } ((I_GEM *)obj->more)->casts_spell = spl->gsn; send_to_char("Spell added to the item.\n\r", ch); return; } else if (obj->pIndexData->item_type == ITEM_WEAPON) { if (((I_WEAPON *)obj->more)->casts_spell != 0) { obj_from(obj); free_it(obj); send_to_char("You try to empower the weapon again and it goes *poof*.\n\r", ch); return; } ((I_WEAPON *)obj->more)->casts_spell = spl->gsn; send_to_char("Spell added to the item.\n\r", ch); return; } send_to_char("Unknown item type...how did you do that?\n\r", ch); return; } void do_unenchant (CHAR_DATA *ch, char* argy) { SINGLE_OBJECT *obj; AFFECT_DATA *paf; DEFINE_COMMAND( "unenchant", do_unenchant, POSITION_STANDING, MAX_LEVEL, LOG_NORMAL, "This command lets you unenchant items and make them normal again.") if ((obj = get_obj_inv(ch, argy)) == NULL) { send_to_char("You don't have that object in your inventory.\n\r", ch); return; } paf = obj->affected; if (paf == NULL) { send_to_char("No enchantments to remove.\n\r", ch); return; } obj->affected = obj->affected->next; free_affect(paf); send_to_char("Ok, enchantment removed.\n\r", ch); return; } void do_lore (CHAR_DATA *ch, char* argy) { SPELL_DATA *spell; char arg1[SML_LENGTH]; int i; int potion_number = -1; char buff[SML_LENGTH]; bool used_this[10]; int total_num = 0; int num_used = 0; DEFINE_COMMAND( "lore", do_lore, POSITION_STANDING, 0, LOG_NORMAL, "This command lets you find out information on certain potions.") if (IS_MOB(ch)) return; for (i=0; i < 10; i++) used_this[i] = FALSE; arg1[0] = '\0'; argy = one_argy(argy, arg1); if ((spell = skill_lookup(arg1, -1)) == NULL) { send_to_char("That spell does not exist, so you cannot brew it into a potion.\n\r", ch); return; } for (i = 0; (pot_info[i].gsn > 0); i++) { if(spell->gsn == pot_info[i].gsn) { potion_number = i; break; } } if (potion_number == -1) { send_to_char("You cannot brew a potion of that.\n\r", ch); return; } sprintf(buff, "In order to brew a potion of %s, you will need ", spell->spell_name); for(i = 0; i < 10; i++) { if (number_range(1,2) == 2 && check_skill(ch, gsn_brew) && pot_info[potion_number].ingredients[i] > 0) { used_this[i] = TRUE; total_num++; } } if (total_num == 0) { strcat(buff, "nothing that you can tell.\n\r"); send_to_char(buff, ch); return; } else if (total_num == 1) { for (i = 0; i < 10; i++) { if (used_this[i] == TRUE) { strcat(buff, get_obj_index(560+pot_info[potion_number].ingredients[i])->short_descr); } } strcat(buff, ".\n\r"); send_to_char(buff, ch); return; } else { for (i = 0; i < 10; i++) { if (used_this[i] == TRUE) { strcat(buff, get_obj_index(560+pot_info[potion_number].ingredients[i])->short_descr); if (num_used < total_num-2) strcat(buff, ", "); else if (num_used == total_num-2) strcat(buff, " and "); else { strcat(buff, ".\n\r"); } num_used++; } } send_to_char(buff, ch); } return; } void do_alchemy (CHAR_DATA *ch, char * argy) { SINGLE_OBJECT *chunk, *chunkn, *newchunk; int i; int type = -1; bool found = TRUE; int vnum = 0; int oldrank; DEFINE_COMMAND( "alchemy", do_alchemy, POSITION_STANDING, 0, LOG_NORMAL, "This command lets you try to change metals into other kinds of metals.") if (IS_MOB (ch)) return; if (!check_skill (ch, gsn_alchemy)) { send_to_char ("You fail to set up the alchemical experiment correctly!\n\r", ch); WAIT_STATE (ch, 5*PULSE_VIOLENCE); return; } if (argy[0] == '\0' || argy == "") { send_to_char ("Syntax: Alchemy <Metalname>.\n\r", ch); return; } for (i = 0; str_cmp (materials[i].name, "END"); i++) { if (!str_cmp (argy, materials[i].name)) { type = i+1; break; } } if (type == -1) { send_to_char ("Syntax: Alchemy <Metalname>.\n\r", ch); return; } if (i > is_member (ch, GUILD_TINKER) * 3 || i > is_member (ch, GUILD_WIZARD) * 3) { send_to_char ("You are not skilled enough to use alchemy at this level!\n\r", ch); return; } if (ch->pcdata->bank < 20) { send_to_char ("You are too poor. It costs 20 coins from your bank to attempt each alchemy, whether you succeed or not.\n\r", ch); return; } for (chunk = ch->carrying; chunk != NULL; chunk = chunkn) { chunkn = chunk->next_content; if (chunk->pIndexData->item_type == ITEM_RAW && ((I_RAW *)chunk->more)->type == RAW_MINERAL && (oldrank = ((I_RAW *)chunk->more)->rank) < type && (ch->pcdata->bank > 20)) { found = TRUE; ch->pcdata->bank -= 20 * (type - oldrank); vnum = chunk->pIndexData->vnum; if (number_range (0, (1 << (type - oldrank) != (1 << (type - oldrank))/2))) { act ("$n just tried to change $p into something better, but failed!", ch, chunk, NULL, TO_ROOM); act ("You just tried to change $p into something better, but failed!", ch, chunk, NULL, TO_CHAR); obj_from (chunk); free_it (chunk); } else { newchunk = create_object (get_obj_index (vnum + 40 * (type -oldrank)), 0); act ("$n just changed $p into $P.", ch, chunk, newchunk, TO_ROOM); act ("You just changed $p into $P.", ch, chunk, newchunk, TO_CHAR); obj_to (newchunk, ch); obj_from (chunk); free_it (chunk); } } } if (!found) { send_to_char ("You didn't have any chunks of minerals you could change.\n\r", ch); } return; }