mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Merge pull request #2350 from vcmi/ban_stuff_on_water_maps
Ban objects on maps without water
This commit is contained in:
@@ -1085,6 +1085,7 @@
|
|||||||
},
|
},
|
||||||
"necklaceOfOceanGuidance":
|
"necklaceOfOceanGuidance":
|
||||||
{
|
{
|
||||||
|
"onlyOnWaterMap" : true,
|
||||||
"bonuses" : [
|
"bonuses" : [
|
||||||
{
|
{
|
||||||
"type" : "MOVEMENT",
|
"type" : "MOVEMENT",
|
||||||
@@ -1325,6 +1326,7 @@
|
|||||||
},
|
},
|
||||||
"bootsOfLevitation":
|
"bootsOfLevitation":
|
||||||
{
|
{
|
||||||
|
"onlyOnWaterMap" : true,
|
||||||
"bonuses" : [
|
"bonuses" : [
|
||||||
{
|
{
|
||||||
"type" : "WATER_WALKING",
|
"type" : "WATER_WALKING",
|
||||||
@@ -1796,6 +1798,7 @@
|
|||||||
},
|
},
|
||||||
"seaCaptainsHat":
|
"seaCaptainsHat":
|
||||||
{
|
{
|
||||||
|
"onlyOnWaterMap" : true,
|
||||||
"bonuses" : [
|
"bonuses" : [
|
||||||
{
|
{
|
||||||
"type" : "WHIRLPOOL_PROTECTION",
|
"type" : "WHIRLPOOL_PROTECTION",
|
||||||
@@ -2159,6 +2162,7 @@
|
|||||||
},
|
},
|
||||||
"admiralsHat":
|
"admiralsHat":
|
||||||
{
|
{
|
||||||
|
"onlyOnWaterMap" : true,
|
||||||
"bonuses" : [
|
"bonuses" : [
|
||||||
{
|
{
|
||||||
"type" : "FREE_SHIP_BOARDING",
|
"type" : "FREE_SHIP_BOARDING",
|
||||||
|
@@ -120,6 +120,10 @@
|
|||||||
"index" : {
|
"index" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"description" : "Private field to break things, do not use."
|
"description" : "Private field to break things, do not use."
|
||||||
|
},
|
||||||
|
"onlyOnWaterMap" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"description" : "It true, artifact won't spawn on a map without water"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -171,6 +171,14 @@
|
|||||||
"index" : {
|
"index" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"description" : "Private field to break things, do not use."
|
"description" : "Private field to break things, do not use."
|
||||||
|
},
|
||||||
|
"onlyOnWaterMap" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"description" : "It true, hero won't show up on a map with water"
|
||||||
|
},
|
||||||
|
"onlyOnMapWithoutWater" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"description" : "It true, hero will show up only if the map contains no water"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -97,5 +97,9 @@
|
|||||||
"expert" : {
|
"expert" : {
|
||||||
"$ref" : "#/definitions/skillBonus"
|
"$ref" : "#/definitions/skillBonus"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"onlyOnWaterMap" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"description" : "It true, skill won't be available on a map without water"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -309,5 +309,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"onlyOnWaterMap" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"description" : "It true, spell won't be available on a map without water"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -164,7 +164,8 @@
|
|||||||
"effects" : {
|
"effects" : {
|
||||||
"main" : { "val" : 150 }
|
"main" : { "val" : 150 }
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"onlyOnWaterMap" : true
|
||||||
},
|
},
|
||||||
"leadership" : {
|
"leadership" : {
|
||||||
"index" : 6,
|
"index" : 6,
|
||||||
|
@@ -13,7 +13,8 @@
|
|||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
}
|
},
|
||||||
|
"onlyOnWaterMap" : true
|
||||||
},
|
},
|
||||||
"scuttleBoat" : {
|
"scuttleBoat" : {
|
||||||
"index" : 1,
|
"index" : 1,
|
||||||
@@ -29,7 +30,8 @@
|
|||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
}
|
},
|
||||||
|
"onlyOnWaterMap" : true
|
||||||
},
|
},
|
||||||
"visions" : {
|
"visions" : {
|
||||||
"index" : 2,
|
"index" : 2,
|
||||||
@@ -237,7 +239,8 @@
|
|||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
}
|
},
|
||||||
|
"onlyOnWaterMap" : true
|
||||||
},
|
},
|
||||||
"dimensionDoor" : {
|
"dimensionDoor" : {
|
||||||
"index" : 8,
|
"index" : 8,
|
||||||
|
@@ -434,6 +434,7 @@ CArtifact * CArtHandler::loadFromJson(const std::string & scope, const JsonNode
|
|||||||
art->advMapDef = graphics["map"].String();
|
art->advMapDef = graphics["map"].String();
|
||||||
|
|
||||||
art->price = static_cast<ui32>(node["value"].Float());
|
art->price = static_cast<ui32>(node["value"].Float());
|
||||||
|
art->onlyOnWaterMap = node["onlyOnWaterMap"].Bool();
|
||||||
|
|
||||||
loadSlots(art, node);
|
loadSlots(art, node);
|
||||||
loadClass(art, node);
|
loadClass(art, node);
|
||||||
|
@@ -111,6 +111,7 @@ public:
|
|||||||
enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes
|
enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes
|
||||||
|
|
||||||
EartClass aClass = ART_SPECIAL;
|
EartClass aClass = ART_SPECIAL;
|
||||||
|
bool onlyOnWaterMap;
|
||||||
|
|
||||||
int32_t getIndex() const override;
|
int32_t getIndex() const override;
|
||||||
int32_t getIconIndex() const override;
|
int32_t getIconIndex() const override;
|
||||||
@@ -159,6 +160,7 @@ public:
|
|||||||
h & modScope;
|
h & modScope;
|
||||||
h & identifier;
|
h & identifier;
|
||||||
h & warMachine;
|
h & warMachine;
|
||||||
|
h & onlyOnWaterMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
CArtifact();
|
CArtifact();
|
||||||
|
@@ -57,7 +57,7 @@ bool CGameInfoCallback::isAllowed(int32_t type, int32_t id) const
|
|||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return gs->map->allowedSpell[id];
|
return gs->map->allowedSpells[id];
|
||||||
case 1:
|
case 1:
|
||||||
return gs->map->allowedArtifact[id];
|
return gs->map->allowedArtifact[id];
|
||||||
case 2:
|
case 2:
|
||||||
|
@@ -424,6 +424,9 @@ CHero * CHeroHandler::loadFromJson(const std::string & scope, const JsonNode & n
|
|||||||
hero->modScope = scope;
|
hero->modScope = scope;
|
||||||
hero->gender = node["female"].Bool() ? EHeroGender::FEMALE : EHeroGender::MALE;
|
hero->gender = node["female"].Bool() ? EHeroGender::FEMALE : EHeroGender::MALE;
|
||||||
hero->special = node["special"].Bool();
|
hero->special = node["special"].Bool();
|
||||||
|
//Default - both false
|
||||||
|
hero->onlyOnWaterMap = node["onlyOnWaterMap"].Bool();
|
||||||
|
hero->onlyOnMapWithoutWater = node["onlyOnMapWithoutWater"].Bool();
|
||||||
|
|
||||||
VLC->generaltexth->registerString(scope, hero->getNameTextID(), node["texts"]["name"].String());
|
VLC->generaltexth->registerString(scope, hero->getNameTextID(), node["texts"]["name"].String());
|
||||||
VLC->generaltexth->registerString(scope, hero->getBiographyTextID(), node["texts"]["biography"].String());
|
VLC->generaltexth->registerString(scope, hero->getBiographyTextID(), node["texts"]["biography"].String());
|
||||||
|
@@ -69,6 +69,8 @@ public:
|
|||||||
std::set<SpellID> spells;
|
std::set<SpellID> spells;
|
||||||
bool haveSpellBook = false;
|
bool haveSpellBook = false;
|
||||||
bool special = false; // hero is special and won't be placed in game (unless preset on map), e.g. campaign heroes
|
bool special = false; // hero is special and won't be placed in game (unless preset on map), e.g. campaign heroes
|
||||||
|
bool onlyOnWaterMap; // hero will be placed only if the map contains water
|
||||||
|
bool onlyOnMapWithoutWater; // hero will be placed only if the map does not contain water
|
||||||
EHeroGender gender = EHeroGender::MALE; // default sex: 0=male, 1=female
|
EHeroGender gender = EHeroGender::MALE; // default sex: 0=male, 1=female
|
||||||
|
|
||||||
/// Graphics
|
/// Graphics
|
||||||
@@ -114,6 +116,8 @@ public:
|
|||||||
h & haveSpellBook;
|
h & haveSpellBook;
|
||||||
h & gender;
|
h & gender;
|
||||||
h & special;
|
h & special;
|
||||||
|
h & onlyOnWaterMap;
|
||||||
|
h & onlyOnMapWithoutWater;
|
||||||
h & iconSpecSmall;
|
h & iconSpecSmall;
|
||||||
h & iconSpecLarge;
|
h & iconSpecLarge;
|
||||||
h & portraitSmall;
|
h & portraitSmall;
|
||||||
|
@@ -199,6 +199,8 @@ CSkill * CSkillHandler::loadFromJson(const std::string & scope, const JsonNode &
|
|||||||
auto * skill = new CSkill(SecondarySkill((si32)index), identifier, major, minor);
|
auto * skill = new CSkill(SecondarySkill((si32)index), identifier, major, minor);
|
||||||
skill->modScope = scope;
|
skill->modScope = scope;
|
||||||
|
|
||||||
|
skill->onlyOnWaterMap = json["onlyOnWaterMap"].Bool();
|
||||||
|
|
||||||
VLC->generaltexth->registerString(scope, skill->getNameTextID(), json["name"].String());
|
VLC->generaltexth->registerString(scope, skill->getNameTextID(), json["name"].String());
|
||||||
switch(json["gainChance"].getType())
|
switch(json["gainChance"].getType())
|
||||||
{
|
{
|
||||||
|
@@ -80,6 +80,8 @@ public:
|
|||||||
void updateFrom(const JsonNode & data);
|
void updateFrom(const JsonNode & data);
|
||||||
void serializeJson(JsonSerializeFormat & handler);
|
void serializeJson(JsonSerializeFormat & handler);
|
||||||
|
|
||||||
|
bool onlyOnWaterMap;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler & h, const int version)
|
template <typename Handler> void serialize(Handler & h, const int version)
|
||||||
{
|
{
|
||||||
h & id;
|
h & id;
|
||||||
@@ -88,6 +90,7 @@ public:
|
|||||||
h & levels;
|
h & levels;
|
||||||
h & obligatoryMajor;
|
h & obligatoryMajor;
|
||||||
h & obligatoryMinor;
|
h & obligatoryMinor;
|
||||||
|
h & onlyOnWaterMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class CSkillHandler;
|
friend class CSkillHandler;
|
||||||
|
@@ -174,7 +174,7 @@ void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *>
|
|||||||
|
|
||||||
void CPrivilegedInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)
|
void CPrivilegedInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)
|
||||||
{
|
{
|
||||||
for (ui32 i = 0; i < gs->map->allowedSpell.size(); i++) //spellh size appears to be greater (?)
|
for (ui32 i = 0; i < gs->map->allowedSpells.size(); i++) //spellh size appears to be greater (?)
|
||||||
{
|
{
|
||||||
const spells::Spell * spell = SpellID(i).toSpell();
|
const spells::Spell * spell = SpellID(i).toSpell();
|
||||||
|
|
||||||
|
@@ -137,7 +137,7 @@ CMap::CMap()
|
|||||||
allHeroes.resize(allowedHeroes.size());
|
allHeroes.resize(allowedHeroes.size());
|
||||||
allowedAbilities = VLC->skillh->getDefaultAllowed();
|
allowedAbilities = VLC->skillh->getDefaultAllowed();
|
||||||
allowedArtifact = VLC->arth->getDefaultAllowed();
|
allowedArtifact = VLC->arth->getDefaultAllowed();
|
||||||
allowedSpell = VLC->spellh->getDefaultAllowed();
|
allowedSpells = VLC->spellh->getDefaultAllowed();
|
||||||
}
|
}
|
||||||
|
|
||||||
CMap::~CMap()
|
CMap::~CMap()
|
||||||
@@ -554,6 +554,105 @@ void CMap::removeObject(CGObjectInstance * obj)
|
|||||||
//TOOD: Clean artifact instances (mostly worn by hero?) and quests related to this object
|
//TOOD: Clean artifact instances (mostly worn by hero?) and quests related to this object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CMap::isWaterMap() const
|
||||||
|
{
|
||||||
|
return waterMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMap::calculateWaterContent()
|
||||||
|
{
|
||||||
|
size_t totalTiles = height * width * levels();
|
||||||
|
size_t waterTiles = 0;
|
||||||
|
|
||||||
|
for(auto tile = terrain.origin(); tile < (terrain.origin() + terrain.num_elements()); ++tile)
|
||||||
|
{
|
||||||
|
if (tile->isWater())
|
||||||
|
{
|
||||||
|
waterTiles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waterTiles >= totalTiles / 100) //At least 1% of area is water
|
||||||
|
{
|
||||||
|
waterMap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return waterMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMap::banWaterContent()
|
||||||
|
{
|
||||||
|
banWaterHeroes();
|
||||||
|
banWaterArtifacts();
|
||||||
|
banWaterSpells();
|
||||||
|
banWaterSkills();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMap::banWaterSpells()
|
||||||
|
{
|
||||||
|
for (int j = 0; j < allowedSpells.size(); j++)
|
||||||
|
{
|
||||||
|
if (allowedSpells[j])
|
||||||
|
{
|
||||||
|
auto* spell = dynamic_cast<const CSpell*>(VLC->spells()->getByIndex(j));
|
||||||
|
if (spell->onlyOnWaterMap && !isWaterMap())
|
||||||
|
{
|
||||||
|
allowedSpells[j] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMap::banWaterArtifacts()
|
||||||
|
{
|
||||||
|
for (int j = 0; j < allowedArtifact.size(); j++)
|
||||||
|
{
|
||||||
|
if (allowedArtifact[j])
|
||||||
|
{
|
||||||
|
auto* art = dynamic_cast<const CArtifact*>(VLC->artifacts()->getByIndex(j));
|
||||||
|
if (art->onlyOnWaterMap && !isWaterMap())
|
||||||
|
{
|
||||||
|
allowedArtifact[j] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMap::banWaterSkills()
|
||||||
|
{
|
||||||
|
for (int j = 0; j < allowedAbilities.size(); j++)
|
||||||
|
{
|
||||||
|
if (allowedAbilities[j])
|
||||||
|
{
|
||||||
|
auto* skill = dynamic_cast<const CSkill*>(VLC->skills()->getByIndex(j));
|
||||||
|
if (skill->onlyOnWaterMap && !isWaterMap())
|
||||||
|
{
|
||||||
|
allowedAbilities[j] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMap::banWaterHeroes()
|
||||||
|
{
|
||||||
|
for (int j = 0; j < allowedHeroes.size(); j++)
|
||||||
|
{
|
||||||
|
if (allowedHeroes[j])
|
||||||
|
{
|
||||||
|
auto* h = dynamic_cast<const CHero*>(VLC->heroTypes()->getByIndex(j));
|
||||||
|
if ((h->onlyOnWaterMap && !isWaterMap()) || (h->onlyOnMapWithoutWater && isWaterMap()))
|
||||||
|
{
|
||||||
|
banHero(HeroTypeID(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMap::banHero(const HeroTypeID & id)
|
||||||
|
{
|
||||||
|
allowedHeroes.at(id) = false;
|
||||||
|
}
|
||||||
|
|
||||||
void CMap::initTerrain()
|
void CMap::initTerrain()
|
||||||
{
|
{
|
||||||
terrain.resize(boost::extents[levels()][width][height]);
|
terrain.resize(boost::extents[levels()][width][height]);
|
||||||
|
@@ -106,6 +106,14 @@ public:
|
|||||||
void moveObject(CGObjectInstance * obj, const int3 & dst);
|
void moveObject(CGObjectInstance * obj, const int3 & dst);
|
||||||
void removeObject(CGObjectInstance * obj);
|
void removeObject(CGObjectInstance * obj);
|
||||||
|
|
||||||
|
bool isWaterMap() const;
|
||||||
|
bool calculateWaterContent();
|
||||||
|
void banWaterArtifacts();
|
||||||
|
void banWaterHeroes();
|
||||||
|
void banHero(const HeroTypeID& id);
|
||||||
|
void banWaterSpells();
|
||||||
|
void banWaterSkills();
|
||||||
|
void banWaterContent();
|
||||||
|
|
||||||
/// Gets object of specified type on requested position
|
/// Gets object of specified type on requested position
|
||||||
const CGObjectInstance * getObjectiveObjectFrom(const int3 & pos, Obj::EObj type);
|
const CGObjectInstance * getObjectiveObjectFrom(const int3 & pos, Obj::EObj type);
|
||||||
@@ -120,7 +128,7 @@ public:
|
|||||||
std::vector<Rumor> rumors;
|
std::vector<Rumor> rumors;
|
||||||
std::vector<DisposedHero> disposedHeroes;
|
std::vector<DisposedHero> disposedHeroes;
|
||||||
std::vector<ConstTransitivePtr<CGHeroInstance> > predefinedHeroes;
|
std::vector<ConstTransitivePtr<CGHeroInstance> > predefinedHeroes;
|
||||||
std::vector<bool> allowedSpell;
|
std::vector<bool> allowedSpells;
|
||||||
std::vector<bool> allowedArtifact;
|
std::vector<bool> allowedArtifact;
|
||||||
std::vector<bool> allowedAbilities;
|
std::vector<bool> allowedAbilities;
|
||||||
std::list<CMapEvent> events;
|
std::list<CMapEvent> events;
|
||||||
@@ -146,6 +154,8 @@ public:
|
|||||||
|
|
||||||
std::map<std::string, ConstTransitivePtr<CGObjectInstance> > instanceNames;
|
std::map<std::string, ConstTransitivePtr<CGObjectInstance> > instanceNames;
|
||||||
|
|
||||||
|
bool waterMap;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// a 3-dimensional array of terrain tiles, access is as follows: x, y, level. where level=1 is underground
|
/// a 3-dimensional array of terrain tiles, access is as follows: x, y, level. where level=1 is underground
|
||||||
boost::multi_array<TerrainTile, 3> terrain;
|
boost::multi_array<TerrainTile, 3> terrain;
|
||||||
@@ -159,7 +169,7 @@ public:
|
|||||||
h & static_cast<CMapHeader&>(*this);
|
h & static_cast<CMapHeader&>(*this);
|
||||||
h & triggeredEvents; //from CMapHeader
|
h & triggeredEvents; //from CMapHeader
|
||||||
h & rumors;
|
h & rumors;
|
||||||
h & allowedSpell;
|
h & allowedSpells;
|
||||||
h & allowedAbilities;
|
h & allowedAbilities;
|
||||||
h & allowedArtifact;
|
h & allowedArtifact;
|
||||||
h & events;
|
h & events;
|
||||||
|
@@ -119,6 +119,7 @@ void CMapLoaderH3M::init()
|
|||||||
|
|
||||||
map->calculateGuardingGreaturePositions();
|
map->calculateGuardingGreaturePositions();
|
||||||
afterRead();
|
afterRead();
|
||||||
|
//map->banWaterContent(); //Not sure if force this for custom scenarios
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapLoaderH3M::readHeader()
|
void CMapLoaderH3M::readHeader()
|
||||||
@@ -774,12 +775,12 @@ void CMapLoaderH3M::readAllowedArtifacts()
|
|||||||
|
|
||||||
void CMapLoaderH3M::readAllowedSpellsAbilities()
|
void CMapLoaderH3M::readAllowedSpellsAbilities()
|
||||||
{
|
{
|
||||||
map->allowedSpell = VLC->spellh->getDefaultAllowed();
|
map->allowedSpells = VLC->spellh->getDefaultAllowed();
|
||||||
map->allowedAbilities = VLC->skillh->getDefaultAllowed();
|
map->allowedAbilities = VLC->skillh->getDefaultAllowed();
|
||||||
|
|
||||||
if(features.levelSOD)
|
if(features.levelSOD)
|
||||||
{
|
{
|
||||||
reader->readBitmaskSpells(map->allowedSpell, true);
|
reader->readBitmaskSpells(map->allowedSpells, true);
|
||||||
reader->readBitmaskSkills(map->allowedAbilities, true);
|
reader->readBitmaskSkills(map->allowedAbilities, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -969,6 +970,7 @@ void CMapLoaderH3M::readTerrain()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
map->calculateWaterContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapLoaderH3M::readObjectTemplates()
|
void CMapLoaderH3M::readObjectTemplates()
|
||||||
|
@@ -834,7 +834,7 @@ void CMapFormatJson::serializeOptions(JsonSerializeFormat & handler)
|
|||||||
|
|
||||||
handler.serializeLIC("allowedArtifacts", &ArtifactID::decode, &ArtifactID::encode, VLC->arth->getDefaultAllowed(), map->allowedArtifact);
|
handler.serializeLIC("allowedArtifacts", &ArtifactID::decode, &ArtifactID::encode, VLC->arth->getDefaultAllowed(), map->allowedArtifact);
|
||||||
|
|
||||||
handler.serializeLIC("allowedSpells", &SpellID::decode, &SpellID::encode, VLC->spellh->getDefaultAllowed(), map->allowedSpell);
|
handler.serializeLIC("allowedSpells", &SpellID::decode, &SpellID::encode, VLC->spellh->getDefaultAllowed(), map->allowedSpells);
|
||||||
|
|
||||||
//todo:events
|
//todo:events
|
||||||
}
|
}
|
||||||
@@ -1115,6 +1115,7 @@ void CMapLoaderJson::readTerrain()
|
|||||||
readTerrainLevel(underground, 1);
|
readTerrainLevel(underground, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map->calculateWaterContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
CMapLoaderJson::MapObjectLoader::MapObjectLoader(CMapLoaderJson * _owner, JsonMap::value_type & json):
|
CMapLoaderJson::MapObjectLoader::MapObjectLoader(CMapLoaderJson * _owner, JsonMap::value_type & json):
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||||
#include "../mapping/CMapEditManager.h"
|
#include "../mapping/CMapEditManager.h"
|
||||||
#include "../CTownHandler.h"
|
#include "../CTownHandler.h"
|
||||||
|
#include "../CHeroHandler.h"
|
||||||
#include "../StringConstants.h"
|
#include "../StringConstants.h"
|
||||||
#include "../filesystem/Filesystem.h"
|
#include "../filesystem/Filesystem.h"
|
||||||
#include "CZonePlacer.h"
|
#include "CZonePlacer.h"
|
||||||
@@ -411,6 +412,8 @@ void CMapGenerator::addHeaderInfo()
|
|||||||
m.description = getMapDescription();
|
m.description = getMapDescription();
|
||||||
m.difficulty = 1;
|
m.difficulty = 1;
|
||||||
addPlayerInfo();
|
addPlayerInfo();
|
||||||
|
m.waterMap = (mapGenOptions.getWaterContent() != EWaterContent::EWaterContent::NONE);
|
||||||
|
m.banWaterContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMapGenerator::getNextMonlithIndex()
|
int CMapGenerator::getNextMonlithIndex()
|
||||||
@@ -452,13 +455,24 @@ const std::vector<ArtifactID> & CMapGenerator::getAllPossibleQuestArtifacts() co
|
|||||||
|
|
||||||
const std::vector<HeroTypeID> CMapGenerator::getAllPossibleHeroes() const
|
const std::vector<HeroTypeID> CMapGenerator::getAllPossibleHeroes() const
|
||||||
{
|
{
|
||||||
|
auto isWaterMap = map->getMap(this).isWaterMap();
|
||||||
//Skip heroes that were banned, including the ones placed in prisons
|
//Skip heroes that were banned, including the ones placed in prisons
|
||||||
std::vector<HeroTypeID> ret;
|
std::vector<HeroTypeID> ret;
|
||||||
for (int j = 0; j < map->getMap(this).allowedHeroes.size(); j++)
|
for (int j = 0; j < map->getMap(this).allowedHeroes.size(); j++)
|
||||||
{
|
{
|
||||||
if (map->getMap(this).allowedHeroes[j])
|
if (map->getMap(this).allowedHeroes[j])
|
||||||
|
{
|
||||||
|
auto * h = dynamic_cast<const CHero*>(VLC->heroTypes()->getByIndex(j));
|
||||||
|
if ((h->onlyOnWaterMap && !isWaterMap) || (h->onlyOnMapWithoutWater && isWaterMap))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ret.push_back(HeroTypeID(j));
|
ret.push_back(HeroTypeID(j));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,7 +485,7 @@ void CMapGenerator::banQuestArt(const ArtifactID & id)
|
|||||||
void CMapGenerator::banHero(const HeroTypeID & id)
|
void CMapGenerator::banHero(const HeroTypeID & id)
|
||||||
{
|
{
|
||||||
//TODO: Protect with mutex
|
//TODO: Protect with mutex
|
||||||
map->getMap(this).allowedHeroes[id] = false;
|
map->getMap(this).banHero(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Zone * CMapGenerator::getZoneWater() const
|
Zone * CMapGenerator::getZoneWater() const
|
||||||
|
@@ -343,9 +343,9 @@ ui32 RmgMap::getTotalZoneCount() const
|
|||||||
bool RmgMap::isAllowedSpell(const SpellID & sid) const
|
bool RmgMap::isAllowedSpell(const SpellID & sid) const
|
||||||
{
|
{
|
||||||
assert(sid >= 0);
|
assert(sid >= 0);
|
||||||
if (sid < mapInstance->allowedSpell.size())
|
if (sid < mapInstance->allowedSpells.size())
|
||||||
{
|
{
|
||||||
return mapInstance->allowedSpell[sid];
|
return mapInstance->allowedSpells[sid];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@@ -784,6 +784,8 @@ CSpell * CSpellHandler::loadFromJson(const std::string & scope, const JsonNode &
|
|||||||
|
|
||||||
spell->special = flags["special"].Bool();
|
spell->special = flags["special"].Bool();
|
||||||
|
|
||||||
|
spell->onlyOnWaterMap = json["onlyOnWaterMap"].Bool();
|
||||||
|
|
||||||
auto findBonus = [&](const std::string & name, std::vector<BonusType> & vec)
|
auto findBonus = [&](const std::string & name, std::vector<BonusType> & vec)
|
||||||
{
|
{
|
||||||
auto it = bonusNameMap.find(name);
|
auto it = bonusNameMap.find(name);
|
||||||
|
@@ -199,7 +199,7 @@ public:
|
|||||||
bool combat; //is this spell combat (true) or adventure (false)
|
bool combat; //is this spell combat (true) or adventure (false)
|
||||||
bool creatureAbility; //if true, only creatures can use this spell
|
bool creatureAbility; //if true, only creatures can use this spell
|
||||||
si8 positiveness; //1 if spell is positive for influenced stacks, 0 if it is indifferent, -1 if it's negative
|
si8 positiveness; //1 if spell is positive for influenced stacks, 0 if it is indifferent, -1 if it's negative
|
||||||
|
bool onlyOnWaterMap; //Spell will be banned on maps without water
|
||||||
std::vector<SpellID> counteredSpells; //spells that are removed when effect of this spell is placed on creature (for bless-curse, haste-slow, and similar pairs)
|
std::vector<SpellID> counteredSpells; //spells that are removed when effect of this spell is placed on creature (for bless-curse, haste-slow, and similar pairs)
|
||||||
|
|
||||||
JsonNode targetCondition; //custom condition on what spell can affect
|
JsonNode targetCondition; //custom condition on what spell can affect
|
||||||
@@ -305,6 +305,7 @@ public:
|
|||||||
h & school;
|
h & school;
|
||||||
h & animationInfo;
|
h & animationInfo;
|
||||||
h & nonMagical;
|
h & nonMagical;
|
||||||
|
h & onlyOnWaterMap;
|
||||||
}
|
}
|
||||||
friend class CSpellHandler;
|
friend class CSpellHandler;
|
||||||
friend class Graphics;
|
friend class Graphics;
|
||||||
|
@@ -88,9 +88,9 @@ QList<QString> RewardsWidget::getListForType(RewardType typeId)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RewardType::SPELL:
|
case RewardType::SPELL:
|
||||||
for(int i = 0; i < map.allowedSpell.size(); ++i)
|
for(int i = 0; i < map.allowedSpells.size(); ++i)
|
||||||
{
|
{
|
||||||
if(map.allowedSpell[i])
|
if(map.allowedSpells[i])
|
||||||
result.append(QString::fromStdString(VLC->spells()->getByIndex(i)->getNameTranslated()));
|
result.append(QString::fromStdString(VLC->spells()->getByIndex(i)->getNameTranslated()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -94,9 +94,9 @@ void MapController::repairMap()
|
|||||||
{
|
{
|
||||||
map()->allowedArtifact.resize(VLC->arth->getDefaultAllowed().size());
|
map()->allowedArtifact.resize(VLC->arth->getDefaultAllowed().size());
|
||||||
}
|
}
|
||||||
if(VLC->spellh->getDefaultAllowed().size() > map()->allowedSpell.size())
|
if(VLC->spellh->getDefaultAllowed().size() > map()->allowedSpells.size())
|
||||||
{
|
{
|
||||||
map()->allowedSpell.resize(VLC->spellh->getDefaultAllowed().size());
|
map()->allowedSpells.resize(VLC->spellh->getDefaultAllowed().size());
|
||||||
}
|
}
|
||||||
if(VLC->heroh->getDefaultAllowed().size() > map()->allowedHeroes.size())
|
if(VLC->heroh->getDefaultAllowed().size() > map()->allowedHeroes.size())
|
||||||
{
|
{
|
||||||
|
@@ -116,12 +116,12 @@ MapSettings::MapSettings(MapController & ctrl, QWidget *parent) :
|
|||||||
item->setCheckState(controller.map()->allowedAbilities[i] ? Qt::Checked : Qt::Unchecked);
|
item->setCheckState(controller.map()->allowedAbilities[i] ? Qt::Checked : Qt::Unchecked);
|
||||||
ui->listAbilities->addItem(item);
|
ui->listAbilities->addItem(item);
|
||||||
}
|
}
|
||||||
for(int i = 0; i < controller.map()->allowedSpell.size(); ++i)
|
for(int i = 0; i < controller.map()->allowedSpells.size(); ++i)
|
||||||
{
|
{
|
||||||
auto * item = new QListWidgetItem(QString::fromStdString(VLC->spellh->objects[i]->getNameTranslated()));
|
auto * item = new QListWidgetItem(QString::fromStdString(VLC->spellh->objects[i]->getNameTranslated()));
|
||||||
item->setData(Qt::UserRole, QVariant::fromValue(i));
|
item->setData(Qt::UserRole, QVariant::fromValue(i));
|
||||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||||
item->setCheckState(controller.map()->allowedSpell[i] ? Qt::Checked : Qt::Unchecked);
|
item->setCheckState(controller.map()->allowedSpells[i] ? Qt::Checked : Qt::Unchecked);
|
||||||
ui->listSpells->addItem(item);
|
ui->listSpells->addItem(item);
|
||||||
}
|
}
|
||||||
for(int i = 0; i < controller.map()->allowedArtifact.size(); ++i)
|
for(int i = 0; i < controller.map()->allowedArtifact.size(); ++i)
|
||||||
@@ -525,10 +525,10 @@ void MapSettings::on_pushButton_clicked()
|
|||||||
auto * item = ui->listAbilities->item(i);
|
auto * item = ui->listAbilities->item(i);
|
||||||
controller.map()->allowedAbilities[i] = item->checkState() == Qt::Checked;
|
controller.map()->allowedAbilities[i] = item->checkState() == Qt::Checked;
|
||||||
}
|
}
|
||||||
for(int i = 0; i < controller.map()->allowedSpell.size(); ++i)
|
for(int i = 0; i < controller.map()->allowedSpells.size(); ++i)
|
||||||
{
|
{
|
||||||
auto * item = ui->listSpells->item(i);
|
auto * item = ui->listSpells->item(i);
|
||||||
controller.map()->allowedSpell[i] = item->checkState() == Qt::Checked;
|
controller.map()->allowedSpells[i] = item->checkState() == Qt::Checked;
|
||||||
}
|
}
|
||||||
for(int i = 0; i < controller.map()->allowedArtifact.size(); ++i)
|
for(int i = 0; i < controller.map()->allowedArtifact.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@@ -140,7 +140,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
|
|||||||
{
|
{
|
||||||
if(ins->storedArtifact)
|
if(ins->storedArtifact)
|
||||||
{
|
{
|
||||||
if(!map->allowedSpell[ins->storedArtifact->getId().getNum()])
|
if(!map->allowedSpells[ins->storedArtifact->getId().getNum()])
|
||||||
issues.emplace_back(QString("Spell scroll %1 is prohibited by map settings").arg(ins->getObjectName().c_str()), false);
|
issues.emplace_back(QString("Spell scroll %1 is prohibited by map settings").arg(ins->getObjectName().c_str()), false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -192,7 +192,7 @@ void MapComparer::compareOptions()
|
|||||||
|
|
||||||
checkEqual(actual->allowedAbilities, expected->allowedAbilities);
|
checkEqual(actual->allowedAbilities, expected->allowedAbilities);
|
||||||
checkEqual(actual->allowedArtifact, expected->allowedArtifact);
|
checkEqual(actual->allowedArtifact, expected->allowedArtifact);
|
||||||
checkEqual(actual->allowedSpell, expected->allowedSpell);
|
checkEqual(actual->allowedSpells, expected->allowedSpells);
|
||||||
|
|
||||||
//todo: compareOptions events
|
//todo: compareOptions events
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user