mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
- CMappedFileLoader class to remap WoG files to h3 names
- WoG should be optional, all remapped files are listed in WoG/config/wogFileOverrides.json - fixed several cases of incorrect positioning of creatures in battles - some missing sounds for battle effects - negative luck support, disabled by default - a bit hackish detection of WoG presence, VCMI should work on SoD-only installs
This commit is contained in:
parent
298f862d86
commit
8be801a6dc
@ -140,12 +140,13 @@ endif()
|
||||
|
||||
# For apple this files will be already inside vcmiclient bundle
|
||||
if (NOT APPLE)
|
||||
# copy whole directory but .svn control files and user-specific settings.json
|
||||
# copy whole directory but .svn control files
|
||||
install(DIRECTORY config DESTINATION ${DATA_DIR} PATTERN ".svn" EXCLUDE)
|
||||
# copy vcmi mod along with all its content
|
||||
install(DIRECTORY Mods/vcmi DESTINATION ${DATA_DIR}/Mods PATTERN ".svn" EXCLUDE)
|
||||
# copy only mod.json for WoG
|
||||
# copy only files added by vcmi for WoG
|
||||
install(FILES Mods/WoG/mod.json DESTINATION ${DATA_DIR}/Mods/WoG)
|
||||
install(DIRECTORY Mods/WoG/config DESTINATION ${DATA_DIR}/Mods/WoG PATTERN ".svn" EXCLUDE)
|
||||
|
||||
install(FILES vcmibuilder DESTINATION ${BIN_DIR} PERMISSIONS
|
||||
OWNER_WRITE OWNER_READ OWNER_EXECUTE
|
||||
|
20
Mods/WoG/config/defaultMods.json
Normal file
20
Mods/WoG/config/defaultMods.json
Normal file
@ -0,0 +1,20 @@
|
||||
// default configuration for mod system loaded at launch
|
||||
|
||||
{
|
||||
"textData" :
|
||||
{
|
||||
"heroClass" : 18,
|
||||
"artifact" : 171,
|
||||
"creature" : 197,
|
||||
"faction" : 9,
|
||||
"hero" : 156
|
||||
},
|
||||
|
||||
"modules":
|
||||
{
|
||||
"STACK_EXPERIENCE": true,
|
||||
"STACK_ARTIFACTS": true,
|
||||
"COMMANDERS": true,
|
||||
"MITHRIL": false //so far unused
|
||||
}
|
||||
}
|
45
Mods/WoG/config/wogFileOverrides.json
Normal file
45
Mods/WoG/config/wogFileOverrides.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
// Text configs
|
||||
"data/crgen1.txt" : "data/zcrgn1.txt",
|
||||
"data/crtraits.txt" : "data/zcrtrait.txt",
|
||||
"data/help.txt" : "data/zelp.txt",
|
||||
"data/objects.txt" : "data/zobjcts.txt",
|
||||
|
||||
// main menu images
|
||||
"data/gamselb0.bmp" : "data/ZPIC1000.bmp", // map selection screen
|
||||
"data/gamselb1.bmp" : "data/ZPIC1001.bmp", // map selection screen
|
||||
"data/loadbar.bmp" : "data/ZPIC106.bmp", // loading screen
|
||||
"data/gamselbk.bmp" : "data/ZPIC1005.bmp", // background
|
||||
"data/newgame.bmp" : "data/ZNEWGAM.bmp", // "new game" text
|
||||
"data/loadgame.bmp" : "data/ZLOADGAM.bmp", // "load game" text
|
||||
|
||||
// main menu buttons
|
||||
"sprites/mmenung.def" : "sprites/zmenung.def",
|
||||
"sprites/mmenulg.def" : "sprites/zmenulg.def",
|
||||
"sprites/mmenuhs.def" : "sprites/zmenuhs.def",
|
||||
"sprites/mmenucr.def" : "sprites/zmenucr.def",
|
||||
"sprites/mmenuqt.def" : "sprites/zmenuqt.def",
|
||||
|
||||
// game type select (single/multi/campaign)
|
||||
"sprites/gtsingl.def" : "sprites/ztsingl.def",
|
||||
"sprites/gtmulti.def" : "sprites/ztmulti.def",
|
||||
"sprites/gtcampn.def" : "sprites/ztcampn.def",
|
||||
"sprites/gttutor.def" : "sprites/zttutor.def",
|
||||
"sprites/gtback.def" : "sprites/ztback.def",
|
||||
|
||||
// campaigns
|
||||
"sprites/csssod.def" : "sprites/zsssod.def",
|
||||
"sprites/cssroe.def" : "sprites/zssroe.def",
|
||||
"sprites/cssarm.def" : "sprites/zssarm.def",
|
||||
"sprites/csscus.def" : "sprites/zsscus.def",
|
||||
|
||||
// resource bars
|
||||
"data/tresbar.bmp" : "data/zresbar.bmp",
|
||||
"data/kresbar.bmp" : "data/z2esbar.bmp",
|
||||
"data/aresbar.bmp" : "data/zresbar.bmp",
|
||||
|
||||
// misc
|
||||
"data/tpcainfo.bmp" : "data/zpcainfo.bmp", // stats images for town fort
|
||||
"music/mainmenu.mp3" : "music/mainmenuwog.mp3",
|
||||
"video/credits.bik" : "video/acredit.bik"
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
{
|
||||
"filesystem":
|
||||
{
|
||||
"" :
|
||||
[
|
||||
{ "type" : "map", "path" : "/Config/wogFileOverrides.json"}
|
||||
],
|
||||
"CONFIG/" :
|
||||
[
|
||||
{ "type" : "dir", "path" : "/Config"}
|
||||
|
@ -16,10 +16,5 @@
|
||||
},
|
||||
|
||||
"name" : "VCMI essential files",
|
||||
"description" : "Essential files required for VCMI to run correctly",
|
||||
|
||||
"depends" :
|
||||
[
|
||||
"wog"
|
||||
]
|
||||
"description" : "Essential files required for VCMI to run correctly"
|
||||
}
|
||||
|
@ -874,7 +874,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
|
||||
|
||||
Rect barRect(9, 182, 732, 18);
|
||||
statusbar = new CGStatusBar(new CPicture(*panel, barRect, 9, 555, false));
|
||||
resdatabar = new CResDataBar("ZRESBAR", 3, 575, 32, 2, 85, 85);
|
||||
resdatabar = new CResDataBar("ARESBAR", 3, 575, 32, 2, 85, 85);
|
||||
|
||||
townlist = new CTownList(3, Point(744, 414), "IAM014", "IAM015");
|
||||
if (from)
|
||||
@ -1518,7 +1518,7 @@ CFortScreen::RecruitArea::RecruitArea(int posX, int posY, const CGTownInstance *
|
||||
if (!town->creatures[level].second.empty())
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER);//Activate only if dwelling is present
|
||||
|
||||
icons = new CPicture("ZPCAINFO", 261, 3);
|
||||
icons = new CPicture("TPCAINFO", 261, 3);
|
||||
buildingPic = new CAnimImage(town->town->clientInfo.buildingsIcons, buildingID, 0, 4, 21);
|
||||
|
||||
const CCreature* creature = NULL;
|
||||
|
@ -282,7 +282,6 @@ int main(int argc, char** argv)
|
||||
};
|
||||
|
||||
if (!testFile("DATA/HELP.TXT", "Heroes III data") &&
|
||||
!testFile("DATA/ZELP.TXT", "In the Wake of Gods data") &&
|
||||
!testFile("MODS/VCMI/MOD.JSON", "VCMI mod") &&
|
||||
!testFile("DATA/StackQueueBgBig.PCX", "VCMI data"))
|
||||
exit(1); // These are unrecoverable errors
|
||||
|
@ -879,8 +879,17 @@ void CPlayerInterface::battleAttack(const BattleAttack *ba)
|
||||
boost::algorithm::replace_first(hlp,"%s", (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str());
|
||||
battleInt->console->addText(hlp);
|
||||
battleInt->displayEffect(18, stack->position);
|
||||
CCS->soundh->playSound(soundBase::GOODLUCK);
|
||||
}
|
||||
if(ba->unlucky()) //unlucky hit
|
||||
{
|
||||
const CStack *stack = cb->battleGetStackByID(ba->stackAttacking);
|
||||
std::string hlp = CGI->generaltexth->allTexts[44];
|
||||
boost::algorithm::replace_first(hlp,"%s", (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str());
|
||||
battleInt->console->addText(hlp);
|
||||
battleInt->displayEffect(48, stack->position);
|
||||
CCS->soundh->playSound(soundBase::BADLUCK);
|
||||
}
|
||||
//TODO: bad luck?
|
||||
if (ba->deathBlow())
|
||||
{
|
||||
const CStack *stack = cb->battleGetStackByID(ba->stackAttacking);
|
||||
@ -892,6 +901,7 @@ void CPlayerInterface::battleAttack(const BattleAttack *ba)
|
||||
const CStack * attacked = cb->battleGetStackByID(i->stackAttacked);
|
||||
battleInt->displayEffect(73, attacked->position);
|
||||
}
|
||||
CCS->soundh->playSound(soundBase::deathBlow);
|
||||
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ VCMI_SOUND_NAME(cyclopMove) VCMI_SOUND_FILE(CYCLMOVE.wav) \
|
||||
VCMI_SOUND_NAME(cyclopShot) VCMI_SOUND_FILE(CYCLSHOT.wav) \
|
||||
VCMI_SOUND_NAME(cyclopWNCE) VCMI_SOUND_FILE(CYCLWNCE.wav) \
|
||||
VCMI_SOUND_NAME(DANGER) VCMI_SOUND_FILE(DANGER.wav) \
|
||||
VCMI_SOUND_NAME(deathBlood) VCMI_SOUND_FILE(DEATHBLO.wav) \
|
||||
VCMI_SOUND_NAME(deathBlow) VCMI_SOUND_FILE(DEATHBLO.wav) \
|
||||
VCMI_SOUND_NAME(deathCloud) VCMI_SOUND_FILE(DEATHCLD.wav) \
|
||||
VCMI_SOUND_NAME(deathRIP) VCMI_SOUND_FILE(DEATHRIP.wav) \
|
||||
VCMI_SOUND_NAME(deathSTR) VCMI_SOUND_FILE(DEATHSTR.wav) \
|
||||
|
@ -556,8 +556,8 @@ void CGarrisonInt::createSlots()
|
||||
|
||||
void CGarrisonInt::recreateSlots()
|
||||
{
|
||||
setSplittingMode(false);
|
||||
selectSlot(nullptr);
|
||||
setSplittingMode(false);
|
||||
|
||||
for(size_t i = 0; i<splitButtons.size(); i++)
|
||||
splitButtons[i]->block(true);
|
||||
@ -629,10 +629,10 @@ void CGarrisonInt::setSplittingMode(bool on)
|
||||
if (inSplittingMode || on)
|
||||
{
|
||||
BOOST_FOREACH(CGarrisonSlot * slot, slotsUp)
|
||||
slot->setHighlight(slot->creature == nullptr || slot->creature == getSelection()->creature);
|
||||
slot->setHighlight( ( on && (slot->creature == nullptr || slot->creature == getSelection()->creature)));
|
||||
|
||||
BOOST_FOREACH(CGarrisonSlot * slot, slotsDown)
|
||||
slot->setHighlight(slot->creature == nullptr || slot->creature == getSelection()->creature);
|
||||
slot->setHighlight( ( on && (slot->creature == nullptr || slot->creature == getSelection()->creature)));
|
||||
inSplittingMode = on;
|
||||
}
|
||||
}
|
||||
@ -1773,7 +1773,7 @@ void CMinorResDataBar::showAll(SDL_Surface * to)
|
||||
|
||||
CMinorResDataBar::CMinorResDataBar()
|
||||
{
|
||||
bg = BitmapHandler::loadBitmap("Z2ESBAR.bmp");
|
||||
bg = BitmapHandler::loadBitmap("KRESBAR.bmp");
|
||||
SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
|
||||
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
|
||||
pos.x = 7;
|
||||
@ -5241,7 +5241,7 @@ CPuzzleWindow::CPuzzleWindow(const int3 &GrailPos, double discoveredRatio):
|
||||
|
||||
new CPicture("PUZZLOGO", 607, 3);
|
||||
new CLabel(700, 95, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[463]);
|
||||
new CResDataBar("ZRESBAR.bmp", 3, 575, 32, 2, 85, 85);
|
||||
new CResDataBar("ARESBAR.bmp", 3, 575, 32, 2, 85, 85);
|
||||
|
||||
int faction = LOCPLINT->cb->getStartInfo()->playerInfos.find(LOCPLINT->playerID)->second.castle;
|
||||
|
||||
|
@ -492,7 +492,7 @@ void CMovementAnimation::endAnim()
|
||||
{
|
||||
const CStack * movedStack = stack;
|
||||
|
||||
myAnim()->pos = CClickableHex::getXYUnitAnim(nextHex, movedStack->attackerOwned, movedStack, owner);
|
||||
myAnim()->pos = CClickableHex::getXYUnitAnim(nextHex, owner->creDir[stack->ID], movedStack, owner);
|
||||
CBattleAnimation::endAnim();
|
||||
|
||||
if(movedStack)
|
||||
@ -604,6 +604,8 @@ CReverseAnimation::CReverseAnimation(CBattleInterface * _owner, const CStack * s
|
||||
|
||||
bool CReverseAnimation::init()
|
||||
{
|
||||
logGlobal->errorStream() << "Pos at " << myAnim()->pos.x << "x" << myAnim()->pos.y;
|
||||
|
||||
if(myAnim() == NULL || myAnim()->getType() == CCreatureAnim::DEATH)
|
||||
{
|
||||
endAnim();
|
||||
@ -614,8 +616,10 @@ bool CReverseAnimation::init()
|
||||
if(!priority && !isEarliest(false))
|
||||
return false;
|
||||
|
||||
if(myAnim()->framesInGroup(CCreatureAnim::TURN_R))
|
||||
myAnim()->setType(CCreatureAnim::TURN_R);
|
||||
//myAnim()->pos = CClickableHex::getXYUnitAnim(hex, owner->creDir[stack->ID], stack, owner);
|
||||
|
||||
if(myAnim()->framesInGroup(CCreatureAnim::TURN_L))
|
||||
myAnim()->setType(CCreatureAnim::TURN_L);
|
||||
else
|
||||
setupSecondPart();
|
||||
|
||||
@ -647,6 +651,8 @@ void CReverseAnimation::nextFrame()
|
||||
|
||||
void CReverseAnimation::endAnim()
|
||||
{
|
||||
logGlobal->errorStream() << "Pos on end " << myAnim()->pos.x << "x" << myAnim()->pos.y;
|
||||
|
||||
CBattleAnimation::endAnim();
|
||||
if( stack->alive() )//don't do that if stack is dead
|
||||
myAnim()->setType(CCreatureAnim::HOLDING);
|
||||
@ -656,6 +662,7 @@ void CReverseAnimation::endAnim()
|
||||
|
||||
void CReverseAnimation::setupSecondPart()
|
||||
{
|
||||
logGlobal->errorStream() << "Pos before 2nd " << myAnim()->pos.x << "x" << myAnim()->pos.y;
|
||||
if(!stack)
|
||||
{
|
||||
endAnim();
|
||||
@ -664,9 +671,7 @@ void CReverseAnimation::setupSecondPart()
|
||||
|
||||
owner->creDir[stack->ID] = !owner->creDir[stack->ID];
|
||||
|
||||
Point coords = CClickableHex::getXYUnitAnim(hex, owner->creDir[stack->ID], stack, owner);
|
||||
myAnim()->pos.x = coords.x;
|
||||
//creAnims[stackID]->pos.y = coords.second;
|
||||
myAnim()->pos = CClickableHex::getXYUnitAnim(hex, owner->creDir[stack->ID], stack, owner);
|
||||
|
||||
if(stack->doubleWide())
|
||||
{
|
||||
@ -682,10 +687,12 @@ void CReverseAnimation::setupSecondPart()
|
||||
}
|
||||
}
|
||||
|
||||
logGlobal->errorStream() << "Pos after 2nd " << myAnim()->pos.x << "x" << myAnim()->pos.y;
|
||||
|
||||
secondPartSetup = true;
|
||||
|
||||
if(myAnim()->framesInGroup(CCreatureAnim::TURN_L))
|
||||
myAnim()->setType(CCreatureAnim::TURN_L);
|
||||
if(myAnim()->framesInGroup(CCreatureAnim::TURN_R))
|
||||
myAnim()->setType(CCreatureAnim::TURN_R);
|
||||
else
|
||||
endAnim();
|
||||
}
|
||||
|
@ -1986,6 +1986,7 @@ void CBattleInterface::battleTriggerEffect(const BattleTriggerEffect & bte)
|
||||
std::string hlp = CGI->generaltexth->allTexts[33];
|
||||
boost::algorithm::replace_first(hlp,"%s",(stack->getName()));
|
||||
displayEffect(20,stack->position);
|
||||
CCS->soundh->playSound(soundBase::GOODMRLE);
|
||||
console->addText(hlp);
|
||||
break;
|
||||
}
|
||||
@ -2640,6 +2641,7 @@ void CBattleInterface::startAction(const BattleAction* action)
|
||||
case Battle::BAD_MORALE:
|
||||
txtid = -34; //negative -> no separate singular/plural form
|
||||
displayEffect(30,stack->position);
|
||||
CCS->soundh->playSound(soundBase::BADMRLE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
"spellBook":
|
||||
{
|
||||
"index" : 0,
|
||||
"type" : ["HERO"]
|
||||
"type" : ["HERO"],
|
||||
},
|
||||
"spellScroll":
|
||||
{
|
||||
|
@ -398,7 +398,7 @@
|
||||
"hateArchAngels" :
|
||||
{
|
||||
"type" : "HATE",
|
||||
"subtype" : "creature.angel",
|
||||
"subtype" : "creature.archangel",
|
||||
"val" : 50
|
||||
},
|
||||
"FLYING_ARMY" :
|
||||
|
@ -4,8 +4,8 @@
|
||||
"textData" :
|
||||
{
|
||||
"heroClass" : 18,
|
||||
"artifact" : 171,
|
||||
"creature" : 197,
|
||||
"artifact" : 144,
|
||||
"creature" : 150,
|
||||
"faction" : 9,
|
||||
"hero" : 156
|
||||
},
|
||||
@ -17,13 +17,14 @@
|
||||
"NEUTRAL_STACK_EXP_DAILY" : 500,
|
||||
"MAX_BUILDING_PER_TURN" : 1,
|
||||
"DWELLINGS_ACCUMULATE_CREATURES" : true,
|
||||
"ALL_CREATURES_GET_DOUBLE_MONTHS" : false
|
||||
"ALL_CREATURES_GET_DOUBLE_MONTHS" : false,
|
||||
"NEGATIVE_LUCK" : false
|
||||
},
|
||||
"modules":
|
||||
{
|
||||
"STACK_EXPERIENCE": true,
|
||||
"STACK_ARTIFACTS": true,
|
||||
"COMMANDERS": true,
|
||||
"STACK_EXPERIENCE": false,
|
||||
"STACK_ARTIFACTS": false,
|
||||
"COMMANDERS": false,
|
||||
"MITHRIL": false //so far unused
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
{
|
||||
//images used in game selection screen
|
||||
"game-select" : ["ZPIC1000", "ZPIC1001"],
|
||||
"game-select" : ["gamselb0", "gamselb1"],
|
||||
|
||||
"loading" : ["ZPIC106", "LoadBar"],
|
||||
"loading" : ["loadbar"],
|
||||
|
||||
//Main menu window, consists of several sub-menus aka items
|
||||
"window":
|
||||
{
|
||||
"background" : "ZPIC1005",
|
||||
"background" : "gamselbk",
|
||||
//"scalable" : true, //background will be scaled to screen size
|
||||
"video" : {"x": 8, "y": 105, "name":"ACREDIT.SMK" },//Floating WoG logo
|
||||
"video" : {"x": 8, "y": 105, "name":"CREDITS.SMK" },//Floating WoG logo
|
||||
//"images" : [],//Optioal, contains any additional images in the same format as video
|
||||
"items" :
|
||||
[
|
||||
@ -17,46 +17,46 @@
|
||||
"name" : "main",
|
||||
"buttons":
|
||||
[
|
||||
{"x": 540, "y": 10, "name":"ZMENUNG", "hotkey" : 110, "help": 3, "command": "to new"},
|
||||
{"x": 532, "y": 132, "name":"ZMENULG", "hotkey" : 108, "help": 4, "command": "to load"},
|
||||
{"x": 524, "y": 251, "name":"ZMENUHS", "hotkey" : 104, "help": 5, "command": "highscores"},
|
||||
{"x": 557, "y": 359, "name":"ZMENUCR", "hotkey" : 99, "help": 6, "command": "to credits"},
|
||||
{"x": 586, "y": 468, "name":"ZMENUQT", "hotkey" : 27, "help": 7, "command": "exit"}
|
||||
{"x": 540, "y": 10, "name":"MMENUNG", "hotkey" : 110, "help": 3, "command": "to new"},
|
||||
{"x": 532, "y": 132, "name":"MMENULG", "hotkey" : 108, "help": 4, "command": "to load"},
|
||||
{"x": 524, "y": 251, "name":"MMENUHS", "hotkey" : 104, "help": 5, "command": "highscores"},
|
||||
{"x": 557, "y": 359, "name":"MMENUCR", "hotkey" : 99, "help": 6, "command": "to credits"},
|
||||
{"x": 586, "y": 468, "name":"MMENUQT", "hotkey" : 27, "help": 7, "command": "exit"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "new",
|
||||
"buttons":
|
||||
[
|
||||
{"x": 545, "y": 4, "name":"ZTSINGL", "hotkey" : 115, "help": 10, "command": "start single"},
|
||||
{"x": 568, "y": 120, "name":"ZTMULTI", "hotkey" : 109, "help": 12, "command": "start multi"},
|
||||
{"x": 541, "y": 233, "name":"ZTCAMPN", "hotkey" : 99, "help": 11, "command": "to campaign"},
|
||||
{"x": 545, "y": 358, "name":"ZTTUTOR", "hotkey" : 116, "help": 13, "command": "start tutorial"},
|
||||
{"x": 582, "y": 464, "name":"ZTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
|
||||
{"x": 545, "y": 4, "name":"GTSINGL", "hotkey" : 115, "help": 10, "command": "start single"},
|
||||
{"x": 568, "y": 120, "name":"GTMULTI", "hotkey" : 109, "help": 12, "command": "start multi"},
|
||||
{"x": 541, "y": 233, "name":"GTCAMPN", "hotkey" : 99, "help": 11, "command": "to campaign"},
|
||||
{"x": 545, "y": 358, "name":"GTTUTOR", "hotkey" : 116, "help": 13, "command": "start tutorial"},
|
||||
{"x": 582, "y": 464, "name":"GTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
|
||||
],
|
||||
"images": [ {"x": 114, "y": 312, "name":"ZNEWGAM"} ]
|
||||
"images": [ {"x": 114, "y": 312, "name":"NEWGAME"} ]
|
||||
},
|
||||
{
|
||||
"name" : "load",
|
||||
"buttons":
|
||||
[
|
||||
{"x": 545, "y": 8, "name":"ZTSINGL", "hotkey" : 115, "help": 10, "command": "load single"},
|
||||
{"x": 568, "y": 120, "name":"ZTMULTI", "hotkey" : 109, "help": 12, "command": "load multi"},
|
||||
{"x": 541, "y": 233, "name":"ZTCAMPN", "hotkey" : 99, "help": 11, "command": "load campaign"},
|
||||
{"x": 545, "y": 358, "name":"ZTTUTOR", "hotkey" : 116, "help": 13, "command": "load tutorial"},
|
||||
{"x": 582, "y": 464, "name":"ZTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
|
||||
{"x": 545, "y": 8, "name":"GTSINGL", "hotkey" : 115, "help": 10, "command": "load single"},
|
||||
{"x": 568, "y": 120, "name":"GTMULTI", "hotkey" : 109, "help": 12, "command": "load multi"},
|
||||
{"x": 541, "y": 233, "name":"GTCAMPN", "hotkey" : 99, "help": 11, "command": "load campaign"},
|
||||
{"x": 545, "y": 358, "name":"GTTUTOR", "hotkey" : 116, "help": 13, "command": "load tutorial"},
|
||||
{"x": 582, "y": 464, "name":"GTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
|
||||
],
|
||||
"images": [ {"x": 114, "y": 312, "name":"ZLOADGAM"} ]
|
||||
"images": [ {"x": 114, "y": 312, "name":"LOADGAME"} ]
|
||||
},
|
||||
{
|
||||
"name" : "campaign",
|
||||
"buttons":
|
||||
[
|
||||
{"x": 535, "y": 4, "name":"ZSSSOD", "hotkey" : 119, "command": "campaigns sod"},
|
||||
{"x": 494, "y": 117, "name":"ZSSROE", "hotkey" : 114, "command": "campaigns roe"},
|
||||
{"x": 486, "y": 241, "name":"ZSSARM", "hotkey" : 97, "command": "campaigns ab"},
|
||||
{"x": 550, "y": 358, "name":"ZSSCUS", "hotkey" : 99, "command": "start campaign"},
|
||||
{"x": 582, "y": 464, "name":"ZTBACK", "hotkey" : 27, "command": "to new"}
|
||||
{"x": 535, "y": 4, "name":"CSSSOD", "hotkey" : 119, "command": "campaigns sod"},
|
||||
{"x": 494, "y": 117, "name":"CSSROE", "hotkey" : 114, "command": "campaigns roe"},
|
||||
{"x": 486, "y": 241, "name":"CSSARM", "hotkey" : 97, "command": "campaigns ab"},
|
||||
{"x": 550, "y": 358, "name":"CSSCUS", "hotkey" : 99, "command": "start campaign"},
|
||||
{"x": 582, "y": 464, "name":"GTBACK", "hotkey" : 27, "command": "to new"}
|
||||
],
|
||||
}
|
||||
]
|
||||
@ -116,7 +116,7 @@
|
||||
|
||||
},
|
||||
{
|
||||
"name":"wog",
|
||||
"name":"wog", /// wog campaigns, currently has no assigned button in campaign screen and thus unused
|
||||
"images" : [ {"x": 0, "y": 0, "name":"CAMPZALL"} ],
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||
"items":
|
||||
|
@ -69,7 +69,7 @@
|
||||
},
|
||||
"type": {
|
||||
"type" : "string",
|
||||
"enum" : [ "dir", "lod", "snd", "vid" ],
|
||||
"enum" : [ "dir", "lod", "snd", "vid", "map" ],
|
||||
"description" : "Type of data source"
|
||||
}
|
||||
}
|
||||
|
@ -89,9 +89,9 @@ std::pair< std::vector<BattleHex>, int > BattleInfo::getPath(BattleHex start, Ba
|
||||
}
|
||||
|
||||
ui32 BattleInfo::calculateDmg( const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero,
|
||||
bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg )
|
||||
bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg )
|
||||
{
|
||||
TDmgRange range = calculateDmgRange(attacker, defender, shooting, charge, lucky, deathBlow, ballistaDoubleDmg);
|
||||
TDmgRange range = calculateDmgRange(attacker, defender, shooting, charge, lucky, unlucky, deathBlow, ballistaDoubleDmg);
|
||||
|
||||
if(range.first != range.second)
|
||||
{
|
||||
@ -636,7 +636,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
|
||||
}
|
||||
case BFieldType::CLOVER_FIELD:
|
||||
{ //+2 luck bonus for neutral creatures
|
||||
curB->addNewBonus(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, +2, Bonus::TERRAIN_OVERLAY)->addLimiter(make_shared<CreatureFactionLimiter>(-1)));
|
||||
curB->addNewBonus(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, +2, Bonus::TERRAIN_OVERLAY)->addLimiter(make_shared<CreatureAlignmentLimiter>(EAlignment::NEUTRAL)));
|
||||
break;
|
||||
}
|
||||
case BFieldType::EVIL_FOG:
|
||||
|
@ -97,7 +97,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
|
||||
shared_ptr<CObstacleInstance> getObstacleOnTile(BattleHex tile) const;
|
||||
std::set<BattleHex> getStoppers(bool whichSidePerspective) const;
|
||||
|
||||
ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg); //charge - number of hexes travelled before attack (for champion's jousting)
|
||||
ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg); //charge - number of hexes travelled before attack (for champion's jousting)
|
||||
void calculateCasualties(std::map<ui32,si32> *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount)
|
||||
|
||||
//void getPotentiallyAttackableHexes(AttackableTiles &at, const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos); //hexes around target that could be attacked in melee
|
||||
|
@ -768,9 +768,9 @@ bool CBattleInfoCallback::battleCanShoot(const CStack * stack, BattleHex dest) c
|
||||
}
|
||||
|
||||
TDmgRange CBattleInfoCallback::calculateDmgRange(const CStack* attacker, const CStack* defender, bool shooting,
|
||||
ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const
|
||||
ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg) const
|
||||
{
|
||||
return calculateDmgRange(attacker, defender, attacker->count, shooting, charge, lucky, deathBlow, ballistaDoubleDmg);
|
||||
return calculateDmgRange(attacker, defender, attacker->count, shooting, charge, lucky, unlucky, deathBlow, ballistaDoubleDmg);
|
||||
}
|
||||
|
||||
TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) const
|
||||
@ -878,6 +878,11 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) c
|
||||
{
|
||||
additiveBonus += 1.0;
|
||||
}
|
||||
//unlucky hit, used only if negative luck is enabled
|
||||
if (info.unluckyHit)
|
||||
{
|
||||
additiveBonus -= 0.5; // FIXME: how bad (and luck in general) should work with following bonuses?
|
||||
}
|
||||
|
||||
//ballista double dmg
|
||||
if(info.ballistaDoubleDamage)
|
||||
@ -965,12 +970,13 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) c
|
||||
}
|
||||
|
||||
TDmgRange CBattleInfoCallback::calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount,
|
||||
bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg ) const
|
||||
bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg ) const
|
||||
{
|
||||
BattleAttackInfo bai(attacker, defender, shooting);
|
||||
bai.attackerCount = attackerCount;
|
||||
bai.chargedFields = charge;
|
||||
bai.luckyHit = lucky;
|
||||
bai.unluckyHit = unlucky;
|
||||
bai.deathBlow = deathBlow;
|
||||
bai.ballistaDoubleDamage = ballistaDoubleDmg;
|
||||
return calculateDmgRange(bai);
|
||||
|
@ -203,6 +203,7 @@ struct DLL_LINKAGE BattleAttackInfo
|
||||
int chargedFields;
|
||||
|
||||
bool luckyHit;
|
||||
bool unluckyHit;
|
||||
bool deathBlow;
|
||||
bool ballistaDoubleDamage;
|
||||
|
||||
@ -235,8 +236,8 @@ public:
|
||||
std::set<const CStack*> batteAdjacentCreatures (const CStack * stack) const;
|
||||
|
||||
TDmgRange calculateDmgRange(const BattleAttackInfo &info) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
|
||||
TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, TQuantity attackerCount, bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
|
||||
TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
|
||||
TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, TQuantity attackerCount, bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
|
||||
TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
|
||||
|
||||
//hextowallpart //int battleGetWallUnderHex(BattleHex hex) const; //returns part of destructible wall / gate / keep under given hex or -1 if not found
|
||||
std::pair<ui32, ui32> battleEstimateDamage(const BattleAttackInfo &bai, std::pair<ui32, ui32> * retaliationDmg = NULL) const; //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair <min dmg, max dmg>
|
||||
|
@ -272,7 +272,7 @@ std::vector<JsonNode> CCreatureHandler::loadLegacyData(size_t dataSize)
|
||||
std::vector<JsonNode> h3Data;
|
||||
h3Data.reserve(dataSize);
|
||||
|
||||
CLegacyConfigParser parser("DATA/ZCRTRAIT.TXT");
|
||||
CLegacyConfigParser parser("DATA/CRTRAITS.TXT");
|
||||
|
||||
parser.endLine(); // header
|
||||
parser.endLine();
|
||||
@ -619,7 +619,10 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
|
||||
BOOST_FOREACH(const JsonNode &ability, config["abilities"].Vector())
|
||||
{
|
||||
if (ability.getType() == JsonNode::DATA_VECTOR)
|
||||
{
|
||||
assert(0); // should be unused now
|
||||
AddAbility(creature, ability.Vector()); // used only for H3 creatures
|
||||
}
|
||||
else
|
||||
{
|
||||
auto b = JsonUtils::parseBonus(ability);
|
||||
|
@ -50,7 +50,7 @@ CDefObjInfoHandler::CDefObjInfoHandler()
|
||||
{
|
||||
VLC->dobjinfo = this;
|
||||
|
||||
auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/ZOBJCTS.TXT"));
|
||||
auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/OBJECTS.TXT"));
|
||||
|
||||
std::istringstream inp(std::string((char*)textFile.first.get(), textFile.second));
|
||||
int objNumber;
|
||||
|
@ -163,7 +163,7 @@ CGeneralTextHandler::CGeneralTextHandler()
|
||||
readToVector("DATA/RESTYPES.TXT", restypes);
|
||||
readToVector("DATA/TERRNAME.TXT", terrainNames);
|
||||
readToVector("DATA/RANDSIGN.TXT", randsign);
|
||||
readToVector("DATA/ZCRGN1.TXT", creGens);
|
||||
readToVector("DATA/CRGEN1.TXT", creGens);
|
||||
readToVector("DATA/CRGEN4.TXT", creGens4);
|
||||
readToVector("DATA/OVERVIEW.TXT", overview);
|
||||
readToVector("DATA/ARRAYTXT.TXT", arraytxt);
|
||||
@ -186,7 +186,7 @@ CGeneralTextHandler::CGeneralTextHandler()
|
||||
while (parser.endLine());
|
||||
}
|
||||
{
|
||||
CLegacyConfigParser parser("DATA/ZELP.TXT");
|
||||
CLegacyConfigParser parser("DATA/HELP.TXT");
|
||||
do
|
||||
{
|
||||
std::string first = parser.readString();
|
||||
|
@ -13,6 +13,7 @@ set(lib_SRCS
|
||||
filesystem/CResourceLoader.cpp
|
||||
filesystem/CFileInputStream.cpp
|
||||
filesystem/CCompressedStream.cpp
|
||||
filesystem/CMappedFileLoader.cpp
|
||||
logging/CBasicLogConfigurator.cpp
|
||||
logging/CLogger.cpp
|
||||
mapping/CCampaignHandler.cpp
|
||||
|
@ -33,36 +33,13 @@ public:
|
||||
*/
|
||||
explicit CFilesystemLoader(const std::string & baseDirectory, size_t depth = 16, bool initial = false);
|
||||
|
||||
/**
|
||||
* Loads a resource with the given resource name.
|
||||
*
|
||||
* @param resourceName The unqiue resource name in space of the filesystem.
|
||||
* @return a input stream object, not null
|
||||
*/
|
||||
std::unique_ptr<CInputStream> load(const std::string & resourceName) const;
|
||||
|
||||
/**
|
||||
* Checks if the file entry exists.
|
||||
*
|
||||
* @return true if the entry exists, false if not.
|
||||
*/
|
||||
bool existsEntry(const std::string & resourceName) const;
|
||||
|
||||
/**
|
||||
* Gets all entries in the filesystem.
|
||||
*
|
||||
* @return a list of all entries in the filesystem.
|
||||
*/
|
||||
boost::unordered_map<ResourceID, std::string> getEntries() const;
|
||||
|
||||
/**
|
||||
* Gets the origin of the archive loader.
|
||||
*
|
||||
* @return the file path to directory with archive (e.g. path/to/h3/mp3)
|
||||
*/
|
||||
std::string getOrigin() const;
|
||||
|
||||
bool createEntry(std::string filename);
|
||||
/// Interface implementation
|
||||
/// @see ISimpleResourceLoader
|
||||
std::unique_ptr<CInputStream> load(const std::string & resourceName) const override;
|
||||
bool existsEntry(const std::string & resourceName) const override;
|
||||
boost::unordered_map<ResourceID, std::string> getEntries() const override;
|
||||
std::string getOrigin() const override;
|
||||
bool createEntry(std::string filename) override;
|
||||
|
||||
private:
|
||||
/** The base directory which is scanned and indexed. */
|
||||
|
@ -57,46 +57,16 @@ public:
|
||||
*/
|
||||
explicit CLodArchiveLoader(const std::string & archive);
|
||||
|
||||
/**
|
||||
* Loads a resource with the given resource name.
|
||||
*
|
||||
* @param resourceName The unqiue resource name in space of the archive.
|
||||
* @return a input stream object, not null.
|
||||
*
|
||||
* @throws std::runtime_error if the archive entry wasn't found
|
||||
*/
|
||||
std::unique_ptr<CInputStream> load(const std::string & resourceName) const;
|
||||
|
||||
/**
|
||||
* Gets all entries in the archive.
|
||||
*
|
||||
* @return a list of all entries in the archive.
|
||||
*/
|
||||
boost::unordered_map<ResourceID, std::string> getEntries() const;
|
||||
|
||||
/**
|
||||
* Gets the archive entry for the requested resource
|
||||
*
|
||||
* @param resourceName The unqiue resource name in space of the archive.
|
||||
* @return the archive entry for the requested resource or a null ptr if the archive wasn't found
|
||||
*/
|
||||
const ArchiveEntry * getArchiveEntry(const std::string & resourceName) const;
|
||||
|
||||
/**
|
||||
* Checks if the archive entry exists.
|
||||
*
|
||||
* @return true if the entry exists, false if not.
|
||||
*/
|
||||
bool existsEntry(const std::string & resourceName) const;
|
||||
|
||||
/**
|
||||
* Gets the origin of the archive loader.
|
||||
*
|
||||
* @return the file path to the archive which is scanned and indexed.
|
||||
*/
|
||||
std::string getOrigin() const;
|
||||
/// Interface implementation
|
||||
/// @see ISimpleResourceLoader
|
||||
std::unique_ptr<CInputStream> load(const std::string & resourceName) const override;
|
||||
boost::unordered_map<ResourceID, std::string> getEntries() const override;
|
||||
bool existsEntry(const std::string & resourceName) const override;
|
||||
std::string getOrigin() const override;
|
||||
|
||||
private:
|
||||
const ArchiveEntry * getArchiveEntry(const std::string & resourceName) const;
|
||||
|
||||
/**
|
||||
* Initializes a LOD archive.
|
||||
*
|
||||
|
45
lib/filesystem/CMappedFileLoader.cpp
Normal file
45
lib/filesystem/CMappedFileLoader.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "StdInc.h"
|
||||
#include "CMappedFileLoader.h"
|
||||
#include "CResourceLoader.h"
|
||||
#include "../JsonNode.h"
|
||||
|
||||
CMappedFileLoader::CMappedFileLoader(const JsonNode &config)
|
||||
{
|
||||
BOOST_FOREACH(auto entry, config.Struct())
|
||||
{
|
||||
fileList[ResourceID(entry.first)] = entry.second.String();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<CInputStream> CMappedFileLoader::load(const std::string & resourceName) const
|
||||
{
|
||||
return CResourceHandler::get()->load(ResourceID(resourceName));
|
||||
}
|
||||
|
||||
bool CMappedFileLoader::existsEntry(const std::string & resourceName) const
|
||||
{
|
||||
for(auto it = fileList.begin(); it != fileList.end(); ++it)
|
||||
{
|
||||
if(it->second == resourceName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::unordered_map<ResourceID, std::string> CMappedFileLoader::getEntries() const
|
||||
{
|
||||
return fileList;
|
||||
}
|
||||
|
||||
std::string CMappedFileLoader::getOrigin() const
|
||||
{
|
||||
return ""; // does not have any meaning with this type of data source
|
||||
}
|
||||
|
||||
std::string CMappedFileLoader::getFullName(const std::string & resourceName) const
|
||||
{
|
||||
return CResourceHandler::get()->getResourceName(ResourceID(resourceName));
|
||||
}
|
53
lib/filesystem/CMappedFileLoader.h
Normal file
53
lib/filesystem/CMappedFileLoader.h
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
/*
|
||||
* CMappedFileLoader.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ISimpleResourceLoader.h"
|
||||
#include "CResourceLoader.h"
|
||||
|
||||
class CFileInfo;
|
||||
class CInputStream;
|
||||
|
||||
/**
|
||||
* Class that implements file mapping (aka *nix symbolic links)
|
||||
* Uses json file as input, content is map:
|
||||
* "fileA.txt" : "fileB.txt"
|
||||
* Note that extension is necessary, but used only to determine type
|
||||
*
|
||||
* fileA - file which will be replaced
|
||||
* fileB - file which will be used as replacement
|
||||
*/
|
||||
class DLL_LINKAGE CMappedFileLoader : public ISimpleResourceLoader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Ctor.
|
||||
*
|
||||
* @param config Specifies filesystem configuration
|
||||
*/
|
||||
explicit CMappedFileLoader(const JsonNode & config);
|
||||
|
||||
/// Interface implementation
|
||||
/// @see ISimpleResourceLoader
|
||||
std::unique_ptr<CInputStream> load(const std::string & resourceName) const override;
|
||||
bool existsEntry(const std::string & resourceName) const override;
|
||||
boost::unordered_map<ResourceID, std::string> getEntries() const override;
|
||||
std::string getOrigin() const override;
|
||||
std::string getFullName(const std::string & resourceName) const override;
|
||||
|
||||
private:
|
||||
/** A list of files in this map
|
||||
* key = ResourceID for resource loader
|
||||
* value = ResourceID to which file this request will be redirected
|
||||
*/
|
||||
boost::unordered_map<ResourceID, std::string> fileList;
|
||||
};
|
@ -3,6 +3,7 @@
|
||||
#include "CFileInfo.h"
|
||||
#include "CLodArchiveLoader.h"
|
||||
#include "CFilesystemLoader.h"
|
||||
#include "CMappedFileLoader.h"
|
||||
|
||||
//For filesystem initialization
|
||||
#include "../JsonNode.h"
|
||||
@ -127,7 +128,7 @@ std::string CResourceLoader::getResourceName(const ResourceID & resourceIdent) c
|
||||
{
|
||||
auto locator = getResource(resourceIdent);
|
||||
if (locator.getLoader())
|
||||
return locator.getLoader()->getOrigin() + '/' + locator.getResourceName();
|
||||
return locator.getLoader()->getFullName(locator.getResourceName());
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -372,6 +373,22 @@ void CResourceHandler::loadArchive(const std::string &prefix, const std::string
|
||||
shared_ptr<ISimpleResourceLoader>(new CLodArchiveLoader(filename)), false);
|
||||
}
|
||||
|
||||
void CResourceHandler::loadJsonMap(const std::string &prefix, const std::string &mountPoint, const JsonNode & config)
|
||||
{
|
||||
std::string URI = prefix + config["path"].String();
|
||||
std::string filename = initialLoader->getResourceName(ResourceID(URI, EResType::TEXT));
|
||||
if (!filename.empty())
|
||||
{
|
||||
auto configData = initialLoader->loadData(ResourceID(URI, EResType::TEXT));
|
||||
|
||||
const JsonNode config((char*)configData.first.get(), configData.second);
|
||||
|
||||
resourceLoader->addLoader(mountPoint,
|
||||
shared_ptr<ISimpleResourceLoader>(new CMappedFileLoader(config)), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CResourceHandler::loadFileSystem(const std::string & prefix, const std::string &fsConfigURI)
|
||||
{
|
||||
auto fsConfigData = initialLoader->loadData(ResourceID(fsConfigURI, EResType::TEXT));
|
||||
@ -390,6 +407,8 @@ void CResourceHandler::loadFileSystem(const std::string & prefix, const JsonNode
|
||||
CStopWatch timer;
|
||||
logGlobal->debugStream() << "\t\tLoading resource at " << prefix + entry["path"].String();
|
||||
|
||||
if (entry["type"].String() == "map")
|
||||
loadJsonMap(prefix, mountPoint.first, entry);
|
||||
if (entry["type"].String() == "dir")
|
||||
loadDirectory(prefix, mountPoint.first, entry);
|
||||
if (entry["type"].String() == "lod")
|
||||
@ -423,8 +442,19 @@ std::vector<std::string> CResourceHandler::getAvailableMods()
|
||||
|
||||
name.erase(0, name.find_last_of('/') + 1); //Remove path prefix
|
||||
|
||||
if (name == "WOG") // check if wog is actually present. Hack-ish but better than crash
|
||||
{
|
||||
if (!initialLoader->existsResource(ResourceID("ALL/DATA/ZVS", EResType::DIRECTORY)) &&
|
||||
!initialLoader->existsResource(ResourceID("ALL/MODS/WOG/DATA/ZVS", EResType::DIRECTORY)))
|
||||
{
|
||||
++iterator;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name.empty()) // this is also triggered for "ALL/MODS/" entry
|
||||
foundMods.push_back(name);
|
||||
|
||||
++iterator;
|
||||
}
|
||||
return foundMods;
|
||||
|
@ -130,32 +130,9 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the identifier.
|
||||
*
|
||||
* @return the name of the identifier
|
||||
*/
|
||||
std::string getName() const;
|
||||
|
||||
/**
|
||||
* Gets the type of the identifier.
|
||||
*
|
||||
* @return the type of the identifier
|
||||
*/
|
||||
EResType::Type getType() const;
|
||||
|
||||
/**
|
||||
* Sets the name of the identifier.
|
||||
*
|
||||
* @param name the name of the identifier. No extension, will be converted to uppercase.
|
||||
*/
|
||||
void setName(std::string name);
|
||||
|
||||
/**
|
||||
* Sets the type of the identifier.
|
||||
*
|
||||
* @param type the type of the identifier.
|
||||
*/
|
||||
void setType(EResType::Type type);
|
||||
|
||||
protected:
|
||||
@ -390,6 +367,7 @@ public:
|
||||
static void loadFileSystem(const std::string &prefix, const JsonNode & fsConfig);
|
||||
static void loadDirectory(const std::string &prefix, const std::string & mountPoint, const JsonNode & config);
|
||||
static void loadArchive(const std::string &prefix, const std::string & mountPoint, const JsonNode & config, EResType::Type archiveType);
|
||||
static void loadJsonMap(const std::string &prefix, const std::string & mountPoint, const JsonNode & config);
|
||||
|
||||
/**
|
||||
* Checks all subfolders of MODS directory for presence of mods
|
||||
|
@ -54,6 +54,14 @@ public:
|
||||
*/
|
||||
virtual std::string getOrigin() const =0;
|
||||
|
||||
/**
|
||||
* Gets full name of resource, e.g. name of file in filesystem.
|
||||
*/
|
||||
virtual std::string getFullName(const std::string & resourceName) const
|
||||
{
|
||||
return getOrigin() + '/' + resourceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new resource with specified filename.
|
||||
*
|
||||
|
@ -697,17 +697,23 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
||||
int attackerLuck = att->LuckVal();
|
||||
const CGHeroInstance * h0 = gs->curB->heroes[0],
|
||||
* h1 = gs->curB->heroes[1];
|
||||
bool noLuck = false;
|
||||
if((h0 && NBonus::hasOfType(h0, Bonus::BLOCK_LUCK)) ||
|
||||
(h1 && NBonus::hasOfType(h1, Bonus::BLOCK_LUCK)))
|
||||
|
||||
if(!(h0 && NBonus::hasOfType(h0, Bonus::BLOCK_LUCK)) &&
|
||||
!(h1 && NBonus::hasOfType(h1, Bonus::BLOCK_LUCK)))
|
||||
{
|
||||
noLuck = true;
|
||||
if(attackerLuck > 0 && rand()%24 < attackerLuck)
|
||||
{
|
||||
bat.flags |= BattleAttack::LUCKY;
|
||||
}
|
||||
if (VLC->modh->settings.data["hardcodedFeatures"]["NEGATIVE_LUCK"].Bool()) // negative luck enabled
|
||||
{
|
||||
if (attackerLuck < 0 && rand()%24 < abs(attackerLuck))
|
||||
{
|
||||
bat.flags |= BattleAttack::UNLUCKY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!noLuck && attackerLuck > 0 && rand()%24 < attackerLuck) //TODO?: negative luck option?
|
||||
{
|
||||
bat.flags |= BattleAttack::LUCKY;
|
||||
}
|
||||
if (rand()%100 < att->valOfBonuses(Bonus::DOUBLE_DAMAGE_CHANCE))
|
||||
{
|
||||
bat.flags |= BattleAttack::DEATH_BLOW;
|
||||
@ -764,7 +770,7 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
|
||||
bsa.flags |= BattleStackAttacked::SECONDARY; //all other targets do not suffer from spells & spell-like abilities
|
||||
bsa.attackerID = att->ID;
|
||||
bsa.stackAttacked = def->ID;
|
||||
bsa.damageAmount = gs->curB->calculateDmg(att, def, gs->curB->battleGetOwner(att), gs->curB->battleGetOwner(def), bat.shot(), distance, bat.lucky(), bat.deathBlow(), bat.ballistaDoubleDmg());
|
||||
bsa.damageAmount = gs->curB->calculateDmg(att, def, gs->curB->battleGetOwner(att), gs->curB->battleGetOwner(def), bat.shot(), distance, bat.lucky(), bat.unlucky(), bat.deathBlow(), bat.ballistaDoubleDmg());
|
||||
def->prepareAttacked(bsa); //calculate casualties
|
||||
|
||||
//life drain handling
|
||||
|
Loading…
Reference in New Issue
Block a user