diff --git a/src/boe.items.cpp b/src/boe.items.cpp index 7fb1bbef..32e25834 100644 --- a/src/boe.items.cpp +++ b/src/boe.items.cpp @@ -97,65 +97,6 @@ short take_food(short amount,bool print_result) { return 0; } -void enchant_weapon(short pc_num,short item_hit,short enchant_type,short new_val) { - if(univ.party[pc_num].items[item_hit].magic || - (univ.party[pc_num].items[item_hit].ability != eItemAbil::NONE)) - return; - univ.party[pc_num].items[item_hit].magic = true; - univ.party[pc_num].items[item_hit].enchanted = true; - std::string store_name = univ.party[pc_num].items[item_hit].full_name; - switch(enchant_type) { - case 0: - store_name += " (+1)"; - univ.party[pc_num].items[item_hit].bonus++; - univ.party[pc_num].items[item_hit].value = new_val; - break; - case 1: - store_name += " (+2)"; - univ.party[pc_num].items[item_hit].bonus += 2; - univ.party[pc_num].items[item_hit].value = new_val; - break; - case 2: - store_name += " (+3)"; - univ.party[pc_num].items[item_hit].bonus += 3; - univ.party[pc_num].items[item_hit].value = new_val; - break; - case 3: - store_name += " (F)"; - univ.party[pc_num].items[item_hit].ability = eItemAbil::CAST_SPELL; - univ.party[pc_num].items[item_hit].abil_data[0] = 5; - univ.party[pc_num].items[item_hit].abil_data[1] = int(eSpell::FLAME); - univ.party[pc_num].items[item_hit].charges = 8; - break; - case 4: - store_name += " (F!)"; - univ.party[pc_num].items[item_hit].value = new_val; - univ.party[pc_num].items[item_hit].ability = eItemAbil::DAMAGING_WEAPON; - univ.party[pc_num].items[item_hit].abil_data[0] = 5; - univ.party[pc_num].items[item_hit].abil_data[1] = int(eDamageType::FIRE); - break; - case 5: - store_name += " (+5)"; - univ.party[pc_num].items[item_hit].value = new_val; - univ.party[pc_num].items[item_hit].bonus += 5; - break; - case 6: - store_name += " (B)"; - univ.party[pc_num].items[item_hit].bonus++; - univ.party[pc_num].items[item_hit].ability = eItemAbil::AFFECT_STATUS; - univ.party[pc_num].items[item_hit].abil_data[0] = 5; - univ.party[pc_num].items[item_hit].abil_data[1] = int(eStatus::BLESS_CURSE); - univ.party[pc_num].items[item_hit].magic_use_type = 0; - univ.party[pc_num].items[item_hit].charges = 8; - break; - } - if(univ.party[pc_num].items[item_hit].value > 15000) - univ.party[pc_num].items[item_hit].value = 15000; - if(univ.party[pc_num].items[item_hit].value < 0) - univ.party[pc_num].items[item_hit].value = 15000; - univ.party[pc_num].items[item_hit].full_name = store_name; -} - void equip_item(short pc_num,short item_num) { unsigned short num_equipped_of_this_type = 0; unsigned short num_hands_occupied = 0; diff --git a/src/boe.items.h b/src/boe.items.h index 4beede48..694d060f 100644 --- a/src/boe.items.h +++ b/src/boe.items.h @@ -8,7 +8,6 @@ void give_gold(short amount,bool print_result); bool take_gold(short amount,bool print_result); void give_food(short amount,bool print_result); short take_food(short amount,bool print_result); -void enchant_weapon(short pc_num,short item_hit,short enchant_type,short new_val); void equip_item(short pc_num,short item_num); void drop_item(short pc_num,short item_num,location where_drop); bool place_item(cItem item,location where,bool forced,bool contained = false); diff --git a/src/boe.text.cpp b/src/boe.text.cpp index 48b31788..6382d784 100644 --- a/src/boe.text.cpp +++ b/src/boe.text.cpp @@ -340,6 +340,7 @@ void place_buy_button(short position,short pc_num,short item_num) { // TODO: The duplication of rectangle here shouldn't be necessary... rectangle button_sources[3] = {rectangle{24,0,36,30},rectangle{36,0,48,30},rectangle{48,0,60,30}}; short val_to_place; + // TODO: This is now duplicated here and in start_town_mode() short aug_cost[10] = {4,7,10,8, 15,15,10, 0,0,0}; if(univ.party[pc_num].items[item_num].variety == eItemType::NO_ITEM) diff --git a/src/boe.town.cpp b/src/boe.town.cpp index 32c9fd27..1e608cdc 100644 --- a/src/boe.town.cpp +++ b/src/boe.town.cpp @@ -393,18 +393,25 @@ void start_town_mode(short which_town, short entry_dir) { // Not use the items data flags, starting with forcing an ability if(univ.town->preset_items[i].ability >= 0) { switch(univ.town.items[j].variety) { - case eItemType::GOLD: - case eItemType::FOOD: // If gold or food, this value is amount - if(univ.town->preset_items[i].ability > 0) - univ.town.items[j].item_level = univ.town->preset_items[i].ability; - break; - default: //leave other type alone - // TODO: Could resupport this "forcing an ability" thing... + case eItemType::ONE_HANDED: + case eItemType::TWO_HANDED: { + if(univ.town->preset_items[i].ability > int(eEnchant::BLESSED)) + break; + // TODO: This array and accompanying calculation is now duplicated here and in place_buy_button() + const short aug_cost[10] = {4,7,10,8, 15,15,10, 0,0,0}; + int ench = univ.town->preset_items[i].ability; + int val = max(aug_cost[ench] * 100, univ.town.items[j].value * (5 + aug_cost[ench])); + univ.town.items[j].enchant_weapon(eEnchant(ench), val); break; + } } } - // TODO: charges are unused! (Also, they're currently stored in ability, not in charges.) + if(univ.town->preset_items[i].charges > 0) { + eItemType variety = univ.town.items[j].variety; + if(univ.town.items[j].charges > 0 || variety == eItemType::GOLD || variety == eItemType::FOOD) + univ.town.items[j].charges = univ.town->preset_items[i].charges; + } if(town_toast) univ.town.items[j].property = false; diff --git a/src/classes/item.cpp b/src/classes/item.cpp index 19a7079c..ba632598 100644 --- a/src/classes/item.cpp +++ b/src/classes/item.cpp @@ -376,6 +376,66 @@ cItem::cItem(eAlchemy recipe) : cItem('alch') { } } +void cItem::enchant_weapon(eEnchant enchant_type,short new_val) { + if(magic || ability != eItemAbil::NONE) + return; + if(variety != eItemType::ONE_HANDED || variety != eItemType::TWO_HANDED) + return; + magic = true; + enchanted = true; + std::string store_name = full_name; + switch(enchant_type) { + case eEnchant::PLUS_ONE: + store_name += " (+1)"; + bonus++; + value = new_val; + break; + case eEnchant::PLUS_TWO: + store_name += " (+2)"; + bonus += 2; + value = new_val; + break; + case eEnchant::PLUS_THREE: + store_name += " (+3)"; + bonus += 3; + value = new_val; + break; + case eEnchant::SHOOT_FLAME: + store_name += " (F)"; + ability = eItemAbil::CAST_SPELL; + abil_data[0] = 5; + abil_data[1] = int(eSpell::FLAME); + charges = 8; + break; + case eEnchant::FLAMING: + store_name += " (F!)"; + value = new_val; + ability = eItemAbil::DAMAGING_WEAPON; + abil_data[0] = 5; + abil_data[1] = int(eDamageType::FIRE); + break; + case eEnchant::PLUS_FIVE: + store_name += " (+5)"; + value = new_val; + bonus += 5; + break; + case eEnchant::BLESSED: + store_name += " (B)"; + bonus++; + ability = eItemAbil::AFFECT_STATUS; + abil_data[0] = 5; + abil_data[1] = int(eStatus::BLESS_CURSE); + magic_use_type = 0; + charges = 8; + break; + } + if(value > 15000) + value = 15000; + if(value < 0) + value = 15000; + full_name = store_name; +} + void cItem::append(legacy::item_record_type& old){ variety = (eItemType) old.variety; item_level = old.item_level; diff --git a/src/classes/item.h b/src/classes/item.h index 0a9ef7f5..4f8bbfe0 100644 --- a/src/classes/item.h +++ b/src/classes/item.h @@ -17,6 +17,8 @@ namespace legacy { struct item_record_type; }; +enum class eEnchant {PLUS_ONE, PLUS_TWO, PLUS_THREE, SHOOT_FLAME, FLAMING, PLUS_FIVE, BLESSED}; + class cItem { public: eItemType variety; @@ -53,6 +55,7 @@ public: short item_weight() const; std::string getAbilName() const; + void enchant_weapon(eEnchant enchant_type, short new_val); cItem(); explicit cItem(long preset); diff --git a/src/classes/town.cpp b/src/classes/town.cpp index b92d9eef..dccce21a 100644 --- a/src/classes/town.cpp +++ b/src/classes/town.cpp @@ -173,8 +173,7 @@ void cTown::cItem::append(legacy::preset_item_type old){ loc.x = old.item_loc.x; loc.y = old.item_loc.y; code = old.item_code; - ability = old.ability; - charges = old.charges; + charges = old.ability; always_there = old.always_there; property = old.property; contained = old.contained; @@ -257,6 +256,7 @@ cTown::cItem::cItem() { loc = {80,80}; code = -1; ability = -1; + charges = 0; always_there = false; property = false; contained = false; @@ -266,7 +266,7 @@ cTown::cItem::cItem(location loc, short num, ::cItem& item) : cItem() { loc = loc; code = num; if(item.variety == eItemType::GOLD || item.variety == eItemType::FOOD) - ability = get_ran(1,4,6); + charges = get_ran(1,4,6); } std::ostream& operator<< (std::ostream& out, eLighting light) { diff --git a/src/scenedit/scen.townout.cpp b/src/scenedit/scen.townout.cpp index 8dbf84cc..48327d2d 100644 --- a/src/scenedit/scen.townout.cpp +++ b/src/scenedit/scen.townout.cpp @@ -210,7 +210,7 @@ static void put_placed_item_in_dlog(cDialog& me, const cTown::cItem& store_place sprintf(str,"X = %d, Y = %d",store_placed_item.loc.x,store_placed_item.loc.y); me["loc"].setText(str); me["name"].setText(scenario.scen_items[store_placed_item.code].full_name); - me["charges"].setTextToNum(store_placed_item.ability); + me["charges"].setTextToNum(store_placed_item.charges); if(store_placed_item.always_there) dynamic_cast(me["always"]).setState(led_red); if(store_placed_item.property) @@ -224,15 +224,15 @@ static void put_placed_item_in_dlog(cDialog& me, const cTown::cItem& store_place static bool get_placed_item_in_dlog(cDialog& me, cTown::cItem& store_placed_item, const short store_which_placed_item) { if(!me.toast(true)) return true; - store_placed_item.ability = me["charges"].getTextAsNum(); - if(store_placed_item.ability < -1 || store_placed_item.ability > 2500) { + store_placed_item.charges = me["charges"].getTextAsNum(); + if(store_placed_item.charges < -1 || store_placed_item.charges > 2500) { giveError("Number of charges/amount of gold or food must be from 0 to 2500.", "If an item with charges (not gold or food) leave this at -1 for the item to have the default number of charges.",&me); return true; } eItemType type = scenario.scen_items[store_placed_item.code].variety; - if(store_placed_item.ability == 0 && (type == eItemType::GOLD || type == eItemType::FOOD)) { + if(store_placed_item.charges == 0 && (type == eItemType::GOLD || type == eItemType::FOOD)) { giveError("You must assign gold or food an amount of at least 1.","",&me); return false; }