Implement a dialog to edit shops in the scenario editor
This commit is contained in:
@@ -29,7 +29,8 @@ title {
|
||||
border: dashed green thin;
|
||||
}
|
||||
|
||||
.dark .text, .dark .led {
|
||||
.dark .text, .dark .led,
|
||||
.dark .button.tiny, .dark .button.push {
|
||||
color: white;
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ title {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.pict.missile {
|
||||
.pict.missile, .pict.item.tiny {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
pict
|
||||
<xsl:if test='@framed = "true" or not(@framed)'>framed </xsl:if>
|
||||
<xsl:value-of select='./@type'/>
|
||||
<xsl:if test='@size = "large" and @type != "monst"'>large</xsl:if>
|
||||
<xsl:if test='@size = "large" and @type != "monst"'> large</xsl:if>
|
||||
<xsl:if test='@size = "small" and @type = "item"'> tiny</xsl:if>
|
||||
</xsl:attribute>
|
||||
<xsl:if test='/dialog/@debug = "true" and @name'>
|
||||
<xsl:attribute name='title'>
|
||||
|
||||
15
rsrc/dialogs/edit-shop-item.xml
Normal file
15
rsrc/dialogs/edit-shop-item.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
|
||||
<dialog defbtn='okay' debug='true'>
|
||||
<pict type='dlog' num='16' top='8' left='8'/>
|
||||
<text size='large' top='8' left='50' width='150' height='17'>Editing Shop Entry</text>
|
||||
<text name='item' framed='true' top='50' left='10' width='200' height='16'/>
|
||||
<button name='choose' type='regular' top='47' left='220'>Choose</button>
|
||||
<text top='75' left='10' width='100' height='16'>Quantity:</text>
|
||||
<field name='amount' type='uint' top='73' left='110' width='80' height='16'/>
|
||||
<text top='75' left='200' width='80' height='16'>0 = infinite</text>
|
||||
<text name='chance-prompt' top='100' left='10' width='100' height='16'>Chance:</text>
|
||||
<field name='chance' type='uint' top='98' left='110' width='80' height='16'/>
|
||||
<button name='cancel' type='regular' def-key='esc' top='120' left='10'>Cancel</button>
|
||||
<button name='okay' type='regular' top='120' left='220'>OK</button>
|
||||
</dialog>
|
||||
22
rsrc/dialogs/edit-shop-special.xml
Normal file
22
rsrc/dialogs/edit-shop-special.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
|
||||
<dialog defbtn='okay' debug='true'>
|
||||
<pict type='dlog' num='16' top='8' left='8'/>
|
||||
<text size='large' top='8' left='50' width='150' height='17'>Editing Shop Entry</text>
|
||||
<text top='50' left='10' width='100' height='16'>Name:</text>
|
||||
<field name='name' top='48' left='110' width='200' height='16'/>
|
||||
<text top='75' left='10' width='100' height='16'>Special Node:</text>
|
||||
<field name='node' top='74' left='110' width='80' height='16'/>
|
||||
<button name='edit' type='large' top='71' left='200'>Create/Edit</button>
|
||||
<text top='100' left='10' width='100' height='16'>Quantity:</text>
|
||||
<field name='amount' type='uint' top='98' left='110' width='80' height='16'/>
|
||||
<text top='125' left='10' width='100' height='16'>Cost:</text>
|
||||
<field name='cost' type='uint' top='123' left='110' width='80' height='16'/>
|
||||
<text top='100' left='190' width='30' height='16'>Icon:</text>
|
||||
<pict name='icon' type='item' size='small' num='0' top='100' left='225'/>
|
||||
<button name='pickicon' top='96' left='247' type='regular'>Choose</button>
|
||||
<text top='150' left='10' width='100' height='16'>Description:</text>
|
||||
<field name='descr' top='148' left='110' width='200' height='100'/>
|
||||
<button name='cancel' type='regular' def-key='esc' top='255' left='10'>Cancel</button>
|
||||
<button name='okay' type='regular' top='255' left='247'>OK</button>
|
||||
</dialog>
|
||||
90
rsrc/dialogs/edit-shop.xml
Normal file
90
rsrc/dialogs/edit-shop.xml
Normal file
@@ -0,0 +1,90 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
|
||||
<dialog defbtn='okay' debug='true'>
|
||||
<pict type='dlog' num='16' top='8' left='8'/>
|
||||
<text size='large' top='8' left='50' width='200' height='17'>Editing Shop</text>
|
||||
<text top='8' left='250' width='100' height='16'>Shop number:</text>
|
||||
<text name='num' top='8' left='350' width='50' height='16'/>
|
||||
<text top='50' left='10' width='100' height='16'>Shop name:</text>
|
||||
<field name='name' top='48' left='110' width='200' height='16'/>
|
||||
<text top='30' left='320' width='150' height='58'>
|
||||
This is just a name to make it easier for you to identify the shop in the list of shops.
|
||||
It's not used in-game.
|
||||
</text>
|
||||
<text top='70' left='10' width='100' height='16'>Shop type:</text>
|
||||
<group name='type'>
|
||||
<led name='t1' top='70' left='110' width='180'>Standard shop (living only)</led>
|
||||
<led name='t2' top='90' left='110' width='180'>Healing/Alchemy (dead can shop)</led>
|
||||
<led name='t3' top='110' left='110' width='180'>Randomly generated</led>
|
||||
</group>
|
||||
<text top='130' left='10' width='100' height='16'>Message to show:</text>
|
||||
<group name='prompt'>
|
||||
<led name='p1' top='130' left='110' width='80'>Shopping</led>
|
||||
<led name='p2' top='150' left='110' width='80'>Healing</led>
|
||||
<led name='p3' top='170' left='110' width='80'>Mage Spells</led>
|
||||
<led name='p4' top='130' left='210' width='80'>Priest Spells</led>
|
||||
<led name='p5' top='150' left='210' width='80'>Mixed Spells</led>
|
||||
<led name='p6' top='170' left='210' width='80'>Alchemy</led>
|
||||
<led name='p7' top='130' left='310' width='80'>Training</led>
|
||||
</group>
|
||||
<button name='rand' type='tiny' top='190' left='10' width='440'>
|
||||
Click here to generate a standard random items shop.
|
||||
(This will replace the entire shop definition.)
|
||||
</button>
|
||||
<text top='210' left='28' width='300' height='16'>Or edit the shop item list below:</text>
|
||||
<stack name='items'>
|
||||
<text name='n1' top='230' left='10' width='15' height='16'/>
|
||||
<pict name='pict1' type='item' num='0' size='small' top='230' left='30'/>
|
||||
<text name='item1' framed='true' top='230' left='55' width='200' height='16'/>
|
||||
|
||||
<text name='n2' top='255' left='10' width='15' height='16'/>
|
||||
<pict name='pict2' type='item' num='0' size='small' top='255' left='30'/>
|
||||
<text name='item2' framed='true' top='255' left='55' width='200' height='16'/>
|
||||
|
||||
<text name='n3' top='280' left='10' width='15' height='16'/>
|
||||
<pict name='pict3' type='item' num='0' size='small' top='280' left='30'/>
|
||||
<text name='item3' framed='true' top='280' left='55' width='200' height='16'/>
|
||||
|
||||
<text name='n4' top='305' left='10' width='15' height='16'/>
|
||||
<pict name='pict4' type='item' num='0' size='small' top='305' left='30'/>
|
||||
<text name='item4' framed='true' top='305' left='55' width='200' height='16'/>
|
||||
|
||||
<text name='n5' top='330' left='10' width='15' height='16'/>
|
||||
<pict name='pict5' type='item' num='0' size='small' top='330' left='30'/>
|
||||
<text name='item5' framed='true' top='330' left='55' width='200' height='16'/>
|
||||
</stack>
|
||||
<button name='ed1' type='regular' top='227' left='265'>Edit</button>
|
||||
<button name='del1' type='regular' top='227' left='330'>Delete</button>
|
||||
<button name='ed2' type='regular' top='252' left='265'>Edit</button>
|
||||
<button name='del2' type='regular' top='252' left='330'>Delete</button>
|
||||
<button name='ed3' type='regular' top='277' left='265'>Edit</button>
|
||||
<button name='del3' type='regular' top='277' left='330'>Delete</button>
|
||||
<button name='ed4' type='regular' top='302' left='265'>Edit</button>
|
||||
<button name='del4' type='regular' top='302' left='330'>Delete</button>
|
||||
<button name='ed5' type='regular' top='327' left='265'>Edit</button>
|
||||
<button name='del5' type='regular' top='327' left='330'>Delete</button>
|
||||
<button name='up' type='up' top='227' left='410'/>
|
||||
<button name='down' type='down' top='327' left='410'/>
|
||||
|
||||
<text top='350' left='10' width='200'>Add an item:</text>
|
||||
<button name='item' type='regular' top='365' left='10'>Item</button>
|
||||
<button name='mage' type='regular' top='365' left='75'>Mage</button>
|
||||
<button name='priest' type='regular' top='365' left='140'>Priest</button>
|
||||
<button name='alch' type='regular' top='365' left='205'>Alchemy</button>
|
||||
<button name='skill' type='regular' top='365' left='270'>Skill</button>
|
||||
|
||||
<button name='heal' type='regular' top='390' left='10'>Healing</button>
|
||||
<button name='treas' type='regular' top='390' left='75'>Treasure</button>
|
||||
<button name='class' type='regular' top='390' left='140'>Class</button>
|
||||
<button name='opt' type='regular' top='390' left='205'>Optional</button>
|
||||
<button name='spec' type='regular' top='390' left='270'>Special</button>
|
||||
|
||||
<text top='360' left='370' width='100' height='16'>Shopping Face:</text>
|
||||
<button name='pickface' type='regular' top='390' left='410'>Choose</button>
|
||||
<pict name='face' type='talk' num='0' top='380' left='370'/>
|
||||
|
||||
<button name='left' type='left' top='430' left='10'/>
|
||||
<button name='right' type='right' top='430' left='75'/>
|
||||
<button name='cancel' type='regular' top='430' left='345'>Cancel</button>
|
||||
<button name='okay' type='regular' top='430' left='410'>OK</button>
|
||||
</dialog>
|
||||
10
rsrc/strings/shop-specials.txt
Normal file
10
rsrc/strings/shop-specials.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Heal Wounds
|
||||
Cure Poison
|
||||
Cure Disease
|
||||
Cure Acid
|
||||
Cure Paralysis
|
||||
Remove Curse
|
||||
Destone
|
||||
Raise Dead
|
||||
Resurrect
|
||||
Cure Dumbfounding
|
||||
@@ -199,6 +199,12 @@ cItem::cItem(long preset) : cItem() {
|
||||
name = "Potion";
|
||||
magic = true;
|
||||
break;
|
||||
case 'spec':
|
||||
item_level = -1;
|
||||
full_name = "Call Special Node";
|
||||
case 'shop':
|
||||
graphic_num = 105; // The blank graphic
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ cShop::cShop(eShopType type, eShopPrompt prompt, pic_num_t pic, int adj, std::st
|
||||
face(pic)
|
||||
{}
|
||||
|
||||
cShop::cShop(std::string name) : cShop(eShopType::NORMAL, eShopPrompt::SHOPPING, 0, 0, name) {}
|
||||
|
||||
cShop::cShop(long preset) {
|
||||
const short loot_index[10] = {1,1,1,1,2,2,2,3,3,4};
|
||||
|
||||
@@ -96,7 +98,7 @@ size_t cShop::size() {
|
||||
});
|
||||
}
|
||||
|
||||
void cShop::addItem(cItem item, size_t quantity, int chance) {
|
||||
void cShop::addItem(size_t n, cItem item, size_t quantity, int chance) {
|
||||
size_t i = firstEmpty();
|
||||
if(i >= items.size()) return;
|
||||
if(item.variety == eItemType::NO_ITEM) return;
|
||||
@@ -104,6 +106,7 @@ void cShop::addItem(cItem item, size_t quantity, int chance) {
|
||||
items[i].item = item;
|
||||
items[i].item.ident = true;
|
||||
items[i].quantity = quantity;
|
||||
items[i].index = n;
|
||||
if(chance < 100)
|
||||
items[i].quantity = min(999,quantity) + chance * 1000;
|
||||
}
|
||||
@@ -168,6 +171,12 @@ static cItem store_alchemy(short which_s) {
|
||||
}
|
||||
|
||||
void cShop::addSpecial(eShopItemType type, int n) {
|
||||
if(type == eShopItemType::EMPTY || type == eShopItemType::CALL_SPECIAL) return;
|
||||
if(type == eShopItemType::OPTIONAL || type == eShopItemType::ITEM) return;
|
||||
replaceSpecial(firstEmpty(), type, n);
|
||||
}
|
||||
|
||||
void cShop::replaceSpecial(size_t i, eShopItemType type, int n) {
|
||||
// TODO: Make this a std::map instead
|
||||
static const short heal_costs[10] = {50,30,80,90,100,250,500,1000,3000,100};
|
||||
static const char*const heal_types[] = {
|
||||
@@ -178,9 +187,11 @@ void cShop::addSpecial(eShopItemType type, int n) {
|
||||
if(type == eShopItemType::ITEM) return;
|
||||
if(type == eShopItemType::OPTIONAL) return;
|
||||
if(type == eShopItemType::CALL_SPECIAL) return;
|
||||
size_t i = firstEmpty();
|
||||
if(i >= items.size()) return;
|
||||
items[i].type = type;
|
||||
if(type >= eShopItemType::HEAL_WOUNDS)
|
||||
items[i].index = int(type) - int(eShopItemType::HEAL_WOUNDS);
|
||||
else items[i].index = n;
|
||||
if(type == eShopItemType::MAGE_SPELL)
|
||||
items[i].item = store_mage_spells(n);
|
||||
else if(type == eShopItemType::PRIEST_SPELL)
|
||||
@@ -191,19 +202,21 @@ void cShop::addSpecial(eShopItemType type, int n) {
|
||||
items[i].item.graphic_num = 108;
|
||||
items[i].item.full_name = get_str("skills", n * 2 + 1);
|
||||
} else if(type == eShopItemType::TREASURE) {
|
||||
items[i].item.graphic_num = 45;
|
||||
items[i].item.item_level = n;
|
||||
items[i].item.full_name = "Treasure (type " + std::to_string(n) + ")";
|
||||
} else if(type == eShopItemType::CLASS) {
|
||||
items[i].item.graphic_num = 65;
|
||||
items[i].item.special_class = n;
|
||||
items[i].item.full_name = "Item of special class " + std::to_string(n);
|
||||
} else {
|
||||
items[i].item.graphic_num = 109;
|
||||
items[i].item.full_name = heal_types[int(type) - int(eShopItemType::HEAL_WOUNDS)];
|
||||
items[i].item.full_name = heal_types[items[i].index];
|
||||
}
|
||||
if(type == eShopItemType::SKILL)
|
||||
items[i].item.value = skill_g_cost[eSkill(n)] * 1.5;
|
||||
else if(type >= eShopItemType::HEAL_WOUNDS)
|
||||
items[i].item.value = heal_costs[int(type) - int(eShopItemType::HEAL_WOUNDS)];
|
||||
items[i].item.value = heal_costs[items[i].index];
|
||||
items[i].quantity = 0;
|
||||
}
|
||||
|
||||
@@ -251,6 +264,18 @@ void cShop::setCostAdjust(int adj) {
|
||||
cost_adj = adj;
|
||||
}
|
||||
|
||||
void cShop::setFace(pic_num_t pic) {
|
||||
face = pic;
|
||||
}
|
||||
|
||||
void cShop::setType(eShopType t) {
|
||||
type = t;
|
||||
}
|
||||
|
||||
void cShop::setPrompt(eShopPrompt p) {
|
||||
prompt = p;
|
||||
}
|
||||
|
||||
void cShop::takeOne(size_t i) {
|
||||
if(items[i].quantity == 1) {
|
||||
items[i].type = eShopItemType::EMPTY;
|
||||
|
||||
@@ -30,6 +30,7 @@ enum class eShopItemType {
|
||||
CLASS,
|
||||
OPTIONAL,
|
||||
CALL_SPECIAL,
|
||||
// All non-healing types must be above here and all healing types below, with HEAL_WOUNDS kept first
|
||||
HEAL_WOUNDS,
|
||||
CURE_POISON,
|
||||
CURE_DISEASE,
|
||||
@@ -44,8 +45,8 @@ enum class eShopItemType {
|
||||
|
||||
struct cShopItem {
|
||||
eShopItemType type = eShopItemType::EMPTY;
|
||||
size_t quantity;
|
||||
cItem item;
|
||||
size_t quantity, index;
|
||||
cItem item = cItem('shop');
|
||||
int getCost(int adj);
|
||||
};
|
||||
|
||||
@@ -61,14 +62,16 @@ public:
|
||||
static const size_t INFINITE = 0;
|
||||
cShop();
|
||||
cShop(eShopType type, eShopPrompt prompt, pic_num_t pic, int adj, std::string name);
|
||||
explicit cShop(std::string name);
|
||||
explicit cShop(long preset);
|
||||
void addItem(cItem item, size_t quantity, int chance = 100);
|
||||
void addItem(size_t i, cItem item, size_t quantity, int chance = 100);
|
||||
void addSpecial(std::string name, std::string descr, pic_num_t pic, int node, int cost, int quantity);
|
||||
void addSpecial(eShopItemType type, int n = 0);
|
||||
template<typename Iter> void addItems(Iter begin, Iter end, size_t quantity) {
|
||||
while(begin != end) addItem(*begin++, quantity);
|
||||
template<typename Iter> void addItems(size_t start, Iter begin, Iter end, size_t quantity) {
|
||||
while(begin != end) addItem(start++, *begin++, quantity);
|
||||
}
|
||||
void replaceItem(size_t i, cShopItem newItem);
|
||||
void replaceSpecial(size_t i, eShopItemType type, int n = 0);
|
||||
size_t size();
|
||||
cShopItem getItem(size_t i) const;
|
||||
eShopType getType() const;
|
||||
@@ -78,6 +81,9 @@ public:
|
||||
eShopPrompt getPrompt() const;
|
||||
void setCostAdjust(int adj);
|
||||
void setName(std::string name);
|
||||
void setType(eShopType t);
|
||||
void setFace(pic_num_t pic);
|
||||
void setPrompt(eShopPrompt p);
|
||||
void takeOne(size_t i);
|
||||
void clearItem(size_t i);
|
||||
void clear();
|
||||
|
||||
@@ -51,7 +51,7 @@ template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){
|
||||
Iterator<Attribute> attr;
|
||||
std::string name;
|
||||
ePicType type;
|
||||
bool wide = false, tall = false, custom = false;
|
||||
bool wide = false, tall = false, custom = false, tiny = false;
|
||||
bool foundTop = false, foundLeft = false, foundType = false, foundNum = false; // required attributes
|
||||
rectangle frame;
|
||||
int width = 0, height = 0;
|
||||
@@ -111,6 +111,7 @@ template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){
|
||||
if(val == "wide") wide = true;
|
||||
else if(val == "tall") tall = true;
|
||||
else if(val == "large") wide = tall = true;
|
||||
else if(val == "small") tiny = true;
|
||||
else throw xBadVal("pict",name,val,attr->Row(),attr->Column(),fname);
|
||||
}else if(name == "def-key"){
|
||||
std::string val;
|
||||
@@ -154,6 +155,9 @@ template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){
|
||||
else if(p.second->getPicType() == PIC_SCEN) p.second->setPict(wasPic, PIC_SCEN_LG);
|
||||
else if(p.second->getPicType() == PIC_DLOG) p.second->setPict(wasPic, PIC_DLOG_LG);
|
||||
}
|
||||
} else if(tiny && type == PIC_ITEM) {
|
||||
pic_num_t wasPic = p.second->getPicNum();
|
||||
p.second->setPict(wasPic, PIC_TINY_ITEM);
|
||||
}
|
||||
frame.right = frame.left;
|
||||
frame.bottom = frame.top;
|
||||
|
||||
@@ -27,6 +27,7 @@ void cPict::init(){
|
||||
drawPict()[PIC_TALK] = &cPict::drawPresetTalk;
|
||||
drawPict()[PIC_SCEN] = &cPict::drawPresetScen;
|
||||
drawPict()[PIC_ITEM] = &cPict::drawPresetItem;
|
||||
drawPict()[PIC_TINY_ITEM] = &cPict::drawPresetTinyItem;
|
||||
drawPict()[PIC_PC] = &cPict::drawPresetPc;
|
||||
drawPict()[PIC_FIELD] = &cPict::drawPresetField;
|
||||
drawPict()[PIC_BOOM] = &cPict::drawPresetBoom;
|
||||
@@ -46,6 +47,7 @@ void cPict::init(){
|
||||
drawPict()[PIC_CUSTOM_TALK] = &cPict::drawCustomTalk;
|
||||
drawPict()[PIC_CUSTOM_SCEN] = &cPict::drawCustomTalk;
|
||||
drawPict()[PIC_CUSTOM_ITEM] = &cPict::drawCustomItem;
|
||||
drawPict()[PIC_CUSTOM_TINY_ITEM] = &cPict::drawCustomTinyItem;
|
||||
drawPict()[PIC_CUSTOM_FULL] = &cPict::drawFullSheet;
|
||||
drawPict()[PIC_CUSTOM_MISSILE] = &cPict::drawCustomMissile;
|
||||
drawPict()[PIC_CUSTOM_DLOG_LG] = &cPict::drawCustomDlogLg;
|
||||
@@ -176,6 +178,8 @@ ePicType operator+ (ePicType lhs, ePicTypeMod rhs){
|
||||
case PIC_CUSTOM_ITEM:
|
||||
case PIC_PARTY_ITEM:
|
||||
return PIC_ITEM;
|
||||
case PIC_CUSTOM_TINY_ITEM:
|
||||
return PIC_TINY_ITEM;
|
||||
case PIC_CUSTOM_FULL:
|
||||
return PIC_FULL;
|
||||
case PIC_CUSTOM_MISSILE:
|
||||
@@ -233,6 +237,12 @@ ePicType operator+ (ePicType lhs, ePicTypeMod rhs){
|
||||
return lhs;
|
||||
}
|
||||
case PIC_LARGE:
|
||||
if(lhs == PIC_DLOG)
|
||||
return PIC_DLOG_LG;
|
||||
else if(lhs == PIC_CUSTOM_DLOG)
|
||||
return PIC_CUSTOM_DLOG_LG;
|
||||
else if(lhs == PIC_SCEN)
|
||||
return PIC_SCEN_LG;
|
||||
return (lhs + PIC_WIDE) + PIC_TALL;
|
||||
case PIC_CUSTOM:
|
||||
switch(lhs){
|
||||
@@ -250,6 +260,8 @@ ePicType operator+ (ePicType lhs, ePicTypeMod rhs){
|
||||
return PIC_CUSTOM_SCEN;
|
||||
case PIC_ITEM:
|
||||
return PIC_CUSTOM_ITEM;
|
||||
case PIC_TINY_ITEM:
|
||||
return PIC_CUSTOM_TINY_ITEM;
|
||||
case PIC_FULL:
|
||||
return PIC_CUSTOM_FULL;
|
||||
case PIC_MISSILE:
|
||||
@@ -330,6 +342,12 @@ ePicType operator- (ePicType lhs, ePicTypeMod rhs){
|
||||
return lhs;
|
||||
}
|
||||
case PIC_LARGE:
|
||||
if(lhs == PIC_DLOG_LG)
|
||||
return PIC_DLOG;
|
||||
else if(lhs == PIC_CUSTOM_DLOG_LG)
|
||||
return PIC_CUSTOM_DLOG_LG;
|
||||
else if(lhs == PIC_SCEN_LG)
|
||||
return PIC_SCEN;
|
||||
return (lhs - PIC_WIDE) - PIC_TALL;
|
||||
case PIC_CUSTOM:
|
||||
switch(lhs){
|
||||
@@ -347,6 +365,8 @@ ePicType operator- (ePicType lhs, ePicTypeMod rhs){
|
||||
return PIC_SCEN;
|
||||
case PIC_CUSTOM_ITEM:
|
||||
return PIC_ITEM;
|
||||
case PIC_CUSTOM_TINY_ITEM:
|
||||
return PIC_TINY_ITEM;
|
||||
case PIC_CUSTOM_FULL:
|
||||
return PIC_FULL;
|
||||
case PIC_CUSTOM_MISSILE:
|
||||
@@ -440,6 +460,7 @@ void cPict::recalcRect() {
|
||||
bounds.width() = 32;
|
||||
bounds.height() = 32;
|
||||
break;
|
||||
case PIC_TINY_ITEM: case PIC_CUSTOM_TINY_ITEM:
|
||||
case PIC_MISSILE: case PIC_CUSTOM_MISSILE:
|
||||
bounds.width() = 18;
|
||||
bounds.height() = 18;
|
||||
@@ -755,6 +776,17 @@ void cPict::drawPresetItem(short num, rectangle to_rect){
|
||||
rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect, sf::BlendAlpha);
|
||||
}
|
||||
|
||||
void cPict::drawPresetTinyItem(short num, rectangle to_rect){
|
||||
to_rect.right = to_rect.left + 18;
|
||||
to_rect.bottom = to_rect.top + 18;
|
||||
fill_rect(*inWindow, to_rect, sf::Color::Black);
|
||||
std::shared_ptr<sf::Texture> from_gw;
|
||||
rectangle from_rect = {0,0,18,18};
|
||||
from_gw = getSheet(SHEET_TINY_ITEM);
|
||||
from_rect.offset(18 * (num % 10), 18 * (num / 10));
|
||||
rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect, sf::BlendAlpha);
|
||||
}
|
||||
|
||||
void cPict::drawPresetPc(short num, rectangle to_rect){
|
||||
std::shared_ptr<sf::Texture> from_gw = getSheet(SHEET_PC);
|
||||
rectangle from_rect = calc_rect(2 * (num / 8), num % 8);
|
||||
@@ -975,6 +1007,16 @@ void cPict::drawCustomItem(short num, rectangle to_rect){
|
||||
rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect, sf::BlendAlpha);
|
||||
}
|
||||
|
||||
void cPict::drawCustomTinyItem(short num, rectangle to_rect){
|
||||
to_rect.right = to_rect.left + 18;
|
||||
to_rect.bottom = to_rect.top + 18;
|
||||
rectangle from_rect;
|
||||
sf::Texture* from_gw;
|
||||
graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num);
|
||||
fill_rect(*inWindow, to_rect, sf::Color::Black);
|
||||
rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect, sf::BlendAlpha);
|
||||
}
|
||||
|
||||
void cPict::drawCustomMissile(short num, rectangle to_rect){
|
||||
num += animFrame % 8;
|
||||
rectangle from_rect;
|
||||
|
||||
@@ -100,6 +100,7 @@ private:
|
||||
void drawPresetScen(short num, rectangle to_rect);
|
||||
void drawPresetScenLg(short num, rectangle to_rect);
|
||||
void drawPresetItem(short num, rectangle to_rect);
|
||||
void drawPresetTinyItem(short num, rectangle to_rect);
|
||||
void drawPresetPc(short num, rectangle to_rect);
|
||||
void drawPresetField(short num, rectangle to_rect);
|
||||
void drawPresetBoom(short num, rectangle to_rect);
|
||||
@@ -117,6 +118,7 @@ private:
|
||||
void drawCustomDlogLg(short num, rectangle to_rect);
|
||||
void drawCustomTalk(short num, rectangle to_rect);
|
||||
void drawCustomItem(short num, rectangle to_rect);
|
||||
void drawCustomTinyItem(short num, rectangle to_rect);
|
||||
void drawCustomMissile(short num, rectangle to_rect);
|
||||
void drawCustomTerMap(short num, rectangle to_rect);
|
||||
void drawPartyMonstSm(short num, rectangle to_rect);
|
||||
|
||||
@@ -31,8 +31,9 @@ enum ePicType {
|
||||
PIC_MISSILE = 12, ///< 18x18 missile graphic from the missiles sheet
|
||||
PIC_DLOG_LG = 13, ///< 72x72 dialog graphic from the dialog sheet
|
||||
PIC_SCEN_LG = 14, ///< 64x64 scenario graphic (currently each is on its own sheet)
|
||||
PIC_TER_MAP = 15, ///< 12x12 map graphic... or should it be 6x6?
|
||||
PIC_TER_MAP = 15, ///< 12x12 map graphic from the terrain map sheet, expanded to 24x24
|
||||
PIC_STATUS = 16, ///< 12x12 status icon
|
||||
PIC_TINY_ITEM = 17, ///< 18x18 item graphic from the small item sheet
|
||||
PIC_MONST_WIDE = 23, ///< 56x36 monster graphic from the preset sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_MONST_TALL = 43, ///< 28x72 monster graphic from the preset sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_MONST_LG = 63, ///< 56x72 monster graphic from the preset sheets, resized to fit in a 28x36 space
|
||||
@@ -46,7 +47,8 @@ enum ePicType {
|
||||
PIC_CUSTOM_FULL = 111, ///< entire sheet graphic, drawn from scenname.exr/sheetxxx.png where xxx is the number
|
||||
PIC_CUSTOM_MISSILE = 112, ///< 18x18 missile graphic drawn from the the custom sheets
|
||||
PIC_CUSTOM_DLOG_LG = 113, ///< 72x72 dialog graphic from the custom sheet, taken from 8 successive slots
|
||||
PIC_CUSTOM_TER_MAP = 115, ///< 12x12 map graphic (should it be 6x6?) taken from the custom sheet
|
||||
PIC_CUSTOM_TER_MAP = 115, ///< 12x12 map graphic taken from the custom sheet and expanded to 24x24
|
||||
PIC_CUSTOM_TINY_ITEM = 117, ///< 28x36 custom item graphic shrunk down into an 18x18 space
|
||||
PIC_CUSTOM_MONST_WIDE = 123,///< 56x36 monster graphic from the custom sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_CUSTOM_MONST_TALL = 143,///< 28x72 monster graphic from the custom sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_CUSTOM_MONST_LG = 163, ///< 56x72 monster graphic from the custom sheets, resized to fit in a 28x36 space
|
||||
|
||||
@@ -236,6 +236,9 @@ bool handle_action(location the_point,sf::Event /*event*/) {
|
||||
case LB_EDIT_QUEST:
|
||||
start_quest_editing();
|
||||
break;
|
||||
case LB_EDIT_SHOPS:
|
||||
start_shops_editing();
|
||||
break;
|
||||
case LB_LOAD_OUT:
|
||||
if(change_made) {
|
||||
if(!save_check("save-section-confirm"))
|
||||
@@ -447,6 +450,14 @@ bool handle_action(location the_point,sf::Event /*event*/) {
|
||||
} else edit_quest(j);
|
||||
start_quest_editing();
|
||||
break;
|
||||
case RB_SHOP:
|
||||
if(option_hit) {
|
||||
if(j == scenario.shops.size() - 1)
|
||||
scenario.shops.pop_back();
|
||||
else scenario.shops[j] = cShop("Unused Shop");
|
||||
} else edit_shop(j);
|
||||
start_shops_editing();
|
||||
break;
|
||||
}
|
||||
mouse_button_held = false;
|
||||
}
|
||||
@@ -2074,6 +2085,7 @@ void set_up_main_screen() {
|
||||
set_lb(-1,LB_TEXT,LB_EDIT_TEXT,"Edit Scenario Text");
|
||||
set_lb(-1,LB_TEXT,LB_EDIT_SPECITEM,"Edit Special Items");
|
||||
set_lb(-1,LB_TEXT,LB_EDIT_QUEST,"Edit Quests");
|
||||
set_lb(-1,LB_TEXT,LB_EDIT_SHOPS,"Edit Shops");
|
||||
set_lb(-1,LB_TEXT,LB_NO_ACTION,"");
|
||||
set_lb(-1,LB_TEXT,LB_NO_ACTION,"Outdoors Options");
|
||||
strb << " Section x = " << cur_out.x << ", y = " << cur_out.y;
|
||||
@@ -2259,6 +2271,27 @@ void start_quest_editing() {
|
||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Command-click or right-click to delete",true);
|
||||
}
|
||||
|
||||
void start_shops_editing() {
|
||||
int num_options = scenario.shops.size() + 1;
|
||||
if(overall_mode < MODE_MAIN_SCREEN)
|
||||
set_up_main_screen();
|
||||
overall_mode = MODE_MAIN_SCREEN;
|
||||
right_sbar->show();
|
||||
right_sbar->setPosition(0);
|
||||
reset_rb();
|
||||
right_sbar->setMaximum(num_options - NRSONPAGE);
|
||||
for(int i = 0; i < num_options; i++) {
|
||||
std::string title;
|
||||
if(i == scenario.shops.size())
|
||||
title = "Create New Shop";
|
||||
else title = scenario.shops[i].getName();
|
||||
title = std::to_string(i) + " - " + title;
|
||||
set_rb(i, RB_SHOP, i, title);
|
||||
}
|
||||
redraw_screen();
|
||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Command-click or right-click to delete",true);
|
||||
}
|
||||
|
||||
extern size_t num_strs(short mode); // defined in scen.keydlgs.cpp
|
||||
|
||||
// mode 0 - scen 1 - out 2 - town 3 - journal
|
||||
|
||||
@@ -30,6 +30,7 @@ void start_monster_editing(short just_redo_text);
|
||||
void start_item_editing(short just_redo_text);
|
||||
void start_special_item_editing();
|
||||
void start_quest_editing();
|
||||
void start_shops_editing();
|
||||
void start_string_editing(short mode,short just_redo_text);
|
||||
void start_special_editing(short mode,short just_redo_text);
|
||||
void town_entry(location spot_hit);
|
||||
|
||||
@@ -10,6 +10,7 @@ enum eLBAction {
|
||||
LB_EDIT_TEXT,
|
||||
LB_EDIT_SPECITEM,
|
||||
LB_EDIT_QUEST,
|
||||
LB_EDIT_SHOPS,
|
||||
LB_LOAD_OUT,
|
||||
LB_EDIT_OUT,
|
||||
LB_LOAD_TOWN,
|
||||
@@ -36,6 +37,7 @@ enum eRBAction {
|
||||
RB_OUT_SIGN = 14,
|
||||
RB_TOWN_SIGN = 15,
|
||||
RB_QUEST = 16,
|
||||
RB_SHOP = 17,
|
||||
};
|
||||
|
||||
enum eLBMode {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "restypes.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "spell.hpp"
|
||||
#include "mathutil.hpp"
|
||||
|
||||
extern short cen_x, cen_y,cur_town;
|
||||
extern bool mouse_button_held;
|
||||
@@ -184,6 +185,8 @@ static bool pick_picture(ePicType type, cDialog& parent, std::string result_fld,
|
||||
cPict& pic_ctrl = dynamic_cast<cPict&>(parent[pic_fld]);
|
||||
if(type == PIC_TER_ANIM && pic < 1000)
|
||||
pic += 960;
|
||||
if(type == PIC_ITEM && pic_ctrl.getPicType() == PIC_TINY_ITEM)
|
||||
type = PIC_TINY_ITEM;
|
||||
pic_ctrl.setPict(pic,type);
|
||||
}
|
||||
}
|
||||
@@ -944,11 +947,11 @@ static bool edit_monst_abil_event_filter(cDialog& me,std::string hit,cMonster& m
|
||||
return true;
|
||||
}
|
||||
|
||||
static short get_monst_abil_num(std::string prompt, int min, int max, cDialog& parent) {
|
||||
static short get_monst_abil_num(std::string prompt, int min, int max, cDialog& parent, int cur = -1) {
|
||||
cDialog numPanel("get-mabil-num", &parent);
|
||||
numPanel["okay"].attachClickHandler(std::bind(&cDialog::toast, &numPanel, false));
|
||||
numPanel["prompt"].setText(prompt + " (" + std::to_string(min) + "-" + std::to_string(max) + ") ");
|
||||
numPanel["number"].setTextToNum(min);
|
||||
numPanel["number"].setTextToNum(minmax(min,max,cur));
|
||||
numPanel.run();
|
||||
|
||||
int result = numPanel["number"].getTextAsNum();
|
||||
@@ -2052,6 +2055,344 @@ void edit_quest(size_t which_quest) {
|
||||
quest_dlg.run();
|
||||
}
|
||||
|
||||
static bool put_shop_item_in_dlog(cPict& pic, cControl& num, cControl& title, const cShop& shop, int which) {
|
||||
cShopItem entry = shop.getItem(which);
|
||||
num.setTextToNum(which);
|
||||
pic.setPict(entry.item.graphic_num);
|
||||
if(entry.type == eShopItemType::EMPTY) {
|
||||
title.setText("");
|
||||
return false;
|
||||
}
|
||||
std::string name = entry.item.full_name;
|
||||
int amount = entry.quantity;
|
||||
if(entry.type == eShopItemType::OPTIONAL) {
|
||||
name += " [" + std::to_string(amount / 1000) + "% chance]";
|
||||
amount %= 1000;
|
||||
}
|
||||
if(amount > 0) {
|
||||
name = std::to_string(amount) + "x " + name;
|
||||
}
|
||||
title.setText(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void put_shop_in_dlog(cDialog& me, const cShop& shop, size_t which_shop) {
|
||||
me["num"].setText(std::to_string(which_shop) + " of " + std::to_string(scenario.shops.size()));
|
||||
me["name"].setText(shop.getName());
|
||||
|
||||
dynamic_cast<cPict&>(me["face"]).setPict(shop.getFace());
|
||||
|
||||
dynamic_cast<cLedGroup&>(me["type"]).setSelected("t" + std::to_string(int(shop.getType()) + 1));
|
||||
dynamic_cast<cLedGroup&>(me["prompt"]).setSelected("p" + std::to_string(int(shop.getPrompt()) + 1));
|
||||
|
||||
cStack& items = dynamic_cast<cStack&>(me["items"]);
|
||||
for(int i = 0; i < 6; i++) {
|
||||
items.setPage(i);
|
||||
for(int j = 0; j < 5; j++) {
|
||||
std::string id = std::to_string(j + 1);
|
||||
if(put_shop_item_in_dlog(dynamic_cast<cPict&>(me["pict" + id]), me["n" + id], me["item" + id], shop, i * 5 + j)) {
|
||||
if(i == 0) {
|
||||
me["ed" + id].show();
|
||||
me["del" + id].show();
|
||||
}
|
||||
} else if(i == 0) {
|
||||
me["ed" + id].hide();
|
||||
me["del" + id].hide();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
items.setPage(0);
|
||||
}
|
||||
|
||||
static bool save_shop_from_dlog(cDialog& me, cShop& shop, size_t which_shop, bool close) {
|
||||
if(!me.toast(true)) return false;
|
||||
|
||||
shop.setName(me["name"].getText());
|
||||
shop.setType(eShopType(dynamic_cast<cLedGroup&>(me["type"]).getSelected()[1] - '1'));
|
||||
shop.setPrompt(eShopPrompt(dynamic_cast<cLedGroup&>(me["prompt"]).getSelected()[1] - '1'));
|
||||
shop.setFace(dynamic_cast<cPict&>(me["face"]).getPicNum());
|
||||
// Items are filled in as they're added by the dialog, so that's all we need to do here
|
||||
|
||||
scenario.shops[which_shop] = shop;
|
||||
if(!close) me.untoast();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool change_shop_dlog_page(cDialog& me, std::string dir, cShop& shop, size_t& which_shop) {
|
||||
if(!save_shop_from_dlog(me, shop, which_shop, false))
|
||||
return true;
|
||||
|
||||
if(dir == "left") {
|
||||
if(which_shop == 0)
|
||||
which_shop = scenario.shops.size();
|
||||
which_shop--;
|
||||
} else if(dir == "right") {
|
||||
which_shop++;
|
||||
if(which_shop == scenario.shops.size())
|
||||
which_shop = 0;
|
||||
}
|
||||
|
||||
shop = scenario.shops[which_shop];
|
||||
put_shop_in_dlog(me, shop, which_shop);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool change_shop_dlog_items_page(cDialog& me, std::string dir, const cShop& shop) {
|
||||
cStack& items = dynamic_cast<cStack&>(me["items"]);
|
||||
int curPage = items.getPage(), maxPage = items.getPageCount();
|
||||
if(dir == "up") {
|
||||
if(curPage == 0)
|
||||
curPage = maxPage - 1;
|
||||
else curPage--;
|
||||
} else if(dir == "down") {
|
||||
if(curPage == maxPage - 1)
|
||||
curPage = 0;
|
||||
else curPage++;
|
||||
}
|
||||
for(int i = 0; i < 5; i++) {
|
||||
std::string id = std::to_string(i + 1);
|
||||
if(shop.getItem(curPage * 5 + i).type == eShopItemType::EMPTY) {
|
||||
me["ed" + id].hide();
|
||||
me["del" + id].hide();
|
||||
} else {
|
||||
me["ed" + id].show();
|
||||
me["del" + id].show();
|
||||
}
|
||||
}
|
||||
items.setPage(curPage);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void edit_shop_item(cDialog& parent, size_t& item, size_t& quantity, bool optional) {
|
||||
using namespace std::placeholders;
|
||||
int was_item = item;
|
||||
cDialog item_dlg("edit-shop-item", &parent);
|
||||
item_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, _1, false));
|
||||
item_dlg["okay"].attachClickHandler(std::bind(&cDialog::toast, _1, true));
|
||||
|
||||
if(optional) {
|
||||
item_dlg["amount"].setTextToNum(quantity % 1000);
|
||||
item_dlg["chance"].setTextToNum(quantity / 1000);
|
||||
item_dlg["amount"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 999, "amount"));
|
||||
item_dlg["chance"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 1, 100, "chance"));
|
||||
} else {
|
||||
item_dlg["amount"].setTextToNum(quantity);
|
||||
item_dlg["chance"].hide();
|
||||
item_dlg["chance-prompt"].hide();
|
||||
}
|
||||
|
||||
item_dlg["item"].setText(scenario.scen_items[item].full_name);
|
||||
item_dlg["choose"].attachClickHandler([&item](cDialog& me, std::string, eKeyMod) -> bool {
|
||||
item = choose_text(STRT_ITEM, item, &me, "Which item?");
|
||||
me["item"].setText(scenario.scen_items[item].full_name);
|
||||
return true;
|
||||
});
|
||||
|
||||
item_dlg.run();
|
||||
if(item_dlg.accepted()) {
|
||||
quantity = item_dlg["amount"].getTextAsNum();
|
||||
if(optional)
|
||||
quantity += 1000 * item_dlg["chance"].getTextAsNum();
|
||||
} else item = was_item;
|
||||
}
|
||||
|
||||
static void edit_shop_special(cDialog& parent, cItem& item, size_t& quantity) {
|
||||
using namespace std::placeholders;
|
||||
cDialog spec_dlg("edit-shop-special", &parent);
|
||||
spec_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, _1, false));
|
||||
spec_dlg["okay"].attachClickHandler(std::bind(&cDialog::toast, _1, true));
|
||||
spec_dlg["cost"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 10000, "cost"));
|
||||
spec_dlg["pickicon"].attachClickHandler(std::bind(pick_picture, PIC_ITEM, _1, "", "icon"));
|
||||
|
||||
spec_dlg["edit"].attachClickHandler([](cDialog& me, std::string, eKeyMod) -> bool {
|
||||
int spec = me["node"].getTextAsNum();
|
||||
if(spec < 0) spec = get_fresh_spec(0);
|
||||
if(edit_spec_enc(spec, 0, &me))
|
||||
me["node"].setTextToNum(spec);
|
||||
return true;
|
||||
});
|
||||
|
||||
spec_dlg["name"].setText(item.full_name);
|
||||
spec_dlg["descr"].setText(item.desc);
|
||||
spec_dlg["node"].setTextToNum(item.item_level);
|
||||
spec_dlg["cost"].setTextToNum(item.value);
|
||||
spec_dlg["amount"].setTextToNum(quantity);
|
||||
dynamic_cast<cPict&>(spec_dlg["icon"]).setPict(item.graphic_num);
|
||||
|
||||
spec_dlg.run();
|
||||
if(spec_dlg.accepted()) {
|
||||
item.full_name = spec_dlg["name"].getText();
|
||||
item.desc = spec_dlg["descr"].getText();
|
||||
item.item_level = spec_dlg["node"].getTextAsNum();
|
||||
item.value = spec_dlg["cost"].getTextAsNum();
|
||||
quantity = spec_dlg["amount"].getTextAsNum();
|
||||
item.graphic_num = dynamic_cast<cPict&>(spec_dlg["icon"]).getPicNum();
|
||||
}
|
||||
}
|
||||
|
||||
static bool edit_shop_entry(cDialog& me, std::string which, cShop& shop) {
|
||||
int btn_i = which[2] - '0';
|
||||
int i = dynamic_cast<cStack&>(me["items"]).getPage() * 5 + btn_i - 1;
|
||||
cShopItem entry = shop.getItem(i);
|
||||
eStrType list;
|
||||
std::string prompt;
|
||||
bool need_string = true;
|
||||
switch(entry.type) {
|
||||
case eShopItemType::EMPTY: return true;
|
||||
case eShopItemType::ITEM:
|
||||
case eShopItemType::OPTIONAL:
|
||||
edit_shop_item(me, entry.index, entry.quantity, entry.type == eShopItemType::OPTIONAL);
|
||||
entry.item = scenario.scen_items[entry.index];
|
||||
shop.replaceItem(i, entry);
|
||||
need_string = false;
|
||||
break;
|
||||
case eShopItemType::CLASS:
|
||||
entry.index = get_monst_abil_num("Which special class?", 1, 100, me, entry.index);
|
||||
shop.replaceSpecial(i, eShopItemType::CLASS, entry.index);
|
||||
need_string = false;
|
||||
break;
|
||||
case eShopItemType::CALL_SPECIAL:
|
||||
edit_shop_special(me, entry.item, entry.quantity);
|
||||
shop.replaceItem(i, entry);
|
||||
need_string = false;
|
||||
break;
|
||||
case eShopItemType::MAGE_SPELL: list = STRT_MAGE; prompt = "Which mage spell?"; break;
|
||||
case eShopItemType::PRIEST_SPELL: list = STRT_PRIEST; prompt = "Which priest spell?"; break;
|
||||
case eShopItemType::ALCHEMY: list = STRT_ALCHEMY; prompt = "Which recipe?"; break;
|
||||
case eShopItemType::SKILL: list = STRT_SKILL; prompt = "Which skill?"; break;
|
||||
case eShopItemType::TREASURE: list = STRT_TREASURE; prompt = "What class of treasure?"; break;
|
||||
case eShopItemType::CURE_ACID: case eShopItemType::CURE_DISEASE: case eShopItemType::CURE_POISON:
|
||||
case eShopItemType::CURE_DUMBFOUNDING: case eShopItemType::CURE_PARALYSIS: case eShopItemType::DESTONE:
|
||||
case eShopItemType::HEAL_WOUNDS: case eShopItemType::RAISE_DEAD: case eShopItemType::REMOVE_CURSE:
|
||||
case eShopItemType::RESURRECT:
|
||||
list = STRT_HEALING;
|
||||
break;
|
||||
}
|
||||
if(need_string) {
|
||||
entry.index = choose_text(list, entry.index, &me, prompt);
|
||||
if(list == STRT_HEALING)
|
||||
shop.replaceSpecial(i, eShopItemType(int(eShopItemType::HEAL_WOUNDS) + entry.index));
|
||||
else shop.replaceSpecial(i, entry.type, entry.index);
|
||||
}
|
||||
std::string pic_id = which, num_id = which, title_id = which;
|
||||
pic_id.replace(0,2,"pict"); num_id.replace(0,2,"n"); title_id.replace(0,2,"item");
|
||||
put_shop_item_in_dlog(dynamic_cast<cPict&>(me[pic_id]), me[num_id], me[title_id], shop, i);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool delete_shop_entry(cDialog& me, std::string which, cShop& shop, size_t which_shop) {
|
||||
cStack& items = dynamic_cast<cStack&>(me["items"]);
|
||||
int page = items.getPage();
|
||||
shop.clearItem((which[3] - '1') + 5 * page);
|
||||
put_shop_in_dlog(me, shop, which_shop);
|
||||
items.setPage(page);
|
||||
change_shop_dlog_items_page(me, "stay", shop);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool add_shop_entry(cDialog& me, std::string type, cShop& shop, size_t which_shop) {
|
||||
if(shop.size() == 30) {
|
||||
giveError("There is no more room in this shop to add another item. Each shop can only have up to 30 items.", &me);
|
||||
return true;
|
||||
}
|
||||
if(type == "item" || type == "opt") {
|
||||
size_t which_item = 0, amount = 0;
|
||||
edit_shop_item(me, which_item, amount, type == "opt");
|
||||
if(scenario.scen_items[which_item].variety == eItemType::NO_ITEM)
|
||||
return true;
|
||||
if(scenario.scen_items[which_item].variety == eItemType::GOLD)
|
||||
return true;
|
||||
if(type == "item")
|
||||
shop.addItem(which_item, scenario.scen_items[which_item], amount);
|
||||
else shop.addItem(which_item, scenario.scen_items[which_item], amount % 1000, amount / 1000);
|
||||
} else if(type == "spec") {
|
||||
cItem item('spec');
|
||||
size_t amount = 0;
|
||||
edit_shop_special(me, item, amount);
|
||||
if(item.item_level < 0)
|
||||
return true;
|
||||
shop.addSpecial(item.full_name, item.desc, item.graphic_num, item.item_level, item.value, amount);
|
||||
} else if(type == "class") {
|
||||
int n = get_monst_abil_num("Which special class?", 0, 100, me);
|
||||
if(n == 0) return true;
|
||||
shop.addSpecial(eShopItemType::CLASS, n);
|
||||
} else {
|
||||
eStrType list;
|
||||
eShopItemType item;
|
||||
std::string prompt;
|
||||
if(type == "mage") {
|
||||
list = STRT_MAGE;
|
||||
item = eShopItemType::MAGE_SPELL;
|
||||
prompt = "Which mage spell?";
|
||||
} else if(type == "priest") {
|
||||
list = STRT_PRIEST;
|
||||
item = eShopItemType::PRIEST_SPELL;
|
||||
prompt = "Which priest spell?";
|
||||
} else if(type == "alch") {
|
||||
list = STRT_ALCHEMY;
|
||||
item = eShopItemType::ALCHEMY;
|
||||
prompt = "Which recipe?";
|
||||
} else if(type == "skill") {
|
||||
list = STRT_SKILL;
|
||||
item = eShopItemType::SKILL;
|
||||
prompt = "Which skill?";
|
||||
} else if(type == "treas") {
|
||||
list = STRT_TREASURE;
|
||||
item = eShopItemType::TREASURE;
|
||||
prompt = "What class of treasure?";
|
||||
} else if(type == "heal") {
|
||||
list = STRT_HEALING;
|
||||
prompt = "What kind of healing?";
|
||||
}
|
||||
int i = choose_text(list, -1, &me, prompt);
|
||||
if(i == -1) return true;
|
||||
if(list == STRT_HEALING) {
|
||||
item = eShopItemType(int(eShopItemType::HEAL_WOUNDS) + i);
|
||||
i = 0;
|
||||
}
|
||||
shop.addSpecial(item, i);
|
||||
}
|
||||
put_shop_in_dlog(me, shop, which_shop);
|
||||
int atItem = shop.size() - 1;
|
||||
int onPage = atItem / 5;
|
||||
dynamic_cast<cStack&>(me["items"]).setPage(onPage);
|
||||
change_shop_dlog_items_page(me, "stay", shop);
|
||||
return true;
|
||||
}
|
||||
|
||||
void edit_shop(size_t which_shop, cDialog* parent) {
|
||||
using namespace std::placeholders;
|
||||
if(which_shop == scenario.shops.size())
|
||||
scenario.shops.emplace_back("New Shop");
|
||||
cShop shop = scenario.shops[which_shop];
|
||||
|
||||
cDialog shop_dlg("edit-shop", parent);
|
||||
shop_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, _1, false));
|
||||
shop_dlg["okay"].attachClickHandler(std::bind(save_shop_from_dlog, _1, std::ref(shop), std::ref(which_shop), true));
|
||||
shop_dlg["pickface"].attachClickHandler(std::bind(pick_picture, PIC_TALK, _1, "", "face"));
|
||||
shop_dlg.attachClickHandlers(std::bind(change_shop_dlog_items_page, _1, _2, std::ref(shop)), {"up", "down"});
|
||||
shop_dlg.attachClickHandlers(std::bind(delete_shop_entry, _1, _2, std::ref(shop), std::ref(which_shop)), {"del1", "del2", "del3", "del4", "del5"});
|
||||
shop_dlg.attachClickHandlers(std::bind(edit_shop_entry, _1, _2, std::ref(shop)), {"ed1", "ed2", "ed3", "ed4", "ed5"});
|
||||
shop_dlg.attachClickHandlers(std::bind(add_shop_entry, _1, _2, std::ref(shop), std::ref(which_shop)), {"item", "opt", "spec", "mage", "priest", "alch", "skill", "treas", "heal", "class"});
|
||||
shop_dlg["rand"].attachClickHandler([&shop,which_shop](cDialog& me, std::string, eKeyMod) -> bool {
|
||||
shop = cShop('junk');
|
||||
put_shop_in_dlog(me, shop, which_shop);
|
||||
return true;
|
||||
});
|
||||
|
||||
if(scenario.shops.size() == 1 || parent != nullptr) {
|
||||
shop_dlg["left"].hide();
|
||||
shop_dlg["right"].hide();
|
||||
} else {
|
||||
shop_dlg.attachClickHandlers(std::bind(change_shop_dlog_page, _1, _2, std::ref(shop), std::ref(which_shop)), {"left", "right"});
|
||||
}
|
||||
|
||||
dynamic_cast<cStack&>(shop_dlg["items"]).setPageCount(6);
|
||||
put_shop_in_dlog(shop_dlg, shop, which_shop);
|
||||
shop_dlg.run();
|
||||
}
|
||||
|
||||
static void put_save_rects_in_dlog(cDialog& me) {
|
||||
short i;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ short edit_item_type(short which_item);
|
||||
cItem edit_item_abil(cItem starting_record,short which_item,cDialog& parent);
|
||||
void edit_spec_item(short which_item);
|
||||
void edit_quest(size_t which_quest);
|
||||
void edit_shop(size_t which_shop, cDialog* parent = nullptr);
|
||||
void edit_save_rects();
|
||||
void edit_horses();
|
||||
void edit_add_town();
|
||||
|
||||
@@ -177,7 +177,7 @@ short choose_text_res(std::string res_list,short first_t,short last_t,unsigned s
|
||||
return dlog.show(cur_choice);
|
||||
}
|
||||
|
||||
short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, const char* title) {
|
||||
short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, std::string title) {
|
||||
location view_loc;
|
||||
|
||||
std::vector<std::string> strings;
|
||||
@@ -263,6 +263,9 @@ short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, con
|
||||
case STRT_TRAP:
|
||||
strings = *ResMgr::get<StringRsrc>("trap-types");
|
||||
break;
|
||||
case STRT_HEALING:
|
||||
strings = *ResMgr::get<StringRsrc>("shop-specials");
|
||||
break;
|
||||
case STRT_BUTTON:
|
||||
for(int btn : available_btns) {
|
||||
strings.push_back(basic_buttons[btn].label);
|
||||
@@ -327,6 +330,9 @@ short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, con
|
||||
case STRT_QUEST_STATUS:
|
||||
strings = {"Available", "Started", "Completed", "Failed"};
|
||||
break;
|
||||
case STRT_TREASURE:
|
||||
strings = {"0 - Junk", "1 - Lousy", "2 - So-so", "3 - Good", "4 - Great"};
|
||||
break;
|
||||
}
|
||||
if(cur_choice < 0 || cur_choice >= strings.size())
|
||||
cur_choice = -1;
|
||||
|
||||
@@ -12,6 +12,7 @@ enum eStrType {
|
||||
STRT_SHOP, STRT_COST_ADJ, STRT_STAIR_MODE, STRT_TALK_NODE,
|
||||
STRT_STATUS, STRT_SPELL_PAT, STRT_SUMMON, STRT_TALK,
|
||||
STRT_ENCHANT, STRT_DIR, STRT_QUEST, STRT_QUEST_STATUS,
|
||||
STRT_HEALING, STRT_TREASURE,
|
||||
};
|
||||
|
||||
bool cre(short val,short min,short max,std::string text1,std::string text2,cDialog* parent) ;
|
||||
@@ -21,7 +22,7 @@ void put_choice_pics(short g_type);
|
||||
pic_num_t choose_graphic(short cur_choice,ePicType g_type,cDialog* parent);
|
||||
short choose_background(short cur_choice, cDialog* parent);
|
||||
short choose_text_res(std::string res_list,short first_t,short last_t,unsigned short cur_choice,cDialog* parent,const char *title);
|
||||
short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent,const char* title);
|
||||
short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent,std::string title);
|
||||
void edit_text_str(short which_str,short mode);
|
||||
bool edit_spec_enc(short which_node,short mode,cDialog* parent);
|
||||
short get_fresh_spec(short which_mode);
|
||||
|
||||
@@ -218,7 +218,7 @@ bool load_scenario_v1(fs::path file_to_load, cScenario& scenario){
|
||||
if(info.type == eShopItemType::ITEM) {
|
||||
int end = info.first + info.count;
|
||||
end = min(end, scenario.scen_items.size());
|
||||
shop.addItems(scenario.scen_items.begin() + info.first, scenario.scen_items.begin() + end, cShop::INFINITE);
|
||||
shop.addItems(info.first, scenario.scen_items.begin() + info.first, scenario.scen_items.begin() + end, cShop::INFINITE);
|
||||
} else {
|
||||
int max = 62;
|
||||
if(info.type == eShopItemType::ALCHEMY)
|
||||
|
||||
Reference in New Issue
Block a user