Add dialog to the scenario editor to let it know what type of graphics are in the custom sheets

- If you do this, it adds the graphics to all relevant select graphic dialogs, at the end, allowing you to choose custom graphics without having to remember the number schemes
This commit is contained in:
2015-01-18 12:32:47 -05:00
parent 181227f79d
commit 967438ecec
19 changed files with 563 additions and 138 deletions

View File

@@ -138,5 +138,12 @@
<last-out-section x="0" y="0"/>
<!-- Last town edited -->
<last-town>0</last-town>
<!-- This is a way to specify what type of graphics are in the custom graphics sheet
For example, this states that the fourth graphic is an item. -->
<graphics><pic index='3'>7</pic></graphics>
</editor>
<!-- All the scenario strings go here -->
<strings/>
<!-- And the journal strings here -->
<journal/>
</scenario>

View File

@@ -158,6 +158,21 @@
</xs:complexType>
</xs:element>
<xs:element name="last-town" type="xs:integer"/>
<xs:element name="graphics" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="pic" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="index" type="xs:integer"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="storage" minOccurs="0" maxOccurs="10">
<xs:complexType>
<xs:sequence>
@@ -196,14 +211,14 @@
<xs:element name="strings">
<xs:complexType>
<xs:sequence>
<xs:element name="string" type="xs:string" maxOccurs="unbounded"/>
<xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="journal">
<xs:complexType>
<xs:sequence>
<xs:element name="string" type="xs:string" maxOccurs="unbounded"/>
<xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>

View File

