// Make a special debugging artifact. std::string architects_cube() { std::string artifact_name(std::string type); it_artifact_tool *art = new it_artifact_tool(); artifact_tool_form_datum *info = &(artifact_tool_form_data[ARTTOOLFORM_CUBE]); art->create_name(info->name); art->color = info->color; art->sym = info->sym; art->materials.push_back(info->material); art->volume = rng(info->volume_min, info->volume_max); art->weight = rng(info->weight_min, info->weight_max); // Set up the basic weapon type artifact_weapon_datum *weapon = &(artifact_weapon_data[info->base_weapon]); art->melee_dam = rng(weapon->bash_min, weapon->bash_max); art->melee_cut = rng(weapon->cut_min, weapon->cut_max); art->m_to_hit = rng(weapon->to_hit_min, weapon->to_hit_max); if( weapon->tag != "" ) { art->item_tags.insert(weapon->tag); } // Add an extra weapon perhaps? art->description = _("The architect's cube."); art->effects_carried.push_back(AEP_SUPER_CLAIRVOYANCE); item_controller->add_item_type( art ); return art->id; }
/* * This routine changes the address of obj. Be careful not to call it * when there might be pointers around in unknown places. For now: only * when obj is in the inventory. */ static void do_oname(struct obj *obj) { char buf[BUFSZ], qbuf[QBUFSZ]; const char *aname; short objtyp; sprintf(qbuf, "What do you want to name %s %s?", is_plural(obj) ? "these" : "this", xname(obj)); getlin(qbuf, buf); if (!*buf || *buf == '\033') return; /* strip leading and trailing spaces; unnames item if all spaces */ mungspaces(buf); /* relax restrictions over proper capitalization for artifacts */ if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp) strcpy(buf, aname); if (obj->oartifact) { pline("The artifact seems to resist the attempt."); return; } else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) { int n = rn2((int)strlen(buf)); char c1, c2; c1 = lowc(buf[n]); do c2 = 'a' + rn2('z'-'a'); while (c1 == c2); buf[n] = (buf[n] == c1) ? c2 : highc(c2); /* keep same case */ pline("While engraving your %s slips.", body_part(HAND)); win_pause_output(P_MESSAGE); pline("You engrave: \"%s\".",buf); } oname(obj, buf); }
/* * This routine changes the address of obj. Be careful not to call it * when there might be pointers around in unknown places. For now: only * when obj is in the inventory. */ int do_oname(const struct nh_cmd_arg *arg) { const char *qbuf, *buf; const char *aname; short objtyp; struct obj *obj; obj = getargobj(arg, nameable, "name"); if (!obj) return 0; qbuf = msgprintf("What do you want to name %s %s?", is_plural(obj) ? "these" : "this", safe_qbuf("", sizeof("What do you want to name these ?"), xname(obj), simple_typename(obj->otyp), is_plural(obj) ? "things" : "thing")); buf = getarglin(arg, qbuf); if (!*buf || *buf == '\033') return 0; /* strip leading and trailing spaces; unnames item if all spaces */ buf = msgmungspaces(buf); /* relax restrictions over proper capitalization for artifacts */ if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp) buf = aname; char slipbuf[strlen(buf) + 1]; if (obj->oartifact) { pline("The artifact seems to resist the attempt."); return 0; } else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) { int n = rn2((int)strlen(buf)); char c1, c2; strcpy(slipbuf, buf); c1 = lowc(buf[n]); do c2 = 'a' + rn2('z' - 'a' + 1); while (c1 == c2); slipbuf[n] = (slipbuf[n] == c1) ? c2 : highc(c2); /* keep same case */ pline("While engraving your %s slips.", body_part(HAND)); win_pause_output(P_MESSAGE); pline("You engrave: \"%s\".", slipbuf); buf = slipbuf; } oname(obj, buf); return 0; }
itype* game::new_artifact() { if (one_in(2)) { // Generate a "tool" artifact it_artifact_tool *art = new it_artifact_tool(); int form = rng(ARTTOOLFORM_NULL + 1, NUM_ARTTOOLFORMS - 1); artifact_tool_form_datum *info = &(artifact_tool_form_data[form]); art->name = artifact_name(info->name); art->color = info->color; art->sym = info->sym; art->m1 = info->m1; art->m2 = info->m2; art->volume = rng(info->volume_min, info->volume_max); art->weight = rng(info->weight_min, info->weight_max); // Set up the basic weapon type artifact_weapon_datum *weapon = &(artifact_weapon_data[info->base_weapon]); art->melee_dam = rng(weapon->bash_min, weapon->bash_max); art->melee_cut = rng(weapon->cut_min, weapon->cut_max); art->m_to_hit = rng(weapon->to_hit_min, weapon->to_hit_max); if( weapon->tag != "" ) { art->item_tags.insert(weapon->tag); } // Add an extra weapon perhaps? if (one_in(2)) { int select = rng(0, 2); if (info->extra_weapons[select] != ARTWEAP_NULL) { weapon = &(artifact_weapon_data[ info->extra_weapons[select] ]); art->volume += weapon->volume; art->weight += weapon->weight; art->melee_dam += rng(weapon->bash_min, weapon->bash_max); art->melee_cut += rng(weapon->bash_min, weapon->bash_max); art->m_to_hit += rng(weapon->to_hit_min, weapon->to_hit_max); if( weapon->tag != "" ) { art->item_tags.insert(weapon->tag); } std::stringstream newname; newname << weapon->adjective << " " << info->name; art->name = artifact_name(newname.str()); } } art->description = string_format(_("This is the %s.\nIt is the only one of its kind.\nIt may have unknown powers; use 'a' to activate them."), art->name.c_str()); // Finally, pick some powers art_effect_passive passive_tmp = AEP_NULL; art_effect_active active_tmp = AEA_NULL; int num_good = 0, num_bad = 0, value = 0; std::vector<art_effect_passive> good_effects = fill_good_passive(); std::vector<art_effect_passive> bad_effects = fill_bad_passive(); // Wielded effects first while (!good_effects.empty() && !bad_effects.empty() && num_good < 3 && num_bad < 3 && (num_good < 1 || num_bad < 1 || one_in(num_good + 1) || one_in(num_bad + 1) || value > 1)) { if (value < 1 && one_in(2)) { // Good int index = rng(0, good_effects.size() - 1); passive_tmp = good_effects[index]; good_effects.erase(good_effects.begin() + index); num_good++; } else if (!bad_effects.empty()) { // Bad effect int index = rng(0, bad_effects.size() - 1); passive_tmp = bad_effects[index]; bad_effects.erase(bad_effects.begin() + index); num_bad++; } value += passive_effect_cost[passive_tmp]; art->effects_wielded.push_back(passive_tmp); } // Next, carried effects; more likely to be just bad num_good = 0; num_bad = 0; value = 0; good_effects = fill_good_passive(); bad_effects = fill_bad_passive(); while (one_in(2) && !good_effects.empty() && !bad_effects.empty() && num_good < 3 && num_bad < 3 && ((num_good > 2 && one_in(num_good + 1)) || num_bad < 1 || one_in(num_bad + 1) || value > 1)) { if (value < 1 && one_in(3)) { // Good int index = rng(0, good_effects.size() - 1); passive_tmp = good_effects[index]; good_effects.erase(good_effects.begin() + index); num_good++; } else { // Bad effect int index = rng(0, bad_effects.size() - 1); passive_tmp = bad_effects[index]; bad_effects.erase(bad_effects.begin() + index); num_bad++; } value += passive_effect_cost[passive_tmp]; art->effects_carried.push_back(passive_tmp); } // Finally, activated effects; not necessarily good or bad num_good = 0; num_bad = 0; value = 0; art->def_charges = 0; art->max_charges = 0; std::vector<art_effect_active> good_a_effects = fill_good_active(); std::vector<art_effect_active> bad_a_effects = fill_bad_active(); while (!good_a_effects.empty() && !bad_a_effects.empty() && num_good < 3 && num_bad < 3 && (value > 3 || (num_bad > 0 && num_good == 0) || !one_in(3 - num_good) || !one_in(3 - num_bad))) { if (!one_in(3) && value <= 1) { // Good effect int index = rng(0, good_a_effects.size() - 1); active_tmp = good_a_effects[index]; good_a_effects.erase(good_a_effects.begin() + index); num_good++; value += active_effect_cost[active_tmp]; } else { // Bad effect int index = rng(0, bad_a_effects.size() - 1); active_tmp = bad_a_effects[index]; bad_a_effects.erase(bad_a_effects.begin() + index); num_bad++; value += active_effect_cost[active_tmp]; } art->effects_activated.push_back(active_tmp); art->max_charges += rng(1, 3); } art->def_charges = art->max_charges; // If we have charges, pick a recharge mechanism if (art->max_charges > 0) art->charge_type = art_charge( rng(ARTC_NULL + 1, NUM_ARTCS - 1) ); if (one_in(8) && num_bad + num_good >= 4) art->charge_type = ARTC_NULL; // 1 in 8 chance that it can't recharge! art->id = itypes.size(); itypes[art->id]=art; artifact_itype_ids.push_back(art->id); return art; } else { // Generate an armor artifact it_artifact_armor *art = new it_artifact_armor(); int form = rng(ARTARMFORM_NULL + 1, NUM_ARTARMFORMS - 1); artifact_armor_form_datum *info = &(artifact_armor_form_data[form]); art->name = artifact_name(info->name); art->sym = '['; // Armor is always [ art->color = info->color; art->m1 = info->m1; art->m2 = info->m2; art->volume = info->volume; art->weight = info->weight; art->melee_dam = info->melee_bash; art->melee_cut = info->melee_cut; art->m_to_hit = info->melee_hit; art->covers = info->covers; art->encumber = info->encumb; art->coverage = info->coverage; art->thickness = info->thickness; art->env_resist = info->env_resist; art->warmth = info->warmth; art->storage = info->storage; std::stringstream description; description << string_format(info->plural? _("This is the %s.\nThey are the only ones of their kind.") : _("This is the %s.\nIt is the only one of its kind."), art->name.c_str()); // Modify the armor further if (!one_in(4)) { int index = rng(0, 4); if (info->available_mods[index] != ARMORMOD_NULL) { artifact_armor_mod mod = info->available_mods[index]; artifact_armor_form_datum *modinfo = &(artifact_armor_mod_data[mod]); if (modinfo->volume >= 0 || art->volume > abs(modinfo->volume)) art->volume += modinfo->volume; else art->volume = 1; if (modinfo->weight >= 0 || art->weight > abs(modinfo->weight)) art->weight += modinfo->weight; else art->weight = 1; art->encumber += modinfo->encumb; if (modinfo->coverage > 0 || art->coverage > abs(modinfo->coverage)) art->coverage += modinfo->coverage; else art->coverage = 0; if (modinfo->thickness > 0 || art->thickness > abs(modinfo->thickness)) art->thickness += modinfo->thickness; else art->thickness = 0; if (modinfo->env_resist > 0 || art->env_resist > abs(modinfo->env_resist)) art->env_resist += modinfo->env_resist; else art->env_resist = 0; art->warmth += modinfo->warmth; if (modinfo->storage > 0 || art->storage > abs(modinfo->storage)) art->storage += modinfo->storage; else art->storage = 0; description << string_format(info->plural? _("\nThey are %s") : _("\nIt is %s"), modinfo->name.c_str()); } } art->description = description.str(); // Finally, pick some effects int num_good = 0, num_bad = 0, value = 0; art_effect_passive passive_tmp = AEP_NULL; std::vector<art_effect_passive> good_effects = fill_good_passive(); std::vector<art_effect_passive> bad_effects = fill_bad_passive(); while (!good_effects.empty() && !bad_effects.empty() && num_good < 3 && num_bad < 3 && (num_good < 1 || one_in(num_good * 2) || value > 1 || (num_bad < 3 && !one_in(3 - num_bad)))) { if (value < 1 && one_in(2)) { // Good effect int index = rng(0, good_effects.size() - 1); passive_tmp = good_effects[index]; good_effects.erase(good_effects.begin() + index); num_good++; } else { // Bad effect int index = rng(0, bad_effects.size() - 1); passive_tmp = bad_effects[index]; bad_effects.erase(bad_effects.begin() + index); num_bad++; } value += passive_effect_cost[passive_tmp]; art->effects_worn.push_back(passive_tmp); } std::stringstream artid; artid << "artifact" << artifact_itype_ids.size(); art->id = artid.str(); itypes[art->id] = art; artifact_itype_ids.push_back(art->id); return art; } }
void it_artifact_armor::create_name(const std::string &type) { name = artifact_name(type); name_plural = name; }