Fix charges in preset items being ignored (except for food/fold) and introduce possibility of placing enchanted items in towns (lacks editor support though)

This commit is contained in:
2015-01-23 04:27:44 -05:00
parent 41db6dcfdf
commit 72dfea868f
8 changed files with 86 additions and 75 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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<cLed&>(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;
}