@@ -0,0 +1,232 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
<!--<!DOCTYPE dialog SYSTEM "dialog.dtd">-->
<dialog skin='light' defbtn='okay'>
<pict type='dlog' num='16' top='6' left='6'/>
<text size='large' top='18' left='50' width='250' height='17'>Classify Custom Graphics:</text>
<text top='18' left='372' width='80' height='16'>First Graphic:</text>
<text name='num0' top='18' left='462' width='40' height='16'/>
<text name='num1' top='48' left='12' width='28' height='16'/>
<text name='num2' top='48' left='48' width='28' height='16'/>
<text name='num3' top='48' left='84' width='28' height='16'/>
<text name='num4' top='48' left='120' width='28' height='16'/>
<text name='num5' top='48' left='156' width='28' height='16'/>
<text name='num6' top='48' left='192' width='28' height='16'/>
<text name='num7' top='48' left='228' width='28' height='16'/>
<text name='num8' top='48' left='264' width='28' height='16'/>
<text name='num9' top='48' left='300' width='28' height='16'/>
<text name='num10' top='48' left='336' width='28' height='16'/>
<pict name='pic1' type='ter' num='0' top='68' left='12'/>
<pict name='pic2' type='ter' num='1' top='68' left='48'/>
<pict name='pic3' type='ter' num='2' top='68' left='84'/>
<pict name='pic4' type='ter' num='3' top='68' left='120'/>
<pict name='pic5' type='ter' num='4' top='68' left='156'/>
<pict name='pic6' type='ter' num='5' top='68' left='192'/>
<pict name='pic7' type='ter' num='6' top='68' left='228'/>
<pict name='pic8' type='ter' num='7' top='68' left='264'/>
<pict name='pic9' type='ter' num='8' top='68' left='300'/>
<pict name='pic10' type='ter' num='9' top='68' left='336'/>
<group name='type1'>
<led name='ter1' top='110' left='20'/>
<led name='anim1' top='125' left='20'/>
<led name='map1' top='140' left='20'/>
<led name='monst-sm1' top='155' left='20'/>
<led name='monst-wide1' top='170' left='20'/>
<led name='monst-tall1' top='185' left='20'/>
<led name='monst-lg1' top='200' left='20'/>
<led name='dlog1' top='215' left='20'/>
<led name='dlog-lg1' top='230' left='20'/>
<led name='talk1' top='245' left='20'/>
<led name='item1' top='260' left='20'/>
<led name='boom1' top='275' left='20'/>
<led name='miss1' top='290' left='20'/>
<led name='none1' top='305' left='20'/>
</group>
<group name='type2'>
<led name='ter2' top='110' left='56'/>
<led name='anim2' top='125' left='56'/>
<led name='map2' top='140' left='56'/>
<led name='monst-sm2' top='155' left='56'/>
<led name='monst-wide2' top='170' left='56'/>
<led name='monst-tall2' top='185' left='56'/>
<led name='monst-lg2' top='200' left='56'/>
<led name='dlog2' top='215' left='56'/>
<led name='dlog-lg2' top='230' left='56'/>
<led name='talk2' top='245' left='56'/>
<led name='item2' top='260' left='56'/>
<led name='boom2' top='275' left='56'/>
<led name='miss2' top='290' left='56'/>
<led name='none2' top='305' left='56'/>
</group>
<group name='type3'>
<led name='ter3' top='110' left='92'/>
<led name='anim3' top='125' left='92'/>
<led name='map3' top='140' left='92'/>
<led name='monst-sm3' top='155' left='92'/>
<led name='monst-wide3' top='170' left='92'/>
<led name='monst-tall3' top='185' left='92'/>
<led name='monst-lg3' top='200' left='92'/>
<led name='dlog3' top='215' left='92'/>
<led name='dlog-lg3' top='230' left='92'/>
<led name='talk3' top='245' left='92'/>
<led name='item3' top='260' left='92'/>
<led name='boom3' top='275' left='92'/>
<led name='miss3' top='290' left='92'/>
<led name='none3' top='305' left='92'/>
</group>
<group name='type4'>
<led name='ter4' top='110' left='128'/>
<led name='anim4' top='125' left='128'/>
<led name='map4' top='140' left='128'/>
<led name='monst-sm4' top='155' left='128'/>
<led name='monst-wide4' top='170' left='128'/>
<led name='monst-tall4' top='185' left='128'/>
<led name='monst-lg4' top='200' left='128'/>
<led name='dlog4' top='215' left='128'/>
<led name='dlog-lg4' top='230' left='128'/>
<led name='talk4' top='245' left='128'/>
<led name='item4' top='260' left='128'/>
<led name='boom4' top='275' left='128'/>
<led name='miss4' top='290' left='128'/>
<led name='none4' top='305' left='128'/>
</group>
<group name='type5'>
<led name='ter5' top='110' left='164'/>
<led name='anim5' top='125' left='164'/>
<led name='map5' top='140' left='164'/>
<led name='monst-sm5' top='155' left='164'/>
<led name='monst-wide5' top='170' left='164'/>
<led name='monst-tall5' top='185' left='164'/>
<led name='monst-lg5' top='200' left='164'/>
<led name='dlog5' top='215' left='164'/>
<led name='dlog-lg5' top='230' left='164'/>
<led name='talk5' top='245' left='164'/>
<led name='item5' top='260' left='164'/>
<led name='boom5' top='275' left='164'/>
<led name='miss5' top='290' left='164'/>
<led name='none5' top='305' left='164'/>
</group>
<group name='type6'>
<led name='ter6' top='110' left='200'/>
<led name='anim6' top='125' left='200'/>
<led name='map6' top='140' left='200'/>
<led name='monst-sm6' top='155' left='200'/>
<led name='monst-wide6' top='170' left='200'/>
<led name='monst-tall6' top='185' left='200'/>
<led name='monst-lg6' top='200' left='200'/>
<led name='dlog6' top='215' left='200'/>
<led name='dlog-lg6' top='230' left='200'/>
<led name='talk6' top='245' left='200'/>
<led name='item6' top='260' left='200'/>
<led name='boom6' top='275' left='200'/>
<led name='miss6' top='290' left='200'/>
<led name='none6' top='305' left='200'/>
</group>
<group name='type7'>
<led name='ter7' top='110' left='236'/>
<led name='anim7' top='125' left='236'/>
<led name='map7' top='140' left='236'/>
<led name='monst-sm7' top='155' left='236'/>
<led name='monst-wide7' top='170' left='236'/>
<led name='monst-tall7' top='185' left='236'/>
<led name='monst-lg7' top='200' left='236'/>
<led name='dlog7' top='215' left='236'/>
<led name='dlog-lg7' top='230' left='236'/>
<led name='talk7' top='245' left='236'/>
<led name='item7' top='260' left='236'/>
<led name='boom7' top='275' left='236'/>
<led name='miss7' top='290' left='236'/>
<led name='none7' top='305' left='236'/>
</group>
<group name='type8'>
<led name='ter8' top='110' left='272'/>
<led name='anim8' top='125' left='272'/>
<led name='map8' top='140' left='272'/>
<led name='monst-sm8' top='155' left='272'/>
<led name='monst-wide8' top='170' left='272'/>
<led name='monst-tall8' top='185' left='272'/>
<led name='monst-lg8' top='200' left='272'/>
<led name='dlog8' top='215' left='272'/>
<led name='dlog-lg8' top='230' left='272'/>
<led name='talk8' top='245' left='272'/>
<led name='item8' top='260' left='272'/>
<led name='boom8' top='275' left='272'/>
<led name='miss8' top='290' left='272'/>
<led name='none8' top='305' left='272'/>
</group>
<group name='type9'>
<led name='ter9' top='110' left='308'/>
<led name='anim9' top='125' left='308'/>
<led name='map9' top='140' left='308'/>
<led name='monst-sm9' top='155' left='308'/>
<led name='monst-wide9' top='170' left='308'/>
<led name='monst-tall9' top='185' left='308'/>
<led name='monst-lg9' top='200' left='308'/>
<led name='dlog9' top='215' left='308'/>
<led name='dlog-lg9' top='230' left='308'/>
<led name='talk9' top='245' left='308'/>
<led name='item9' top='260' left='308'/>
<led name='boom9' top='275' left='308'/>
<led name='miss9' top='290' left='308'/>
<led name='none9' top='305' left='308'/>
</group>
<group name='type10'>
<led name='ter10' top='110' left='344'/>
<led name='anim10' top='125' left='344'/>
<led name='map10' top='140' left='344'/>
<led name='monst-sm10' top='155' left='344'/>
<led name='monst-wide10' top='170' left='344'/>
<led name='monst-tall10' top='185' left='344'/>
<led name='monst-lg10' top='200' left='344'/>
<led name='dlog10' top='215' left='344'/>
<led name='dlog-lg10' top='230' left='344'/>
<led name='talk10' top='245' left='344'/>
<led name='item10' top='260' left='344'/>
<led name='boom10' top='275' left='344'/>
<led name='miss10' top='290' left='344'/>
<led name='none10' top='305' left='344'/>
</group>
<text framed='true' left='20' top='110' width='492' height='12'/>
<text framed='true' left='20' top='125' width='492' height='12'/>
<text framed='true' left='20' top='140' width='492' height='12'/>
<text framed='true' left='20' top='155' width='492' height='12'/>
<text framed='true' left='20' top='170' width='492' height='12'/>
<text framed='true' left='20' top='185' width='492' height='12'/>
<text framed='true' left='20' top='200' width='492' height='12'/>
<text framed='true' left='20' top='215' width='492' height='12'/>
<text framed='true' left='20' top='230' width='492' height='12'/>
<text framed='true' left='20' top='245' width='492' height='12'/>
<text framed='true' left='20' top='260' width='492' height='12'/>
<text framed='true' left='20' top='275' width='492' height='12'/>
<text framed='true' left='20' top='290' width='492' height='12'/>
<text framed='true' left='20' top='305' width='492' height='12'/>
<text top='108' left='372' width='140' height='16'>Terrain (non-animated)</text>
<text top='123' left='372' width='140' height='16'>Terrain (animated)</text>
<text top='138' left='372' width='140' height='16'>Terrain (6 map icons)</text>
<text top='153' left='372' width='140' height='16'>Monster (1x1 small)</text>
<text top='168' left='372' width='140' height='16'>Monster (2x1 wide)</text>
<text top='183' left='372' width='140' height='16'>Monster (1x2 tall)</text>
<text top='198' left='372' width='140' height='16'>Monster (2x2 large)</text>
<text top='213' left='372' width='140' height='16'>Dialog Icon (36x36 split)</text>
<text top='228' left='372' width='140' height='16'>Large Dialog Icon (72x72)</text>
<text top='243' left='372' width='140' height='16'>Talk Portrait (32x32 split)</text>
<text top='258' left='372' width='140' height='16'>Item</text>
<text top='273' left='372' width='140' height='16'>Boom (currently unused)</text>
<text top='288' left='372' width='140' height='16'>Missile</text>
<text top='303' left='372' width='140' height='16'>Part of another graphic</text>
<text top='326' left='20' width='500' height='140'>
You can use this dialog to let the scenario editor know how to interpret the contents of your
custom graphics sheets. Above you see a single line of one of your sheets. For each slot,
you can specify what type of graphic it is intended to represent; this information will be
used by the editor to offer that graphic in relevant contexts (for example, marking it as an
item graphic will cause the editor to include it in the list of item graphics to select).
This is solely for use by the editor and does not prevent you from using a graphic in more than
one way (for example, both as an item and as a monster); in that case, you would simply have
to enter the number manually. For graphics that take up more than one slot, mark only the
first slot as the required type; subsequent slots should instead be marked as "part of another graphic".
</text>
<button name='left' type='left' def-key='left' top='454' left='30'/>
<button name='right' type='right' def-key='right' top='454' left='95'/>
<button name='cancel' type='regular' def-key='esc' top='454' left='384'>Cancel</button>
<button name='okay' type='regular' top='454' left='449'>OK</button>
</dialog>

