Add new shop type and enhance existing ones a little
- Shops can now sell skill upgrades without skill point costs (currently available only through special node, not through dialogue) - Spell shops now show level and spell point cost - Alchemy shops now show ingredients - Make use of the constants defined for indexing the shop rects - Support for arbitrary quantities of items in shops, rather than simply infinite for normal shops and one for magic shops (there's no hook for this yet, though, so it can't be used)
This commit is contained in:
@@ -123,6 +123,7 @@
|
||||
913D05BD0FA1EA0A00184C18 /* pc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 913D05BB0FA1EA0A00184C18 /* pc.cpp */; };
|
||||
913D05BE0FA1EA0A00184C18 /* pc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 913D05BB0FA1EA0A00184C18 /* pc.cpp */; };
|
||||
913D6C050FC57A8E00E12527 /* boeresources.icns in Resources */ = {isa = PBXBuildFile; fileRef = 913D6C040FC57A8E00E12527 /* boeresources.icns */; };
|
||||
914698F81A73434400F20F5E /* shop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91FDB5791A4E774E00DE5983 /* shop.cpp */; };
|
||||
914701A718F62ABF008A6DC9 /* dungeon.ttf in Copy Fonts */ = {isa = PBXBuildFile; fileRef = 914701A418F629D4008A6DC9 /* dungeon.ttf */; };
|
||||
914701A818F62AC0008A6DC9 /* maidenword.ttf in Copy Fonts */ = {isa = PBXBuildFile; fileRef = 914701A518F629D4008A6DC9 /* maidenword.ttf */; };
|
||||
914B2AA318E7E507007B6799 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 914B2AA118E7E500007B6799 /* Cocoa.framework */; };
|
||||
@@ -1545,6 +1546,7 @@
|
||||
915E090C1A317E2E008BDF00 /* map_parse.cpp in Sources */,
|
||||
9179A4661A48683100FEF872 /* stack.cpp in Sources */,
|
||||
91222FC11A72366D008413A5 /* spell.cpp in Sources */,
|
||||
914698F81A73434400F20F5E /* shop.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -119,8 +119,6 @@ cCreature save_monster_type;
|
||||
short wand_loc_count = 0;
|
||||
short monst_place_count = 0; // 1 - standard place 2 - place last
|
||||
|
||||
// 0 - whole area, 1 - active area 2 - graphic 3 - item name
|
||||
// 4 - item cost 5 - item extra str 6 - item help button
|
||||
rectangle shopping_rects[8][7];
|
||||
std::queue<pending_special_type> special_queue;
|
||||
bool end_scenario = false;
|
||||
@@ -138,7 +136,8 @@ void init_screen_locs() {
|
||||
shopping_rects[0][SHOPRECT_ITEM_NAME].top += 4;
|
||||
shopping_rects[0][SHOPRECT_ITEM_NAME].left += 28;
|
||||
shopping_rects[0][SHOPRECT_ITEM_COST].top += 20;
|
||||
shopping_rects[0][SHOPRECT_ITEM_COST].left += 154;
|
||||
// TODO: Might need to put this back to what it was (I was trying to make more room for alchemy info)
|
||||
shopping_rects[0][SHOPRECT_ITEM_COST].left += 170;//154;
|
||||
shopping_rects[0][SHOPRECT_ITEM_EXTRA].top += 20;
|
||||
shopping_rects[0][SHOPRECT_ITEM_EXTRA].left += 34;
|
||||
shopping_rects[0][SHOPRECT_ITEM_HELP].top += 3;
|
||||
@@ -1624,8 +1623,8 @@ bool handle_keystroke(sf::Event& event){
|
||||
}
|
||||
for(i = 0; i < 8; i++)
|
||||
if(chr2 == shop_chars[i]) {
|
||||
pass_point.x = shopping_rects[i][1].left + 9 + ul.x;
|
||||
pass_point.y = shopping_rects[i][1].top + 9 + ul.y;
|
||||
pass_point.x = shopping_rects[i][SHOPRECT_ACTIVE_AREA].left + 9 + ul.x;
|
||||
pass_point.y = shopping_rects[i][SHOPRECT_ACTIVE_AREA].top + 9 + ul.y;
|
||||
pass_event.mouseButton.x = pass_point.x;
|
||||
pass_event.mouseButton.y = pass_point.y;
|
||||
are_done = handle_action(pass_event);
|
||||
|
||||
@@ -53,6 +53,7 @@ extern sf::RenderWindow mini_map;
|
||||
extern bool game_run_before,skip_boom_delay;
|
||||
extern cUniverse univ;
|
||||
extern sf::Texture pc_gworld;
|
||||
extern std::map<eSkill,short> skill_max;
|
||||
|
||||
extern cScenarioList scen_headers;
|
||||
|
||||
@@ -88,8 +89,6 @@ extern std::vector<word_rect_t> talk_words;
|
||||
// n000 + i - magic store n item i
|
||||
// talk_area_rect and talk_help_rect used for this too
|
||||
eGameMode store_pre_shop_mode;
|
||||
// 0 - whole area, 1 - active area 2 - graphic 3 - item name
|
||||
// 4 - item cost 5 - item extra str 6 - item help button
|
||||
extern rectangle shopping_rects[8][7];
|
||||
// TODO: The duplication of rectangle here shouldn't be necessary...
|
||||
rectangle bottom_help_rects[4] = {rectangle{356,6,368,250},rectangle{374,6,386,270},rectangle{386,6,398,250},rectangle{398,6,410,250}};
|
||||
@@ -194,11 +193,11 @@ void handle_shop_event(location p) {
|
||||
for(i = 0; i < 8; i++) {
|
||||
store_what_picked = i + shop_sbar->getPosition();
|
||||
if(store_what_picked >= active_shop.size()) break;
|
||||
if(p.in(shopping_rects[i][1])) {
|
||||
click_shop_rect(shopping_rects[i][1]);
|
||||
if(p.in(shopping_rects[i][SHOPRECT_ACTIVE_AREA])) {
|
||||
click_shop_rect(shopping_rects[i][SHOPRECT_ACTIVE_AREA]);
|
||||
handle_sale(active_shop.getItem(store_what_picked), store_what_picked);
|
||||
} else if(p.in(shopping_rects[i][6]) && active_shop.getType() != eShopType::HEALING){
|
||||
click_shop_rect(shopping_rects[i][6]);
|
||||
} else if(p.in(shopping_rects[i][SHOPRECT_ITEM_HELP]) && active_shop.getType() != eShopType::HEALING){
|
||||
click_shop_rect(shopping_rects[i][SHOPRECT_ITEM_HELP]);
|
||||
handle_info_request(active_shop.getItem(store_what_picked));
|
||||
}
|
||||
}
|
||||
@@ -208,6 +207,7 @@ void handle_sale(cShopItem item, int i) {
|
||||
cItem base_item = item.item;
|
||||
short cost = item.cost;
|
||||
rectangle dummy_rect = {0,0,0,0};
|
||||
size_t size_before = active_shop.size();
|
||||
|
||||
switch(item.type) {
|
||||
case eShopItemType::ITEM:
|
||||
@@ -216,11 +216,10 @@ void handle_sale(cShopItem item, int i) {
|
||||
play_sound(-38);
|
||||
take_gold(cost,true);
|
||||
univ.party[current_pc].give_item(base_item,true);
|
||||
if(active_shop.getType() != eShopType::ITEMS) {
|
||||
// Magic shops have limited stock
|
||||
active_shop.clearItem(i);
|
||||
// Magic shops have limited stock
|
||||
active_shop.takeOne(i);
|
||||
if(active_shop.size() != size_before)
|
||||
shop_sbar->setMaximum(shop_sbar->getMaximum() - 1);
|
||||
}
|
||||
break;
|
||||
case eBuyStatus::NO_SPACE: ASB("Can't carry any more items."); break;
|
||||
case eBuyStatus::NEED_GOLD: ASB("Not enough cash."); break;
|
||||
@@ -325,6 +324,27 @@ void handle_sale(cShopItem item, int i) {
|
||||
give_help(41,0);
|
||||
}
|
||||
break;
|
||||
case eShopItemType::SKILL:
|
||||
if(base_item.item_level < 0 || base_item.item_level > 18) {
|
||||
beep();
|
||||
giveError("Error: The scenario tried to sell you an invalid skill!");
|
||||
break;
|
||||
}
|
||||
eSkill skill = eSkill(base_item.item_level);
|
||||
if(univ.party[current_pc].skills[skill] >= skill_max[skill])
|
||||
ASB("You're already an expert in this skill.");
|
||||
else if(!take_gold(cost, false))
|
||||
ASB("Not enough gold.");
|
||||
else {
|
||||
// TODO: No idea what's a good sound here.
|
||||
play_sound(62);
|
||||
ASB("You learn a little...");
|
||||
active_shop.takeOne(i);
|
||||
if(active_shop.size() != size_before)
|
||||
shop_sbar->setMaximum(shop_sbar->getMaximum() - 1);
|
||||
univ.party[current_pc].skills[skill]++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(overall_mode != MODE_SHOPPING) {
|
||||
@@ -356,6 +376,9 @@ void handle_info_request(cShopItem item) {
|
||||
case eShopItemType::PRIEST_SPELL:
|
||||
display_spells(eSkill::PRIEST_SPELLS,base_item.item_level - 900 - 30,0);
|
||||
break;
|
||||
case eShopItemType::SKILL:
|
||||
display_skills(eSkill(base_item.item_level), nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +389,7 @@ void set_up_shop_array(eShopType store_shop_type, short store_shop_min, short st
|
||||
switch(store_shop_type) {
|
||||
case eShopType::ITEMS:
|
||||
for(int i = store_shop_min; i <= store_shop_max; i++)
|
||||
active_shop.addItem(get_stored_item(i));
|
||||
active_shop.addItem(get_stored_item(i), cShop::INFINITE);
|
||||
break;
|
||||
case eShopType::HEALING:
|
||||
if(univ.party[current_pc].cur_health < univ.party[current_pc].max_health)
|
||||
@@ -396,19 +419,19 @@ void set_up_shop_array(eShopType store_shop_type, short store_shop_min, short st
|
||||
active_shop.addSpecial(eShopItemType::FOOD, i);
|
||||
break;
|
||||
case eShopType::MAGIC_JUNK:
|
||||
active_shop.addItems(univ.party.magic_store_items[0].begin(), univ.party.magic_store_items[0].end());
|
||||
active_shop.addItems(univ.party.magic_store_items[0].begin(), univ.party.magic_store_items[0].end(), 1);
|
||||
break;
|
||||
case eShopType::MAGIC_LOUSY:
|
||||
active_shop.addItems(univ.party.magic_store_items[1].begin(), univ.party.magic_store_items[1].end());
|
||||
active_shop.addItems(univ.party.magic_store_items[1].begin(), univ.party.magic_store_items[1].end(), 1);
|
||||
break;
|
||||
case eShopType::MAGIC_SO_SO:
|
||||
active_shop.addItems(univ.party.magic_store_items[2].begin(), univ.party.magic_store_items[2].end());
|
||||
active_shop.addItems(univ.party.magic_store_items[2].begin(), univ.party.magic_store_items[2].end(), 1);
|
||||
break;
|
||||
case eShopType::MAGIC_GOOD:
|
||||
active_shop.addItems(univ.party.magic_store_items[3].begin(), univ.party.magic_store_items[3].end());
|
||||
active_shop.addItems(univ.party.magic_store_items[3].begin(), univ.party.magic_store_items[3].end(), 1);
|
||||
break;
|
||||
case eShopType::MAGIC_GREAT:
|
||||
active_shop.addItems(univ.party.magic_store_items[4].begin(), univ.party.magic_store_items[4].end());
|
||||
active_shop.addItems(univ.party.magic_store_items[4].begin(), univ.party.magic_store_items[4].end(), 1);
|
||||
break;
|
||||
case eShopType::MAGE:
|
||||
for(int i = store_shop_min; i <= store_shop_max && i < 62; i++)
|
||||
@@ -422,6 +445,10 @@ void set_up_shop_array(eShopType store_shop_type, short store_shop_min, short st
|
||||
for(int i = store_shop_min; i <= store_shop_max && i < 20; i++)
|
||||
active_shop.addSpecial(eShopItemType::ALCHEMY, i);
|
||||
break;
|
||||
case eShopType::SKILLS:
|
||||
for(int i = max(0,store_shop_min); i <= min(18,store_shop_max); i++)
|
||||
active_shop.addSpecial(eShopItemType::SKILL, i);
|
||||
break;
|
||||
}
|
||||
shop_sbar->setMaximum(active_shop.size() - 8);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <memory>
|
||||
#include "location.h"
|
||||
#include "shop.hpp"
|
||||
#include "spell.hpp"
|
||||
|
||||
short monsters_faces[190] = {
|
||||
0,1,2,3,4,5,6,7,8,9,
|
||||
@@ -67,6 +68,9 @@ extern short store_talk_face_pic;
|
||||
extern cUniverse univ;
|
||||
extern cCustomGraphics spec_scen_g;
|
||||
extern bool fog_lifted;
|
||||
extern const short alch_difficulty[20];
|
||||
extern const eItemAbil alch_ingred1[20];
|
||||
extern const eItemAbil alch_ingred2[20];
|
||||
|
||||
// Talk vars
|
||||
extern eGameMode store_pre_talk_mode;
|
||||
@@ -765,12 +769,13 @@ void draw_shop_graphics(bool pressed,rectangle clip_area_rect) {
|
||||
for(i = 0; i < 8; i++) {
|
||||
current_pos = i + shop_sbar->getPosition();
|
||||
cShopItem item = active_shop.getItem(i);
|
||||
eSpell spell; eSkill skill;
|
||||
if(item.type == eShopItemType::EMPTY)
|
||||
continue; // theoretically, this shouldn't happen
|
||||
cur_cost = item.cost;
|
||||
base_item = item.item;
|
||||
std::string cur_name = base_item.full_name, cur_info_str;
|
||||
rectangle from_rect, to_rect = shopping_rects[i][2];
|
||||
rectangle from_rect, to_rect = shopping_rects[i][SHOPRECT_GRAPHIC];
|
||||
sf::Texture* from_gw;
|
||||
switch(item.type) {
|
||||
case eShopItemType::ITEM:
|
||||
@@ -778,13 +783,21 @@ void draw_shop_graphics(bool pressed,rectangle clip_area_rect) {
|
||||
cur_info_str = get_item_interesting_string(base_item);
|
||||
break;
|
||||
case eShopItemType::ALCHEMY:
|
||||
cur_info_str = "";
|
||||
cur_info_str = get_str("item-abilities", int(alch_ingred1[base_item.item_level]) + 1);
|
||||
if(alch_ingred2[base_item.item_level] != eItemAbil::NONE) {
|
||||
cur_info_str += " and " + get_str("item-abilities", int(alch_ingred2[base_item.item_level]) + 1);
|
||||
}
|
||||
break;
|
||||
case eShopItemType::MAGE_SPELL:
|
||||
cur_info_str = "";
|
||||
spell = cSpell::fromNum(eSkill::MAGE_SPELLS, base_item.item_level);
|
||||
cur_info_str = "Level: " + std::to_string((*spell).level) + " SP: " + std::to_string((*spell).cost);
|
||||
break;
|
||||
case eShopItemType::PRIEST_SPELL:
|
||||
cur_info_str = "";
|
||||
spell = cSpell::fromNum(eSkill::PRIEST_SPELLS, base_item.item_level);
|
||||
cur_info_str = "Level: " + std::to_string((*spell).level) + " SP: " + std::to_string((*spell).cost);
|
||||
break;
|
||||
case eShopItemType::SKILL:
|
||||
cur_info_str = "Increase skill by 1";
|
||||
break;
|
||||
default: // Healing
|
||||
cur_info_str = "";
|
||||
@@ -793,18 +806,16 @@ void draw_shop_graphics(bool pressed,rectangle clip_area_rect) {
|
||||
graf_pos_ref(from_gw, from_rect) = calc_item_rect(base_item.graphic_num,to_rect);
|
||||
rect_draw_some_item(*from_gw, from_rect, talk_gworld, to_rect, sf::BlendAlpha);
|
||||
|
||||
// Now draw item shopping_rects[i][7]
|
||||
// 0 - whole area, 1 - active area 2 - graphic 3 - item name
|
||||
// 4 - item cost 5 - item extra str 6 - item help button
|
||||
// Now draw item
|
||||
style.pointSize = 12;
|
||||
style.lineHeight = 12;
|
||||
win_draw_string(talk_gworld,shopping_rects[i][3],cur_name,eTextMode::WRAP,style);
|
||||
win_draw_string(talk_gworld,shopping_rects[i][SHOPRECT_ITEM_NAME],cur_name,eTextMode::WRAP,style);
|
||||
cur_name = "Cost: " + std::to_string(cur_cost);
|
||||
win_draw_string(talk_gworld,shopping_rects[i][4],cur_name,eTextMode::WRAP,style);
|
||||
win_draw_string(talk_gworld,shopping_rects[i][SHOPRECT_ITEM_COST],cur_name,eTextMode::WRAP,style);
|
||||
style.pointSize = 10;
|
||||
win_draw_string(talk_gworld,shopping_rects[i][5],cur_info_str,eTextMode::WRAP,style);
|
||||
win_draw_string(talk_gworld,shopping_rects[i][SHOPRECT_ITEM_EXTRA],cur_info_str,eTextMode::WRAP,style);
|
||||
if(active_shop.getType() != eShopType::HEALING) // Draw info button
|
||||
rect_draw_some_item(invenbtn_gworld,item_info_from,talk_gworld,shopping_rects[i][6],pressed ? sf::BlendNone : sf::BlendAlpha);
|
||||
rect_draw_some_item(invenbtn_gworld,item_info_from,talk_gworld,shopping_rects[i][SHOPRECT_ITEM_HELP],pressed ? sf::BlendNone : sf::BlendAlpha);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2310,21 +2310,11 @@ void start_town_targeting(eSpell s_num,short who_c,bool freebie,eSpellPat pat) {
|
||||
}
|
||||
}
|
||||
|
||||
extern short alch_difficulty[20];
|
||||
extern const short alch_difficulty[20];
|
||||
extern const eItemAbil alch_ingred1[20];
|
||||
extern const eItemAbil alch_ingred2[20];
|
||||
|
||||
void do_alchemy() {
|
||||
static const eItemAbil ingred1_needed[20] = {
|
||||
eItemAbil::HOLLY,eItemAbil::COMFREY,eItemAbil::HOLLY,eItemAbil::COMFREY,eItemAbil::WORMGRASS,
|
||||
eItemAbil::NETTLE,eItemAbil::NETTLE,eItemAbil::WORMGRASS,eItemAbil::GRAYMOLD,eItemAbil::WORMGRASS,
|
||||
eItemAbil::GRAYMOLD,eItemAbil::ASPTONGUE,eItemAbil::GRAYMOLD,eItemAbil::MANDRAKE,eItemAbil::EMBERF,
|
||||
eItemAbil::MANDRAKE,eItemAbil::MANDRAKE,eItemAbil::NETTLE,eItemAbil::GRAYMOLD,eItemAbil::MANDRAKE,
|
||||
};
|
||||
static const eItemAbil ingred2_needed[20] = {
|
||||
eItemAbil::NONE,eItemAbil::NONE,eItemAbil::NONE,eItemAbil::WORMGRASS,eItemAbil::NONE,
|
||||
eItemAbil::NONE,eItemAbil::NONE,eItemAbil::NETTLE,eItemAbil::NONE,eItemAbil::ASPTONGUE,
|
||||
eItemAbil::HOLLY,eItemAbil::NONE,eItemAbil::COMFREY,eItemAbil::NONE,eItemAbil::NONE,
|
||||
eItemAbil::ASPTONGUE,eItemAbil::EMBERF,eItemAbil::EMBERF,eItemAbil::ASPTONGUE,eItemAbil::EMBERF,
|
||||
};
|
||||
static const short fail_chance[20] = {
|
||||
50,40,30,20,10,
|
||||
8,6,4,2,0,
|
||||
@@ -2347,19 +2337,19 @@ void do_alchemy() {
|
||||
return;
|
||||
}
|
||||
|
||||
if((which_item = univ.party[pc_num].has_abil(ingred1_needed[which_p])) == 24) {
|
||||
if((which_item = univ.party[pc_num].has_abil(alch_ingred1[which_p])) == 24) {
|
||||
add_string_to_buf("Alchemy: Don't have ingredients.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ingred2_needed[which_p] != eItemAbil::NONE) {
|
||||
if(univ.party[pc_num].has_abil(ingred2_needed[which_p]) == 24) {
|
||||
if(alch_ingred2[which_p] != eItemAbil::NONE) {
|
||||
if(univ.party[pc_num].has_abil(alch_ingred2[which_p]) == 24) {
|
||||
add_string_to_buf("Alchemy: Don't have ingredients.");
|
||||
return;
|
||||
}
|
||||
univ.party[pc_num].remove_charge(which_item);
|
||||
// We call this twice because remove_charge might move the item and change its index
|
||||
which_item2 = univ.party[pc_num].has_abil(ingred2_needed[which_p]);
|
||||
which_item2 = univ.party[pc_num].has_abil(alch_ingred2[which_p]);
|
||||
univ.party[pc_num].remove_charge(which_item2);
|
||||
} else univ.party[pc_num].remove_charge(which_item);
|
||||
|
||||
|
||||
@@ -11,6 +11,34 @@
|
||||
#include "mathutil.hpp"
|
||||
#include "graphtool.hpp" // for get_str
|
||||
|
||||
std::map<eSkill,short> skill_cost = {
|
||||
{eSkill::STRENGTH,3}, {eSkill::DEXTERITY,3}, {eSkill::INTELLIGENCE,3},
|
||||
{eSkill::EDGED_WEAPONS,2}, {eSkill::BASHING_WEAPONS,2}, {eSkill::POLE_WEAPONS,2},
|
||||
{eSkill::THROWN_MISSILES,1}, {eSkill::ARCHERY,2}, {eSkill::DEFENSE,2},
|
||||
{eSkill::MAGE_SPELLS,6}, {eSkill::PRIEST_SPELLS,5}, {eSkill::MAGE_LORE,1},
|
||||
{eSkill::ALCHEMY,2}, {eSkill::ITEM_LORE,4}, {eSkill::DISARM_TRAPS,2},
|
||||
{eSkill::LOCKPICKING,1}, {eSkill::ASSASSINATION,4}, {eSkill::POISON,2},
|
||||
{eSkill::LUCK,5},
|
||||
};
|
||||
std::map<eSkill,short> skill_max = {
|
||||
{eSkill::STRENGTH,20}, {eSkill::DEXTERITY,20}, {eSkill::INTELLIGENCE,20},
|
||||
{eSkill::EDGED_WEAPONS,20}, {eSkill::BASHING_WEAPONS,20}, {eSkill::POLE_WEAPONS,20},
|
||||
{eSkill::THROWN_MISSILES,20}, {eSkill::ARCHERY,20}, {eSkill::DEFENSE,20},
|
||||
{eSkill::MAGE_SPELLS,7}, {eSkill::PRIEST_SPELLS,7}, {eSkill::MAGE_LORE,20},
|
||||
{eSkill::ALCHEMY,20}, {eSkill::ITEM_LORE,10}, {eSkill::DISARM_TRAPS,20},
|
||||
{eSkill::LOCKPICKING,20}, {eSkill::ASSASSINATION,20}, {eSkill::POISON,20},
|
||||
{eSkill::LUCK,20},
|
||||
};
|
||||
std::map<eSkill,short> skill_g_cost = {
|
||||
{eSkill::STRENGTH,50}, {eSkill::DEXTERITY,503}, {eSkill::INTELLIGENCE,50},
|
||||
{eSkill::EDGED_WEAPONS,40}, {eSkill::BASHING_WEAPONS,40}, {eSkill::POLE_WEAPONS,40},
|
||||
{eSkill::THROWN_MISSILES,30}, {eSkill::ARCHERY,50}, {eSkill::DEFENSE,40},
|
||||
{eSkill::MAGE_SPELLS,250}, {eSkill::PRIEST_SPELLS,250}, {eSkill::MAGE_LORE,25},
|
||||
{eSkill::ALCHEMY,100}, {eSkill::ITEM_LORE,200}, {eSkill::DISARM_TRAPS,30},
|
||||
{eSkill::LOCKPICKING,20}, {eSkill::ASSASSINATION,100}, {eSkill::POISON,80},
|
||||
{eSkill::LUCK,0},
|
||||
};
|
||||
|
||||
static long cost_mult[7] = {5,7,10,13,16,20,25};
|
||||
|
||||
cShop::cShop() {}
|
||||
@@ -31,7 +59,7 @@ size_t cShop::size() {
|
||||
});
|
||||
}
|
||||
|
||||
void cShop::addItem(cItem item) {
|
||||
void cShop::addItem(cItem item, size_t quantity) {
|
||||
size_t i = firstEmpty();
|
||||
if(i >= items.size()) return;
|
||||
if(item.variety == eItemType::NO_ITEM) return;
|
||||
@@ -43,6 +71,7 @@ void cShop::addItem(cItem item) {
|
||||
items[i].cost *= item.charges;
|
||||
items[i].cost *= cost_mult[cost_adj];
|
||||
items[i].cost /= 10;
|
||||
items[i].quantity = quantity;
|
||||
}
|
||||
|
||||
static cItem store_mage_spells(short which_s) {
|
||||
@@ -122,15 +151,21 @@ void cShop::addSpecial(eShopItemType type, int n) {
|
||||
items[i].item = store_priest_spells(n);
|
||||
else if(type == eShopItemType::ALCHEMY)
|
||||
items[i].item = store_alchemy(n);
|
||||
else {
|
||||
else if(type == eShopItemType::SKILL) {
|
||||
items[i].item.graphic_num = 108;
|
||||
items[i].item.full_name = get_str("skills", n * 2 + 1);
|
||||
} else {
|
||||
items[i].item.graphic_num = 109;
|
||||
items[i].item.full_name = heal_types[int(type) - 700];
|
||||
}
|
||||
if(type == eShopItemType::MAGE_SPELL || type == eShopItemType::PRIEST_SPELL || type == eShopItemType::ALCHEMY)
|
||||
items[i].cost = items[i].item.value;
|
||||
else if(type == eShopItemType::SKILL)
|
||||
items[i].cost = skill_g_cost[eSkill(n)] * 1.5;
|
||||
else items[i].cost = heal_costs[int(type) - 700];
|
||||
items[i].cost *= cost_mult[cost_adj];
|
||||
items[i].cost /= 10;
|
||||
items[i].quantity = 0;
|
||||
}
|
||||
|
||||
cShopItem cShop::getItem(size_t i) const {
|
||||
@@ -149,6 +184,13 @@ std::string cShop::getName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
void cShop::takeOne(size_t i) {
|
||||
if(items[i].quantity == 1)
|
||||
clearItem(i);
|
||||
else if(items[i].quantity > 0)
|
||||
items[i].quantity--;
|
||||
}
|
||||
|
||||
void cShop::clearItem(size_t i) {
|
||||
std::copy(items.begin() + i + 1, items.end(), items.begin() + i);
|
||||
items.back().type = eShopItemType::EMPTY;
|
||||
|
||||
@@ -29,11 +29,13 @@ enum class eShopItemType {
|
||||
PRIEST_SPELL = 900,
|
||||
ALCHEMY = 500,
|
||||
FOOD = 600,
|
||||
SKILL = 1000,
|
||||
};
|
||||
|
||||
struct cShopItem {
|
||||
eShopItemType type = eShopItemType::EMPTY;
|
||||
int cost;
|
||||
size_t quantity;
|
||||
cItem item;
|
||||
};
|
||||
|
||||
@@ -44,18 +46,20 @@ class cShop {
|
||||
eShopType type;
|
||||
size_t firstEmpty();
|
||||
public:
|
||||
static const size_t INFINITE = 0;
|
||||
cShop();
|
||||
cShop(eShopType type, int adj, std::string name);
|
||||
void addItem(cItem item);
|
||||
void addItem(cItem item, size_t quantity);
|
||||
void addSpecial(eShopItemType type, int n = 0);
|
||||
template<typename Iter> void addItems(Iter begin, Iter end) {
|
||||
while(begin != end) addItem(*begin++);
|
||||
template<typename Iter> void addItems(Iter begin, Iter end, size_t quantity) {
|
||||
while(begin != end) addItem(*begin++, quantity);
|
||||
}
|
||||
size_t size();
|
||||
cShopItem getItem(size_t i) const;
|
||||
eShopType getType() const;
|
||||
int getCostAdjust() const;
|
||||
std::string getName() const;
|
||||
void takeOne(size_t i);
|
||||
void clearItem(size_t i);
|
||||
void clear();
|
||||
};
|
||||
|
||||
@@ -1002,6 +1002,7 @@ enum class eShopType {
|
||||
MAGIC_GOOD = 8,
|
||||
MAGIC_GREAT = 9,
|
||||
FOOD = 10,
|
||||
SKILLS = 11,
|
||||
};
|
||||
|
||||
enum class eAlchemy {
|
||||
|
||||
@@ -41,34 +41,10 @@ extern short which_pc_displayed;
|
||||
cPlayer *store_pc;
|
||||
sf::Texture button_num_gworld;
|
||||
|
||||
std::map<eSkill,short> skill_cost = {
|
||||
{eSkill::STRENGTH,3}, {eSkill::DEXTERITY,3}, {eSkill::INTELLIGENCE,3},
|
||||
{eSkill::EDGED_WEAPONS,2}, {eSkill::BASHING_WEAPONS,2}, {eSkill::POLE_WEAPONS,2},
|
||||
{eSkill::THROWN_MISSILES,1}, {eSkill::ARCHERY,2}, {eSkill::DEFENSE,2},
|
||||
{eSkill::MAGE_SPELLS,6}, {eSkill::PRIEST_SPELLS,5}, {eSkill::MAGE_LORE,1},
|
||||
{eSkill::ALCHEMY,2}, {eSkill::ITEM_LORE,4}, {eSkill::DISARM_TRAPS,2},
|
||||
{eSkill::LOCKPICKING,1}, {eSkill::ASSASSINATION,4}, {eSkill::POISON,2},
|
||||
{eSkill::LUCK,5},
|
||||
};
|
||||
std::map<eSkill,short> skill_max = {
|
||||
{eSkill::STRENGTH,20}, {eSkill::DEXTERITY,20}, {eSkill::INTELLIGENCE,20},
|
||||
{eSkill::EDGED_WEAPONS,20}, {eSkill::BASHING_WEAPONS,20}, {eSkill::POLE_WEAPONS,20},
|
||||
{eSkill::THROWN_MISSILES,20}, {eSkill::ARCHERY,20}, {eSkill::DEFENSE,20},
|
||||
{eSkill::MAGE_SPELLS,7}, {eSkill::PRIEST_SPELLS,7}, {eSkill::MAGE_LORE,20},
|
||||
{eSkill::ALCHEMY,20}, {eSkill::ITEM_LORE,10}, {eSkill::DISARM_TRAPS,20},
|
||||
{eSkill::LOCKPICKING,20}, {eSkill::ASSASSINATION,20}, {eSkill::POISON,20},
|
||||
{eSkill::LUCK,20},
|
||||
};
|
||||
std::map<eSkill,short> skill_g_cost = {
|
||||
{eSkill::STRENGTH,50}, {eSkill::DEXTERITY,503}, {eSkill::INTELLIGENCE,50},
|
||||
{eSkill::EDGED_WEAPONS,40}, {eSkill::BASHING_WEAPONS,40}, {eSkill::POLE_WEAPONS,40},
|
||||
{eSkill::THROWN_MISSILES,30}, {eSkill::ARCHERY,50}, {eSkill::DEFENSE,40},
|
||||
{eSkill::MAGE_SPELLS,250}, {eSkill::PRIEST_SPELLS,250}, {eSkill::MAGE_LORE,25},
|
||||
{eSkill::ALCHEMY,100}, {eSkill::ITEM_LORE,200}, {eSkill::DISARM_TRAPS,30},
|
||||
{eSkill::LOCKPICKING,20}, {eSkill::ASSASSINATION,100}, {eSkill::POISON,80},
|
||||
{eSkill::LUCK,0},
|
||||
};
|
||||
// The index here is the skill's level, not the skill itself; thus 20 is the max index since no spell can go above 20.
|
||||
extern std::map<eSkill,short> skill_cost;
|
||||
extern std::map<eSkill,short> skill_max;
|
||||
extern std::map<eSkill,short> skill_g_cost;
|
||||
// The index here is the skill's level, not the skill itself; thus 20 is the max index since no skill can go above 20.
|
||||
short skill_bonus[21] = {
|
||||
-3,-3,-2,-1,0,0,1,1,1,2,
|
||||
2,2,3,3,3,3,4,4,4,5,5};
|
||||
@@ -238,12 +214,24 @@ void pick_race_abil(cPlayer *pc,short mode) {
|
||||
pickAbil.run();
|
||||
}
|
||||
|
||||
short alch_difficulty[20] = {
|
||||
extern const short alch_difficulty[20] = {
|
||||
1,1,1,3,3,
|
||||
4,5,5,7,9,
|
||||
9,10,12,12,9,
|
||||
14,19,10,16,20
|
||||
};
|
||||
extern const eItemAbil alch_ingred1[20] = {
|
||||
eItemAbil::HOLLY,eItemAbil::COMFREY,eItemAbil::HOLLY,eItemAbil::COMFREY,eItemAbil::WORMGRASS,
|
||||
eItemAbil::NETTLE,eItemAbil::NETTLE,eItemAbil::WORMGRASS,eItemAbil::GRAYMOLD,eItemAbil::WORMGRASS,
|
||||
eItemAbil::GRAYMOLD,eItemAbil::ASPTONGUE,eItemAbil::GRAYMOLD,eItemAbil::MANDRAKE,eItemAbil::EMBERF,
|
||||
eItemAbil::MANDRAKE,eItemAbil::MANDRAKE,eItemAbil::NETTLE,eItemAbil::GRAYMOLD,eItemAbil::MANDRAKE,
|
||||
};
|
||||
extern const eItemAbil alch_ingred2[20] = {
|
||||
eItemAbil::NONE,eItemAbil::NONE,eItemAbil::NONE,eItemAbil::WORMGRASS,eItemAbil::NONE,
|
||||
eItemAbil::NONE,eItemAbil::NONE,eItemAbil::NETTLE,eItemAbil::NONE,eItemAbil::ASPTONGUE,
|
||||
eItemAbil::HOLLY,eItemAbil::NONE,eItemAbil::COMFREY,eItemAbil::NONE,eItemAbil::NONE,
|
||||
eItemAbil::ASPTONGUE,eItemAbil::EMBERF,eItemAbil::EMBERF,eItemAbil::ASPTONGUE,eItemAbil::EMBERF,
|
||||
};
|
||||
|
||||
void display_alchemy(bool allowEdit) {
|
||||
short i;
|
||||
|
||||
@@ -252,7 +252,7 @@ short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, con
|
||||
strings = *ResMgr::get<StringRsrc>("special-contexts");
|
||||
break;
|
||||
case STRT_SHOP:
|
||||
strings = {"Items", "Mage Spells", "Priest Spells", "Alchemy", "Healing", "Magic Shop: Junk", "Magic Shop: Lousy", "Magic Shop: So-so", "Magic Shop: Good", "Magic Shop: Great"};
|
||||
strings = {"Items", "Mage Spells", "Priest Spells", "Alchemy", "Healing", "Magic Shop: Junk", "Magic Shop: Lousy", "Magic Shop: So-so", "Magic Shop: Good", "Magic Shop: Great", "Skill Shop"};
|
||||
break;
|
||||
case STRT_COST_ADJ:
|
||||
strings = {"Extremely Cheap", "Very Reasonable", "Pretty Average", "Somewhat Pricey", "Expensive", "Exorbitant", "Utterly Ridiculous"};
|
||||
@@ -660,12 +660,12 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t&
|
||||
else btn = 's';
|
||||
}
|
||||
if(btn == '#') {
|
||||
// TODO: Enumify the shop types
|
||||
switch(eShopType(me["x1b"].getTextAsNum())) {
|
||||
case eShopType::ITEMS: btn = 'i'; break;
|
||||
case eShopType::MAGE: btn = 'A'; break;
|
||||
case eShopType::PRIEST: btn = 'P'; break;
|
||||
case eShopType::ALCHEMY: btn = 'a'; break;
|
||||
case eShopType::SKILLS: btn = 'k'; break;
|
||||
}
|
||||
}
|
||||
short val = me[field].getTextAsNum(), mode = (btn == 'S' || btn == '$') ? 0 : edit_stack.top().mode, store;
|
||||
|
||||
Reference in New Issue
Block a user