mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
- removed creature-related code from ModHandler
- new towns can be loaded as mods - removed separate DefInfos for towns\capitals - a bit simpler handling of adventure map def's
This commit is contained in:
parent
c336abcf4a
commit
f7915d9e61
@ -146,13 +146,14 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
|
|||||||
//set correct value for alpha\unused channel
|
//set correct value for alpha\unused channel
|
||||||
for (int i=0; i< ret->format->palette->ncolors; i++)
|
for (int i=0; i< ret->format->palette->ncolors; i++)
|
||||||
ret->format->palette->colors[i].unused = 255;
|
ret->format->palette->colors[i].unused = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tlog1<<"Failed to open "<<fname<<" via SDL_Image\n";
|
tlog1<<"Failed to open "<<fname<<" via SDL_Image\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SDL_SetColorKey(ret, SDL_SRCCOLORKEY, SDL_MapRGB(ret->format, 0, 255, 255));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,7 +1152,10 @@ void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )
|
|||||||
builds = new CCastleBuildings(town);
|
builds = new CCastleBuildings(town);
|
||||||
|
|
||||||
BOOST_FOREACH(const CStructure * str, town->town->clientInfo.structures)
|
BOOST_FOREACH(const CStructure * str, town->town->clientInfo.structures)
|
||||||
tlog1 << int(str->building->bid) << " -> " << int(str->pos.z) << "\n";
|
{
|
||||||
|
if (str->building)
|
||||||
|
tlog1 << int(str->building->bid) << " -> " << int(str->pos.z) << "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDLK_KP_MINUS:
|
case SDLK_KP_MINUS:
|
||||||
@ -1165,7 +1168,10 @@ void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )
|
|||||||
builds = new CCastleBuildings(town);
|
builds = new CCastleBuildings(town);
|
||||||
|
|
||||||
BOOST_FOREACH(const CStructure * str, town->town->clientInfo.structures)
|
BOOST_FOREACH(const CStructure * str, town->town->clientInfo.structures)
|
||||||
tlog1 << int(str->building->bid) << " -> " << int(str->pos.z) << "\n";
|
{
|
||||||
|
if (str->building)
|
||||||
|
tlog1 << int(str->building->bid) << " -> " << int(str->pos.z) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -778,7 +778,7 @@ static void listenForEvents()
|
|||||||
delete CGI->dobjinfo.get();
|
delete CGI->dobjinfo.get();
|
||||||
const_cast<CGameInfo*>(CGI)->dobjinfo = new CDefObjInfoHandler;
|
const_cast<CGameInfo*>(CGI)->dobjinfo = new CDefObjInfoHandler;
|
||||||
const_cast<CGameInfo*>(CGI)->dobjinfo->load();
|
const_cast<CGameInfo*>(CGI)->dobjinfo->load();
|
||||||
const_cast<CGameInfo*>(CGI)->modh->recreateAdvMapDefs(); //add info about new creatures to dobjinfo
|
const_cast<CGameInfo*>(CGI)->modh->reload(); //add info about new creatures to dobjinfo
|
||||||
};
|
};
|
||||||
|
|
||||||
switch(ev.user.code)
|
switch(ev.user.code)
|
||||||
|
@ -346,7 +346,9 @@ SDL_Surface * Graphics::getPic(int ID, bool fort, bool builded)
|
|||||||
{
|
{
|
||||||
assert(vstd::contains(CGI->townh->towns, ID));
|
assert(vstd::contains(CGI->townh->towns, ID));
|
||||||
int pom = CGI->townh->towns[ID].clientInfo.icons[fort][builded];
|
int pom = CGI->townh->towns[ID].clientInfo.icons[fort][builded];
|
||||||
return smallIcons->ourImages[pom + 2].bitmap;
|
if (smallIcons->ourImages.size() > pom + 2)
|
||||||
|
return smallIcons->ourImages[pom + 2].bitmap;
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,12 +480,12 @@ void Graphics::loadFonts()
|
|||||||
|
|
||||||
CDefEssential * Graphics::getDef( const CGObjectInstance * obj )
|
CDefEssential * Graphics::getDef( const CGObjectInstance * obj )
|
||||||
{
|
{
|
||||||
return advmapobjGraphics[obj->defInfo->id][obj->defInfo->subid][obj->defInfo->name];
|
return advmapobjGraphics[obj->defInfo->name];
|
||||||
}
|
}
|
||||||
|
|
||||||
CDefEssential * Graphics::getDef( const CGDefInfo * info )
|
CDefEssential * Graphics::getDef( const CGDefInfo * info )
|
||||||
{
|
{
|
||||||
return advmapobjGraphics[info->id][info->subid][info->name];
|
return advmapobjGraphics[info->name];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::loadErmuToPicture()
|
void Graphics::loadErmuToPicture()
|
||||||
|
@ -54,11 +54,10 @@ public:
|
|||||||
CDefEssential * heroMoveArrows;
|
CDefEssential * heroMoveArrows;
|
||||||
std::vector<CDefEssential *> heroAnims; // [class id: 0 - 17] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
std::vector<CDefEssential *> heroAnims; // [class id: 0 - 17] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
||||||
std::vector<CDefEssential *> boatAnims; // [boat type: 0 - 3] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
std::vector<CDefEssential *> boatAnims; // [boat type: 0 - 3] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
||||||
std::map<std::string, CDefEssential*> mapObjectDefs; //pointers to loaded defs (key is filename, uppercase)
|
|
||||||
CDefHandler * FoWfullHide; //for Fog of War
|
CDefHandler * FoWfullHide; //for Fog of War
|
||||||
CDefHandler * FoWpartialHide; //for For of War
|
CDefHandler * FoWpartialHide; //for For of War
|
||||||
|
|
||||||
std::map<int, std::map<int, std::map<std::string, CDefEssential *> > > advmapobjGraphics;
|
std::map<std::string, CDefEssential *> advmapobjGraphics;
|
||||||
CDefEssential * getDef(const CGObjectInstance * obj);
|
CDefEssential * getDef(const CGObjectInstance * obj);
|
||||||
CDefEssential * getDef(const CGDefInfo * info);
|
CDefEssential * getDef(const CGDefInfo * info);
|
||||||
//creatures
|
//creatures
|
||||||
|
@ -403,11 +403,11 @@ void NewStructures::applyCl( CClient *cl )
|
|||||||
{
|
{
|
||||||
if(id== EBuilding::CAPITOL) //fort or capitol
|
if(id== EBuilding::CAPITOL) //fort or capitol
|
||||||
{
|
{
|
||||||
town->defInfo = GS(cl)->capitols[town->subID];
|
town->defInfo = const_cast<CGDefInfo*>(CGI->dobjinfo->capitols[town->subID].get());
|
||||||
}
|
}
|
||||||
if(id == EBuilding::FORT)
|
if(id == EBuilding::FORT)
|
||||||
{
|
{
|
||||||
town->defInfo = GS(cl)->forts[town->subID];
|
town->defInfo = const_cast<CGDefInfo*>(CGI->dobjinfo->gobjs[Obj::TOWN][town->subID].get());
|
||||||
}
|
}
|
||||||
if(vstd::contains(cl->playerint,town->tempOwner))
|
if(vstd::contains(cl->playerint,town->tempOwner))
|
||||||
cl->playerint[town->tempOwner]->buildChanged(town,id,1);
|
cl->playerint[town->tempOwner]->buildChanged(town,id,1);
|
||||||
@ -420,7 +420,7 @@ void RazeStructures::applyCl (CClient *cl)
|
|||||||
{
|
{
|
||||||
if (id == 13) //fort or capitol
|
if (id == 13) //fort or capitol
|
||||||
{
|
{
|
||||||
town->defInfo = GS(cl)->forts[town->subID];
|
town->defInfo = const_cast<CGDefInfo*>(CGI->dobjinfo->gobjs[Obj::TOWN][town->subID].get());
|
||||||
}
|
}
|
||||||
if(vstd::contains (cl->playerint,town->tempOwner))
|
if(vstd::contains (cl->playerint,town->tempOwner))
|
||||||
cl->playerint[town->tempOwner]->buildChanged (town,id,2);
|
cl->playerint[town->tempOwner]->buildChanged (town,id,2);
|
||||||
|
@ -74,7 +74,8 @@ void blitAt(SDL_Surface * src, int x, int y, SDL_Surface * dst)
|
|||||||
|
|
||||||
void blitAt(SDL_Surface * src, const SDL_Rect & pos, SDL_Surface * dst)
|
void blitAt(SDL_Surface * src, const SDL_Rect & pos, SDL_Surface * dst)
|
||||||
{
|
{
|
||||||
blitAt(src,pos.x,pos.y,dst);
|
if (src)
|
||||||
|
blitAt(src,pos.x,pos.y,dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Color genRGB(int r, int g, int b, int a=0)
|
SDL_Color genRGB(int r, int g, int b, int a=0)
|
||||||
|
@ -240,6 +240,36 @@ void CMapHandler::borderAndTerrainBitmapInit()
|
|||||||
}
|
}
|
||||||
delete bord;
|
delete bord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void processDef (const CGDefInfo* def)
|
||||||
|
{
|
||||||
|
if(def->id == Obj::EVENT)
|
||||||
|
{
|
||||||
|
graphics->advmapobjGraphics[def->name] = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CDefEssential * ourDef = graphics->getDef(def);
|
||||||
|
if(!ourDef) //if object has already set handler (eg. heroes) it should not be overwritten
|
||||||
|
{
|
||||||
|
if(def->name.size())
|
||||||
|
{
|
||||||
|
graphics->advmapobjGraphics[def->name] = CDefHandler::giveDefEss(def->name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tlog2 << "No def name for " << def->id << " " << def->subid << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ourDef = graphics->getDef(def);
|
||||||
|
|
||||||
|
}
|
||||||
|
//alpha transformation
|
||||||
|
for(size_t yy=0; yy < ourDef->ourImages.size(); ++yy)
|
||||||
|
{
|
||||||
|
CSDL_Ext::alphaTransform(ourDef->ourImages[yy].bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CMapHandler::initObjectRects()
|
void CMapHandler::initObjectRects()
|
||||||
{
|
{
|
||||||
//initializing objects / rects
|
//initializing objects / rects
|
||||||
@ -249,11 +279,15 @@ void CMapHandler::initObjectRects()
|
|||||||
if( !obj
|
if( !obj
|
||||||
|| (obj->ID==Obj::HERO && static_cast<const CGHeroInstance*>(obj)->inTownGarrison) //garrisoned hero
|
|| (obj->ID==Obj::HERO && static_cast<const CGHeroInstance*>(obj)->inTownGarrison) //garrisoned hero
|
||||||
|| (obj->ID==Obj::BOAT && static_cast<const CGBoat*>(obj)->hero) //boat with hero (hero graphics is used)
|
|| (obj->ID==Obj::BOAT && static_cast<const CGBoat*>(obj)->hero) //boat with hero (hero graphics is used)
|
||||||
|| !obj->defInfo
|
|| !obj->defInfo )
|
||||||
|| !graphics->getDef(obj)) //no graphic...
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!graphics->getDef(obj)) //try to load it
|
||||||
|
processDef(obj->defInfo);
|
||||||
|
if (!graphics->getDef(obj)) // stil no graphics? exit
|
||||||
|
continue;
|
||||||
|
|
||||||
const SDL_Surface *bitmap = graphics->getDef(obj)->ourImages[0].bitmap;
|
const SDL_Surface *bitmap = graphics->getDef(obj)->ourImages[0].bitmap;
|
||||||
for(int fx=0; fx<bitmap->w>>5; ++fx) //bitmap->w/32
|
for(int fx=0; fx<bitmap->w>>5; ++fx) //bitmap->w/32
|
||||||
{
|
{
|
||||||
@ -294,53 +328,20 @@ void CMapHandler::initObjectRects()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void processDef (const CGDefInfo* def)
|
|
||||||
{
|
|
||||||
if(def->id == Obj::EVENT)
|
|
||||||
{
|
|
||||||
graphics->advmapobjGraphics[def->id][def->subid][def->name] = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CDefEssential * ourDef = graphics->getDef(def);
|
|
||||||
if(!ourDef) //if object has already set handler (eg. heroes) it should not be overwritten
|
|
||||||
{
|
|
||||||
if(def->name.size())
|
|
||||||
{
|
|
||||||
if(vstd::contains(graphics->mapObjectDefs, def->name))
|
|
||||||
{
|
|
||||||
graphics->advmapobjGraphics[def->id][def->subid][def->name] = graphics->mapObjectDefs[def->name];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
graphics->mapObjectDefs[def->name] = graphics->advmapobjGraphics[def->id][def->subid][def->name] = CDefHandler::giveDefEss(def->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tlog2 << "No def name for " << def->id << " " << def->subid << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ourDef = graphics->getDef(def);
|
|
||||||
|
|
||||||
}
|
|
||||||
//alpha transformation
|
|
||||||
for(size_t yy=0; yy < ourDef->ourImages.size(); ++yy)
|
|
||||||
{
|
|
||||||
CSDL_Ext::alphaTransform(ourDef->ourImages[yy].bitmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void CMapHandler::initHeroDef(const CGHeroInstance * h)
|
void CMapHandler::initHeroDef(const CGHeroInstance * h)
|
||||||
{
|
{
|
||||||
graphics->advmapobjGraphics[h->defInfo->id][h->defInfo->subid][h->defInfo->name] = graphics->flags1[0];
|
graphics->advmapobjGraphics[h->defInfo->name] = graphics->flags1[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::init()
|
void CMapHandler::init()
|
||||||
{
|
{
|
||||||
CStopWatch th;
|
CStopWatch th;
|
||||||
th.getDiff();
|
th.getDiff();
|
||||||
|
|
||||||
graphics->advmapobjGraphics[8][0]["AB01_.DEF"] = graphics->boatAnims[0];
|
graphics->advmapobjGraphics["AB01_.DEF"] = graphics->boatAnims[0];
|
||||||
graphics->advmapobjGraphics[8][1]["AB02_.DEF"] = graphics->boatAnims[1];
|
graphics->advmapobjGraphics["AB02_.DEF"] = graphics->boatAnims[1];
|
||||||
graphics->advmapobjGraphics[8][2]["AB03_.DEF"] = graphics->boatAnims[2];
|
graphics->advmapobjGraphics["AB03_.DEF"] = graphics->boatAnims[2];
|
||||||
// Size of visible terrain.
|
// Size of visible terrain.
|
||||||
int mapW = conf.go()->ac.advmapW;
|
int mapW = conf.go()->ac.advmapW;
|
||||||
int mapH = conf.go()->ac.advmapH;
|
int mapH = conf.go()->ac.advmapH;
|
||||||
@ -381,18 +382,6 @@ void CMapHandler::init()
|
|||||||
std::for_each(map->customDefs.begin(),map->customDefs.end(),processDef); //load h3m defs
|
std::for_each(map->customDefs.begin(),map->customDefs.end(),processDef); //load h3m defs
|
||||||
tlog0<<"\tUnpacking and handling defs: "<<th.getDiff()<<std::endl;
|
tlog0<<"\tUnpacking and handling defs: "<<th.getDiff()<<std::endl;
|
||||||
|
|
||||||
//it seems to be completely unnecessary and useless
|
|
||||||
// for(int i=0;i<PLAYER_LIMIT;i++)
|
|
||||||
// {
|
|
||||||
// for(size_t j=0; j < map->players[i].heroesNames.size(); ++j)
|
|
||||||
// {
|
|
||||||
// usedHeroes.insert(map->players[i].heroesNames[j].heroID);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// tlog0<<"\tChecking used heroes: "<<th.getDif()<<std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
prepareFOWDefs();
|
prepareFOWDefs();
|
||||||
roadsRiverTerrainInit(); //road's and river's DefHandlers; and simple values initialization
|
roadsRiverTerrainInit(); //road's and river's DefHandlers; and simple values initialization
|
||||||
borderAndTerrainBitmapInit();
|
borderAndTerrainBitmapInit();
|
||||||
@ -414,7 +403,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
|
|||||||
|
|
||||||
// Basic rectangle for a tile. Should be a const but conflicts with SDL headers
|
// Basic rectangle for a tile. Should be a const but conflicts with SDL headers
|
||||||
SDL_Rect rtile = { 0, 0, 32, 32 };
|
SDL_Rect rtile = { 0, 0, 32, 32 };
|
||||||
|
|
||||||
// Absolute coords of the first pixel in the top left corner
|
// Absolute coords of the first pixel in the top left corner
|
||||||
int srx_init = offsetX + extRect->x;
|
int srx_init = offsetX + extRect->x;
|
||||||
int sry_init = offsetY + extRect->y;
|
int sry_init = offsetY + extRect->y;
|
||||||
|
@ -30,8 +30,16 @@ public:
|
|||||||
|
|
||||||
template<typename T> void print(const T &data, int lvl)
|
template<typename T> void print(const T &data, int lvl)
|
||||||
{
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
|
// with love from ffmpeg - library is trying to print some warnings from separate thread
|
||||||
|
// this results in broken console on Linux. Lock stdout to print all our data at once
|
||||||
|
flockfile(stdout);
|
||||||
|
#endif
|
||||||
setColor(lvl);
|
setColor(lvl);
|
||||||
std::cout << data << std::flush;
|
std::cout << data << std::flush;
|
||||||
setColor(-1);
|
setColor(-1);
|
||||||
|
#ifndef _WIN32
|
||||||
|
funlockfile(stdout);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -611,6 +611,162 @@ void CCreatureHandler::loadSoundsInfo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCreatureHandler::load(const JsonNode & node)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(auto & entry, node.Struct())
|
||||||
|
{
|
||||||
|
if (!entry.second.isNull()) // may happens if mod removed creature by setting json entry to null
|
||||||
|
{
|
||||||
|
CCreature * creature = loadCreature(entry.second);
|
||||||
|
creature->nameRef = entry.first;
|
||||||
|
creature->idNumber = creatures.size();
|
||||||
|
nameToID[entry.first] = creatures.size();
|
||||||
|
|
||||||
|
creatures.push_back(creature);
|
||||||
|
tlog3 << "Added creature: " << entry.first << "\n";
|
||||||
|
//TODO: notify modHandler that this refName can be resolved to ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CCreature * CCreatureHandler::loadCreature(const JsonNode & node)
|
||||||
|
{
|
||||||
|
CCreature * cre = new CCreature();
|
||||||
|
|
||||||
|
const JsonNode & name = node["name"];
|
||||||
|
cre->nameSing = name["singular"].String();
|
||||||
|
cre->namePl = name["plural"].String();
|
||||||
|
|
||||||
|
cre->cost = Res::ResourceSet(node["cost"]);
|
||||||
|
|
||||||
|
cre->level = node["level"].Float();
|
||||||
|
cre->faction = node["faction"].Float(); //TODO: replaced by string -> id conversion
|
||||||
|
cre->fightValue = node["fightValue"].Float();
|
||||||
|
cre->AIValue = node["aiValue"].Float();
|
||||||
|
cre->growth = node["growth"].Float();
|
||||||
|
cre->hordeGrowth = node["horde"].Float(); // Needed at least until configurable buildings
|
||||||
|
|
||||||
|
cre->addBonus(node["hitPoints"].Float(), Bonus::STACK_HEALTH);
|
||||||
|
cre->addBonus(node["speed"].Float(), Bonus::STACKS_SPEED);
|
||||||
|
cre->addBonus(node["attack"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
|
||||||
|
cre->addBonus(node["defense"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
|
||||||
|
const JsonNode & vec = node["damage"];
|
||||||
|
cre->addBonus(vec["min"].Float(), Bonus::CREATURE_DAMAGE, 1);
|
||||||
|
cre->addBonus(vec["max"].Float(), Bonus::CREATURE_DAMAGE, 2);
|
||||||
|
|
||||||
|
auto & amounts = node ["advMapAmount"];
|
||||||
|
cre->ammMin = amounts["min"].Float();
|
||||||
|
cre->ammMax = amounts["max"].Float();
|
||||||
|
|
||||||
|
//optional
|
||||||
|
BOOST_FOREACH (auto & str, node["upgrades"].Vector())
|
||||||
|
{
|
||||||
|
cre->upgradeNames.insert (str.String());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node["shots"].isNull())
|
||||||
|
cre->addBonus(node["shots"].Float(), Bonus::SHOTS);
|
||||||
|
|
||||||
|
if (node["spellPoints"].isNull())
|
||||||
|
cre->addBonus(node["spellPoints"].Float(), Bonus::CASTS);
|
||||||
|
|
||||||
|
cre->doubleWide = node["doubleWide"].Bool();
|
||||||
|
|
||||||
|
BOOST_FOREACH (const JsonNode &bonus, node["abilities"].Vector())
|
||||||
|
{
|
||||||
|
auto b = ParseBonus(bonus);
|
||||||
|
b->source = Bonus::CREATURE_ABILITY;
|
||||||
|
b->duration = Bonus::PERMANENT;
|
||||||
|
cre->addNewBonus(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH (const JsonNode &exp, node["stackExperience"].Vector())
|
||||||
|
{
|
||||||
|
auto bonus = ParseBonus (exp["bonus"]);
|
||||||
|
bonus->source = Bonus::STACK_EXPERIENCE;
|
||||||
|
bonus->duration = Bonus::PERMANENT;
|
||||||
|
const JsonVector &values = exp["values"].Vector();
|
||||||
|
int lowerLimit = 1;//, upperLimit = 255;
|
||||||
|
if (values[0].getType() == JsonNode::JsonType::DATA_BOOL)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH (const JsonNode &val, values)
|
||||||
|
{
|
||||||
|
if (val.Bool() == true)
|
||||||
|
{
|
||||||
|
bonus->limiter = make_shared<RankRangeLimiter>(RankRangeLimiter(lowerLimit));
|
||||||
|
cre->addNewBonus (new Bonus(*bonus)); //bonuses must be unique objects
|
||||||
|
break; //TODO: allow bonuses to turn off?
|
||||||
|
}
|
||||||
|
++lowerLimit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int lastVal = 0;
|
||||||
|
BOOST_FOREACH (const JsonNode &val, values)
|
||||||
|
{
|
||||||
|
if (val.Float() != lastVal)
|
||||||
|
{
|
||||||
|
bonus->val = val.Float() - lastVal;
|
||||||
|
bonus->limiter.reset (new RankRangeLimiter(lowerLimit));
|
||||||
|
cre->addNewBonus (new Bonus(*bonus));
|
||||||
|
}
|
||||||
|
lastVal = val.Float();
|
||||||
|
++lowerLimit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//graphics
|
||||||
|
|
||||||
|
const JsonNode & graphics = node["graphics"];
|
||||||
|
cre->animDefName = graphics["animation"].String();
|
||||||
|
cre->timeBetweenFidgets = graphics["timeBetweenFidgets"].Float();
|
||||||
|
cre->troopCountLocationOffset = graphics["troopCountLocationOffset"].Float();
|
||||||
|
cre->attackClimaxFrame = graphics["attackClimaxFrame"].Float();
|
||||||
|
|
||||||
|
const JsonNode & animationTime = graphics["animationTime"];
|
||||||
|
cre->walkAnimationTime = animationTime["walk"].Float();
|
||||||
|
cre->attackAnimationTime = animationTime["attack"].Float();
|
||||||
|
cre->flightAnimationDistance = animationTime["flight"].Float(); //?
|
||||||
|
//TODO: background?
|
||||||
|
const JsonNode & missile = graphics["missile"];
|
||||||
|
//TODO: parse
|
||||||
|
cre->projectile = missile["projectile"].String();
|
||||||
|
cre->projectileSpin = missile["spinning"].Bool();
|
||||||
|
|
||||||
|
const JsonNode & offsets = missile["offset"];
|
||||||
|
cre->upperRightMissleOffsetX = offsets["upperX"].Float();
|
||||||
|
cre->upperRightMissleOffsetY = offsets["upperY"].Float();
|
||||||
|
cre->rightMissleOffsetX = offsets["middleX"].Float();
|
||||||
|
cre->rightMissleOffsetY = offsets["middleY"].Float();
|
||||||
|
cre->lowerRightMissleOffsetX = offsets["lowerX"].Float();
|
||||||
|
cre->lowerRightMissleOffsetY = offsets["lowerY"].Float();
|
||||||
|
int i = 0;
|
||||||
|
BOOST_FOREACH (auto & angle, missile["frameAngles"].Vector())
|
||||||
|
{
|
||||||
|
cre->missleFrameAngles[i++] = angle.Float();
|
||||||
|
}
|
||||||
|
cre->advMapDef = graphics["map"].String();
|
||||||
|
cre->iconIndex = graphics["iconIndex"].Float();
|
||||||
|
|
||||||
|
const JsonNode & sounds = node["sound"];
|
||||||
|
|
||||||
|
#define GET_SOUND_VALUE(value_name) do { cre->sounds.value_name = sounds[#value_name].String(); } while(0)
|
||||||
|
GET_SOUND_VALUE(attack);
|
||||||
|
GET_SOUND_VALUE(defend);
|
||||||
|
GET_SOUND_VALUE(killed);
|
||||||
|
GET_SOUND_VALUE(move);
|
||||||
|
GET_SOUND_VALUE(shoot);
|
||||||
|
GET_SOUND_VALUE(wince);
|
||||||
|
GET_SOUND_VALUE(ext1);
|
||||||
|
GET_SOUND_VALUE(ext2);
|
||||||
|
GET_SOUND_VALUE(startMoving);
|
||||||
|
GET_SOUND_VALUE(endMoving);
|
||||||
|
#undef GET_SOUND_VALUE
|
||||||
|
|
||||||
|
return cre;
|
||||||
|
}
|
||||||
|
|
||||||
void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser & parser) //help function for parsing CREXPBON.txt
|
void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser & parser) //help function for parsing CREXPBON.txt
|
||||||
{
|
{
|
||||||
bool enable = false; //some bonuses are activated with values 2 or 1
|
bool enable = false; //some bonuses are activated with values 2 or 1
|
||||||
@ -914,7 +1070,7 @@ static int retreiveRandNum(const boost::function<int()> &randGen)
|
|||||||
|
|
||||||
template <typename T> const T & pickRandomElementOf(const std::vector<T> &v, const boost::function<int()> &randGen)
|
template <typename T> const T & pickRandomElementOf(const std::vector<T> &v, const boost::function<int()> &randGen)
|
||||||
{
|
{
|
||||||
return v[retreiveRandNum(randGen) % v.size()];
|
return v.at(retreiveRandNum(randGen) % v.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, int tier) const
|
int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, int tier) const
|
||||||
@ -936,7 +1092,6 @@ int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, i
|
|||||||
assert(b->getNodeType() == CBonusSystemNode::CREATURE);
|
assert(b->getNodeType() == CBonusSystemNode::CREATURE);
|
||||||
int creid = static_cast<const CCreature*>(b)->idNumber;
|
int creid = static_cast<const CCreature*>(b)->idNumber;
|
||||||
if(!vstd::contains(notUsedMonsters, creid))
|
if(!vstd::contains(notUsedMonsters, creid))
|
||||||
|
|
||||||
allowed.push_back(creid);
|
allowed.push_back(creid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,27 +140,40 @@ public:
|
|||||||
si8 expAfterUpgrade;//multiplier in %
|
si8 expAfterUpgrade;//multiplier in %
|
||||||
|
|
||||||
//Commanders
|
//Commanders
|
||||||
std::map <ui8, ui32> factionCommanders;
|
std::map <TFaction, TCreature> factionCommanders;
|
||||||
BonusList commanderLevelPremy; //bonus values added with each level-up
|
BonusList commanderLevelPremy; //bonus values added with each level-up
|
||||||
std::vector< std::vector <ui8> > skillLevels; //how much of a bonus will be given to commander with every level. SPELL_POWER also gives CASTS and RESISTANCE
|
std::vector< std::vector <ui8> > skillLevels; //how much of a bonus will be given to commander with every level. SPELL_POWER also gives CASTS and RESISTANCE
|
||||||
std::vector <std::pair <Bonus, std::pair <ui8, ui8> > > skillRequirements; // first - Bonus, second - which two skills are needed to use it
|
std::vector <std::pair <Bonus, std::pair <ui8, ui8> > > skillRequirements; // first - Bonus, second - which two skills are needed to use it
|
||||||
|
|
||||||
void deserializationFix();
|
/// loading functions
|
||||||
void loadCreatures();
|
|
||||||
void buildBonusTreeForTiers();
|
|
||||||
void loadAnimationInfo();
|
|
||||||
void loadUnitAnimInfo(CCreature & unit, CLegacyConfigParser &parser);
|
|
||||||
void loadSoundsInfo();
|
|
||||||
void loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser &parser);
|
|
||||||
int stringToNumber(std::string & s);//help function for parsing CREXPBON.txt
|
|
||||||
|
|
||||||
int pickRandomMonster(const boost::function<int()> &randGen = 0, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any
|
/// load all creatures from H3 files
|
||||||
void addBonusForTier(int tier, Bonus *b); //tier must be <1-7>
|
void loadCreatures();
|
||||||
void addBonusForAllCreatures(Bonus *b);
|
/// load all creatures from json structure
|
||||||
|
void load(const JsonNode & node);
|
||||||
|
/// load one creature from json config
|
||||||
|
CCreature * loadCreature(const JsonNode & node);
|
||||||
|
/// generates tier-specific bonus tree entries
|
||||||
|
void buildBonusTreeForTiers();
|
||||||
|
/// read cranim.txt file from H3
|
||||||
|
void loadAnimationInfo();
|
||||||
|
/// read one line from cranim.txt
|
||||||
|
void loadUnitAnimInfo(CCreature & unit, CLegacyConfigParser &parser);
|
||||||
|
/// load cr_sounds.json config
|
||||||
|
void loadSoundsInfo();
|
||||||
|
/// parse crexpbon.txt file from H3
|
||||||
|
void loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser &parser);
|
||||||
|
/// help function for parsing CREXPBON.txt
|
||||||
|
int stringToNumber(std::string & s);
|
||||||
|
|
||||||
CCreatureHandler();
|
CCreatureHandler();
|
||||||
~CCreatureHandler();
|
~CCreatureHandler();
|
||||||
|
|
||||||
|
void deserializationFix();
|
||||||
|
int pickRandomMonster(const boost::function<int()> &randGen = 0, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any
|
||||||
|
void addBonusForTier(int tier, Bonus *b); //tier must be <1-7>
|
||||||
|
void addBonusForAllCreatures(Bonus *b);
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
|
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "GameConstants.h"
|
||||||
#include "../lib/ConstTransitivePtr.h"
|
#include "../lib/ConstTransitivePtr.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -50,11 +50,14 @@ class DLL_LINKAGE CDefObjInfoHandler
|
|||||||
public:
|
public:
|
||||||
bmap<int, bmap<int, ConstTransitivePtr<CGDefInfo> > > gobjs;
|
bmap<int, bmap<int, ConstTransitivePtr<CGDefInfo> > > gobjs;
|
||||||
|
|
||||||
|
bmap<TFaction, ConstTransitivePtr<CGDefInfo> > capitols;
|
||||||
|
bmap<TFaction, ConstTransitivePtr<CGDefInfo> > villages;
|
||||||
|
|
||||||
void load();
|
void load();
|
||||||
~CDefObjInfoHandler();
|
~CDefObjInfoHandler();
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & gobjs;
|
h & gobjs & capitols & villages;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -660,11 +660,11 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
|
|||||||
CGTownInstance *t = dynamic_cast<CGTownInstance*>(cur);
|
CGTownInstance *t = dynamic_cast<CGTownInstance*>(cur);
|
||||||
t->town = &VLC->townh->towns[t->subID];
|
t->town = &VLC->townh->towns[t->subID];
|
||||||
if(t->hasCapitol())
|
if(t->hasCapitol())
|
||||||
t->defInfo = capitols[t->subID];
|
t->defInfo = VLC->dobjinfo->capitols[t->subID];
|
||||||
else if(t->hasFort())
|
else if(t->hasFort())
|
||||||
t->defInfo = forts[t->subID];
|
t->defInfo = VLC->dobjinfo->gobjs[Obj::TOWN][t->subID];
|
||||||
else
|
else
|
||||||
t->defInfo = villages[t->subID];
|
t->defInfo = VLC->dobjinfo->villages[t->subID];
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -685,13 +685,14 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
|
|||||||
if(!t) {tlog2<<"Wrong random town at "<<cur->pos<<std::endl; return;}
|
if(!t) {tlog2<<"Wrong random town at "<<cur->pos<<std::endl; return;}
|
||||||
cur->ID = ran.first;
|
cur->ID = ran.first;
|
||||||
cur->subID = ran.second;
|
cur->subID = ran.second;
|
||||||
t->town = &VLC->townh->towns[ran.second];
|
//FIXME: copy-pasted from above
|
||||||
|
t->town = &VLC->townh->towns[t->subID];
|
||||||
if(t->hasCapitol())
|
if(t->hasCapitol())
|
||||||
t->defInfo = capitols[t->subID];
|
t->defInfo = VLC->dobjinfo->capitols[t->subID];
|
||||||
else if(t->hasFort())
|
else if(t->hasFort())
|
||||||
t->defInfo = forts[t->subID];
|
t->defInfo = VLC->dobjinfo->gobjs[Obj::TOWN][t->subID];
|
||||||
else
|
else
|
||||||
t->defInfo = villages[t->subID];
|
t->defInfo = VLC->dobjinfo->villages[t->subID];
|
||||||
t->randomizeArmy(t->subID);
|
t->randomizeArmy(t->subID);
|
||||||
map->towns.push_back(t);
|
map->towns.push_back(t);
|
||||||
return;
|
return;
|
||||||
@ -700,7 +701,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
|
|||||||
cur->ID = ran.first;
|
cur->ID = ran.first;
|
||||||
cur->subID = ran.second;
|
cur->subID = ran.second;
|
||||||
map->removeBlockVisTiles(cur); //recalculate blockvis tiles - picked object might have different than random placeholder
|
map->removeBlockVisTiles(cur); //recalculate blockvis tiles - picked object might have different than random placeholder
|
||||||
map->customDefs.push_back(cur->defInfo = VLC->dobjinfo->gobjs[ran.first][ran.second]);
|
map->customDefs.push_back(cur->defInfo = VLC->dobjinfo->gobjs[ran.first][ran.second]);
|
||||||
if(!cur->defInfo)
|
if(!cur->defInfo)
|
||||||
{
|
{
|
||||||
tlog1<<"*BIG* WARNING: Missing def declaration for "<<cur->ID<<" "<<cur->subID<<std::endl;
|
tlog1<<"*BIG* WARNING: Missing def declaration for "<<cur->ID<<" "<<cur->subID<<std::endl;
|
||||||
@ -761,10 +762,6 @@ CGameState::~CGameState()
|
|||||||
//delete initialOpts;
|
//delete initialOpts;
|
||||||
delete applierGs;
|
delete applierGs;
|
||||||
delete objCaller;
|
delete objCaller;
|
||||||
|
|
||||||
//TODO: delete properly that definfos
|
|
||||||
villages.clear();
|
|
||||||
capitols.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BattleInfo * CGameState::setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town)
|
BattleInfo * CGameState::setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town)
|
||||||
@ -866,18 +863,18 @@ void CGameState::init(StartInfo * si)
|
|||||||
switch(scenarioOps->mode)
|
switch(scenarioOps->mode)
|
||||||
{
|
{
|
||||||
case StartInfo::NEW_GAME:
|
case StartInfo::NEW_GAME:
|
||||||
tlog0 << "Open map file: " << scenarioOps->mapname << std::endl;
|
tlog0 << "Open map file: " << scenarioOps->mapname << std::endl;
|
||||||
map = CMapService::loadMap(scenarioOps->mapname).release();
|
map = CMapService::loadMap(scenarioOps->mapname).release();
|
||||||
break;
|
break;
|
||||||
case StartInfo::CAMPAIGN:
|
case StartInfo::CAMPAIGN:
|
||||||
{
|
{
|
||||||
tlog0 << "Open campaign map file: " << scenarioOps->campState->currentMap << std::endl;
|
tlog0 << "Open campaign map file: " << scenarioOps->campState->currentMap << std::endl;
|
||||||
auto campaign = scenarioOps->campState;
|
auto campaign = scenarioOps->campState;
|
||||||
assert(vstd::contains(campaign->camp->mapPieces, scenarioOps->campState->currentMap));
|
assert(vstd::contains(campaign->camp->mapPieces, scenarioOps->campState->currentMap));
|
||||||
|
|
||||||
std::string & mapContent = campaign->camp->mapPieces[scenarioOps->campState->currentMap];
|
std::string & mapContent = campaign->camp->mapPieces[scenarioOps->campState->currentMap];
|
||||||
auto buffer = reinterpret_cast<const ui8 *>(mapContent.data());
|
auto buffer = reinterpret_cast<const ui8 *>(mapContent.data());
|
||||||
map = CMapService::loadMap(buffer, mapContent.size()).release();
|
map = CMapService::loadMap(buffer, mapContent.size()).release();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case StartInfo::DUEL:
|
case StartInfo::DUEL:
|
||||||
@ -906,7 +903,6 @@ void CGameState::init(StartInfo * si)
|
|||||||
scenarioOps->mapfileChecksum = map->checksum;
|
scenarioOps->mapfileChecksum = map->checksum;
|
||||||
|
|
||||||
day = 0;
|
day = 0;
|
||||||
loadTownDInfos();
|
|
||||||
|
|
||||||
tlog4 << "Initialization:";
|
tlog4 << "Initialization:";
|
||||||
tlog4 << "\tPicking grail position";
|
tlog4 << "\tPicking grail position";
|
||||||
@ -920,14 +916,14 @@ void CGameState::init(StartInfo * si)
|
|||||||
std::vector<int3> allowedPos;
|
std::vector<int3> allowedPos;
|
||||||
|
|
||||||
// add all not blocked tiles in range
|
// add all not blocked tiles in range
|
||||||
for (int i = 0; i < map->width ; i++)
|
for (int i = 0; i < map->width ; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < map->height ; j++)
|
for (int j = 0; j < map->height ; j++)
|
||||||
{
|
{
|
||||||
for (int k = 0; k <= map->twoLevel ; k++)
|
for (int k = 0; k <= map->twoLevel ; k++)
|
||||||
{
|
{
|
||||||
const TerrainTile &t = map->terrain[i][j][k];
|
const TerrainTile &t = map->terrain[i][j][k];
|
||||||
if(!t.blocked
|
if(!t.blocked
|
||||||
&& !t.visitable
|
&& !t.visitable
|
||||||
&& t.terType != ETerrainType::WATER
|
&& t.terType != ETerrainType::WATER
|
||||||
&& t.terType != ETerrainType::ROCK
|
&& t.terType != ETerrainType::ROCK
|
||||||
@ -946,7 +942,7 @@ void CGameState::init(StartInfo * si)
|
|||||||
map->grailPos = allowedPos[ran() % allowedPos.size()];
|
map->grailPos = allowedPos[ran() % allowedPos.size()];
|
||||||
else
|
else
|
||||||
tlog2 << "Warning: Grail cannot be placed, no appropriate tile found!\n";
|
tlog2 << "Warning: Grail cannot be placed, no appropriate tile found!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
//picking random factions for players
|
//picking random factions for players
|
||||||
tlog4 << "\tPicking random factions for players";
|
tlog4 << "\tPicking random factions for players";
|
||||||
@ -1771,38 +1767,6 @@ int CGameState::getPlayerRelations( ui8 color1, ui8 color2 )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameState::loadTownDInfos()
|
|
||||||
{
|
|
||||||
assert(!VLC->dobjinfo->gobjs[Obj::TOWN].empty()); //make sure that at least some def info was found
|
|
||||||
|
|
||||||
const CGDefInfo * baseInfo = VLC->dobjinfo->gobjs[Obj::TOWN].begin()->second;
|
|
||||||
auto & townInfos = VLC->dobjinfo->gobjs[Obj::TOWN];
|
|
||||||
|
|
||||||
|
|
||||||
BOOST_FOREACH(auto & town, VLC->townh->towns)
|
|
||||||
{
|
|
||||||
if (!vstd::contains(VLC->dobjinfo->gobjs[Obj::TOWN], town.first)) // no obj info for this town type
|
|
||||||
{
|
|
||||||
CGDefInfo * info = new CGDefInfo(*baseInfo);
|
|
||||||
info->subid = town.first;
|
|
||||||
|
|
||||||
townInfos[town.first] = info;
|
|
||||||
}
|
|
||||||
forts[town.first] = townInfos[town.first];
|
|
||||||
townInfos[town.first]->name = town.second.clientInfo.advMapCastle;
|
|
||||||
|
|
||||||
villages[town.first] = new CGDefInfo(*townInfos[town.first]);
|
|
||||||
villages[town.first]->name = town.second.clientInfo.advMapVillage;
|
|
||||||
|
|
||||||
capitols[town.first] = new CGDefInfo(*townInfos[town.first]);
|
|
||||||
capitols[town.first]->name = town.second.clientInfo.advMapCapitol;
|
|
||||||
|
|
||||||
map->customDefs.push_back(villages[town.first]);
|
|
||||||
map->customDefs.push_back(forts[town.first]);
|
|
||||||
map->customDefs.push_back(capitols[town.first]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameState::getNeighbours(const TerrainTile &srct, int3 tile, std::vector<int3> &vec, const boost::logic::tribool &onLand, bool limitCoastSailing)
|
void CGameState::getNeighbours(const TerrainTile &srct, int3 tile, std::vector<int3> &vec, const boost::logic::tribool &onLand, bool limitCoastSailing)
|
||||||
{
|
{
|
||||||
static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
|
static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
|
||||||
|
@ -40,7 +40,6 @@ class CGHeroInstance;
|
|||||||
class CGTownInstance;
|
class CGTownInstance;
|
||||||
class CArmedInstance;
|
class CArmedInstance;
|
||||||
class CGDwelling;
|
class CGDwelling;
|
||||||
class CGDefInfo;
|
|
||||||
class CObjectScript;
|
class CObjectScript;
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
class CCreature;
|
class CCreature;
|
||||||
@ -389,7 +388,6 @@ public:
|
|||||||
ConstTransitivePtr<CMap> map;
|
ConstTransitivePtr<CMap> map;
|
||||||
bmap<TPlayerColor, PlayerState> players;
|
bmap<TPlayerColor, PlayerState> players;
|
||||||
bmap<TPlayerColor, TeamState> teams;
|
bmap<TPlayerColor, TeamState> teams;
|
||||||
bmap<TPlayerColor, ConstTransitivePtr<CGDefInfo> > villages, forts, capitols; //def-info for town graphics
|
|
||||||
CBonusSystemNode globalEffects;
|
CBonusSystemNode globalEffects;
|
||||||
bmap<const CGHeroInstance*, const CGObjectInstance*> ongoingVisits;
|
bmap<const CGHeroInstance*, const CGObjectInstance*> ongoingVisits;
|
||||||
|
|
||||||
@ -411,7 +409,6 @@ public:
|
|||||||
void init(StartInfo * si);
|
void init(StartInfo * si);
|
||||||
|
|
||||||
void initDuel();
|
void initDuel();
|
||||||
void loadTownDInfos();
|
|
||||||
void randomizeObject(CGObjectInstance *cur);
|
void randomizeObject(CGObjectInstance *cur);
|
||||||
std::pair<int,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
std::pair<int,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
||||||
int pickHero(int owner);
|
int pickHero(int owner);
|
||||||
@ -450,11 +447,6 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & scenarioOps & initialOpts & currentPlayer & day & map & players & teams & hpool & globalEffects;
|
h & scenarioOps & initialOpts & currentPlayer & day & map & players & teams & hpool & globalEffects;
|
||||||
h & villages & forts & capitols;
|
|
||||||
if(!h.saving)
|
|
||||||
{
|
|
||||||
loadTownDInfos();
|
|
||||||
}
|
|
||||||
BONUS_TREE_DESERIALIZATION_FIX
|
BONUS_TREE_DESERIALIZATION_FIX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,26 +30,14 @@ CModHandler::CModHandler()
|
|||||||
VLC->modh = this;
|
VLC->modh = this;
|
||||||
|
|
||||||
loadConfigFromFile ("defaultMods");
|
loadConfigFromFile ("defaultMods");
|
||||||
|
findAvailableMods();
|
||||||
//CResourceHandler::loadModsFilesystems(); //scan for all mods
|
//CResourceHandler::loadModsFilesystems(); //scan for all mods
|
||||||
//TODO: mod filesystem is already initialized at LibClasses launch
|
//TODO: mod filesystem is already initialized at LibClasses launch
|
||||||
//TODO: load default (last?) config
|
//TODO: load default (last?) config
|
||||||
}
|
}
|
||||||
artID CModHandler::addNewArtifact (CArtifact * art)
|
|
||||||
{
|
|
||||||
int id = artifacts.size();
|
|
||||||
artifacts.push_back (art);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
creID CModHandler::addNewCreature (CCreature * cre)
|
|
||||||
{
|
|
||||||
int id = creatures.size();
|
|
||||||
creatures.push_back (cre);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CModHandler::loadConfigFromFile (std::string name)
|
void CModHandler::loadConfigFromFile (std::string name)
|
||||||
{
|
{
|
||||||
|
|
||||||
const JsonNode config(ResourceID("config/" + name + ".json"));
|
const JsonNode config(ResourceID("config/" + name + ".json"));
|
||||||
const JsonNode & hardcodedFeatures = config["hardcodedFeatures"];
|
const JsonNode & hardcodedFeatures = config["hardcodedFeatures"];
|
||||||
|
|
||||||
@ -67,28 +55,6 @@ void CModHandler::loadConfigFromFile (std::string name)
|
|||||||
modules.MITHRIL = gameModules["MITHRIL"].Bool();
|
modules.MITHRIL = gameModules["MITHRIL"].Bool();
|
||||||
|
|
||||||
//TODO: load only mods from the list
|
//TODO: load only mods from the list
|
||||||
|
|
||||||
//TODO: read mods from Mods/ folder
|
|
||||||
|
|
||||||
auto & configList = CResourceHandler::get()->getResourcesWithName (ResourceID("CONFIG/mod.json"));
|
|
||||||
|
|
||||||
BOOST_FOREACH(auto & entry, configList)
|
|
||||||
{
|
|
||||||
auto stream = entry.getLoader()->load (entry.getResourceName());
|
|
||||||
std::unique_ptr<ui8[]> textData (new ui8[stream->getSize()]);
|
|
||||||
stream->read (textData.get(), stream->getSize());
|
|
||||||
|
|
||||||
tlog3 << "\t\tFound mod file: " << entry.getResourceName() << "\n";
|
|
||||||
const JsonNode config ((char*)textData.get(), stream->getSize());
|
|
||||||
|
|
||||||
VLC->townh->loadFactions(config["factions"]);
|
|
||||||
|
|
||||||
const JsonNode *value = &config["creatures"];
|
|
||||||
BOOST_FOREACH (auto creature, value->Vector())
|
|
||||||
{
|
|
||||||
loadCreature (creature);//create and push back creature
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModHandler::saveConfigToFile (std::string name)
|
void CModHandler::saveConfigToFile (std::string name)
|
||||||
@ -105,229 +71,80 @@ void CModHandler::saveConfigToFile (std::string name)
|
|||||||
//file << savedConf;
|
//file << savedConf;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCreature * CModHandler::loadCreature (const JsonNode &node)
|
|
||||||
|
void CModHandler::findAvailableMods()
|
||||||
{
|
{
|
||||||
CCreature * cre = new CCreature();
|
//TODO: read mods from Mods/ folder
|
||||||
const JsonNode *value; //optional value
|
|
||||||
|
|
||||||
//TODO: ref name?
|
auto & configList = CResourceHandler::get()->getResourcesWithName (ResourceID("CONFIG/mod.json"));
|
||||||
const JsonNode & name = node["name"];
|
|
||||||
cre->nameSing = name["singular"].String();
|
|
||||||
cre->namePl = name["plural"].String();
|
|
||||||
value = &name["reference"];
|
|
||||||
if (!value->isNull())
|
|
||||||
cre->nameRef = value->String();
|
|
||||||
else
|
|
||||||
cre->nameRef = cre->nameSing;
|
|
||||||
|
|
||||||
cre->cost = Res::ResourceSet(node["cost"]);
|
BOOST_FOREACH(auto & entry, configList)
|
||||||
|
|
||||||
cre->level = node["level"].Float();
|
|
||||||
cre->faction = 9; //neutral faction is 9 for now. Will be replaced by string -> id conversion
|
|
||||||
//TODO: node["faction"].String() to id
|
|
||||||
cre->fightValue = node["fightValue"].Float();
|
|
||||||
cre->AIValue = node["aiValue"].Float();
|
|
||||||
cre->growth = node["growth"].Float();
|
|
||||||
cre->hordeGrowth = node["horde"].Float(); // Needed at least until configurable buildings
|
|
||||||
|
|
||||||
cre->addBonus(node["hitPoints"].Float(), Bonus::STACK_HEALTH);
|
|
||||||
cre->addBonus(node["speed"].Float(), Bonus::STACKS_SPEED);
|
|
||||||
cre->addBonus(node["attack"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
|
|
||||||
cre->addBonus(node["defense"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
|
|
||||||
const JsonNode & vec = node["damage"];
|
|
||||||
cre->addBonus(vec["min"].Float(), Bonus::CREATURE_DAMAGE, 1);
|
|
||||||
cre->addBonus(vec["max"].Float(), Bonus::CREATURE_DAMAGE, 2);
|
|
||||||
|
|
||||||
auto & amounts = node ["advMapAmount"];
|
|
||||||
cre->ammMin = amounts["min"].Float();
|
|
||||||
cre->ammMax = amounts["max"].Float();
|
|
||||||
|
|
||||||
//optional
|
|
||||||
BOOST_FOREACH (auto & str, node["upgrades"].Vector())
|
|
||||||
{
|
{
|
||||||
cre->upgradeNames.insert (str.String());
|
auto stream = entry.getLoader()->load (entry.getResourceName());
|
||||||
}
|
std::unique_ptr<ui8[]> textData (new ui8[stream->getSize()]);
|
||||||
|
stream->read (textData.get(), stream->getSize());
|
||||||
|
|
||||||
value = &node["shots"];
|
tlog3 << "\t\tFound mod file: " << entry.getResourceName() << "\n";
|
||||||
if (!value->isNull())
|
allMods[allMods.size()].config.reset(new JsonNode((char*)textData.get(), stream->getSize()));
|
||||||
cre->addBonus(value->Float(), Bonus::SHOTS);
|
|
||||||
|
|
||||||
value = &node["spellPoints"];
|
|
||||||
if (!value->isNull())
|
|
||||||
cre->addBonus(value->Float(), Bonus::CASTS);
|
|
||||||
|
|
||||||
cre->doubleWide = node["doubleWide"].Bool();
|
|
||||||
|
|
||||||
BOOST_FOREACH (const JsonNode &bonus, node["abilities"].Vector())
|
|
||||||
{
|
|
||||||
auto b = ParseBonus(bonus);
|
|
||||||
b->source = Bonus::CREATURE_ABILITY;
|
|
||||||
b->duration = Bonus::PERMANENT;
|
|
||||||
cre->addNewBonus(b);
|
|
||||||
}
|
|
||||||
BOOST_FOREACH (const JsonNode &exp, node["stackExperience"].Vector())
|
|
||||||
{
|
|
||||||
auto bonus = ParseBonus (exp["bonus"]);
|
|
||||||
bonus->source = Bonus::STACK_EXPERIENCE;
|
|
||||||
bonus->duration = Bonus::PERMANENT;
|
|
||||||
const JsonVector &values = exp["values"].Vector();
|
|
||||||
int lowerLimit = 1;//, upperLimit = 255;
|
|
||||||
if (values[0].getType() == JsonNode::JsonType::DATA_BOOL)
|
|
||||||
{
|
|
||||||
BOOST_FOREACH (const JsonNode &val, values)
|
|
||||||
{
|
|
||||||
if (val.Bool() == true)
|
|
||||||
{
|
|
||||||
bonus->limiter = make_shared<RankRangeLimiter>(RankRangeLimiter(lowerLimit));
|
|
||||||
cre->addNewBonus (new Bonus(*bonus)); //bonuses must be unique objects
|
|
||||||
break; //TODO: allow bonuses to turn off?
|
|
||||||
}
|
|
||||||
++lowerLimit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int lastVal = 0;
|
|
||||||
BOOST_FOREACH (const JsonNode &val, values)
|
|
||||||
{
|
|
||||||
if (val.Float() != lastVal)
|
|
||||||
{
|
|
||||||
bonus->val = val.Float() - lastVal;
|
|
||||||
bonus->limiter.reset (new RankRangeLimiter(lowerLimit));
|
|
||||||
cre->addNewBonus (new Bonus(*bonus));
|
|
||||||
}
|
|
||||||
lastVal = val.Float();
|
|
||||||
++lowerLimit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//graphics
|
|
||||||
|
|
||||||
const JsonNode & graphics = node["graphics"];
|
|
||||||
cre->animDefName = graphics["animation"].String();
|
|
||||||
cre->timeBetweenFidgets = graphics["timeBetweenFidgets"].Float();
|
|
||||||
cre->troopCountLocationOffset = graphics["troopCountLocationOffset"].Float();
|
|
||||||
cre->attackClimaxFrame = graphics["attackClimaxFrame"].Float();
|
|
||||||
|
|
||||||
const JsonNode & animationTime = graphics["animationTime"];
|
|
||||||
cre->walkAnimationTime = animationTime["walk"].Float();
|
|
||||||
cre->attackAnimationTime = animationTime["attack"].Float();
|
|
||||||
cre->flightAnimationDistance = animationTime["flight"].Float(); //?
|
|
||||||
//TODO: background?
|
|
||||||
const JsonNode & missile = graphics["missile"];
|
|
||||||
//TODO: parse
|
|
||||||
value = &missile["projectile"];
|
|
||||||
if (value->isNull())
|
|
||||||
cre->projectile = "PLCBOWX.DEF";
|
|
||||||
else
|
|
||||||
cre->projectile = value->String();
|
|
||||||
|
|
||||||
value = &missile["spinning"];
|
|
||||||
if (value->isNull())
|
|
||||||
cre->projectileSpin = false; //no animation by default to avoid crash
|
|
||||||
else
|
|
||||||
cre->projectileSpin = value->Bool();
|
|
||||||
|
|
||||||
const JsonNode & offsets = missile["offset"];
|
|
||||||
cre->upperRightMissleOffsetX = offsets["upperX"].Float();
|
|
||||||
cre->upperRightMissleOffsetY = offsets["upperY"].Float();
|
|
||||||
cre->rightMissleOffsetX = offsets["middleX"].Float();
|
|
||||||
cre->rightMissleOffsetY = offsets["middleY"].Float();
|
|
||||||
cre->lowerRightMissleOffsetX = offsets["lowerX"].Float();
|
|
||||||
cre->lowerRightMissleOffsetY = offsets["lowerY"].Float();
|
|
||||||
int i = 0;
|
|
||||||
BOOST_FOREACH (auto & angle, missile["frameAngles"].Vector())
|
|
||||||
{
|
|
||||||
cre->missleFrameAngles[i++] = angle.Float();
|
|
||||||
}
|
|
||||||
cre->advMapDef = graphics["map"].String();
|
|
||||||
cre->iconIndex = graphics["iconIndex"].Float();
|
|
||||||
|
|
||||||
const JsonNode & sounds = node["sound"];
|
|
||||||
|
|
||||||
#define GET_SOUND_VALUE(value_name) do { cre->sounds.value_name = sounds[#value_name].String(); } while(0)
|
|
||||||
GET_SOUND_VALUE(attack);
|
|
||||||
GET_SOUND_VALUE(defend);
|
|
||||||
GET_SOUND_VALUE(killed);
|
|
||||||
GET_SOUND_VALUE(move);
|
|
||||||
GET_SOUND_VALUE(shoot);
|
|
||||||
GET_SOUND_VALUE(wince);
|
|
||||||
GET_SOUND_VALUE(ext1);
|
|
||||||
GET_SOUND_VALUE(ext2);
|
|
||||||
GET_SOUND_VALUE(startMoving);
|
|
||||||
GET_SOUND_VALUE(endMoving);
|
|
||||||
#undef GET_SOUND_VALUE
|
|
||||||
|
|
||||||
creatures.push_back(cre);
|
|
||||||
|
|
||||||
tlog3 << "Added new creature " << cre->nameRef << "\n";
|
|
||||||
|
|
||||||
return cre;
|
|
||||||
}
|
|
||||||
void CModHandler::recreateAdvMapDefs()
|
|
||||||
{
|
|
||||||
BOOST_FOREACH (auto creature, creatures)
|
|
||||||
{
|
|
||||||
//generate adventure map object info & graphics
|
|
||||||
CGDefInfo* nobj = new CGDefInfo (*VLC->dobjinfo->gobjs[Obj::MONSTER][0]);//copy all typical properties
|
|
||||||
nobj->name = creature->advMapDef; //change only def name (?)
|
|
||||||
VLC->dobjinfo->gobjs[Obj::MONSTER][creature->idNumber] = nobj;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CModHandler::recreateHandlers()
|
|
||||||
|
void CModHandler::loadActiveMods()
|
||||||
{
|
{
|
||||||
//TODO: consider some template magic to unify all handlers?
|
BOOST_FOREACH(auto & mod, allMods)
|
||||||
|
|
||||||
//VLC->arth->artifacts.clear();
|
|
||||||
//VLC->creh->creatures.clear(); //TODO: what about items from original game?
|
|
||||||
|
|
||||||
BOOST_FOREACH (auto creature, creatures)
|
|
||||||
{
|
{
|
||||||
creature->idNumber = VLC->creh->creatures.size(); //calculate next index for every used creature
|
const JsonNode & config = *mod.second.config;
|
||||||
BOOST_FOREACH (auto bonus, creature->getBonusList())
|
|
||||||
{
|
|
||||||
bonus->sid = creature->idNumber;
|
|
||||||
}
|
|
||||||
VLC->creh->creatures.push_back (creature);
|
|
||||||
//TODO: use refName?
|
|
||||||
//if (creature->nameRef.size())
|
|
||||||
// VLC->creh->nameToID[creature->nameRef] = creature->idNumber;
|
|
||||||
VLC->creh->nameToID[creature->nameSing] = creature->idNumber;
|
|
||||||
|
|
||||||
|
VLC->townh->load(config["factions"]);
|
||||||
|
VLC->creh->load(config["creatures"]);
|
||||||
}
|
}
|
||||||
recreateAdvMapDefs();
|
|
||||||
BOOST_FOREACH (auto creature, VLC->creh->creatures) //populate upgrades described with string
|
|
||||||
{
|
|
||||||
BOOST_FOREACH (auto upgradeName, creature->upgradeNames)
|
|
||||||
{
|
|
||||||
auto it = VLC->creh->nameToID.find(upgradeName);
|
|
||||||
if (it != VLC->creh->nameToID.end())
|
|
||||||
{
|
|
||||||
creature->upgrades.insert (it->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VLC->creh->buildBonusTreeForTiers(); //do that after all new creatures are loaded
|
VLC->creh->buildBonusTreeForTiers(); //do that after all new creatures are loaded
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_FOREACH (auto mod, activeMods) //inactive part
|
void CModHandler::reload()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
BOOST_FOREACH (auto art, allMods[mod].artifacts)
|
assert(!VLC->dobjinfo->gobjs[Obj::MONSTER].empty()); //make sure that at least some def info was found
|
||||||
{
|
|
||||||
VLC->arth->artifacts.push_back (artifacts[art]);
|
|
||||||
|
|
||||||
//TODO: recreate types / limiters based on string id
|
const CGDefInfo * baseInfo = VLC->dobjinfo->gobjs[Obj::MONSTER].begin()->second;
|
||||||
|
|
||||||
|
BOOST_FOREACH(auto & crea, VLC->creh->creatures)
|
||||||
|
{
|
||||||
|
if (!vstd::contains(VLC->dobjinfo->gobjs[Obj::MONSTER], crea->idNumber)) // no obj info for this type
|
||||||
|
{
|
||||||
|
CGDefInfo * info = new CGDefInfo(*baseInfo);
|
||||||
|
info->subid = crea->idNumber;
|
||||||
|
info->name = crea->advMapDef;
|
||||||
|
|
||||||
|
VLC->dobjinfo->gobjs[Obj::MONSTER][crea->idNumber] = info;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BOOST_FOREACH (auto creature, allMods[mod].creatures)
|
}
|
||||||
{
|
|
||||||
VLC->creh->creatures.push_back (creatures[creature]);
|
|
||||||
//TODO VLC->creh->notUsedMonster.push_back (creatures[creature]);
|
|
||||||
|
|
||||||
//TODO: recreate upgrades and other properties based on string id
|
{
|
||||||
|
assert(!VLC->dobjinfo->gobjs[Obj::TOWN].empty()); //make sure that at least some def info was found
|
||||||
|
|
||||||
|
const CGDefInfo * baseInfo = VLC->dobjinfo->gobjs[Obj::TOWN].begin()->second;
|
||||||
|
auto & townInfos = VLC->dobjinfo->gobjs[Obj::TOWN];
|
||||||
|
|
||||||
|
BOOST_FOREACH(auto & town, VLC->townh->towns)
|
||||||
|
{
|
||||||
|
auto & cientInfo = town.second.clientInfo;
|
||||||
|
|
||||||
|
if (!vstd::contains(VLC->dobjinfo->gobjs[Obj::TOWN], town.first)) // no obj info for this type
|
||||||
|
{
|
||||||
|
CGDefInfo * info = new CGDefInfo(*baseInfo);
|
||||||
|
info->subid = town.first;
|
||||||
|
|
||||||
|
townInfos[town.first] = info;
|
||||||
|
}
|
||||||
|
townInfos[town.first]->name = cientInfo.advMapCastle;
|
||||||
|
|
||||||
|
VLC->dobjinfo->villages[town.first] = new CGDefInfo(*townInfos[town.first]);
|
||||||
|
VLC->dobjinfo->villages[town.first]->name = cientInfo.advMapVillage;
|
||||||
|
|
||||||
|
VLC->dobjinfo->capitols[town.first] = new CGDefInfo(*townInfos[town.first]);
|
||||||
|
VLC->dobjinfo->capitols[town.first]->name = cientInfo.advMapCapitol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CModHandler::~CModHandler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
@ -20,65 +20,46 @@
|
|||||||
class CModHandler;
|
class CModHandler;
|
||||||
class CModIndentifier;
|
class CModIndentifier;
|
||||||
class CModInfo;
|
class CModInfo;
|
||||||
|
class JsonNode;
|
||||||
|
|
||||||
typedef si32 artID;
|
typedef si32 TModID;
|
||||||
typedef si32 creID;
|
|
||||||
|
|
||||||
class DLL_LINKAGE CModIdentifier
|
|
||||||
{
|
|
||||||
//TODO? are simple integer identifiers enough?
|
|
||||||
int id;
|
|
||||||
public:
|
|
||||||
// int operator ()() {return 0;};
|
|
||||||
bool operator < (CModIdentifier rhs) const {return true;}; //for map
|
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
|
||||||
{
|
|
||||||
h & id;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class DLL_LINKAGE CModInfo
|
class DLL_LINKAGE CModInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector <CModIdentifier> requirements;
|
/// TODO: list of mods that should be loaded before this one
|
||||||
std::vector <ResourceID> usedFiles;
|
std::vector <TModID> requirements;
|
||||||
//TODO: config options?
|
|
||||||
|
|
||||||
//items added by this mod
|
/// mod configuration (mod.json).
|
||||||
std::vector <artID> artifacts;
|
std::unique_ptr<JsonNode> config;
|
||||||
std::vector <creID> creatures;
|
|
||||||
|
|
||||||
//TODO: some additional scripts?
|
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & requirements & artifacts & creatures;
|
h & requirements & config;
|
||||||
//h & usedFiles; //TODO: make seralizable?
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CModHandler
|
class DLL_LINKAGE CModHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string currentConfig; //save settings in this file
|
//std::string currentConfig; //save settings in this file
|
||||||
//list of all possible objects in game, including inactive mods or not allowed
|
|
||||||
std::vector <ConstTransitivePtr<CCreature> > creatures;
|
|
||||||
std::vector <ConstTransitivePtr<CArtifact> > artifacts;
|
|
||||||
|
|
||||||
std::map <CModIdentifier, CModInfo> allMods;
|
std::map <TModID, CModInfo> allMods;
|
||||||
std::set <CModIdentifier> activeMods;
|
std::set <TModID> activeMods;//TODO: use me
|
||||||
|
|
||||||
//create unique object indentifier
|
/// management of game settings config
|
||||||
artID addNewArtifact (CArtifact * art);
|
void loadConfigFromFile (std::string name);
|
||||||
creID addNewCreature (CCreature * cre);
|
|
||||||
|
|
||||||
void loadConfigFromFile (std::string name);
|
|
||||||
void saveConfigToFile (std::string name);
|
void saveConfigToFile (std::string name);
|
||||||
CCreature * loadCreature (const JsonNode &node);
|
|
||||||
void recreateAdvMapDefs();
|
/// find all available mods and load them into FS
|
||||||
void recreateHandlers();
|
void findAvailableMods();
|
||||||
|
|
||||||
|
/// load content from all available mods
|
||||||
|
void loadActiveMods();
|
||||||
|
|
||||||
|
/// actions that should be triggered on map restart
|
||||||
|
/// TODO: merge into appropriate handlers?
|
||||||
|
void reload();
|
||||||
|
|
||||||
struct DLL_LINKAGE hardcodedFeatures
|
struct DLL_LINKAGE hardcodedFeatures
|
||||||
{
|
{
|
||||||
@ -110,12 +91,9 @@ public:
|
|||||||
} modules;
|
} modules;
|
||||||
|
|
||||||
CModHandler();
|
CModHandler();
|
||||||
~CModHandler();
|
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & currentConfig;
|
|
||||||
h & creatures & artifacts;
|
|
||||||
h & allMods & activeMods & settings & modules;
|
h & allMods & activeMods & settings & modules;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -442,7 +442,7 @@ void CTownHandler::loadPuzzle(CFaction &faction, const JsonNode &source)
|
|||||||
assert(faction.puzzleMap.size() == GameConstants::PUZZLE_MAP_PIECES);
|
assert(faction.puzzleMap.size() == GameConstants::PUZZLE_MAP_PIECES);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTownHandler::loadFactions(const JsonNode &source)
|
void CTownHandler::load(const JsonNode &source)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(auto & node, source.Struct())
|
BOOST_FOREACH(auto & node, source.Struct())
|
||||||
{
|
{
|
||||||
@ -469,6 +469,8 @@ void CTownHandler::loadFactions(const JsonNode &source)
|
|||||||
}
|
}
|
||||||
if (!node.second["puzzleMap"].isNull())
|
if (!node.second["puzzleMap"].isNull())
|
||||||
loadPuzzle(faction, node.second["puzzleMap"]);
|
loadPuzzle(faction, node.second["puzzleMap"]);
|
||||||
|
|
||||||
|
tlog3 << "Added faction: " << node.first << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,5 +520,5 @@ void CTownHandler::load()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadFactions(buildingsConf);
|
load(buildingsConf);
|
||||||
}
|
}
|
||||||
|
@ -209,12 +209,11 @@ public:
|
|||||||
|
|
||||||
/// main loading function for mods, accepts merged JSON source and add all entries from it into game
|
/// main loading function for mods, accepts merged JSON source and add all entries from it into game
|
||||||
/// all entries in JSON should be checked for validness before using this function
|
/// all entries in JSON should be checked for validness before using this function
|
||||||
void loadFactions(const JsonNode & source);
|
void load(const JsonNode & source);
|
||||||
|
|
||||||
/// "entry point" for loading of OH3 town.
|
/// "entry point" for loading of OH3 town.
|
||||||
/// reads legacy txt's from H3 + vcmi json, merges them
|
/// reads legacy txt's from H3 + vcmi json, merges them
|
||||||
/// and loads resulting structure to game using loadTowns method
|
/// and loads resulting structure to game using loadTowns method
|
||||||
/// in future may require loaded Creature Handler
|
|
||||||
void load();
|
void load();
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
@ -4,6 +4,8 @@ class JsonNode;
|
|||||||
typedef std::map <std::string, JsonNode> JsonMap;
|
typedef std::map <std::string, JsonNode> JsonMap;
|
||||||
typedef std::vector <JsonNode> JsonVector;
|
typedef std::vector <JsonNode> JsonVector;
|
||||||
|
|
||||||
|
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const JsonNode &node);
|
||||||
|
|
||||||
struct Bonus;
|
struct Bonus;
|
||||||
class ResourceID;
|
class ResourceID;
|
||||||
|
|
||||||
@ -96,6 +98,23 @@ public:
|
|||||||
static void merge(JsonNode & dest, JsonNode & source);
|
static void merge(JsonNode & dest, JsonNode & source);
|
||||||
/// this function will preserve data stored in source by creating copy
|
/// this function will preserve data stored in source by creating copy
|
||||||
static void mergeCopy(JsonNode & dest, JsonNode source);
|
static void mergeCopy(JsonNode & dest, JsonNode source);
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
if (h.saving)
|
||||||
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << *this;
|
||||||
|
std::string str = stream.str();
|
||||||
|
h & str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
h & str;
|
||||||
|
JsonNode(str.c_str(), str.size()).swap(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -136,8 +155,6 @@ public:
|
|||||||
JsonWriter(std::ostream &output, const JsonNode &node);
|
JsonWriter(std::ostream &output, const JsonNode &node);
|
||||||
};
|
};
|
||||||
|
|
||||||
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const JsonNode &node);
|
|
||||||
|
|
||||||
//Tiny string class that uses const char* as data for speed, members are private
|
//Tiny string class that uses const char* as data for speed, members are private
|
||||||
//for ease of debugging and some compatibility with std::string
|
//for ease of debugging and some compatibility with std::string
|
||||||
class constString
|
class constString
|
||||||
|
@ -86,7 +86,6 @@ void registerTypes1(Serializer &s)
|
|||||||
s.template registerType<StackOwnerLimiter>();
|
s.template registerType<StackOwnerLimiter>();
|
||||||
|
|
||||||
s.template registerType<CModInfo>();
|
s.template registerType<CModInfo>();
|
||||||
s.template registerType<CModIdentifier>();
|
|
||||||
|
|
||||||
s.template registerType<CBonusSystemNode>();
|
s.template registerType<CBonusSystemNode>();
|
||||||
s.template registerType<CArtifact>();
|
s.template registerType<CArtifact>();
|
||||||
|
@ -101,7 +101,8 @@ void LibClasses::init()
|
|||||||
spellh->loadSpells();
|
spellh->loadSpells();
|
||||||
tlog0<<"\tSpell handler: "<<pomtime.getDiff()<<std::endl;
|
tlog0<<"\tSpell handler: "<<pomtime.getDiff()<<std::endl;
|
||||||
|
|
||||||
modh->recreateHandlers(); //load all new creatures parsed in the meantime.
|
modh->loadActiveMods();
|
||||||
|
modh->reload();
|
||||||
//FIXME: make sure that everything is ok after game restart
|
//FIXME: make sure that everything is ok after game restart
|
||||||
//TODO: This should be done every time mod config changes
|
//TODO: This should be done every time mod config changes
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user