View File

@@ -90,6 +90,7 @@ BEGIN
MENUITEM "&Scenario Details", IDM_SCEN_DETAILS
MENUITEM "Scenario Intr&o Text", IDM_SCEN_INTRO
MENUITEM "Set Starting &Location", IDM_SCEN_START
MENUITEM "Classify Custom &Graphics" IDM_SCEN_CUSTOM_PICS
MENUITEM SEPARATOR
MENUITEM "Advanced:", IDM_SCEN_NEW_TOWN, GRAYED
MENUITEM " Edit Special &Nodes", IDM_SCEN_ADV_SPECIALS

View File

@@ -66,6 +66,7 @@
#define IDM_EDIT_PASTE 160
#define IDM_EDIT_DELETE 161
#define IDM_EDIT_SELECT 162
#define IDM_SCEN_CUSTOM_PICS 163
// Next default values for new objects
//
@@ -74,6 +75,6 @@
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40014
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 163
#define _APS_NEXT_SYMED_VALUE 164
#endif
#endif

View File

@@ -58,6 +58,7 @@ public:
short store_item_towns[3];
cSpecItem special_items[50];
short rating,uses_custom_graphics;
std::vector<ePicType> custom_graphics;
std::array<cMonster,256> scen_monsters;
cVehicle boats[30];
cVehicle horses[30];

View File

