mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Merge pull request #3714 from vcmi/biome_system
Biome system implementation
This commit is contained in:
@@ -37,6 +37,7 @@ void CGameInfo::setFromLib()
|
||||
terrainTypeHandler = VLC->terrainTypeHandler;
|
||||
battleFieldHandler = VLC->battlefieldsHandler;
|
||||
obstacleHandler = VLC->obstacleHandler;
|
||||
//TODO: biomeHandler?
|
||||
}
|
||||
|
||||
const ArtifactService * CGameInfo::artifacts() const
|
||||
|
||||
689
config/biomes.json
Normal file
689
config/biomes.json
Normal file
@@ -0,0 +1,689 @@
|
||||
{
|
||||
"templateSet2":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "crater"
|
||||
},
|
||||
"templates" : ["AVLct1d0", "AVLct2d0", "AVLct3d0", "AVLct4d0", "AVLct5d0", "AVLctrd0"]
|
||||
},
|
||||
"dirtRedFlowers":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLfl1d0", "AVLfl6d0", "AVLfl7d0"]
|
||||
},
|
||||
"dirtLightFlowers":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLfl4d0", "AVLfl5d0"]
|
||||
},
|
||||
"dirtYellowFlowers":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLfl3d0", "AVLfl8d0"]
|
||||
},
|
||||
"dirtPurpleFlowers":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLfl2d0", "AVLfl9d0"]
|
||||
},
|
||||
"templateSet5":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "lake"
|
||||
},
|
||||
"templates" : ["AVLlk1d0", "AVLlk2d0", "AVLlk3d0"]
|
||||
},
|
||||
"templateSet7":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLmd1d0", "AVLmd2d0"]
|
||||
},
|
||||
"templateSet8":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["avlmtdr1", "avlmtdr2", "avlmtdr3", "avlmtdr4", "avlmtdr5", "avlmtdr6", "avlmtdr7", "avlmtdr8"]
|
||||
},
|
||||
"templateSet9":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["avlautr0", "avlautr1", "AVLAUTR2", "AVLAUTR3", "AVLAUTR4", "AVLAUTR5", "AVLautr6", "AVLautr7"]
|
||||
},
|
||||
"templateSet10":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLoc1d0", "AVLoc2d0", "AVLoc3d0"]
|
||||
},
|
||||
"templateSet11":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLPNTR0", "AVLPNTR1", "AVLPNTR2", "AVLPNTR3", "AVLPNTR4", "AVLPNTR5", "AVLpntr6", "AVLpntr7"]
|
||||
},
|
||||
"templateSet13":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AvLRD01", "AvLRD02", "AvLRD04", "AVLrk3d0", "AVLrk5d0"]
|
||||
},
|
||||
"templateSet14":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLsh1d0", "AVLsh2d0", "AVLsh3d0", "AVLsh4d0", "AVLsh5d0", "AVLsh6d0", "AVLsh7d0", "AVLsh8d0"]
|
||||
},
|
||||
"dirtStumps":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AvLdlog", "AvLStm1", "AvLStm2", "AvLStm3"]
|
||||
},
|
||||
"templateSet16":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLtr1d0", "AVLtr2d0", "AVLtr3d0"]
|
||||
},
|
||||
"templateSet17":{
|
||||
"biome":{
|
||||
"terrain" : "dirt",
|
||||
"objectType" : "other"
|
||||
},
|
||||
"templates" : ["avlxdt00", "avlxdt01", "avlxdt02", "avlxdt03", "avlxdt04", "avlxdt05", "avlxdt06", "avlxdt07", "avlxdt08", "avlxdt09", "avlxdt10", "avlxdt11"]
|
||||
},
|
||||
"cactus":{
|
||||
"biome":{
|
||||
"terrain" : "sand",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLca010", "AVLca020", "AVLca030", "AVLca040", "AVLca050", "AVLca060", "AVLca070", "AVLca080", "AVLca090", "AVLca100", "AVLca110", "AVLca120", "AVLca130"]
|
||||
},
|
||||
"sandCraters":{
|
||||
"biome":{
|
||||
"terrain" : "sand",
|
||||
"objectType" : "crater"
|
||||
},
|
||||
"templates" : ["AVLctds0", "AVLspit0"]
|
||||
},
|
||||
"templateSet32":{
|
||||
"biome":{
|
||||
"terrain" : "sand",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["AVLmtds1", "AVLmtds2", "AVLmtds3", "AVLmtds4", "AVLmtds5", "AVLmtds6"]
|
||||
},
|
||||
"templateSet34":{
|
||||
"biome":{
|
||||
"terrain" : "sand",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLdun10", "AVLdun20", "AVLdun30"]
|
||||
},
|
||||
"templateSet36":{
|
||||
"biome":{
|
||||
"terrain" : "sand",
|
||||
"objectType" : "animal"
|
||||
},
|
||||
"templates" : ["AVLskul0"]
|
||||
},
|
||||
"sandPalms":{
|
||||
"biome":{
|
||||
"terrain" : "sand",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLplm10", "AVLplm20", "AVLplm30", "AVLplm40", "AVLplm50"]
|
||||
},
|
||||
"sandYucca":{
|
||||
"biome":{
|
||||
"terrain" : "sand",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLyuc10", "AVLyuc20", "AVLyuc30"]
|
||||
},
|
||||
"templateSet38":{
|
||||
"biome":{
|
||||
"terrain" : "sand",
|
||||
"objectType" : "other"
|
||||
},
|
||||
"templates" : ["avlxds01", "avlxds02", "avlxds03", "avlxds04", "avlxds05", "avlxds06", "avlxds07", "avlxds08", "avlxds09", "avlxds10", "avlxds11", "avlxds12"]
|
||||
},
|
||||
"templateSet50":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "crater"
|
||||
},
|
||||
"templates" : ["AVLct1g0", "AVLct2g0", "AVLct3g0", "AVLct4g0", "AVLct5g0", "AVLct6g0", "AVLctrg0"]
|
||||
},
|
||||
"grassRedFlowers":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLf01g0", "AVLf02g0", "AVLf07g0"]
|
||||
},
|
||||
"grassPurpleFlowers":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLf03g0", "AVLf08g0", "AVLf12g0"]
|
||||
},
|
||||
"grassYellowFlowers":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLf04g0", "AVLf05g0", "AVLf09g0", "AVLf10g0", "AVLf11g0"]
|
||||
},
|
||||
"grassWhiteFlowers":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLf06g0"]
|
||||
},
|
||||
"templateSet53":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "lake"
|
||||
},
|
||||
"templates" : ["AVLlk1g0", "AVLlk2g0", "AVLlk3g0"]
|
||||
},
|
||||
"templateSet54":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AvLdlog"]
|
||||
},
|
||||
"templateSet55":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLmd1g0", "AVLmd2g0"]
|
||||
},
|
||||
"greyMountains":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["AVLmtgn0", "AVLmtgn1", "AVLmtgn2", "AVLmtgn3", "AVLmtgn4", "AVLmtgn5"]
|
||||
},
|
||||
"brownMountains":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["AVLmtgr1", "AVLmtgr2", "AVLmtgr3", "AVLmtgr4", "AVLmtgr5", "AVLmtgr6"]
|
||||
},
|
||||
"greenOakTrees":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLSPTR0", "AVLSPTR1", "AVLSPTR2", "AVLSPTR3", "AVLSPTR4", "AVLSPTR5", "AVLSPTR6", "AVLsptr7", "AVLsptr8"]
|
||||
},
|
||||
"autumnOakTrees":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["avlautr0", "avlautr1", "AVLAUTR2", "AVLAUTR3", "AVLAUTR4", "AVLAUTR5", "AVLautr6", "AVLautr7"]
|
||||
},
|
||||
"templateSet58":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLoc1g0", "AVLoc2g0", "AVLoc3g0"]
|
||||
},
|
||||
"templateSet59":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLPNTR0", "AVLPNTR1", "AVLPNTR2", "AVLPNTR3", "AVLPNTR4", "AVLPNTR5", "AVLpntr6", "AVLpntr7"]
|
||||
},
|
||||
"templateSet61":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AvLRG01", "AvLRG02", "AvLRG03", "AvLRG04", "AvLRG05", "AvLRG06", "AvLRG07", "AvLRG08", "AvLRG09", "AvLRG10", "AvLRG11"]
|
||||
},
|
||||
"templateSet62":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLsh1g0", "AVLsh2g0", "AVLsh3g0", "AVLsh4g0", "AVLsh5g0", "AVLsh6g0"]
|
||||
},
|
||||
"templateSet63":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AvLStm1", "AvLStm2", "AvLStm3"]
|
||||
},
|
||||
"swampTreesOnGrass":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"faction" : "fortress",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLswmp0", "AVLswmp1", "AVLswmp2", "AVLswmp3", "AVLswmp4", "AVLswmp5", "AVLswmp6", "AVLswmp7", "AVLtr1d0", "AVLtr2d0", "AVLtr3d0", "AVLwlw10", "AVLwlw20", "AVLwlw30"]
|
||||
},
|
||||
"templateSet65":{
|
||||
"biome":{
|
||||
"terrain" : "grass",
|
||||
"objectType" : "other"
|
||||
},
|
||||
"templates" : ["avlxgr01", "avlxgr02", "avlxgr03", "avlxgr04", "avlxgr05", "avlxgr06", "avlxgr07", "avlxgr08", "avlxgr09", "avlxgr10", "avlxgr11", "avlxgr12"]
|
||||
},
|
||||
"templateSet77":{
|
||||
"biome":{
|
||||
"terrain" : "snow",
|
||||
"objectType" : "crater"
|
||||
},
|
||||
"templates" : ["AVLctsn0"]
|
||||
},
|
||||
"templateSet78":{
|
||||
"biome":{
|
||||
"terrain" : "snow",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLd1sn0", "AVLd2sn0", "AVLd3sn0", "AVLd4sn0", "AVLd5sn0", "AVLd6sn0", "AVLd7sn0", "AVLd8sn0", "AVLd9sn0", "AVLddsn0", "AVLddsn1", "AVLddsn2", "AVLddsn3", "AVLddsn4", "AVLddsn5", "AVLddsn6", "AVLddsn7"]
|
||||
},
|
||||
"templateSet79":{
|
||||
"biome":{
|
||||
"terrain" : "snow",
|
||||
"objectType" : "lake"
|
||||
},
|
||||
"templates" : ["AVLflk10", "AVLflk20", "AVLflk30"]
|
||||
},
|
||||
"templateSet81":{
|
||||
"biome":{
|
||||
"terrain" : "snow",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["AVLmtsn1", "AVLmtsn2", "AVLmtsn3", "AVLmtsn4", "AVLmtsn5", "AVLmtsn6"]
|
||||
},
|
||||
"templateSet82":{
|
||||
"biome":{
|
||||
"terrain" : "snow",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLo1sn0", "AVLo2sn0", "AVLo3sn0"]
|
||||
},
|
||||
"templateSet83":{
|
||||
"biome":{
|
||||
"terrain" : "snow",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLSNTR0", "AVLSNTR1", "AVLSNTR2", "AVLSNTR3", "AVLSNTR4", "AVLSNTR5", "AVLsntr6", "AVLsntr7"]
|
||||
},
|
||||
"templateSet85":{
|
||||
"biome":{
|
||||
"terrain" : "snow",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLr1sn0", "AVLr2sn0", "AVLr3sn0", "AVLr4sn0", "AVLr5sn0", "AVLr6sn0", "AVLr7sn0", "AVLr8sn0"]
|
||||
},
|
||||
"templateSet86":{
|
||||
"biome":{
|
||||
"terrain" : "snow",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLs1sn0", "AVLs2sn0", "AVLs3sn0"]
|
||||
},
|
||||
"templateSet87":{
|
||||
"biome":{
|
||||
"terrain" : "snow",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLp1sn0", "AVLp2sn0"]
|
||||
},
|
||||
"templateSet99":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "crater"
|
||||
},
|
||||
"templates" : ["AVLctrs0"]
|
||||
},
|
||||
"templateSet100":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLdead0", "AVLdead1", "AVLdead2", "AVLdead3", "AVLdead4", "AVLdead5", "AVLdead6", "AVLdead7", "AVLdt1s0", "AVLdt2s0", "AVLdt3s0", "AVLswp60", "AVLswp70"]
|
||||
},
|
||||
"templateSet102":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "lake"
|
||||
},
|
||||
"templates" : ["AVLlk1s0", "AVLlk2s0", "AVLlk3s0", "AVLswp50"]
|
||||
},
|
||||
"templateSet103":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLman10", "AVLman20", "AVLman30", "AVLman40", "AVLman50"]
|
||||
},
|
||||
"templateSet104":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLmoss0"]
|
||||
},
|
||||
"templateSet105":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["AVLmtsw1", "AVLmtsw2", "AVLmtsw3", "AVLmtsw4", "AVLmtsw5", "AVLmtsw6"]
|
||||
},
|
||||
"swampTrees":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLSPTR0", "AVLSPTR1", "AVLSPTR2", "AVLSPTR3", "AVLSPTR4", "AVLSPTR5", "AVLSPTR6", "AVLsptr7", "AVLsptr8"]
|
||||
},
|
||||
"templateSet108":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLrk1s0", "AVLrk2s0", "AVLrk3s0", "AVLrk4s0"]
|
||||
},
|
||||
"templateSet109":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLs01s0", "AVLs02s0", "AVLs03s0", "AVLs04s0", "AVLs05s0", "AVLs06s0", "AVLs07s0", "AVLs08s0", "AVLs09s0", "AVLs10s0", "AVLs11s0", "AVLswp10", "AVLswp20", "AVLswp30", "AVLswp40"]
|
||||
},
|
||||
"floodedPalms":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLswmp0", "AVLswmp1", "AVLswmp2", "AVLswmp3", "AVLswmp4", "AVLswmp5", "AVLswmp6", "AVLswmp7"]
|
||||
},
|
||||
"swampTrees2":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLtr1d0", "AVLtr2d0", "AVLtr3d0", "AVLwlw10", "AVLwlw20", "AVLwlw30"]
|
||||
},
|
||||
"swampPalms":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["avlswtr0", "avlswtr1", "avlswtr2", "avlswtr3", "avlswtr4", "avlswtr5", "avlswtr6", "avlswtr7", "avlswtr8", "avlswtr9"]
|
||||
},
|
||||
"swampSinglePalms":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["avlswt00", "avlswt01", "avlswt02", "avlswt03", "avlswt04", "avlswt05", "avlswt06", "avlswt07", "avlswt08", "avlswt09", "avlswt10", "avlswt11", "avlswt12", "avlswt13", "avlswt14", "avlswt15", "avlswt16", "avlswt17", "avlswt18", "avlswt19"]
|
||||
},
|
||||
"templateSet112":{
|
||||
"biome":{
|
||||
"terrain" : "swamp",
|
||||
"objectType" : "other"
|
||||
},
|
||||
"templates" : ["avlxsw01", "avlxsw02", "avlxsw03", "avlxsw04", "avlxsw05", "avlxsw06", "avlxsw07", "avlxsw08", "avlxsw09", "avlxsw10", "avlxsw11"]
|
||||
},
|
||||
"templateSet124":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLca1r0", "AVLca2r0"]
|
||||
},
|
||||
"roughCraters":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "crater"
|
||||
},
|
||||
"templates" : ["AVLglly0", "AVLct1r0", "AVLct2r0", "AVLct3r0", "AVLct4r0", "AVLct5r0", "AVLct6r0", "AVLct7r0", "AVLct8r0", "AVLct9r0", "AVLctrr0"]
|
||||
},
|
||||
"templateSet129":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLmd1r0", "AVLmd2r0", "AVLmd3r0"]
|
||||
},
|
||||
"templateSet130":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["avlmtrf1", "avlmtrf2", "avlmtrf3", "avlmtrf4", "avlmtrf5", "avlmtrf6"]
|
||||
},
|
||||
"templateSet131":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLoc1r0", "AVLoc2r0", "AVLoc3r0", "AVLoc4r0"]
|
||||
},
|
||||
"templateSet133":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["avlbuzr0", "AVLr02r0", "AVLr03r0", "AVLr04r0", "AVLr06r0", "AVLr07r0", "AVLr08r0", "AVLr09r0", "AVLr10r0", "AVLr11r0", "AVLr12r0", "AVLr13r0", "AVLr14r0", "AVLr15r0", "AvLRR01", "AvLRR05"]
|
||||
},
|
||||
"templateSet134":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLsh1r0", "AVLsh2r0", "AVLsh3r0", "avlsh4r0", "avlsh5r0", "avlsh6r0", "avlsh7r0", "avlsh8r0", "avlsh9r0"]
|
||||
},
|
||||
"templateSet135":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "animal"
|
||||
},
|
||||
"templates" : ["AVLskul0"]
|
||||
},
|
||||
"roughStumps":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AvLdlog", "AvLStm1", "AvLStm2", "AvLStm3"]
|
||||
},
|
||||
"roughSmallTree":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLroug0", "AVLroug1", "AVLroug2"]
|
||||
},
|
||||
"roughYucca":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLyuc10", "AVLyuc20", "AVLyuc30"]
|
||||
},
|
||||
"roughLake":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "lake"
|
||||
},
|
||||
"templates" : ["AVLlk1r"]
|
||||
},
|
||||
"templateSet139":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "other"
|
||||
},
|
||||
"templates" : ["AVLtRo00", "AVLtRo01", "AVLtRo02", "AVLtRo03", "AVLtRo04", "AVLtRo05", "AVLtRo06", "AVLtRo07", "AVLtRo08", "AVLtRo09", "AVLtRo10", "AVLtRo11", "AVLtRo12", "AVLtrRo0", "AVLtrRo1", "AVLtrRo2", "AVLtrRo3", "AVLtrRo4", "AVLtrRo5", "AVLtrRo6", "AVLtrRo7"]
|
||||
},
|
||||
"templateSet140":{
|
||||
"biome":{
|
||||
"terrain" : "rough",
|
||||
"objectType" : "other"
|
||||
},
|
||||
"templates" : ["avlxro01", "avlxro02", "avlxro03", "avlxro04", "avlxro05", "avlxro06", "avlxro07", "avlxro08", "avlxro09", "avlxro10", "avlxro11", "avlxro12"]
|
||||
},
|
||||
"templateSet152":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "crater"
|
||||
},
|
||||
"templates" : ["AVLct1u0", "AVLct2u0", "AVLct3u0", "AVLct4u0", "AVLct5u0"]
|
||||
},
|
||||
"templateSet153":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLdead0", "AVLdead1", "AVLdead2", "AVLdead3", "AVLdead4", "AVLdead5", "AVLdead6", "AVLdead7"]
|
||||
},
|
||||
"templateSet155":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "lake"
|
||||
},
|
||||
"templates" : ["AVLlk1u0", "AVLlk2u0", "AVLlk3u0"]
|
||||
},
|
||||
"templateSet156":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "lake"
|
||||
},
|
||||
"templates" : ["AVLlv1u0", "AVLlv2u0", "AVLlv3u0"]
|
||||
},
|
||||
"templateSet157":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "lake"
|
||||
},
|
||||
"templates" : ["AVLllk10", "AVLllk20"]
|
||||
},
|
||||
"templateSet158":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "plant"
|
||||
},
|
||||
"templates" : ["AVLms010", "AVLms020", "AVLms030", "AVLms040", "AVLms050", "AVLms060", "AVLms070", "AVLms080", "AVLms090", "AVLms100", "AVLms110", "AVLms120"]
|
||||
},
|
||||
"templateSet159":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["AVLmtsb0", "AVLmtsb1", "AVLmtsb2", "AVLmtsb3", "AVLmtsb4", "AVLmtsb5"]
|
||||
},
|
||||
"templateSet160":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLoc1u0", "AVLoc2u0", "AVLoc3u0", "AVLoc4u0"]
|
||||
},
|
||||
"templateSet162":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLr01u0", "AVLr02u0", "AVLr03u0", "AVLr04u0", "AVLr05u0", "AVLr06u0", "AVLr07u0", "AVLr08u0", "AVLr09u0", "AVLr10u0", "AVLr11u0", "AVLr12u0", "AVLr13u0", "AVLr14u0", "AVLr15u0", "AVLr16u0", "AVLstg10", "AVLstg20", "AVLstg30", "AVLstg40", "AVLstg50", "AVLstg60"]
|
||||
},
|
||||
"templateSet163":{
|
||||
"biome":{
|
||||
"terrain" : "subterra",
|
||||
"objectType" : "other"
|
||||
},
|
||||
"templates" : ["avlxsu01", "avlxsu02", "avlxsu03", "avlxsu04", "avlxsu05", "avlxsu06", "avlxsu07", "avlxsu08", "avlxsu09", "avlxsu10", "avlxsu11", "avlxsu12"]
|
||||
},
|
||||
"lavaChasm":{
|
||||
"biome":{
|
||||
"terrain" : "lava",
|
||||
"objectType" : "crater"
|
||||
},
|
||||
"templates" : ["AVLc10l0", "AVLc11l0", "AVLc12l0", "AVLc13l0", "AVLc14l0", "AVLct1l0", "AVLct2l0", "AVLct3l0", "AVLct4l0", "AVLct5l0", "AVLct6l0", "AVLct7l0", "AVLct8l0", "AVLct9l0", "AVLctrl0"]
|
||||
},
|
||||
"lavaDeadTree":{
|
||||
"biome":{
|
||||
"terrain" : "lava",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLdead0", "AVLdead1", "AVLdead2", "AVLdead3", "AVLdead4", "AVLdead5", "AVLdead6", "AVLdead7"]
|
||||
},
|
||||
"lavaLake":{
|
||||
"biome":{
|
||||
"terrain" : "lava",
|
||||
"objectType" : "lake"
|
||||
},
|
||||
"templates" : ["AVLlav10", "AVLlav20", "AVLlav30", "AVLlav40", "AVLlav50", "AVLlav60", "AVLlav70", "AVLlav80", "AVLlav90", "AVLlv100", "AVLlv110", "AVLlv120", "AVLlv130", "AVLlv140", "AVLlv150", "AVLlv160", "AVLlv170", "AVLlv180", "AVLlv190", "AVLlv200", "AVLlv210", "AVLlv220", "AVLlv230", "AVLlv240", "AVLlv250", "AVLlv260"]
|
||||
},
|
||||
"templateSet180":{
|
||||
"biome":{
|
||||
"terrain" : "lava",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["AVLmtvo1", "AVLmtvo2", "AVLmtvo3", "AVLmtvo4", "AVLmtvo5", "AVLmtvo6"]
|
||||
},
|
||||
"volcanos":{
|
||||
"biome":{
|
||||
"terrain" : "lava",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["AVLvol10", "AVLvol20", "AVLvol30", "AVLvol40", "AVLvol50"]
|
||||
},
|
||||
"templateSet192":{
|
||||
"biome":{
|
||||
"terrain" : "water",
|
||||
"objectType" : "tree"
|
||||
},
|
||||
"templates" : ["AVLklp10", "AVLklp20"]
|
||||
},
|
||||
"templateSet193":{
|
||||
"biome":{
|
||||
"terrain" : "water",
|
||||
"objectType" : "rock"
|
||||
},
|
||||
"templates" : ["AVLrk1w0", "AVLrk2w0", "AVLrk3w0", "AVLrk4w0"]
|
||||
},
|
||||
"templateSet194":{
|
||||
"biome":{
|
||||
"terrain" : "water",
|
||||
"objectType" : "mountain"
|
||||
},
|
||||
"templates" : ["AVLref10", "AVLref20", "AVLref30", "AVLref40", "AVLref50", "AVLref60"]
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,11 @@
|
||||
"config/objects/witchHut.json"
|
||||
],
|
||||
|
||||
"biomes" :
|
||||
[
|
||||
"config/biomes.json"
|
||||
],
|
||||
|
||||
"artifacts" :
|
||||
[
|
||||
"config/artifacts.json"
|
||||
|
||||
67
config/schemas/biome.json
Normal file
67
config/schemas/biome.json
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"type" : "object",
|
||||
"$schema" : "http://json-schema.org/draft-04/schema",
|
||||
"title" : "VCMI map obstacle set format",
|
||||
"description" : "Description of map object set, used only as sub-schema of object",
|
||||
"required" : ["biome", "templates"],
|
||||
"additionalProperties" : true, // may have type-dependant properties
|
||||
"properties" : {
|
||||
"biome" : {
|
||||
"type" : "object",
|
||||
"properties": {
|
||||
"objectType" : {
|
||||
"type" : "string",
|
||||
"enmum": ["mountain", "tree", "lake", "crater", "rock", "plant", "structure", "animal", "other"],
|
||||
"description" : "Type of the obstacle set"
|
||||
},
|
||||
"terrain" : {
|
||||
"anyOf": [
|
||||
{
|
||||
"type" : "string",
|
||||
"description" : "Terrain of the obstacle set"
|
||||
},
|
||||
{
|
||||
"type" : "array",
|
||||
"items" : { "type" : "string" },
|
||||
"description" : "Terrains of the obstacle set"
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
"faction" : {
|
||||
"anyOf": [
|
||||
{
|
||||
"type" : "string",
|
||||
"description" : "Faction of the zone"
|
||||
},
|
||||
{
|
||||
"type" : "array",
|
||||
"items" : { "type" : "string" },
|
||||
"description" : "Factions of the zone"
|
||||
}
|
||||
]
|
||||
},
|
||||
"alignment" : {
|
||||
"anyOf": [
|
||||
{
|
||||
"type" : "string",
|
||||
"enum" : ["good", "evil", "neutral"],
|
||||
"description" : "Alignment of faction of the zone"
|
||||
},
|
||||
{
|
||||
"type" : "array",
|
||||
"items" : { "type" : "string" },
|
||||
"description" : "Alignment of faction of the zone"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"templates" : {
|
||||
"type" : "array",
|
||||
"items" : { "type" : "string" },
|
||||
"description" : "Object templates of the obstacle set"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,6 +255,11 @@
|
||||
"description" : "List of configuration files for objects",
|
||||
"items" : { "type" : "string", "format" : "textFile" }
|
||||
},
|
||||
"biomes" : {
|
||||
"type" : "array",
|
||||
"description" : "List of configuration files for biomes",
|
||||
"items" : { "type" : "string", "format" : "textFile" }
|
||||
},
|
||||
"bonuses" : {
|
||||
"type" : "array",
|
||||
"description" : "List of configuration files for bonuses",
|
||||
|
||||
@@ -73,6 +73,7 @@ Other:
|
||||
- [Terrain](Entities_Format/Terrain_Format.md)
|
||||
- [River](Entities_Format/River_Format.md)
|
||||
- [Road](Entities_Format/Road_Format.md)
|
||||
- [Biome](Entities_Format/Biome_Format.md)
|
||||
- [Battlefield](Entities_Format/Battlefield_Format.md)
|
||||
- [Battle Obstacle](Entities_Format/Battle_Obstacle_Format.md)
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ set(lib_MAIN_SRCS
|
||||
mapObjects/IObjectInterface.cpp
|
||||
mapObjects/MiscObjects.cpp
|
||||
mapObjects/ObjectTemplate.cpp
|
||||
mapObjects/ObstacleSetHandler.cpp
|
||||
|
||||
mapping/CDrawRoadsOperation.cpp
|
||||
mapping/CMap.cpp
|
||||
@@ -482,6 +483,7 @@ set(lib_MAIN_HEADERS
|
||||
mapObjects/MapObjects.h
|
||||
mapObjects/MiscObjects.h
|
||||
mapObjects/ObjectTemplate.h
|
||||
mapObjects/ObstacleSetHandler.h
|
||||
|
||||
mapping/CDrawRoadsOperation.h
|
||||
mapping/CMapDefines.h
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "rmg/CRmgTemplateStorage.h"
|
||||
#include "mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "mapObjects/CObjectHandler.h"
|
||||
#include "mapObjects/ObstacleSetHandler.h"
|
||||
#include "mapping/CMapEditManager.h"
|
||||
#include "ScriptHandler.h"
|
||||
#include "BattleFieldHandler.h"
|
||||
@@ -223,6 +224,7 @@ void LibClasses::init(bool onlyEssential)
|
||||
createHandler(arth, "Artifact", pomtime);
|
||||
createHandler(creh, "Creature", pomtime);
|
||||
createHandler(townh, "Town", pomtime);
|
||||
createHandler(biomeHandler, "Obstacle set", pomtime);
|
||||
createHandler(objh, "Object", pomtime);
|
||||
createHandler(objtypeh, "Object types information", pomtime);
|
||||
createHandler(spellh, "Spell", pomtime);
|
||||
|
||||
@@ -23,6 +23,7 @@ class CSkillHandler;
|
||||
class CBuildingHandler;
|
||||
class CObjectHandler;
|
||||
class CObjectClassesHandler;
|
||||
class ObstacleSetHandler;
|
||||
class CTownHandler;
|
||||
class CGeneralTextHandler;
|
||||
class CModHandler;
|
||||
@@ -85,6 +86,7 @@ public:
|
||||
std::shared_ptr<CCreatureHandler> creh;
|
||||
std::shared_ptr<CSpellHandler> spellh;
|
||||
std::shared_ptr<CSkillHandler> skillh;
|
||||
// TODO: Remove ObjectHandler altogether?
|
||||
std::shared_ptr<CObjectHandler> objh;
|
||||
std::shared_ptr<CObjectClassesHandler> objtypeh;
|
||||
std::shared_ptr<CTownHandler> townh;
|
||||
@@ -99,6 +101,7 @@ public:
|
||||
std::shared_ptr<BattleFieldHandler> battlefieldsHandler;
|
||||
std::shared_ptr<ObstacleHandler> obstacleHandler;
|
||||
std::shared_ptr<GameSettings> settingsHandler;
|
||||
std::shared_ptr<ObstacleSetHandler> biomeHandler;
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
std::shared_ptr<scripting::ScriptHandler> scriptHandler;
|
||||
|
||||
@@ -457,7 +457,47 @@ public:
|
||||
WHIRLPOOL = 111,
|
||||
WINDMILL = 112,
|
||||
WITCH_HUT = 113,
|
||||
BRUSH = 114, // TODO: How does it look like?
|
||||
BUSH = 115,
|
||||
CACTUS = 116,
|
||||
CANYON = 117,
|
||||
CRATER = 118,
|
||||
DEAD_VEGETATION = 119,
|
||||
FLOWERS = 120,
|
||||
FROZEN_LAKE = 121,
|
||||
HEDGE = 122,
|
||||
HILL = 123,
|
||||
HOLE = 124,
|
||||
KELP = 125,
|
||||
LAKE = 126,
|
||||
LAVA_FLOW = 127,
|
||||
LAVA_LAKE = 128,
|
||||
MUSHROOMS = 129,
|
||||
LOG = 130,
|
||||
MANDRAKE = 131,
|
||||
MOSS = 132,
|
||||
MOUND = 133,
|
||||
MOUNTAIN = 134,
|
||||
OAK_TREES = 135,
|
||||
OUTCROPPING = 136,
|
||||
PINE_TREES = 137,
|
||||
PLANT = 138,
|
||||
RIVER_DELTA = 143,
|
||||
ROCK = 147,
|
||||
SAND_DUNE = 148,
|
||||
SAND_PIT = 149,
|
||||
SHRUB = 150,
|
||||
SKULL = 151,
|
||||
STALAGMITE = 152,
|
||||
STUMP = 153,
|
||||
TAR_PIT = 154,
|
||||
TREES = 155,
|
||||
VINE = 156,
|
||||
VOLCANIC_VENT = 157,
|
||||
VOLCANO = 158,
|
||||
WILLOW_TREES = 159,
|
||||
YUCCA_TREES = 160,
|
||||
REEF = 161,
|
||||
RANDOM_MONSTER_L5 = 162,
|
||||
RANDOM_MONSTER_L6 = 163,
|
||||
RANDOM_MONSTER_L7 = 164,
|
||||
|
||||
@@ -13,7 +13,8 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
enum class EAlignment : int8_t
|
||||
{
|
||||
GOOD,
|
||||
ANY = -1,
|
||||
GOOD = 0,
|
||||
EVIL,
|
||||
NEUTRAL
|
||||
};
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "../mapObjects/MiscObjects.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../mapObjects/CGTownInstance.h"
|
||||
#include "../mapObjects/ObstacleSetHandler.h"
|
||||
#include "../modding/IdentifierStorage.h"
|
||||
#include "../modding/CModHandler.h"
|
||||
#include "../modding/ModScope.h"
|
||||
@@ -211,10 +212,28 @@ TObjectTypeHandler CObjectClassesHandler::loadSubObjectFromJson(const std::strin
|
||||
createdObject->subtype = index;
|
||||
createdObject->init(entry);
|
||||
|
||||
bool staticObject = createdObject->isStaticObject();
|
||||
if (staticObject)
|
||||
{
|
||||
for (auto & templ : createdObject->getTemplates())
|
||||
{
|
||||
// Register templates for new objects from mods
|
||||
VLC->biomeHandler->addTemplate(scope, templ->stringID, templ);
|
||||
}
|
||||
}
|
||||
|
||||
auto range = legacyTemplates.equal_range(std::make_pair(obj->id, index));
|
||||
for (auto & templ : boost::make_iterator_range(range.first, range.second))
|
||||
{
|
||||
if (staticObject)
|
||||
{
|
||||
// Register legacy templates as "core"
|
||||
// FIXME: Why does it clear stringID?
|
||||
VLC->biomeHandler->addTemplate("core", templ.second->stringID, templ.second);
|
||||
}
|
||||
|
||||
createdObject->addTemplate(templ.second);
|
||||
|
||||
}
|
||||
legacyTemplates.erase(range.first, range.second);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "../mapObjects/MiscObjects.h"
|
||||
#include "../mapObjects/CGCreature.h"
|
||||
#include "../mapObjects/ObstacleSetHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@@ -33,6 +34,7 @@ class CObstacleConstructor : public CDefaultObjectTypeHandler<CGObjectInstance>
|
||||
{
|
||||
public:
|
||||
bool isStaticObject() override;
|
||||
|
||||
};
|
||||
|
||||
class CreatureInstanceConstructor : public CDefaultObjectTypeHandler<CGCreature>
|
||||
|
||||
470
lib/mapObjects/ObstacleSetHandler.cpp
Normal file
470
lib/mapObjects/ObstacleSetHandler.cpp
Normal file
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* ObstacleSetHandler.cpp, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "ObstacleSetHandler.h"
|
||||
|
||||
#include "../modding/IdentifierStorage.h"
|
||||
#include "../constants/StringConstants.h"
|
||||
#include "../TerrainHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
ObstacleSet::ObstacleSet():
|
||||
type(INVALID),
|
||||
allowedTerrains({TerrainId::NONE})
|
||||
{
|
||||
}
|
||||
|
||||
ObstacleSet::ObstacleSet(EObstacleType type, TerrainId terrain):
|
||||
type(type),
|
||||
allowedTerrains({terrain})
|
||||
{
|
||||
}
|
||||
|
||||
void ObstacleSet::addObstacle(std::shared_ptr<const ObjectTemplate> obstacle)
|
||||
{
|
||||
obstacles.push_back(obstacle);
|
||||
}
|
||||
|
||||
void ObstacleSet::removeEmptyTemplates()
|
||||
{
|
||||
vstd::erase_if(obstacles, [](const std::shared_ptr<const ObjectTemplate> &tmpl)
|
||||
{
|
||||
if (tmpl->getBlockedOffsets().empty())
|
||||
{
|
||||
logMod->warn("Obstacle template %s blocks no tiles, removing it", tmpl->stringID);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
ObstacleSetFilter::ObstacleSetFilter(std::vector<ObstacleSet::EObstacleType> allowedTypes, TerrainId terrain = TerrainId::ANY_TERRAIN, FactionID faction = FactionID::ANY, EAlignment alignment = EAlignment::ANY):
|
||||
allowedTypes(allowedTypes),
|
||||
terrain(terrain),
|
||||
faction(faction),
|
||||
alignment(alignment)
|
||||
{
|
||||
}
|
||||
|
||||
ObstacleSetFilter::ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain = TerrainId::ANY_TERRAIN, FactionID faction = FactionID::ANY, EAlignment alignment = EAlignment::ANY):
|
||||
allowedTypes({allowedType}),
|
||||
terrain(terrain),
|
||||
faction(faction),
|
||||
alignment(alignment)
|
||||
{
|
||||
}
|
||||
|
||||
bool ObstacleSetFilter::filter(const ObstacleSet &set) const
|
||||
{
|
||||
if (terrain != TerrainId::ANY_TERRAIN && !vstd::contains(set.getTerrains(), terrain))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (faction != FactionID::ANY)
|
||||
{
|
||||
auto factions = set.getFactions();
|
||||
if (!factions.empty() && !vstd::contains(factions, faction))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Also check specific factions
|
||||
if (alignment != EAlignment::ANY)
|
||||
{
|
||||
auto alignments = set.getAlignments();
|
||||
if (!alignments.empty() && !vstd::contains(alignments, alignment))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TerrainId ObstacleSetFilter::getTerrain() const
|
||||
{
|
||||
return terrain;
|
||||
}
|
||||
|
||||
std::set<TerrainId> ObstacleSet::getTerrains() const
|
||||
{
|
||||
return allowedTerrains;
|
||||
}
|
||||
|
||||
void ObstacleSet::setTerrain(TerrainId terrain)
|
||||
{
|
||||
this->allowedTerrains = {terrain};
|
||||
}
|
||||
|
||||
void ObstacleSet::setTerrains(const std::set<TerrainId> & terrains)
|
||||
{
|
||||
this->allowedTerrains = terrains;
|
||||
}
|
||||
|
||||
void ObstacleSet::addTerrain(TerrainId terrain)
|
||||
{
|
||||
this->allowedTerrains.insert(terrain);
|
||||
}
|
||||
|
||||
std::set<FactionID> ObstacleSet::getFactions() const
|
||||
{
|
||||
return allowedFactions;
|
||||
}
|
||||
|
||||
void ObstacleSet::addFaction(FactionID faction)
|
||||
{
|
||||
this->allowedFactions.insert(faction);
|
||||
}
|
||||
|
||||
void ObstacleSet::addAlignment(EAlignment alignment)
|
||||
{
|
||||
this->allowedAlignments.insert(alignment);
|
||||
}
|
||||
|
||||
std::set<EAlignment> ObstacleSet::getAlignments() const
|
||||
{
|
||||
return allowedAlignments;
|
||||
}
|
||||
|
||||
ObstacleSet::EObstacleType ObstacleSet::getType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
void ObstacleSet::setType(EObstacleType type)
|
||||
{
|
||||
this->type = type;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<const ObjectTemplate>> ObstacleSet::getObstacles() const
|
||||
{
|
||||
return obstacles;
|
||||
}
|
||||
|
||||
ObstacleSet::EObstacleType ObstacleSetHandler::convertObstacleClass(MapObjectID id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case Obj::MOUNTAIN:
|
||||
case Obj::VOLCANIC_VENT:
|
||||
case Obj::VOLCANO:
|
||||
case Obj::REEF:
|
||||
return ObstacleSet::MOUNTAINS;
|
||||
case Obj::OAK_TREES:
|
||||
case Obj::PINE_TREES:
|
||||
case Obj::TREES:
|
||||
case Obj::DEAD_VEGETATION:
|
||||
case Obj::HEDGE:
|
||||
case Obj::KELP:
|
||||
case Obj::WILLOW_TREES:
|
||||
case Obj::YUCCA_TREES:
|
||||
return ObstacleSet::TREES;
|
||||
case Obj::FROZEN_LAKE:
|
||||
case Obj::LAKE:
|
||||
case Obj::LAVA_FLOW:
|
||||
case Obj::LAVA_LAKE:
|
||||
return ObstacleSet::LAKES;
|
||||
case Obj::CANYON:
|
||||
case Obj::CRATER:
|
||||
case Obj::SAND_PIT:
|
||||
case Obj::TAR_PIT:
|
||||
return ObstacleSet::CRATERS;
|
||||
case Obj::HILL:
|
||||
case Obj::MOUND:
|
||||
case Obj::OUTCROPPING:
|
||||
case Obj::ROCK:
|
||||
case Obj::SAND_DUNE:
|
||||
case Obj::STALAGMITE:
|
||||
return ObstacleSet::ROCKS;
|
||||
case Obj::BUSH:
|
||||
case Obj::CACTUS:
|
||||
case Obj::FLOWERS:
|
||||
case Obj::MUSHROOMS:
|
||||
case Obj::LOG:
|
||||
case Obj::MANDRAKE:
|
||||
case Obj::MOSS:
|
||||
case Obj::PLANT:
|
||||
case Obj::SHRUB:
|
||||
case Obj::STUMP:
|
||||
case Obj::VINE:
|
||||
return ObstacleSet::PLANTS;
|
||||
case Obj::SKULL:
|
||||
return ObstacleSet::ANIMALS;
|
||||
default:
|
||||
return ObstacleSet::OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
ObstacleSet::EObstacleType ObstacleSet::typeFromString(const std::string &str)
|
||||
{
|
||||
static const std::map<std::string, EObstacleType> OBSTACLE_TYPE_NAMES =
|
||||
{
|
||||
{"mountain", MOUNTAINS},
|
||||
{"tree", TREES},
|
||||
{"lake", LAKES},
|
||||
{"crater", CRATERS},
|
||||
{"rock", ROCKS},
|
||||
{"plant", PLANTS},
|
||||
{"structure", STRUCTURES},
|
||||
{"animal", ANIMALS},
|
||||
{"other", OTHER}
|
||||
};
|
||||
|
||||
if (OBSTACLE_TYPE_NAMES.find(str) != OBSTACLE_TYPE_NAMES.end())
|
||||
{
|
||||
return OBSTACLE_TYPE_NAMES.at(str);
|
||||
}
|
||||
|
||||
// TODO: How to handle that?
|
||||
throw std::runtime_error("Invalid obstacle type: " + str);
|
||||
}
|
||||
|
||||
std::string ObstacleSet::toString() const
|
||||
{
|
||||
static const std::map<EObstacleType, std::string> OBSTACLE_TYPE_STRINGS =
|
||||
{
|
||||
{MOUNTAINS, "mountain"},
|
||||
{TREES, "tree"},
|
||||
{LAKES, "lake"},
|
||||
{CRATERS, "crater"},
|
||||
{ROCKS, "rock"},
|
||||
{PLANTS, "plant"},
|
||||
{STRUCTURES, "structure"},
|
||||
{ANIMALS, "animal"},
|
||||
{OTHER, "other"}
|
||||
};
|
||||
|
||||
return OBSTACLE_TYPE_STRINGS.at(type);
|
||||
}
|
||||
|
||||
std::vector<ObstacleSet::EObstacleType> ObstacleSetFilter::getAllowedTypes() const
|
||||
{
|
||||
return allowedTypes;
|
||||
}
|
||||
|
||||
void ObstacleSetFilter::setType(ObstacleSet::EObstacleType type)
|
||||
{
|
||||
allowedTypes = {type};
|
||||
}
|
||||
|
||||
void ObstacleSetFilter::setTypes(std::vector<ObstacleSet::EObstacleType> types)
|
||||
{
|
||||
this->allowedTypes = types;
|
||||
}
|
||||
|
||||
std::vector<JsonNode> ObstacleSetHandler::loadLegacyData()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void ObstacleSetHandler::loadObject(std::string scope, std::string name, const JsonNode & data)
|
||||
{
|
||||
auto os = loadFromJson(scope, data, name, biomes.size());
|
||||
if(os)
|
||||
{
|
||||
addObstacleSet(os);
|
||||
// TODO: Define some const array of object types ("biome" etc.)
|
||||
VLC->identifiersHandler->registerObject(scope, "biome", name, biomes.back()->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
logMod->error("Failed to load obstacle set: %s", name);
|
||||
}
|
||||
}
|
||||
|
||||
void ObstacleSetHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index)
|
||||
{
|
||||
//Unused
|
||||
loadObject(scope, name, data);
|
||||
}
|
||||
|
||||
std::shared_ptr<ObstacleSet> ObstacleSetHandler::loadFromJson(const std::string & scope, const JsonNode & json, const std::string & name, size_t index)
|
||||
{
|
||||
auto os = std::make_shared<ObstacleSet>();
|
||||
os->id = index;
|
||||
|
||||
auto biome = json["biome"].Struct();
|
||||
os->setType(ObstacleSet::typeFromString(biome["objectType"].String()));
|
||||
|
||||
// TODO: Handle any (every) terrain option
|
||||
|
||||
if (biome["terrain"].isString())
|
||||
{
|
||||
auto terrainName = biome["terrain"].String();
|
||||
|
||||
VLC->identifiers()->requestIdentifier(scope, "terrain", terrainName, [os](si32 id)
|
||||
{
|
||||
os->setTerrain(TerrainId(id));
|
||||
});
|
||||
}
|
||||
else if (biome["terrain"].isVector())
|
||||
{
|
||||
auto terrains = biome["terrain"].Vector();
|
||||
|
||||
for (const auto & terrain : terrains)
|
||||
{
|
||||
VLC->identifiers()->requestIdentifier(scope, "terrain", terrain.String(), [os](si32 id)
|
||||
{
|
||||
os->addTerrain(TerrainId(id));
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logMod->error("No terrain specified for obstacle set %s", name);
|
||||
}
|
||||
|
||||
auto handleFaction = [os, scope](const std::string & str)
|
||||
{
|
||||
VLC->identifiers()->requestIdentifier(scope, "faction", str, [os](si32 id)
|
||||
{
|
||||
os->addFaction(FactionID(id));
|
||||
});
|
||||
};
|
||||
|
||||
if (biome["faction"].isString())
|
||||
{
|
||||
auto factionName = biome["faction"].String();
|
||||
handleFaction(factionName);
|
||||
}
|
||||
else if (biome["faction"].isVector())
|
||||
{
|
||||
auto factions = biome["faction"].Vector();
|
||||
for (const auto & node : factions)
|
||||
{
|
||||
handleFaction(node.String());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Move this parser to some utils
|
||||
auto parseAlignment = [](const std::string & str) ->EAlignment
|
||||
{
|
||||
int alignment = vstd::find_pos(GameConstants::ALIGNMENT_NAMES, str);
|
||||
if (alignment == -1)
|
||||
{
|
||||
logMod->error("Incorrect alignment: ", str);
|
||||
return EAlignment::ANY;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<EAlignment>(alignment);
|
||||
}
|
||||
};
|
||||
|
||||
if (biome["alignment"].isString())
|
||||
{
|
||||
os->addAlignment(parseAlignment(biome["alignment"].String()));
|
||||
}
|
||||
else if (biome["alignment"].isVector())
|
||||
{
|
||||
auto alignments = biome["alignment"].Vector();
|
||||
for (const auto & node : alignments)
|
||||
{
|
||||
os->addAlignment(parseAlignment(node.String()));
|
||||
}
|
||||
}
|
||||
|
||||
auto templates = json["templates"].Vector();
|
||||
for (const auto & node : templates)
|
||||
{
|
||||
logMod->trace("Registering obstacle template: %s in scope %s", node.String(), scope);
|
||||
|
||||
auto identifier = boost::algorithm::to_lower_copy(node.String());
|
||||
auto jsonName = JsonNode(identifier);
|
||||
|
||||
VLC->identifiers()->requestIdentifier(node.getModScope(), "obstacleTemplate", identifier, [this, os](si32 id)
|
||||
{
|
||||
logMod->trace("Resolved obstacle id: %d", id);
|
||||
os->addObstacle(obstacleTemplates[id]);
|
||||
});
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
void ObstacleSetHandler::addTemplate(const std::string & scope, const std::string &name, std::shared_ptr<const ObjectTemplate> tmpl)
|
||||
{
|
||||
auto id = obstacleTemplates.size();
|
||||
|
||||
auto strippedName = boost::algorithm::to_lower_copy(name);
|
||||
auto pos = strippedName.find(".def");
|
||||
if(pos != std::string::npos)
|
||||
strippedName.erase(pos, 4);
|
||||
|
||||
if (VLC->identifiersHandler->getIdentifier(scope, "obstacleTemplate", strippedName, true))
|
||||
{
|
||||
logMod->warn("Duplicate obstacle template: %s", strippedName);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save by name
|
||||
VLC->identifiersHandler->registerObject(scope, "obstacleTemplate", strippedName, id);
|
||||
|
||||
// Index by id
|
||||
obstacleTemplates[id] = tmpl;
|
||||
}
|
||||
}
|
||||
|
||||
void ObstacleSetHandler::addObstacleSet(std::shared_ptr<ObstacleSet> os)
|
||||
{
|
||||
biomes.push_back(os);
|
||||
}
|
||||
|
||||
void ObstacleSetHandler::afterLoadFinalization()
|
||||
{
|
||||
for (auto &os :biomes)
|
||||
{
|
||||
os->removeEmptyTemplates();
|
||||
}
|
||||
vstd::erase_if(biomes, [](const std::shared_ptr<ObstacleSet> &os)
|
||||
{
|
||||
if (os->getObstacles().empty())
|
||||
{
|
||||
logMod->warn("Obstacle set %d is empty, removing it", os->id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// Populate map
|
||||
for (auto &os : biomes)
|
||||
{
|
||||
obstacleSets[os->getType()].push_back(os);
|
||||
}
|
||||
}
|
||||
|
||||
TObstacleTypes ObstacleSetHandler::getObstacles( const ObstacleSetFilter &filter) const
|
||||
{
|
||||
TObstacleTypes result;
|
||||
|
||||
for (const auto &allowedType : filter.getAllowedTypes())
|
||||
{
|
||||
auto it = obstacleSets.find(allowedType);
|
||||
if(it != obstacleSets.end())
|
||||
{
|
||||
for (const auto &os : it->second)
|
||||
{
|
||||
if (filter.filter(*os))
|
||||
{
|
||||
result.push_back(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
133
lib/mapObjects/ObstacleSetHandler.h
Normal file
133
lib/mapObjects/ObstacleSetHandler.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* ObstacleSetHandler.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 "../GameConstants.h"
|
||||
#include "../constants/EntityIdentifiers.h"
|
||||
#include "../IHandlerBase.h"
|
||||
#include "../json/JsonNode.h"
|
||||
#include "ObjectTemplate.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class DLL_LINKAGE ObstacleSet
|
||||
{
|
||||
public:
|
||||
|
||||
// TODO: Create string constants for these
|
||||
|
||||
enum EObstacleType
|
||||
{
|
||||
INVALID = -1,
|
||||
MOUNTAINS = 0,
|
||||
TREES,
|
||||
LAKES, // Inluding dry or lava lakes
|
||||
CRATERS, // Chasms, Canyons, etc.
|
||||
ROCKS,
|
||||
PLANTS, // Flowers, cacti, mushrooms, logs, shrubs, etc.
|
||||
STRUCTURES, // Buildings, ruins, etc.
|
||||
ANIMALS, // Living, or bones
|
||||
OTHER // Crystals, shipwrecks, barrels, etc.
|
||||
};
|
||||
ObstacleSet();
|
||||
explicit ObstacleSet(EObstacleType type, TerrainId terrain);
|
||||
|
||||
void addObstacle(std::shared_ptr<const ObjectTemplate> obstacle);
|
||||
void removeEmptyTemplates();
|
||||
std::vector<std::shared_ptr<const ObjectTemplate>> getObstacles() const;
|
||||
|
||||
EObstacleType getType() const;
|
||||
void setType(EObstacleType type);
|
||||
|
||||
std::set<TerrainId> getTerrains() const;
|
||||
void setTerrain(TerrainId terrain);
|
||||
void setTerrains(const std::set<TerrainId> & terrains);
|
||||
void addTerrain(TerrainId terrain);
|
||||
std::set<EAlignment> getAlignments() const;
|
||||
void addAlignment(EAlignment alignment);
|
||||
std::set<FactionID> getFactions() const;
|
||||
void addFaction(FactionID faction);
|
||||
|
||||
static EObstacleType typeFromString(const std::string &str);
|
||||
std::string toString() const;
|
||||
|
||||
si32 id;
|
||||
|
||||
private:
|
||||
|
||||
EObstacleType type;
|
||||
std::set<TerrainId> allowedTerrains; // Empty means all terrains
|
||||
std::set<FactionID> allowedFactions; // Empty means all factions
|
||||
std::set<EAlignment> allowedAlignments; // Empty means all alignments
|
||||
std::vector<std::shared_ptr<const ObjectTemplate>> obstacles;
|
||||
};
|
||||
|
||||
typedef std::vector<std::shared_ptr<ObstacleSet>> TObstacleTypes;
|
||||
|
||||
class DLL_LINKAGE ObstacleSetFilter
|
||||
{
|
||||
public:
|
||||
ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain, FactionID faction, EAlignment alignment);
|
||||
ObstacleSetFilter(std::vector<ObstacleSet::EObstacleType> allowedTypes, TerrainId terrain, FactionID faction, EAlignment alignment);
|
||||
|
||||
bool filter(const ObstacleSet &set) const;
|
||||
|
||||
void setType(ObstacleSet::EObstacleType type);
|
||||
void setTypes(std::vector<ObstacleSet::EObstacleType> types);
|
||||
std::vector<ObstacleSet::EObstacleType> getAllowedTypes() const;
|
||||
TerrainId getTerrain() const;
|
||||
|
||||
void setAlignment(EAlignment alignment);
|
||||
|
||||
private:
|
||||
std::vector<ObstacleSet::EObstacleType> allowedTypes;
|
||||
FactionID faction;
|
||||
EAlignment alignment;
|
||||
// TODO: Filter by faction, surface/underground, etc.
|
||||
const TerrainId terrain;
|
||||
};
|
||||
|
||||
// TODO: Instantiate ObstacleSetHandler
|
||||
class DLL_LINKAGE ObstacleSetHandler : public IHandlerBase, boost::noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
ObstacleSetHandler() = default;
|
||||
~ObstacleSetHandler() = default;
|
||||
|
||||
std::vector<JsonNode> loadLegacyData() override;
|
||||
virtual void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
||||
virtual void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
|
||||
std::shared_ptr<ObstacleSet> loadFromJson(const std::string & scope, const JsonNode & json, const std::string & name, size_t index);
|
||||
|
||||
ObstacleSet::EObstacleType convertObstacleClass(MapObjectID id);
|
||||
|
||||
// TODO: Populate obstacleSets with all the obstacle sets from the game data
|
||||
void addTemplate(const std::string & scope, const std::string &name, std::shared_ptr<const ObjectTemplate> tmpl);
|
||||
|
||||
void addObstacleSet(std::shared_ptr<ObstacleSet> set);
|
||||
|
||||
void afterLoadFinalization() override;
|
||||
|
||||
TObstacleTypes getObstacles(const ObstacleSetFilter &filter) const;
|
||||
|
||||
private:
|
||||
|
||||
std::vector< std::shared_ptr<ObstacleSet> > biomes;
|
||||
|
||||
// TODO: Serialize?
|
||||
std::map<si32, std::shared_ptr<const ObjectTemplate>> obstacleTemplates;
|
||||
|
||||
// FIXME: Store pointers?
|
||||
std::map<ObstacleSet::EObstacleType, std::vector<std::shared_ptr<ObstacleSet>>> obstacleSets;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "../mapObjects/CGObjectInstance.h"
|
||||
#include "../mapObjects/ObjectTemplate.h"
|
||||
#include "../mapObjects/ObstacleSetHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@@ -36,6 +37,11 @@ void ObstacleProxy::collectPossibleObstacles(TerrainId terrain)
|
||||
}
|
||||
}
|
||||
}
|
||||
sortObstacles();
|
||||
}
|
||||
|
||||
void ObstacleProxy::sortObstacles()
|
||||
{
|
||||
for(const auto & o : obstaclesBySize)
|
||||
{
|
||||
possibleObstacles.emplace_back(o);
|
||||
@@ -46,6 +52,161 @@ void ObstacleProxy::collectPossibleObstacles(TerrainId terrain)
|
||||
});
|
||||
}
|
||||
|
||||
bool ObstacleProxy::prepareBiome(const ObstacleSetFilter & filter, CRandomGenerator & rand)
|
||||
{
|
||||
possibleObstacles.clear();
|
||||
|
||||
std::vector<std::shared_ptr<ObstacleSet>> obstacleSets;
|
||||
|
||||
size_t selectedSets = 0;
|
||||
const size_t MINIMUM_SETS = 3; // Original Lava has only 4 types of sets
|
||||
const size_t MAXIMUM_SETS = 9;
|
||||
const size_t MIN_SMALL_SETS = 3;
|
||||
const size_t MAX_SMALL_SETS = 5;
|
||||
|
||||
auto terrain = filter.getTerrain();
|
||||
auto localFilter = filter;
|
||||
localFilter.setType(ObstacleSet::EObstacleType::MOUNTAINS);
|
||||
|
||||
TObstacleTypes mountainSets = VLC->biomeHandler->getObstacles(localFilter);
|
||||
|
||||
if (!mountainSets.empty())
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(mountainSets, rand));
|
||||
selectedSets++;
|
||||
logGlobal->info("Mountain set added");
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->warn("No mountain sets found for terrain %s", TerrainId::encode(terrain.getNum()));
|
||||
// FIXME: Do we ever want to generate obstacles without any mountains?
|
||||
}
|
||||
|
||||
localFilter.setType(ObstacleSet::EObstacleType::TREES);
|
||||
TObstacleTypes treeSets = VLC->biomeHandler->getObstacles(localFilter);
|
||||
|
||||
// 1 or 2 tree sets
|
||||
size_t treeSetsCount = std::min<size_t>(treeSets.size(), rand.nextInt(1, 2));
|
||||
for (size_t i = 0; i < treeSetsCount; i++)
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(treeSets, rand));
|
||||
selectedSets++;
|
||||
}
|
||||
logGlobal->info("Added %d tree sets", treeSetsCount);
|
||||
|
||||
// Some obstacle types may be completely missing from water, but it's not a problem
|
||||
localFilter.setTypes({ObstacleSet::EObstacleType::LAKES, ObstacleSet::EObstacleType::CRATERS});
|
||||
TObstacleTypes largeSets = VLC->biomeHandler->getObstacles(localFilter);
|
||||
|
||||
// We probably don't want to have lakes and craters at the same time, choose one of them
|
||||
|
||||
if (!largeSets.empty())
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(largeSets, rand));
|
||||
selectedSets++;
|
||||
|
||||
// TODO: Convert to string
|
||||
logGlobal->info("Added large set of type %s", obstacleSets.back()->getType());
|
||||
}
|
||||
|
||||
localFilter.setType(ObstacleSet::EObstacleType::ROCKS);
|
||||
TObstacleTypes rockSets = VLC->biomeHandler->getObstacles(localFilter);
|
||||
|
||||
size_t rockSetsCount = std::min<size_t>(rockSets.size(), rand.nextInt(1, 2));
|
||||
for (size_t i = 0; i < rockSetsCount; i++)
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(rockSets, rand));
|
||||
selectedSets++;
|
||||
}
|
||||
logGlobal->info("Added %d rock sets", rockSetsCount);
|
||||
|
||||
localFilter.setType(ObstacleSet::EObstacleType::PLANTS);
|
||||
TObstacleTypes plantSets = VLC->biomeHandler->getObstacles(localFilter);
|
||||
|
||||
// 1 or 2 sets (3 - rock sets)
|
||||
size_t plantSetsCount = std::min<size_t>(plantSets.size(), rand.nextInt(1, std::max<size_t>(3 - rockSetsCount, 2)));
|
||||
for (size_t i = 0; i < plantSetsCount; i++)
|
||||
{
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(plantSets, rand));
|
||||
selectedSets++;
|
||||
}
|
||||
}
|
||||
logGlobal->info("Added %d plant sets", plantSetsCount);
|
||||
|
||||
//3 to 5 of total small sets (rocks, plants, structures, animals and others)
|
||||
//This gives total of 6 to 9 different sets
|
||||
|
||||
size_t maxSmallSets = std::min<size_t>(MAX_SMALL_SETS, std::max(MIN_SMALL_SETS, MAXIMUM_SETS - selectedSets));
|
||||
|
||||
size_t smallSets = rand.nextInt(MIN_SMALL_SETS, maxSmallSets);
|
||||
|
||||
localFilter.setTypes({ObstacleSet::EObstacleType::STRUCTURES, ObstacleSet::EObstacleType::ANIMALS});
|
||||
TObstacleTypes smallObstacleSets = VLC->biomeHandler->getObstacles(localFilter);
|
||||
RandomGeneratorUtil::randomShuffle(smallObstacleSets, rand);
|
||||
|
||||
localFilter.setType(ObstacleSet::EObstacleType::OTHER);
|
||||
TObstacleTypes otherSets = VLC->biomeHandler->getObstacles(localFilter);
|
||||
RandomGeneratorUtil::randomShuffle(otherSets, rand);
|
||||
|
||||
while (smallSets > 0)
|
||||
{
|
||||
if (!smallObstacleSets.empty())
|
||||
{
|
||||
obstacleSets.push_back(smallObstacleSets.back());
|
||||
smallObstacleSets.pop_back();
|
||||
selectedSets++;
|
||||
smallSets--;
|
||||
logGlobal->info("Added small set of type %s", obstacleSets.back()->getType());
|
||||
}
|
||||
else if(otherSets.empty())
|
||||
{
|
||||
logGlobal->warn("No other sets found for terrain %s", terrain.encode(terrain.getNum()));
|
||||
break;
|
||||
}
|
||||
|
||||
if (smallSets > 0)
|
||||
{
|
||||
// Fill with whatever's left
|
||||
if (!otherSets.empty())
|
||||
{
|
||||
obstacleSets.push_back(otherSets.back());
|
||||
otherSets.pop_back();
|
||||
selectedSets++;
|
||||
smallSets--;
|
||||
|
||||
logGlobal->info("Added set of other obstacles");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy this set to our possible obstacles
|
||||
|
||||
if (selectedSets >= MINIMUM_SETS ||
|
||||
(terrain == TerrainId::WATER && selectedSets > 0))
|
||||
{
|
||||
obstaclesBySize.clear();
|
||||
for (const auto & os : obstacleSets)
|
||||
{
|
||||
for (const auto & temp : os->getObstacles())
|
||||
{
|
||||
if(temp->getBlockMapOffset().valid())
|
||||
{
|
||||
obstaclesBySize[temp->getBlockedOffsets().size()].push_back(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sortObstacles();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false; // Proceed with old method
|
||||
}
|
||||
}
|
||||
|
||||
void ObstacleProxy::addBlockedTile(const int3& tile)
|
||||
{
|
||||
blockedArea.add(tile);
|
||||
|
||||
@@ -20,6 +20,7 @@ class CGObjectInstance;
|
||||
class ObjectTemplate;
|
||||
class CRandomGenerator;
|
||||
class IGameCallback;
|
||||
class ObstacleSetFilter;
|
||||
|
||||
class DLL_LINKAGE ObstacleProxy
|
||||
{
|
||||
@@ -29,6 +30,7 @@ public:
|
||||
virtual ~ObstacleProxy() = default;
|
||||
|
||||
void collectPossibleObstacles(TerrainId terrain);
|
||||
bool prepareBiome(const ObstacleSetFilter & filter, CRandomGenerator & rand);
|
||||
|
||||
void addBlockedTile(const int3 & tile);
|
||||
|
||||
@@ -52,6 +54,7 @@ public:
|
||||
|
||||
protected:
|
||||
int getWeightedObjects(const int3& tile, CRandomGenerator& rand, IGameCallback * cb, std::list<rmg::Object>& allObjects, std::vector<std::pair<rmg::Object*, int3>>& weightedObjects);
|
||||
void sortObstacles();
|
||||
|
||||
rmg::Area blockedArea;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "../IHandlerBase.h"
|
||||
#include "../Languages.h"
|
||||
#include "../ObstacleHandler.h"
|
||||
#include "../mapObjects/ObstacleSetHandler.h"
|
||||
#include "../RiverHandler.h"
|
||||
#include "../RoadHandler.h"
|
||||
#include "../ScriptHandler.h"
|
||||
@@ -207,7 +208,7 @@ void CContentHandler::init()
|
||||
handlers.insert(std::make_pair("rivers", ContentTypeHandler(VLC->riverTypeHandler.get(), "river")));
|
||||
handlers.insert(std::make_pair("roads", ContentTypeHandler(VLC->roadTypeHandler.get(), "road")));
|
||||
handlers.insert(std::make_pair("obstacles", ContentTypeHandler(VLC->obstacleHandler.get(), "obstacle")));
|
||||
//TODO: any other types of moddables?
|
||||
handlers.insert(std::make_pair("biomes", ContentTypeHandler(VLC->biomeHandler.get(), "biome")));
|
||||
}
|
||||
|
||||
bool CContentHandler::preloadModData(const std::string & modName, JsonNode modConfig, bool validate)
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "../../mapping/CMap.h"
|
||||
#include "../../mapping/ObstacleProxy.h"
|
||||
#include "../../mapObjects/CGObjectInstance.h"
|
||||
#include "../../mapObjects/ObstacleSetHandler.h"
|
||||
#include "../../CTownHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@@ -34,7 +36,20 @@ void ObstaclePlacer::process()
|
||||
if(!manager)
|
||||
return;
|
||||
|
||||
collectPossibleObstacles(zone.getTerrainType());
|
||||
auto faction = zone.getTownType().toFaction();
|
||||
|
||||
ObstacleSetFilter filter(ObstacleSet::EObstacleType::INVALID, zone.getTerrainType(), faction->getId(), faction->alignment);
|
||||
|
||||
if (!prepareBiome(filter, zone.getRand()))
|
||||
{
|
||||
logGlobal->warn("Failed to prepare biome, using all possible obstacles");
|
||||
// Use all if we fail to create proper biome
|
||||
collectPossibleObstacles(zone.getTerrainType());
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->info("Biome prepared successfully for zone %d", zone.getId());
|
||||
}
|
||||
|
||||
{
|
||||
auto area = zone.area();
|
||||
|
||||
Reference in New Issue
Block a user