New item variety: Special

- When picked up or purchased, the party gains a special item
This commit is contained in:
2015-01-20 17:17:23 -05:00
parent decdc3111b
commit 7837459177
13 changed files with 49 additions and 32 deletions

View File

@@ -54,7 +54,7 @@
<led name='xbow' state='off' top='119' left='448' width='90'>Crossbow</led>
<led name='bolt' state='off' top='134' left='448' width='90'>Bolts</led>
<led name='missile' state='off' top='149' left='448' width='90'>Missile (no ammo)</led>
<led name='unused1' state='off' top='164' left='448' width='90'>Unused</led>
<led name='special' state='off' top='164' left='448' width='90'>Special Item</led>
<led name='unused2' state='off' top='179' left='448' width='80'>Unused</led>
</group>
<pict name="pic" type='dlog' num='16' top='8' left='11'/>

View File

@@ -926,7 +926,6 @@ bool handle_action(sf::Event event) {
bool need_redraw = false, did_something = false, need_reprint = false;
bool pc_delayed = false;
location cur_loc,loc_in_sec,cur_direction;
unsigned char debug_storage;
short button_hit = 12;
bool right_button = event.mouseButton.button == sf::Mouse::Right;
eGameMode previous_mode;
@@ -934,9 +933,6 @@ bool handle_action(sf::Event event) {
std::ostringstream str;
location the_point,point_in_area;
debug_storage = univ.party.spec_items[1];
the_point = location(event.mouseButton.x, event.mouseButton.y);
the_point.x -= ul.x;
the_point.y -= ul.y;

View File

@@ -224,7 +224,10 @@ void handle_sale(cShopItem item, int i) {
case eBuyStatus::NO_SPACE: ASB("Can't carry any more items."); break;
case eBuyStatus::NEED_GOLD: ASB("Not enough cash."); break;
case eBuyStatus::TOO_HEAVY: ASB("Item is too heavy."); break;
case eBuyStatus::HAVE_LOTS: ASB("You own too many of this."); break;
case eBuyStatus::HAVE_LOTS:
if(base_item.variety == eItemType::SPECIAL) ASB("You already own this.");
else ASB("You own too many of this.");
break;
}
break;
case eShopItemType::ALCHEMY:
@@ -791,7 +794,7 @@ void handle_talk_event(location p) {
strnum2 = -1;
break;
case eTalkNode::BUY_SPEC_ITEM:
if(univ.party.spec_items[a] > 0) {
if(univ.party.spec_items[a]) {
save_talk_str1 = "You already have it.";
strnum1 = -1;
}
@@ -802,7 +805,7 @@ void handle_talk_event(location p) {
else {
univ.party.gold -= b;
put_pc_screen();
univ.party.spec_items[a] = 1;
univ.party.spec_items[a] = true;
}
strnum2 = 0;
save_talk_str2 = "";

View File

@@ -643,17 +643,19 @@ static bool display_item_event_filter(cDialog& me, std::string id, size_t& first
item.property = false;
}
if(item_array[item_hit]->variety == eItemType::GOLD) {
if(item_array[item_hit]->item_level > 3000)
item_array[item_hit]->item_level = 3000;
if(item.variety == eItemType::GOLD) {
if(item.item_level > 3000)
item.item_level = 3000;
set_item_flag(&item);
give_gold(item_array[item_hit]->item_level,false);
give_gold(item.item_level,false);
play_sound(39); // formerly force_play_sound
} else if(item_array[item_hit]->variety == eItemType::FOOD) {
give_food(item_array[item_hit]->item_level,false);
} else if(item.variety == eItemType::FOOD) {
give_food(item.item_level,false);
set_item_flag(&item);
set_item_flag(item_array[item_hit]);
play_sound(62); // formerly force_play_sound
} else if(item.variety == eItemType::SPECIAL) {
univ.party.spec_items[item.item_level] = true;
set_item_flag(&item);
} else {
if(!allow_overload && item.item_weight() > univ.party[current_getting_pc].free_weight()) {
beep(); // TODO: This is a game event, so it should have a game sound, not a system alert.
@@ -1051,6 +1053,7 @@ void refresh_store_items() {
for(j = 0; j < 10; j++) {
univ.party.magic_store_items[i][j] = return_treasure(loot_index[j]);
if(univ.party.magic_store_items[i][j].variety == eItemType::GOLD ||
univ.party.magic_store_items[i][j].variety == eItemType::SPECIAL ||
univ.party.magic_store_items[i][j].variety == eItemType::FOOD)
univ.party.magic_store_items[i][j] = cItem();
univ.party.magic_store_items[i][j].ident = true;

View File

@@ -912,6 +912,9 @@ std::string get_item_interesting_string(cItem item) {
case eItemType::GOLD:
sout << item.item_level << " gold pieces.";
break;
case eItemType::SPECIAL:
sout << "Special";
break;
case eItemType::FOOD:
sout << item.item_level << " food.";
break;

View File

@@ -168,7 +168,7 @@ static void init_party_scen_data() {
univ.party.key_times[i] = 30000;
univ.party.party_event_timers.clear();
for(i = 0; i < 50; i++)
univ.party.spec_items[i] = (univ.scenario.special_items[i].flags >= 10) ? 1 : 0;
univ.party.spec_items[i] = univ.scenario.special_items[i].flags >= 10;
for(i = 0; i < 200; i++)
univ.party.m_killed[i] = 0;
@@ -289,7 +289,7 @@ void put_party_in_scen(std::string scen_name) {
// this is kludgy, put here to prevent problems
for(i = 0; i < 50; i++)
univ.party.spec_items[i] = (univ.scenario.special_items[i].flags >= 10) ? 1 : 0;
univ.party.spec_items[i] = univ.scenario.special_items[i].flags >= 100;
// Compatibility flags
if(univ.scenario.format.prog_make_ver[0] < 2){

View File

@@ -2445,7 +2445,7 @@ void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
set_sd = false;
}
else {
univ.party.spec_items[spec.ex1a] = (spec.ex1b == 0) ? 1 : 0;
univ.party.spec_items[spec.ex1a] = spec.ex1b == 0;
}
if(stat_window == 6)
set_stat_window(6);
@@ -2512,9 +2512,9 @@ void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
give_gold(spec.ex1b,true);
give_food(spec.ex2a,true);
if((spec.m3 >= 0) && (spec.m3 < 50)) {
if(univ.party.spec_items[spec.m3] == 0)
if(!univ.party.spec_items[spec.m3])
ASB("You get a special item.");
univ.party.spec_items[spec.m3] = 1;
univ.party.spec_items[spec.m3] = true;
*redraw = true;
if(stat_window == 6)
set_stat_window(6);

View File

@@ -498,7 +498,7 @@ void set_stat_window(short new_stat) {
for(i = 0; i < 60; i++)
spec_item_array[i] = -1;
for(i = 0; i < 50; i++) ////
if(univ.party.spec_items[i] > 0) {
if(univ.party.spec_items[i]) {
spec_item_array[array_pos] = i;
array_pos++;
}

View File

@@ -400,6 +400,9 @@ void start_town_mode(short which_town, short entry_dir) {
// place the preset item, if party hasn't gotten it already
if(univ.town.items[j].variety == eItemType::NO_ITEM) {
univ.town.items[j] = get_stored_item(univ.town->preset_items[i].code);
// Don't place special items if already in the party's possession
if(univ.town.items[j].variety == eItemType::SPECIAL && univ.party.spec_items[univ.town.items[j].item_level])
break;
univ.town.items[j].item_loc = univ.town->preset_items[i].loc;
// Not use the items data flags, starting with forcing an ability

View File

@@ -99,7 +99,7 @@ public:
bool can_find_town[200];
short key_times[100];
std::vector<cTimer> party_event_timers;
char spec_items[50];
std::array<bool,50> spec_items;
char help_received[120];
short m_killed[200]; // monsters killed per town, I think
long long total_m_killed, total_dam_done, total_xp_gained, total_dam_taken;

View File

@@ -116,7 +116,7 @@ void cPlayer::sort_items() {
{it::TOOL, 7}, {it::FOOD, 20}, {it::SHIELD, 10}, {it::ARMOR, 10}, {it::HELM, 10},
{it::GLOVES, 10}, {it::SHIELD_2, 10}, {it::BOOTS, 10}, {it::RING, 5}, {it::NECKLACE, 6},
{it::WEAPON_POISON, 4}, {it::NON_USE_OBJECT, 11}, {it::PANTS, 12}, {it::CROSSBOW, 9}, {it::BOLTS, 9},
{it::MISSILE_NO_AMMO, 9}, {it::UNUSED1, 20}, {it::UNUSED2, 20}
{it::MISSILE_NO_AMMO, 9}, {it::UNUSED1, 20}, {it::SPECIAL, 20}
};
bool no_swaps = false;
@@ -153,6 +153,12 @@ bool cPlayer::give_item(cItem item, bool do_print, bool allow_overload) {
print_result("You get some food.");
return true;
}
if(item.variety == eItemType::SPECIAL) {
party.spec_items[item.item_level] = true;
if(do_print && print_result)
print_result("You get a special item.");
return true;
}
if(!allow_overload && item.item_weight() > free_weight()) {
if(do_print && print_result) {
//beep(); // TODO: This is a game event, so it should have a game sound, not a system alert.
@@ -286,7 +292,10 @@ short cPlayer::skill(eSkill skill) {
}
eBuyStatus cPlayer::ok_to_buy(short cost,cItem item) {
if(item.variety != eItemType::GOLD && item.variety != eItemType::FOOD) {
if(item.variety == eItemType::SPECIAL) {
if(party.spec_items[item.item_level])
return eBuyStatus::HAVE_LOTS;
} else if(item.variety != eItemType::GOLD && item.variety != eItemType::FOOD) {
for(int i = 0; i < 24; i++)
if(items[i].variety != eItemType::NO_ITEM && items[i].type_flag == item.type_flag && items[i].charges > 123)
return eBuyStatus::HAVE_LOTS;

View File

@@ -298,8 +298,8 @@ enum class eItemType {
CROSSBOW = 23,
BOLTS = 24,
MISSILE_NO_AMMO = 25, //e.g slings
UNUSED1 = 26, // these are here solely because they are options in the editor
UNUSED2 = 27,
SPECIAL = 26, // these are here solely because they are options in the editor
UNUSED1 = 27,
};
inline bool isArmourType(eItemType type) {

View File

@@ -1208,8 +1208,8 @@ static void put_item_info_in_dlog(cDialog& me, cItem& store_item, short which_it
case eItemType::UNUSED1:
variety.setSelected("unused1");
break;
case eItemType::UNUSED2:
variety.setSelected("unused2");
case eItemType::SPECIAL:
variety.setSelected("special");
break;
}
@@ -1284,7 +1284,7 @@ static void save_item_info(cDialog& me, cItem& store_item, short which_item) {
else if(variety == "bolt") store_item.variety = eItemType::BOLTS;
else if(variety == "missile") store_item.variety = eItemType::MISSILE_NO_AMMO;
else if(variety == "unused1") store_item.variety = eItemType::UNUSED1;
else if(variety == "unused2") store_item.variety = eItemType::UNUSED2;
else if(variety == "special") store_item.variety = eItemType::SPECIAL;
store_item.weap_type = eSkill(me["weap-type"].getTextAsNum());
store_item.missile = me["missile"].getTextAsNum();
@@ -1305,7 +1305,7 @@ static void save_item_info(cDialog& me, cItem& store_item, short which_item) {
if(store_item.type_flag > 0 && store_item.charges == 0)
store_item.charges = 1;
eItemAbilCat cat = getItemAbilCategory(store_item.ability);
if((cat == eItemAbilCat::SPELL || cat == eItemAbilCat::NONSPELL || cat == eItemAbilCat::REAGENT) && store_item.charges == 0)
if((cat == eItemAbilCat::USABLE || cat == eItemAbilCat::REAGENT) && store_item.charges == 0)
store_item.charges = 1;
if(was_charges != store_item.charges)
giveError("Due to either the selected special ability or the presence of a type flag, this item's charges have been set to 1.", &me);
@@ -1362,8 +1362,8 @@ static bool edit_item_type_event_filter(cDialog& me, std::string item_hit, cItem
giveError("You must give the item a type (weapon, armor, etc.) before you can choose its abilities.","",&me);
return true;
}
if(store_item.variety == eItemType::GOLD || store_item.variety == eItemType::FOOD) {
giveError("Gold and Food cannot be given special abilities.","",&me);
if(store_item.variety == eItemType::GOLD || store_item.variety == eItemType::FOOD || store_item.variety == eItemType::SPECIAL) {
giveError("Gold, Food, and Special Items cannot be given special abilities.","",&me);
return true;
}
temp_item = edit_item_abil(store_item,store_which_item);