@@ -120,7 +120,7 @@ void cPict::setPict(pic_num_t num, ePicType type){
picType += PIC_PARTY;
} else {
if(picType != PIC_CUSTOM_TER_MAP)
picNum -= 1000;
picNum %= 1000;
picType += PIC_CUSTOM;
}
}
@@ -584,7 +584,6 @@ void cPict::draw(){
}
void cPict::drawPresetTer(short num, rectangle to_rect){
std::cout << "Getting terrain icon from sheet " << num / 50 << ".\n";
std::shared_ptr<sf::Texture> from_gw = getSheet(SHEET_TER, num / 50);
num = num % 50;
rectangle from_rect = calc_rect(num % 10, num / 10);
@@ -596,7 +595,6 @@ void cPict::drawPresetTer(short num, rectangle to_rect){
void cPict::drawPresetTerAnim(short num, rectangle to_rect){
rectangle from_rect = calc_rect(4 * (num / 5) + animFrame % 4, num % 5);
std::shared_ptr<sf::Texture> from_gw = getSheet(SHEET_TER_ANIM);
std::cout << "Getting animated terrain graphic " << num << " from sheet 20\n";
if(to_rect.right - to_rect.left > 28) {
to_rect.inset(4,0);
to_rect.right = to_rect.left + 28;
@@ -832,7 +830,6 @@ void cPict::drawStatusIcon(short num, rectangle to_rect){
}
void cPict::drawCustomTer(short num, rectangle to_rect){
std::cout << "Drawing graphic " << num << " as a custom terrain pic.\n";
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 36;
rectangle from_rect;
@@ -842,7 +839,6 @@ void cPict::drawCustomTer(short num, rectangle to_rect){
}
void cPict::drawCustomTerAnim(short num, rectangle to_rect){
std::cout << "Drawing graphic " << num << " as a custom animated terrain pic.\n";
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 36;
num += animFrame % 4;
@@ -855,7 +851,6 @@ void cPict::drawCustomTerAnim(short num, rectangle to_rect){
void cPict::drawCustomMonstSm(short num, rectangle to_rect){
static const short adj[4] = {0, 2, 1, 3};
num += adj[animFrame % 4];
std::cout << "Drawing graphic " << num << " as a custom space pic.\n";
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 36;
fill_rect(*inWindow, to_rect, sf::Color::Black);
@@ -976,7 +971,6 @@ void cPict::drawCustomTalk(short num, rectangle to_rect){
}
void cPict::drawCustomItem(short num, rectangle to_rect){
std::cout << "Drawing graphic " << num << " as a custom space pic." << std::endl;
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 36;
rectangle from_rect;
@@ -1013,7 +1007,6 @@ void cPict::drawCustomTerMap(short num, rectangle to_rect){
}
void cPict::drawPartyMonstSm(short num, rectangle to_rect){
std::cout << "Drawing graphic " << num << " as a custom space pic.\n";
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 36;
sf::Texture* from_gw;
@@ -1093,7 +1086,6 @@ void cPict::drawPartyScen(short num, rectangle to_rect){
}
void cPict::drawPartyItem(short num, rectangle to_rect){
std::cout << "Drawing graphic " << num << " as a custom space pic.\n";
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 36;
sf::Texture* from_gw;
@@ -1105,7 +1097,6 @@ void cPict::drawPartyItem(short num, rectangle to_rect){
}
void cPict::drawPartyPc(short num, rectangle to_rect){
std::cout << "Drawing graphic " << num << " as a custom space pic.\n";
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 36;
sf::Texture* from_gw;

View File

@@ -43,8 +43,8 @@ public:
///
/// - If type is PIC_MONST, it automatically looks up the chosen icon to determine
/// whether it should apply the tall or wide modifiers.
/// - If num is 4 digits in decimal and type is not PIC_FULL, it automatically subtracts 1000 and applies the custom modifier.
/// (If type is PIC_TER_MAP, it does not subtract 1000.)
/// - If num is 4 digits in decimal and type is not PIC_FULL, it automatically takes the remainder by 1000
/// and applies the custom modifier. (If type is PIC_TER_MAP, it does not take the remainder by 1000.)
/// - If num is 10000 or greater and type is PIC_TER_MAP, it automatically subtracts 10000 and applies the party modifier.
void setPict(pic_num_t num, ePicType type);
/// Set the pict's icon.

View File

@@ -1,6 +1,8 @@
#include <cstdio>
#include <cstring>
#include <functional>
#include <numeric>
#include <boost/lexical_cast.hpp>
#include "scen.global.h"
#include "classes.h"
@@ -26,6 +28,7 @@ extern cOutdoors* current_terrain;
extern short mode_count,to_create;
extern ter_num_t template_terrain[64][64];
extern cScenario scenario;
extern cCustomGraphics spec_scen_g;
extern cSpecial null_spec_node;
extern cSpeech null_talk_node;
extern location cur_out;
@@ -130,12 +133,11 @@ bool check_range(cDialog& me,std::string id,bool losing,long min_val,long max_va
}
// TODO: I have two functions that do this. (The other one is choose_graphic.)
static bool pick_picture(ePicType type, cDialog& parent, std::string result_fld, std::string pic_fld, pic_num_t modifier){
static bool pick_picture(ePicType type, cDialog& parent, std::string result_fld, std::string pic_fld){
pic_num_t cur_sel = 0;
if(result_fld != ""){
cControl& fld_ctrl = parent[result_fld];
cur_sel = fld_ctrl.getTextAsNum();
cur_sel -= modifier;
}else if(pic_fld != ""){
cPict& pic_ctrl = dynamic_cast<cPict&>(parent[pic_fld]);
if(pic_ctrl.getPicType() == type)
@@ -145,10 +147,12 @@ static bool pick_picture(ePicType type, cDialog& parent, std::string result_fld,
if(pic != NO_PIC){
if(result_fld != ""){
cTextField& fld_ctrl = dynamic_cast<cTextField&>(parent[result_fld]);
fld_ctrl.setTextToNum(pic + modifier);
fld_ctrl.setTextToNum(pic);
}
if(pic_fld != ""){
cPict& pic_ctrl = dynamic_cast<cPict&>(parent[pic_fld]);
if(type == PIC_TER_ANIM && pic < 1000)
pic += 960;
pic_ctrl.setPict(pic,type);
}
}
@@ -326,8 +330,8 @@ short edit_ter_type(ter_num_t which_ter) {
cDialog ter_dlg("edit-terrain");
// Attach handlers
ter_dlg["pict"].attachFocusHandler(std::bind(check_range,_1,_2,_3,0,2999,"terrain graphic"));
ter_dlg["pickpict"].attachClickHandler(std::bind(pick_picture,PIC_TER,_1,"pict","graphic",0));
ter_dlg["pickanim"].attachClickHandler(std::bind(pick_picture,PIC_TER_ANIM,_1,"pict","graphic",960));
ter_dlg["pickpict"].attachClickHandler(std::bind(pick_picture,PIC_TER,_1,"pict","graphic"));
ter_dlg["pickanim"].attachClickHandler(std::bind(pick_picture,PIC_TER_ANIM,_1,"pict","graphic"));
ter_dlg["light"].attachFocusHandler(std::bind(check_range,_1,_2,_3,0,255,"light radius"));
ter_dlg["trans"].attachFocusHandler(std::bind(check_range,_1,_2,_3,0,65535,"\"transform to what?\""));
ter_dlg["ground"].attachFocusHandler(std::bind(check_range,_1,_2,_3,0,255,"ground type"));
@@ -349,7 +353,7 @@ short edit_ter_type(ter_num_t which_ter) {
}
static void put_monst_info_in_dlog(cDialog& me, cMonster& store_monst, mon_num_t which_monst) {
char str[256];
std::ostringstream strb;
if(store_monst.picture_num < 1000)
dynamic_cast<cPict&>(me["icon"]).setPict(store_monst.picture_num,PIC_MONST);
@@ -372,10 +376,11 @@ static void put_monst_info_in_dlog(cDialog& me, cMonster& store_monst, mon_num_t
me["num"].setTextToNum(which_monst);
me["name"].setText(store_monst.m_name);
me["pic"].setTextToNum(store_monst.picture_num);
sprintf((char *) str,"Width = %d",store_monst.x_width);
me["w"].setText(str);
sprintf((char *) str,"Height = %d",store_monst.y_width);
me["h"].setText(str);
strb << "Width = " << int(store_monst.x_width);
me["w"].setText(strb.str());
strb.str("");
strb << "Height = " << int(store_monst.y_width);
me["h"].setText(strb.str());
me["level"].setTextToNum(store_monst.level);
me["health"].setTextToNum(store_monst.m_health);
me["armor"].setTextToNum(store_monst.armor);
@@ -416,33 +421,46 @@ static void put_monst_info_in_dlog(cDialog& me, cMonster& store_monst, mon_num_t
static bool check_monst_pic(cDialog& me, std::string id, bool losing, cMonster& store_monst) {
if(!losing) return true;
static size_t max_preset = m_pic_index.size() - 1;
static const std::string error = "Non-customized monster pic must be from 0 to " + std::to_string(max_preset) + ".";
if(check_range(me, id, losing, 0, 4999, "Monster pic")) {
// later check pic num for error, and assign widths if custom
if(store_monst.picture_num >= 1000) {
if((store_monst.picture_num >= 1000) && (store_monst.picture_num < 2000)) {
pic_num_t pic = me[id].getTextAsNum();
store_monst.picture_num = pic;
cPict& icon = dynamic_cast<cPict&>(me["icon"]);
switch(pic / 1000) {
case 0:
if(cre(pic,0,max_preset,error,"",&me)) return false;
store_monst.x_width = m_pic_index[store_monst.picture_num].x;
store_monst.y_width = m_pic_index[store_monst.picture_num].y;
icon.setPict(pic, PIC_MONST);
break;
case 1:
store_monst.x_width = 1;
store_monst.y_width = 1;
}
if((store_monst.picture_num >= 2000) && (store_monst.picture_num < 3000)) {
icon.setPict(pic, PIC_MONST);
break;
case 2:
store_monst.x_width = 2;
store_monst.y_width = 1;
}
if((store_monst.picture_num >= 3000) && (store_monst.picture_num < 4000)) {
icon.setPict(pic, PIC_MONST_WIDE);
break;
case 3:
store_monst.x_width = 1;
store_monst.y_width = 2;
}
if((store_monst.picture_num >= 4000) && (store_monst.picture_num < 5000)) {
icon.setPict(pic, PIC_MONST_TALL);
break;
case 4:
store_monst.x_width = 2;
store_monst.y_width = 2;
}
}
else {
// TODO: Update this with new value if more monster pictures are added later
if(cre(store_monst.picture_num,0,200,"Non-customized monster pic must be from 0 to 200.","",&me)) return false;
store_monst.x_width = m_pic_index[store_monst.picture_num].x;
store_monst.y_width = m_pic_index[store_monst.picture_num].y;
icon.setPict(pic, PIC_MONST_LG);
break;
}
std::ostringstream strb;
strb << "Width = " << int(store_monst.x_width);
me["w"].setText(strb.str());
strb.str("");
strb << "Height = " << int(store_monst.y_width);
me["h"].setText(strb.str());
}
return true;
}
@@ -545,13 +563,19 @@ static bool check_monst_dice(cDialog& me, std::string fld, bool losing) {
return check_range(me, fld, losing, 1, 50, "attack damage per die");
}
static bool pick_monst_picture(cDialog& me) {
bool result = pick_picture(PIC_MONST, me, "pic", "icon");
me["pic"].triggerFocusHandler(me, "pic", true);
return result;
}
short edit_monst_type(short which_monst) {
using namespace std::placeholders;
cMonster store_monst = scenario.scen_monsters[which_monst];
cDialog monst_dlg("edit-monster");
monst_dlg["pickicon"].attachClickHandler(std::bind(pick_picture,PIC_MONST,_1,"pic","icon",0));
monst_dlg["picktalk"].attachClickHandler(std::bind(pick_picture,PIC_TALK,_1,"talk","",0));
monst_dlg["pickicon"].attachClickHandler(std::bind(pick_monst_picture,_1));
monst_dlg["picktalk"].attachClickHandler(std::bind(pick_picture,PIC_TALK,_1,"talk",""));
monst_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, &monst_dlg, false));
monst_dlg["pic"].attachFocusHandler(std::bind(check_monst_pic, _1, _2, _3, std::ref(store_monst)));
monst_dlg["level"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 40, "level"));
@@ -830,9 +854,9 @@ static bool edit_item_type_event_filter(cDialog& me, std::string item_hit, cItem
if(store_which_item > 399) store_which_item = 0;
store_item = scenario.scen_items[store_which_item];
put_item_info_in_dlog(me, store_item, store_which_item);
} else if(item_hit == "choospic") {
} else if(item_hit == "choosepic") {
if(!save_item_info(me, store_item, store_which_item)) return true;
i = pick_picture(PIC_ITEM, me, "picnum", "pic", 0);
i = pick_picture(PIC_ITEM, me, "picnum", "pic");
if(i < 0) return true;
store_item.graphic_num = i;
} else if(item_hit == "abils") {
@@ -1637,3 +1661,154 @@ void edit_scenario_events() {
evt_dlg.run();
}
static void fill_custom_pics_types(cDialog& me, std::vector<ePicType>& pics, pic_num_t first) {
pic_num_t last = first + 9;
if(last >= pics.size()) pics.resize(last + 1, PIC_FULL);
me["num0"].setTextToNum(first);
for(pic_num_t i = first; i <= last; i++) {
std::string id = std::to_string(i - first + 1);
cLedGroup& grp = dynamic_cast<cLedGroup&>(me["type" + id]);
cPict& pic = dynamic_cast<cPict&>(me["pic" + id]);
pic.setPict(i, PIC_CUSTOM_TER);
cControl& num = me["num" + id];
num.setTextToNum(1000 + i);
switch(pics[i]) {
case PIC_TER:
grp.setSelected("ter" + id);
break;
case PIC_TER_ANIM:
grp.setSelected("anim" + id);
num.setTextToNum(2000 + i);
break;
case PIC_TER_MAP:
grp.setSelected("map" + id);
break;
case PIC_MONST:
grp.setSelected("monst-sm" + id);
break;
case PIC_MONST_WIDE:
grp.setSelected("monst-wide" + id);
num.setTextToNum(2000 + i);
break;
case PIC_MONST_TALL:
grp.setSelected("monst-tall" + id);
num.setTextToNum(3000 + i);
break;
case PIC_MONST_LG:
grp.setSelected("monst-lg" + id);
num.setTextToNum(4000 + i);
break;
case PIC_DLOG:
grp.setSelected("dlog" + id);
break;
case PIC_DLOG_LG:
grp.setSelected("dlog-lg" + id);
break;
case PIC_TALK:
grp.setSelected("talk" + id);
pic.setPict(i, PIC_CUSTOM_TALK);
break;
case PIC_ITEM:
grp.setSelected("item" + id);
break;
case PIC_BOOM:
grp.setSelected("boom" + id);
break;
case PIC_MISSILE:
grp.setSelected("miss" + id);
break;
case PIC_FULL:
grp.setSelected("none" + id);
break;
}
}
}
static bool set_custom_pic_type(cDialog& me, std::string hit, std::vector<ePicType>& pics, pic_num_t first) {
hit = dynamic_cast<cLedGroup&>(me[hit]).getSelected();
size_t iNum = hit.find_last_not_of("0123456789");
std::string id = hit.substr(iNum + 1);
hit = hit.substr(0, iNum + 1);
pic_num_t pic = boost::lexical_cast<int>(id) + first - 1;
cControl& num = me["num" + id];
num.setTextToNum(1000 + pic);
if(hit == "ter") {
pics[pic] = PIC_TER;
} else if(hit == "anim") {
pics[pic] = PIC_TER_ANIM;
num.setTextToNum(2000 + pic);
} else if(hit == "map") {
pics[pic] = PIC_TER_MAP;
} else if(hit == "monst-sm") {
pics[pic] = PIC_MONST;
} else if(hit == "monst-wide") {
pics[pic] = PIC_MONST_WIDE;
num.setTextToNum(2000 + pic);
} else if(hit == "monst-tall") {
pics[pic] = PIC_MONST_TALL;
num.setTextToNum(3000 + pic);
} else if(hit == "monst-lg") {
pics[pic] = PIC_MONST_LG;
num.setTextToNum(4000 + pic);
} else if(hit == "dlog") {
pics[pic] = PIC_DLOG;
} else if(hit == "dlog-lg") {
pics[pic] = PIC_DLOG_LG;
} else if(hit == "talk") {
pics[pic] = PIC_TALK;
} else if(hit == "item") {
pics[pic] = PIC_ITEM;
} else if(hit == "boom") {
pics[pic] = PIC_BOOM;
} else if(hit == "miss") {
pics[pic] = PIC_MISSILE;
} else if(hit == "none") {
pics[pic] = PIC_FULL;
}
return true;
}
static bool save_pics_types(cDialog& me, const std::vector<ePicType>& pics) {
if(!me.toast(true)) return true;
scenario.custom_graphics = pics;
return true;
}
static bool change_pics_page(cDialog& me, std::string hit, std::vector<ePicType>& pics, pic_num_t& first) {
size_t num_pics = spec_scen_g.count();
if(hit == "left") {
if(first == 0) first = ((num_pics - 1) / 10) * 10;
else first -= 10;
} else if(hit == "right") {
if(first + 10 >= num_pics) first = 0;
else first += 10;
} else return true;
fill_custom_pics_types(me, pics, first);
return true;
}
void edit_custom_pics_types() {
if(spec_scen_g.count() == 0) {
giveError("You don't have any custom graphics to classify!");
return;
}
using namespace std::placeholders;
std::vector<ePicType> pics = scenario.custom_graphics;
pic_num_t first_pic = 0;
cDialog pic_dlg("graphic-types");
for(int i = 0; i < 10; i++) {
std::string id = std::to_string(i + 1);
pic_dlg["type" + id].attachFocusHandler(std::bind(set_custom_pic_type, _1, _2, std::ref(pics), std::ref(first_pic)));
}
pic_dlg["okay"].attachClickHandler(std::bind(save_pics_types, _1, std::ref(pics)));
pic_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, _1, false));
pic_dlg.attachClickHandlers(std::bind(change_pics_page, _1, _2, std::ref(pics), std::ref(first_pic)), {"left", "right"});
fill_custom_pics_types(pic_dlg, pics, first_pic);
if(spec_scen_g.count() <= 10) {
pic_dlg["left"].hide();
pic_dlg["right"].hide();
}
pic_dlg.run();
}

View File

@@ -1,6 +1,7 @@
class cDialog;
void edit_custom_pics_types();
short edit_ter_type(ter_num_t which_ter);
short edit_monst_type(short which_monst);
cMonster edit_monst_abil(cMonster starting_record,short parent_num);

View File

@@ -170,6 +170,17 @@ void save_scenario(fs::path toFile) {
data.PushElement("default-ground", scenario.default_ground);
data.PushElement("last-out-section", scenario.last_out_edited);
data.PushElement("last-town", scenario.last_town_edited);
if(!scenario.custom_graphics.empty()) {
data.OpenElement("graphics");
for(size_t i = 0; i < scenario.custom_graphics.size(); i++) {
if(scenario.custom_graphics[i] == PIC_FULL) continue;
data.OpenElement("pic");
data.PushAttribute("index", i);
data.PushText(scenario.custom_graphics[i]);
data.CloseElement("pic");
}
data.CloseElement("graphics");
}
for(int i = 0; i < 10; i++) {
if(scenario.storage_shortcuts[i].ter_type >= 0) {
cScenario::cItemStorage shortcut = scenario.storage_shortcuts[i];

View File

@@ -2,6 +2,7 @@
#include <stack>
#include <set>
#include <map>
#include <numeric>
#include <boost/lexical_cast.hpp>
#include "scen.global.h"
#include "classes.h"
@@ -54,19 +55,27 @@ bool cre(short val,short min,short max,std::string text1,std::string text2,cDial
// TODO: I have two functions that do this. (The other one is pick_picture.)
pic_num_t choose_graphic(short cur_choice,ePicType g_type,cDialog* parent) {
int i = 0;
std::vector<std::pair<pic_num_t,ePicType>> pics;
std::vector<pic_num_t> all_pics;
size_t total_pics = 0;
cPictChoice* pic_dlg = nullptr;
switch(g_type) {
case PIC_TER: // TODO: Increase upper limit to allow picking of the added graphics
pic_dlg = new cPictChoice(0, 252, PIC_TER, parent);
break;
case PIC_TER_ANIM: // TODO: Increase to allow picking of the added graphics
pic_dlg = new cPictChoice(0, 13, PIC_TER_ANIM, parent);
break;
case PIC_MONST:
case PIC_MONST_WIDE:
case PIC_MONST_TALL:
case PIC_MONST_LG:
case PIC_TER: total_pics = 859; break;
case PIC_TER_ANIM: total_pics = 20; break;
case PIC_DLOG: total_pics = 44; break;
case PIC_TALK: total_pics = 84; break;
case PIC_SCEN: total_pics = 30; break;
case PIC_ITEM: total_pics = 123; break;
case PIC_PC: total_pics = 36; break;
case PIC_FIELD: all_pics = field_pics; break;
case PIC_BOOM: all_pics = boom_pics; break;
case PIC_DLOG_LG: all_pics = lgdlog_pics; break;
case PIC_MISSILE: total_pics = 16; break;
case PIC_STATUS: total_pics = 27; break;
case PIC_SCEN_LG: total_pics = 4; break;
case PIC_TER_MAP: total_pics = 980; break;
case PIC_MONST: case PIC_MONST_WIDE:
case PIC_MONST_TALL: case PIC_MONST_LG:
std::vector<std::pair<pic_num_t,ePicType>> pics;
for(m_pic_index_t m_pic : m_pic_index) {
// TODO: Put the added monster graphics in m_pic_index to allow picking them
ePicType type = PIC_MONST;
@@ -74,64 +83,45 @@ pic_num_t choose_graphic(short cur_choice,ePicType g_type,cDialog* parent) {
if(m_pic.y == 2) type += PIC_TALL;
pics.push_back({i++, type});
}
for(size_t i = 0; i < scenario.custom_graphics.size(); i++) {
if(scenario.custom_graphics[i] == PIC_MONST)
pics.push_back({1000 + i, PIC_CUSTOM_MONST});
else if(scenario.custom_graphics[i] == PIC_MONST_WIDE)
pics.push_back({2000 + i, PIC_CUSTOM_MONST_WIDE});
else if(scenario.custom_graphics[i] == PIC_MONST_TALL)
pics.push_back({3000 + i, PIC_CUSTOM_MONST_TALL});
else if(scenario.custom_graphics[i] == PIC_MONST_LG)
pics.push_back({4000 + i, PIC_CUSTOM_MONST_LG});
if(cur_choice == pics.back().first)
cur_choice = pics.size() - 1;
}
pic_dlg = new cPictChoice(pics, parent);
break;
case PIC_DLOG: // TODO: Increase upper limit to allow picking of the added graphics
pic_dlg = new cPictChoice(0, 31, PIC_DLOG, parent);
break;
case PIC_TALK:
pic_dlg = new cPictChoice(0, 83, PIC_TALK, parent);
break;
case PIC_SCEN:
pic_dlg = new cPictChoice(0, 29, PIC_SCEN, parent);
break;
case PIC_ITEM:
pic_dlg = new cPictChoice(0, 122, PIC_ITEM, parent);
break;
case PIC_PC:
pic_dlg = new cPictChoice(0, 35, PIC_PC, parent);
break;
case PIC_FIELD:
pic_dlg = new cPictChoice(field_pics, PIC_FIELD, parent);
break;
case PIC_BOOM:
pic_dlg = new cPictChoice(boom_pics, PIC_BOOM, parent);
break;
case PIC_DLOG_LG:
pic_dlg = new cPictChoice(lgdlog_pics, PIC_DLOG_LG, parent);
break;
case PIC_FULL:
// TODO: Should this be handled at all?
break;
case PIC_MISSILE:
pic_dlg = new cPictChoice(0, 15, PIC_MISSILE, parent);
break;
case PIC_STATUS:
pic_dlg = new cPictChoice(0, 17, PIC_STATUS, parent);
break;
case PIC_SCEN_LG:
pic_dlg = new cPictChoice(0, 3, PIC_SCEN_LG, parent);
break;
case PIC_TER_MAP:
pic_dlg = new cPictChoice(0, 418, PIC_TER_MAP, parent);
break;
default: // Custom or party; assume custom, since this is the scenario editor and the party sheet isn't available
if(g_type & PIC_PARTY) break;
ePicType g_base_type = g_type - PIC_CUSTOM;
pic_num_t totalPics = spec_scen_g.count();
pic_num_t last;
if(g_base_type == PIC_DLOG || g_base_type == PIC_TALK || g_base_type == PIC_SCEN)
last = totalPics - 2;
else if(g_base_type == PIC_TER_ANIM || g_base_type == PIC_MONST || g_base_type == PIC_PC || g_base_type == PIC_MISSILE)
last = totalPics - 4;
else if(g_base_type==PIC_DLOG_LG || g_base_type==PIC_SCEN_LG || g_base_type==PIC_MONST_WIDE || g_base_type==PIC_MONST_TALL)
last = totalPics - 8;
else if(g_base_type == PIC_MONST_LG) last = totalPics - 16;
else if(g_base_type == PIC_TER_MAP) last = totalPics * 6 - 1; // TODO: Check this formula
else last = totalPics = 1;
pic_dlg = new cPictChoice(0, last, g_type, parent);
}
if(!pic_dlg) return cur_choice;
if(!pic_dlg) {
if(all_pics.size());
else if(total_pics > 0) {
all_pics.resize(total_pics);
std::iota(all_pics.begin(), all_pics.end(), 0);
} else return cur_choice;
// Now add the custom pics
for(size_t i = 0; i < scenario.custom_graphics.size(); i++) {
if(scenario.custom_graphics[i] == g_type) {
if(g_type == PIC_TER_MAP) {
for(int j = 1; j <= 6; j++)
all_pics.push_back(j * 1000 + i);
} else if(g_type == PIC_TER_ANIM)
all_pics.push_back(2000 + i);
else all_pics.push_back(1000 + i);
}
}
if(cur_choice >= 1000) {
auto selected = std::find(all_pics.begin(), all_pics.end(), cur_choice);
if(selected == all_pics.end()) cur_choice = -1;
else cur_choice = selected - all_pics.begin();
}
pic_dlg = new cPictChoice(all_pics, g_type, parent);
}
bool made_choice = pic_dlg->show(cur_choice);
pic_num_t item_hit = pic_dlg->getPicChosen();
delete pic_dlg;

View File

@@ -263,6 +263,10 @@ void handle_menu_choice(eMenu item_hit) {
set_starting_loc();
change_made = true;
break;
case eMenu::SCEN_PICS:
edit_custom_pics_types();
change_made = true;
break;
case eMenu::SCEN_SPECIALS:
right_sbar->setPosition(0);
start_special_editing(0,0);

View File

@@ -373,6 +373,14 @@
<reference key="NSOnImage" ref="229763992"/>
<reference key="NSMixedImage" ref="909111550"/>
</object>
<object class="NSMenuItem" id="963208893">
<reference key="NSMenu" ref="399390342"/>
<string key="NSTitle">Classify Custom Graphics</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="229763992"/>
<reference key="NSMixedImage" ref="909111550"/>
</object>
<object class="NSMenuItem" id="1007446984">
<reference key="NSMenu" ref="399390342"/>
<bool key="NSIsDisabled">YES</bool>
@@ -1364,6 +1372,7 @@
<reference ref="580939217"/>
<reference ref="949025402"/>
<reference ref="72958416"/>
<reference ref="963208893"/>
</array>
<reference key="parent" ref="741259600"/>
</object>
@@ -1838,6 +1847,11 @@
<reference key="object" ref="776162233"/>
<reference key="parent" ref="720053764"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">887</int>
<reference key="object" ref="963208893"/>
<reference key="parent" ref="399390342"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -1961,12 +1975,13 @@
<string key="884.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="885.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="886.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="887.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">886</int>
<int key="maxID">887</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>

View File

@@ -24,6 +24,7 @@ enum class eMenu {
SCEN_SAVE_ITEM_RECTS, SCEN_HORSES, SCEN_BOATS,
TOWN_VARYING, SCEN_TIMERS, SCEN_ITEM_SHORTCUTS, TOWN_DELETE,
SCEN_DATA_DUMP, SCEN_TEXT_DUMP,
SCEN_PICS,
// Town menu
TOWN_DETAILS, TOWN_WANDERING, TOWN_BOUNDARIES, TOWN_AREAS,
TOWN_ITEMS_RANDOM, TOWN_ITEMS_NOT_PROPERTY, TOWN_ITEMS_CLEAR,

View File

@@ -64,7 +64,7 @@ void init_menubar() {
eMenu::EDIT_CUT, eMenu::EDIT_COPY, eMenu::EDIT_PASTE, eMenu::EDIT_DELETE, eMenu::EDIT_SELECT_ALL,
};
static const eMenu scen_choices[] = {
eMenu::TOWN_CREATE, eMenu::NONE, eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::TOWN_START, eMenu::NONE, eMenu::NONE,
eMenu::TOWN_CREATE, eMenu::NONE, eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::TOWN_START, eMenu::SCEN_PICS, eMenu::NONE, eMenu::NONE,
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::TOWN_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
eMenu::SCEN_HORSES, eMenu::SCEN_BOATS, eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,

View File

@@ -69,7 +69,7 @@ void init_menubar() {
eMenu::EDIT_CUT, eMenu::EDIT_COPY, eMenu::EDIT_PASTE, eMenu::EDIT_DELETE, eMenu::EDIT_SELECT_ALL,
};
static const eMenu scen_choices[] = {
eMenu::TOWN_CREATE, eMenu::NONE, eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::TOWN_START, eMenu::NONE, eMenu::NONE,
eMenu::TOWN_CREATE, eMenu::NONE, eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::TOWN_START, eMenu::SCEN_PICS, eMenu::NONE, eMenu::NONE,
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::TOWN_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
eMenu::SCEN_HORSES, eMenu::SCEN_BOATS, eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,

View File

@@ -502,7 +502,7 @@ std::string get_str(std::string list, short j){
return strings[j - 1];
}
m_pic_index_t m_pic_index[] = {
extern const std::vector<m_pic_index_t> m_pic_index = {
{1, 1, 1},
{2, 1, 1},
{3, 1, 1},
@@ -702,27 +702,6 @@ m_pic_index_t m_pic_index[] = {
{203, 1, 1},
//180
{204, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
//190
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
{0, 1, 1},
//200
};
// TODO: Put these classes in a header?

View File

@@ -11,6 +11,7 @@
#include <string>
#include <memory>
#include <vector>
#include <functional>
#include <boost/filesystem/path.hpp>
#include <SFML/Graphics.hpp>
@@ -138,7 +139,7 @@ short can_see(location p1,location p2,std::function<short(short,short)> get_obsc
std::string get_str(std::string list, short j);
#ifndef GRAPHTOOL_CPP
extern m_pic_index_t m_pic_index[200];
extern const std::vector<m_pic_index_t> m_pic_index;
extern tessel_ref_t bg[];
#endif