Index: ps/trunk/binaries/data/mods/public/maps/scenario.rnc
===================================================================
--- ps/trunk/binaries/data/mods/public/maps/scenario.rnc (revision 23528)
+++ ps/trunk/binaries/data/mods/public/maps/scenario.rnc (revision 23529)
@@ -1,130 +1,135 @@
namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"
##
# NOTE: To modify this Relax NG grammar, edit the Relax NG Compact (.rnc) file
# and use a converter tool like trang to generate the Relax NG XML (.rng) file
##
start = Scenario
##
# Defines #
##
color_rgb =
attribute r { xsd:decimal { minInclusive = "0" maxInclusive = "1" } },
attribute g { xsd:decimal { minInclusive = "0" maxInclusive = "1" } },
attribute b { xsd:decimal { minInclusive = "0" maxInclusive = "1" } }
suncolor_rgb = # RGB can be > 1 due to overbrightness
attribute r { xsd:decimal { minInclusive = "0" } },
attribute g { xsd:decimal { minInclusive = "0" } },
attribute b { xsd:decimal { minInclusive = "0" } }
pos_xyz =
attribute x { xsd:float },
attribute y { xsd:float },
attribute z { xsd:float }
pos_xz =
attribute x { xsd:decimal },
attribute z { xsd:decimal }
angle = attribute angle { xsd:float }
##
# Scenario #
##
# TODO: bounds are not documented for many of these
Scenario = element Scenario {
attribute version { xsd:positiveInteger } &
element Environment {
element SkySet { text } &
element SunColor { suncolor_rgb } &
element SunElevation { angle } &
element SunRotation { angle } &
element TerrainAmbientColor { color_rgb } &
element UnitsAmbientColor { color_rgb } &
element Fog {
element FogFactor {
xsd:decimal { minInclusive = "0" } # TODO: what is the max?
} &
element FogThickness {
xsd:decimal { minInclusive = "0" } # TODO: what is the max?
} &
element FogColor { color_rgb }
}? &
element Water {
element WaterBody {
element Type { text } & # Not implemented
element Color { color_rgb } &
element Height { xsd:decimal } &
element Waviness { xsd:decimal } &
element Murkiness { xsd:decimal } &
element Tint { color_rgb } &
element WindAngle { xsd:decimal }?
}
} &
element Postproc {
element Brightness { xsd:decimal },
element Contrast { xsd:decimal },
element Saturation { xsd:decimal },
element Bloom { xsd:decimal },
element PostEffect { text }
}?
} &
element Terrain {
attribute patches { xsd:positiveInteger }?,
attribute texture { text }?,
attribute priority { xsd:nonNegativeInteger }?,
attribute height { xsd:positiveInteger }?
}? &
element Script {
text
}? &
element Camera { # Camera can have weird float values
element Position { pos_xyz },
element Rotation { angle },
element Declination { angle }
}? &
element ScriptSettings {
text
} &
element Entities {
element Entity {
attribute uid { xsd:positiveInteger } &
element Template { text } &
element Player { xsd:nonNegativeInteger }? &
element Position {
pos_xz
} &
element Orientation {
attribute y { xsd:decimal }
} &
element Obstruction {
attribute group { xsd:positiveInteger },
attribute group2 { xsd:positiveInteger }?
}? &
+ element Garrison {
+ element GarrisonedEntity {
+ attribute uid { xsd:positiveInteger } &
+ } &
+ } &
element Actor {
attribute seed { xsd:integer }
}?
}*
}? &
element Paths {
element Path {
attribute name { text } &
attribute timescale { xsd:decimal } &
attribute orientation { text } &
attribute mode { text } &
attribute style { text } &
element Node {
attribute deltatime {
xsd:decimal { minInclusive = "0" }
} &
element Position { pos_xyz }? &
element Target { pos_xyz }?
}*
}*
}? &
element Triggers { # Unused
empty
}?
}
Index: ps/trunk/binaries/data/mods/public/maps/scenario.rng
===================================================================
--- ps/trunk/binaries/data/mods/public/maps/scenario.rng (revision 23528)
+++ ps/trunk/binaries/data/mods/public/maps/scenario.rng (revision 23529)
@@ -1,318 +1,329 @@
0
1
0
1
0
1
0
0
0
0
0
+
+
+
+
+
+
+
+
+
+
+
0
Index: ps/trunk/binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml (revision 23528)
+++ ps/trunk/binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml (revision 23529)
@@ -1,16189 +1,16219 @@
sunny
0.00194336
0
ocean
19.8295
3.5
0.825195
0
0
1
0.99
0.140234
hdr
actor|particle/smoke_volcano.xml
gaia/geology_stonemine_medit_quarry
0
gaia/geology_stonemine_medit_quarry
0
gaia/geology_metal_mediterranean_slabs
0
gaia/geology_metal_mediterranean_slabs
0
gaia/geology_metal_mediterranean_slabs
0
gaia/geology_metal_mediterranean_slabs
0
gaia/geology_metal_mediterranean_slabs
0
gaia/geology_metal_mediterranean_slabs
0
gaia/geology_metal_mediterranean_slabs
0
gaia/geology_stonemine_medit_quarry
0
gaia/geology_stonemine_medit_quarry
0
gaia/geology_stonemine_medit_quarry
0
gaia/geology_stonemine_medit_quarry
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_medit_fan_palm
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_desert_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_dry_a.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_sm_lush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_tempe_b.xml
actor|props/flora/bush_tempe_b.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_b.xml
actor|props/flora/bush_tempe_b.xml
actor|props/flora/bush_tempe_b.xml
actor|props/flora/bush_tempe_b.xml
actor|props/flora/bush_tempe_b.xml
actor|props/flora/bush_tempe_b.xml
actor|props/flora/bush_tempe_b.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/grass_soft_dry_large.xml
actor|props/flora/grass_soft_dry_large.xml
actor|props/flora/grass_soft_dry_large.xml
actor|props/flora/grass_soft_dry_large.xml
actor|props/flora/grass_soft_dry_large.xml
actor|props/flora/grass_soft_dry_large.xml
actor|props/flora/grass_soft_dry_large.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/fauna_fish_tuna
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_grapes
0
gaia/flora_bush_berry
0
gaia/flora_bush_berry
0
gaia/flora_bush_berry
0
gaia/flora_bush_berry
0
gaia/flora_bush_berry
0
gaia/flora_bush_berry
0
gaia/flora_bush_berry
0
gaia/flora_bush_berry
0
gaia/flora_bush_berry
0
gaia/flora_bush_berry
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_aleppo_pine
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_carob
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_poplar_lombardy
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_apple
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
gaia/flora_tree_cypress
0
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|geology/stone_medit_med.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm_dry.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_medit_sm.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_tempe_a.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_tropic_a.xml
actor|props/flora/bush_tropic_a.xml
actor|props/flora/bush_tropic_a.xml
actor|props/flora/bush_tropic_a.xml
actor|props/flora/bush_tropic_a.xml
actor|props/flora/bush_tropic_a.xml
actor|props/flora/bush_tropic_a.xml
actor|props/flora/bush_tropic_a.xml
actor|props/flora/bush_tropic_a.xml
actor|props/flora/bush_tropic_b.xml
actor|props/flora/bush_tropic_b.xml
actor|props/flora/bush_tropic_b.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small_tall.xml
actor|props/flora/grass_soft_dry_small.xml
actor|props/flora/grass_soft_dry_small.xml
actor|props/flora/grass_soft_dry_small.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/bush_tempe_underbrush.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_dry_large_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_small_tall.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
actor|props/flora/grass_soft_dry_tuft_a.xml
gaia/geology_stone_mediterranean
0
gaia/geology_stone_mediterranean
0
gaia/geology_stone_mediterranean
0
gaia/geology_stone_mediterranean
0
gaia/geology_stone_mediterranean
0
gaia/geology_stone_mediterranean
0
gaia/geology_stone_mediterranean
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_wolf
0
gaia/fauna_wolf
0
gaia/fauna_wolf
0
gaia/fauna_wolf
0
gaia/fauna_bear
0
gaia/fauna_bear
0
gaia/fauna_bear
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_deer
0
gaia/fauna_boar
0
gaia/fauna_boar
0
gaia/fauna_boar
0
gaia/fauna_boar
0
gaia/fauna_boar
0
gaia/fauna_boar
0
gaia/fauna_boar
0
gaia/fauna_boar
0
gaia/fauna_boar
0
gaia/fauna_boar
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
actor|props/flora/bush_medit_underbrush.xml
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_tall
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_short
0
gaia/flora_tree_cretan_date_palm_tall
0
skirmish/units/default_infantry_ranged_b
1
skirmish/units/default_support_female_citizen
1
skirmish/units/default_support_female_citizen
1
skirmish/units/default_infantry_melee_b
1
skirmish/units/default_infantry_melee_b
1
skirmish/units/default_ship_trireme
1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
skirmish/units/default_support_female_citizen
1
skirmish/units/default_support_female_citizen
1
skirmish/units/default_support_female_citizen
1
skirmish/units/default_support_female_citizen
1
skirmish/units/default_infantry_melee_b
1
skirmish/units/default_infantry_melee_b
1
skirmish/units/default_infantry_ranged_b
1
skirmish/units/default_infantry_ranged_b
1
skirmish/units/default_cavalry
1
skirmish/units/default_infantry_ranged_b
1
skirmish/units/default_ship_trireme
2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
skirmish/units/default_support_female_citizen
2
skirmish/units/default_support_female_citizen
2
skirmish/units/default_support_female_citizen
2
skirmish/units/default_support_female_citizen
2
skirmish/units/default_infantry_melee_b
2
skirmish/units/default_infantry_melee_b
2
skirmish/units/default_infantry_ranged_b
2
skirmish/units/default_infantry_ranged_b
2
skirmish/units/default_cavalry
2
skirmish/units/default_infantry_ranged_b
2
skirmish/units/default_support_female_citizen
2
skirmish/units/default_support_female_citizen
2
skirmish/units/default_infantry_ranged_b
2
skirmish/units/default_infantry_melee_b
2
skirmish/units/default_infantry_melee_b
2
gaia/fauna_fish
0
gaia/fauna_fish
0
gaia/fauna_whale_fin
0
gaia/fauna_whale_fin
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_oak
0
gaia/flora_tree_oak
0
gaia/flora_tree_tamarix
0
gaia/flora_tree_tamarix
0
gaia/flora_tree_tamarix
0
gaia/flora_tree_tamarix
0
gaia/flora_tree_dead
0
gaia/ruins/unfinished_greek_temple
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_dead
0
gaia/flora_tree_dead
0
gaia/geology_stone_mediterranean
0
gaia/geology_stone_mediterranean
0
gaia/geology_metal_mediterranean
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/flora_tree_olive
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/geology_stone_mediterranean
0
gaia/geology_metal_mediterranean_slabs
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
gaia/fauna_goat
0
Index: ps/trunk/binaries/data/mods/public/simulation/components/GarrisonHolder.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/GarrisonHolder.js (revision 23528)
+++ ps/trunk/binaries/data/mods/public/simulation/components/GarrisonHolder.js (revision 23529)
@@ -1,729 +1,739 @@
function GarrisonHolder() {}
GarrisonHolder.prototype.Schema =
"" +
"" +
"" +
"" +
"" +
"tokens" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"tokens" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"";
/**
* Initialize GarrisonHolder Component
* Garrisoning when loading a map is set in the script of the map, by setting initGarrison
* which should contain the array of garrisoned entities.
*/
GarrisonHolder.prototype.Init = function()
{
// Garrisoned Units
this.entities = [];
this.timer = undefined;
this.allowGarrisoning = new Map();
this.visibleGarrisonPoints = [];
if (this.template.VisibleGarrisonPoints)
{
let points = this.template.VisibleGarrisonPoints;
for (let point in points)
this.visibleGarrisonPoints.push({
"offset": {
"x": +points[point].X,
"y": +points[point].Y,
"z": +points[point].Z
},
"angle": points[point].Angle ? +points[point].Angle * Math.PI / 180 : null,
"entity": null
});
}
};
/**
* @return {Object} max and min range at which entities can garrison the holder.
*/
GarrisonHolder.prototype.GetLoadingRange = function()
{
return { "max": +this.template.LoadingRange, "min": 0 };
};
GarrisonHolder.prototype.CanPickup = function(ent)
{
if (!this.template.Pickup || this.IsFull())
return false;
let cmpOwner = Engine.QueryInterface(this.entity, IID_Ownership);
return !!cmpOwner && IsOwnedByPlayer(cmpOwner.GetOwner(), ent);
};
GarrisonHolder.prototype.GetEntities = function()
{
return this.entities;
};
/**
* @return {Array} unit classes which can be garrisoned inside this
* particular entity. Obtained from the entity's template.
*/
GarrisonHolder.prototype.GetAllowedClasses = function()
{
return this.template.List._string;
};
GarrisonHolder.prototype.GetCapacity = function()
{
return ApplyValueModificationsToEntity("GarrisonHolder/Max", +this.template.Max, this.entity);
};
GarrisonHolder.prototype.IsFull = function()
{
return this.GetGarrisonedEntitiesCount() >= this.GetCapacity();
};
GarrisonHolder.prototype.GetHealRate = function()
{
return ApplyValueModificationsToEntity("GarrisonHolder/BuffHeal", +this.template.BuffHeal, this.entity);
};
/**
* Set this entity to allow or disallow garrisoning in the entity.
* Every component calling this function should do it with its own ID, and as long as one
* component doesn't allow this entity to garrison, it can't be garrisoned
* When this entity already contains garrisoned soldiers,
* these will not be able to ungarrison until the flag is set to true again.
*
* This more useful for modern-day features. For example you can't garrison or ungarrison
* a driving vehicle or plane.
* @param {boolean} allow - Whether the entity should be garrisonable.
*/
GarrisonHolder.prototype.AllowGarrisoning = function(allow, callerID)
{
this.allowGarrisoning.set(callerID, allow);
};
GarrisonHolder.prototype.IsGarrisoningAllowed = function()
{
return Array.from(this.allowGarrisoning.values()).every(allow => allow);
};
GarrisonHolder.prototype.GetGarrisonedEntitiesCount = function()
{
let count = this.entities.length;
for (let ent of this.entities)
{
let cmpGarrisonHolder = Engine.QueryInterface(ent, IID_GarrisonHolder);
if (cmpGarrisonHolder)
count += cmpGarrisonHolder.GetGarrisonedEntitiesCount();
}
return count;
};
GarrisonHolder.prototype.IsAllowedToGarrison = function(ent)
{
if (!this.IsGarrisoningAllowed())
return false;
if (!IsOwnedByMutualAllyOfEntity(ent, this.entity))
return false;
let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
if (!cmpIdentity)
return false;
let entityClasses = cmpIdentity.GetClassesList();
return MatchesClassList(entityClasses, this.template.List._string) && !!Engine.QueryInterface(ent, IID_Garrisonable);
};
/**
* Garrison a unit inside. The timer for AutoHeal is started here.
* @param {number} vgpEntity - The visual garrison point that will be used.
* If vgpEntity is given, this visualGarrisonPoint will be used for the entity.
* @return {boolean} Whether the entity was garrisonned.
*/
GarrisonHolder.prototype.Garrison = function(entity, vgpEntity)
{
let cmpPosition = Engine.QueryInterface(entity, IID_Position);
if (!cmpPosition)
return false;
if (!this.PerformGarrison(entity))
return false;
let visibleGarrisonPoint = vgpEntity;
if (!visibleGarrisonPoint)
for (let vgp of this.visibleGarrisonPoints)
{
if (vgp.entity)
continue;
visibleGarrisonPoint = vgp;
break;
}
if (visibleGarrisonPoint)
{
visibleGarrisonPoint.entity = entity;
// Angle of turrets:
// Renamed entities (vgpEntity != undefined) should keep their angle.
// Otherwise if an angle is given in the visibleGarrisonPoint, use it.
// If no such angle given (usually walls for which outside/inside not well defined), we keep
// the current angle as it was used for garrisoning and thus quite often was from inside to
// outside, except when garrisoning from outWorld where we take as default PI.
let cmpTurretPosition = Engine.QueryInterface(this.entity, IID_Position);
if (!vgpEntity && visibleGarrisonPoint.angle != null)
cmpPosition.SetYRotation(cmpTurretPosition.GetRotation().y + visibleGarrisonPoint.angle);
else if (!vgpEntity && !cmpPosition.IsInWorld())
cmpPosition.SetYRotation(cmpTurretPosition.GetRotation().y + Math.PI);
let cmpUnitMotion = Engine.QueryInterface(entity, IID_UnitMotion);
if (cmpUnitMotion)
cmpUnitMotion.SetFacePointAfterMove(false);
cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset);
let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
if (cmpUnitAI)
cmpUnitAI.SetTurretStance();
}
else
cmpPosition.MoveOutOfWorld();
return true;
};
/**
* @return {boolean} Whether the entity was garrisonned.
*/
GarrisonHolder.prototype.PerformGarrison = function(entity)
{
if (!this.HasEnoughHealth())
return false;
// Check if the unit is allowed to be garrisoned inside the building
if (!this.IsAllowedToGarrison(entity))
return false;
// Check the capacity
let extraCount = 0;
let cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder);
if (cmpGarrisonHolder)
extraCount += cmpGarrisonHolder.GetGarrisonedEntitiesCount();
if (this.GetGarrisonedEntitiesCount() + extraCount >= this.GetCapacity())
return false;
if (!this.timer && this.GetHealRate() > 0)
{
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
}
// Actual garrisoning happens here
this.entities.push(entity);
this.UpdateGarrisonFlag();
let cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
if (cmpProductionQueue)
cmpProductionQueue.PauseProduction();
let cmpAura = Engine.QueryInterface(entity, IID_Auras);
if (cmpAura && cmpAura.HasGarrisonAura())
cmpAura.ApplyGarrisonAura(this.entity);
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [entity], "removed": [] });
return true;
};
/**
* Simply eject the unit from the garrisoning entity without moving it
* @param {number} entity - Id of the entity to be ejected.
* @param {boolean} forced - Whether eject is forced (i.e. if building is destroyed).
* @return {boolean} Whether the entity was ejected.
*/
GarrisonHolder.prototype.Eject = function(entity, forced)
{
let entityIndex = this.entities.indexOf(entity);
// Error: invalid entity ID, usually it's already been ejected
if (entityIndex == -1)
return false;
// Find spawning location
let cmpFootprint = Engine.QueryInterface(this.entity, IID_Footprint);
let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
let cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
// If the garrisonHolder is a sinking ship, restrict the location to the intersection of both passabilities
// TODO: should use passability classes to be more generic
let pos;
if ((!cmpHealth || cmpHealth.GetHitpoints() == 0) && cmpIdentity && cmpIdentity.HasClass("Ship"))
pos = cmpFootprint.PickSpawnPointBothPass(entity);
else
pos = cmpFootprint.PickSpawnPoint(entity);
if (pos.y < 0)
{
// Error: couldn't find space satisfying the unit's passability criteria
if (!forced)
return false;
// If ejection is forced, we need to continue, so use center of the building
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
pos = cmpPosition.GetPosition();
}
this.entities.splice(entityIndex, 1);
let cmpEntPosition = Engine.QueryInterface(entity, IID_Position);
let cmpEntUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
for (let vgp of this.visibleGarrisonPoints)
{
if (vgp.entity != entity)
continue;
cmpEntPosition.SetTurretParent(INVALID_ENTITY, new Vector3D());
let cmpEntUnitMotion = Engine.QueryInterface(entity, IID_UnitMotion);
if (cmpEntUnitMotion)
cmpEntUnitMotion.SetFacePointAfterMove(true);
if (cmpEntUnitAI)
cmpEntUnitAI.ResetTurretStance();
vgp.entity = null;
break;
}
if (cmpEntUnitAI)
cmpEntUnitAI.Ungarrison();
let cmpEntProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
if (cmpEntProductionQueue)
cmpEntProductionQueue.UnpauseProduction();
let cmpEntAura = Engine.QueryInterface(entity, IID_Auras);
if (cmpEntAura && cmpEntAura.HasGarrisonAura())
cmpEntAura.RemoveGarrisonAura(this.entity);
cmpEntPosition.JumpTo(pos.x, pos.z);
cmpEntPosition.SetHeightOffset(0);
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
if (cmpPosition)
cmpEntPosition.SetYRotation(cmpPosition.GetPosition().horizAngleTo(pos));
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "removed": [entity] });
return true;
};
/**
* Ejects units and orders them to move to the rally point. If an ejection
* with a given obstruction radius has failed, we won't try anymore to eject
* entities with a bigger obstruction as that is compelled to also fail.
* @param {Array} entities - An array containing the ids of the entities to eject.
* @param {boolean} forced - Whether eject is forced (ie: if building is destroyed).
* @return {boolean} Whether the entities were ejected.
*/
GarrisonHolder.prototype.PerformEject = function(entities, forced)
{
if (!this.IsGarrisoningAllowed() && !forced)
return false;
let ejectedEntities = [];
let success = true;
let failedRadius;
let radius;
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
for (let entity of entities)
{
if (failedRadius !== undefined)
{
let cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction);
radius = cmpObstruction ? cmpObstruction.GetUnitRadius() : 0;
if (radius >= failedRadius)
continue;
}
if (this.Eject(entity, forced))
{
let cmpEntOwnership = Engine.QueryInterface(entity, IID_Ownership);
if (cmpOwnership && cmpEntOwnership && cmpOwnership.GetOwner() == cmpEntOwnership.GetOwner())
ejectedEntities.push(entity);
}
else
{
success = false;
if (failedRadius !== undefined)
failedRadius = Math.min(failedRadius, radius);
else
{
let cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction);
failedRadius = cmpObstruction ? cmpObstruction.GetUnitRadius() : 0;
}
}
}
this.OrderWalkToRallyPoint(ejectedEntities);
this.UpdateGarrisonFlag();
return success;
};
/**
* Order entities to walk to the rally point.
* @param {Array} entities - An array containing all the ids of the entities.
*/
GarrisonHolder.prototype.OrderWalkToRallyPoint = function(entities)
{
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
let cmpRallyPoint = Engine.QueryInterface(this.entity, IID_RallyPoint);
if (!cmpRallyPoint || !cmpRallyPoint.GetPositions()[0])
return;
let commands = GetRallyPointCommands(cmpRallyPoint, entities);
// Ignore the rally point if it is autogarrison
if (commands[0].type == "garrison" && commands[0].target == this.entity)
return;
for (let command of commands)
ProcessCommand(cmpOwnership.GetOwner(), command);
};
/**
* Unload unit from the garrisoning entity and order them
* to move to the rally point.
* @return {boolean} Whether the command was successful.
*/
GarrisonHolder.prototype.Unload = function(entity, forced)
{
return this.PerformEject([entity], forced);
};
/**
* Unload one or all units that match a template and owner from
* the garrisoning entity and order them to move to the rally point.
* @param {string} template - Type of units that should be ejected.
* @param {number} owner - Id of the player whose units should be ejected.
* @param {boolean} all - Whether all units should be ejected.
* @param {boolean} forced - Whether unload is forced.
* @return {boolean} Whether the unloading was successful.
*/
GarrisonHolder.prototype.UnloadTemplate = function(template, owner, all, forced)
{
let entities = [];
let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
for (let entity of this.entities)
{
let cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
// Units with multiple ranks are grouped together.
let name = cmpIdentity.GetSelectionGroupName() || cmpTemplateManager.GetCurrentTemplateName(entity);
if (name != template || owner != Engine.QueryInterface(entity, IID_Ownership).GetOwner())
continue;
entities.push(entity);
// If 'all' is false, only ungarrison the first matched unit.
if (!all)
break;
}
return this.PerformEject(entities, forced);
};
/**
* Unload all units, that belong to certain player
* and order all own units to move to the rally point.
* @param {boolean} forced - Whether unload is forced.
* @param {number} owner - Id of the player whose units should be ejected.
* @return {boolean} Whether the unloading was successful.
*/
GarrisonHolder.prototype.UnloadAllByOwner = function(owner, forced)
{
let entities = this.entities.filter(ent => {
let cmpOwnership = Engine.QueryInterface(ent, IID_Ownership);
return cmpOwnership && cmpOwnership.GetOwner() == owner;
});
return this.PerformEject(entities, forced);
};
/**
* Unload all units from the entity and order them to move to the rally point.
* @param {boolean} forced - Whether unload is forced.
* @return {boolean} Whether the unloading was successful.
*/
GarrisonHolder.prototype.UnloadAll = function(forced)
{
return this.PerformEject(this.entities.slice(), forced);
};
/**
* Used to check if the garrisoning entity's health has fallen below
* a certain limit after which all garrisoned units are unloaded.
*/
GarrisonHolder.prototype.OnHealthChanged = function(msg)
{
if (!this.HasEnoughHealth() && this.entities.length)
this.EjectOrKill(this.entities.slice());
};
GarrisonHolder.prototype.HasEnoughHealth = function()
{
let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
return cmpHealth.GetHitpoints() > Math.floor(+this.template.EjectHealth * cmpHealth.GetMaxHitpoints());
};
/**
* Called every second. Heals garrisoned units.
*/
GarrisonHolder.prototype.HealTimeout = function(data)
{
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
if (!this.entities.length)
{
cmpTimer.CancelTimer(this.timer);
this.timer = undefined;
return;
}
for (let entity of this.entities)
{
let cmpHealth = Engine.QueryInterface(entity, IID_Health);
if (cmpHealth && !cmpHealth.IsUnhealable())
cmpHealth.Increase(this.GetHealRate());
}
this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
};
/**
* Updates the garrison flag depending whether something is garrisoned in the entity.
*/
GarrisonHolder.prototype.UpdateGarrisonFlag = function()
{
let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
if (!cmpVisual)
return;
cmpVisual.SetVariant("garrison", this.entities.length ? "garrisoned" : "ungarrisoned");
};
/**
* Cancel timer when destroyed.
*/
GarrisonHolder.prototype.OnDestroy = function()
{
if (this.timer)
{
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
cmpTimer.CancelTimer(this.timer);
}
};
/**
* If a garrisoned entity is captured, or about to be killed (so its owner changes to '-1'),
* remove it from the building so we only ever contain valid entities.
*/
GarrisonHolder.prototype.OnGlobalOwnershipChanged = function(msg)
{
// The ownership change may be on the garrisonholder
if (this.entity == msg.entity)
{
let entities = this.entities.filter(ent => msg.to == INVALID_PLAYER || !IsOwnedByMutualAllyOfEntity(this.entity, ent));
if (entities.length)
this.EjectOrKill(entities);
return;
}
// or on some of its garrisoned units
let entityIndex = this.entities.indexOf(msg.entity);
if (entityIndex != -1)
{
// If the entity is dead, remove it directly instead of ejecting the corpse
let cmpHealth = Engine.QueryInterface(msg.entity, IID_Health);
if (cmpHealth && cmpHealth.GetHitpoints() == 0)
{
this.entities.splice(entityIndex, 1);
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "removed": [msg.entity] });
this.UpdateGarrisonFlag();
for (let point of this.visibleGarrisonPoints)
if (point.entity == msg.entity)
point.entity = null;
}
else if (msg.to == INVALID_PLAYER || !IsOwnedByMutualAllyOfEntity(this.entity, msg.entity))
this.EjectOrKill([msg.entity]);
}
};
/**
* Update list of garrisoned entities if one gets renamed (e.g. by promotion).
*/
GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg)
{
let entityIndex = this.entities.indexOf(msg.entity);
if (entityIndex != -1)
{
let vgpRenamed;
for (let vgp of this.visibleGarrisonPoints)
{
if (vgp.entity != msg.entity)
continue;
vgpRenamed = vgp;
break;
}
this.Eject(msg.entity, true);
this.Garrison(msg.newentity, vgpRenamed);
}
if (!this.initGarrison)
return;
// Update the pre-game garrison because of SkirmishReplacement
if (msg.entity == this.entity)
{
let cmpGarrisonHolder = Engine.QueryInterface(msg.newentity, IID_GarrisonHolder);
if (cmpGarrisonHolder)
cmpGarrisonHolder.initGarrison = this.initGarrison;
}
else
{
entityIndex = this.initGarrison.indexOf(msg.entity);
if (entityIndex != -1)
this.initGarrison[entityIndex] = msg.newentity;
}
};
/**
* Eject all foreign garrisoned entities which are no more allied.
*/
GarrisonHolder.prototype.OnDiplomacyChanged = function()
{
this.EjectOrKill(this.entities.filter(ent => !IsOwnedByMutualAllyOfEntity(this.entity, ent)));
};
/**
* Eject or kill a garrisoned unit which can no more be garrisoned
* (garrisonholder's health too small or ownership changed).
*/
GarrisonHolder.prototype.EjectOrKill = function(entities)
{
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
// Eject the units which can be ejected (if not in world, it generally means this holder
// is inside a holder which kills its entities, so do not eject)
if (cmpPosition && cmpPosition.IsInWorld())
{
let ejectables = entities.filter(ent => this.IsEjectable(ent));
if (ejectables.length)
this.PerformEject(ejectables, false);
}
// And destroy all remaining entities
let killedEntities = [];
for (let entity of entities)
{
let entityIndex = this.entities.indexOf(entity);
if (entityIndex == -1)
continue;
let cmpHealth = Engine.QueryInterface(entity, IID_Health);
if (cmpHealth)
cmpHealth.Kill();
this.entities.splice(entityIndex, 1);
killedEntities.push(entity);
}
if (killedEntities.length)
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "removed": killedEntities });
this.UpdateGarrisonFlag();
};
/**
* Whether an entity is ejectable.
* @param {number} entity - The entity-ID to be tested.
* @return {boolean} - Whether the entity is ejectable.
*/
GarrisonHolder.prototype.IsEjectable = function(entity)
{
if (!this.entities.find(ent => ent == entity))
return false;
let ejectableClasses = this.template.EjectClassesOnDestroy._string;
let entityClasses = Engine.QueryInterface(entity, IID_Identity).GetClassesList();
return MatchesClassList(entityClasses, ejectableClasses);
};
/**
+ * Sets the intitGarrison to the specified entities. Used by the mapreader.
+ *
+ * @param {number[]} entities - The entity IDs to garrison on init.
+ */
+GarrisonHolder.prototype.SetInitGarrison = function(entities)
+{
+ this.initGarrison = clone(entities);
+};
+
+/**
* Initialise the garrisoned units.
*/
GarrisonHolder.prototype.OnGlobalInitGame = function(msg)
{
if (!this.initGarrison)
return;
for (let ent of this.initGarrison)
{
let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
if (cmpUnitAI && cmpUnitAI.CanGarrison(this.entity) && this.Garrison(ent))
cmpUnitAI.Autogarrison(this.entity);
}
this.initGarrison = undefined;
};
GarrisonHolder.prototype.OnValueModification = function(msg)
{
if (msg.component != "GarrisonHolder" || msg.valueNames.indexOf("GarrisonHolder/BuffHeal") == -1)
return;
if (this.timer && this.GetHealRate() == 0)
{
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
cmpTimer.CancelTimer(this.timer);
this.timer = undefined;
}
else if (!this.timer && this.GetHealRate() > 0)
{
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
}
};
Engine.RegisterComponentType(IID_GarrisonHolder, "GarrisonHolder", GarrisonHolder);
Index: ps/trunk/binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js (revision 23528)
+++ ps/trunk/binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js (revision 23529)
@@ -1,7 +1,5 @@
-Engine.RegisterInterface("GarrisonHolder");
-
/**
* Message of the form { "added": number[], "removed": number[] }
* sent from the GarrisonHolder component to the current entity whenever the garrisoned units change.
*/
Engine.RegisterMessageType("GarrisonedUnitsChanged");
Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Setup.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/helpers/Setup.js (revision 23528)
+++ ps/trunk/binaries/data/mods/public/simulation/helpers/Setup.js (revision 23529)
@@ -1,82 +1,72 @@
/**
* Used to initialize non-player settings relevant to the map, like
* default stance and victory conditions. DO NOT load players here
*/
function LoadMapSettings(settings)
{
if (!settings)
settings = {};
if (settings.DefaultStance)
for (let ent of Engine.GetEntitiesWithInterface(IID_UnitAI))
{
let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
cmpUnitAI.SwitchToStance(settings.DefaultStance);
}
if (settings.RevealMap)
{
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
if (cmpRangeManager)
cmpRangeManager.SetLosRevealAll(-1, true);
}
if (settings.DisableTreasures)
for (let ent of Engine.GetEntitiesWithInterface(IID_ResourceSupply))
{
let cmpResourceSupply = Engine.QueryInterface(ent, IID_ResourceSupply);
if (cmpResourceSupply.GetType().generic == "treasure")
Engine.DestroyEntity(ent);
}
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
if (cmpRangeManager)
cmpRangeManager.SetLosCircular(!!settings.CircularMap);
let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager);
if (cmpObstructionManager)
cmpObstructionManager.SetPassabilityCircular(!!settings.CircularMap);
if (settings.TriggerDifficulty !== undefined)
Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger).SetDifficulty(settings.TriggerDifficulty);
else if (settings.SupportedTriggerDifficulties) // used by Atlas and autostart games
{
let difficulties = Engine.ReadJSONFile("simulation/data/settings/trigger_difficulties.json").Data;
let defaultDiff = difficulties.find(d => d.Name == settings.SupportedTriggerDifficulties.Default).Difficulty;
Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger).SetDifficulty(defaultDiff);
}
let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
let gameSettings = { "victoryConditions": settings.VictoryConditions };
if (gameSettings.victoryConditions.indexOf("capture_the_relic") != -1)
{
gameSettings.relicCount = settings.RelicCount;
gameSettings.relicDuration = settings.RelicDuration * 60 * 1000;
}
if (gameSettings.victoryConditions.indexOf("wonder") != -1)
gameSettings.wonderDuration = settings.WonderDuration * 60 * 1000;
if (gameSettings.victoryConditions.indexOf("regicide") != -1)
gameSettings.regicideGarrison = settings.RegicideGarrison;
cmpEndGameManager.SetGameSettings(gameSettings);
cmpEndGameManager.SetAlliedVictory(settings.LockTeams || !settings.LastManStanding);
if (settings.LockTeams && settings.LastManStanding)
warn("Last man standing is only available in games with unlocked teams!");
- if (settings.Garrison)
- for (let holder in settings.Garrison)
- {
- let cmpGarrisonHolder = Engine.QueryInterface(+holder, IID_GarrisonHolder);
- if (!cmpGarrisonHolder)
- warn("Map error in Setup.js: entity " + holder + " can not garrison units");
- else
- cmpGarrisonHolder.initGarrison = settings.Garrison[holder];
- }
-
let cmpCeasefireManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CeasefireManager);
if (settings.Ceasefire)
cmpCeasefireManager.StartCeasefire(settings.Ceasefire * 60 * 1000);
}
Engine.RegisterGlobal("LoadMapSettings", LoadMapSettings);
Index: ps/trunk/source/graphics/MapReader.cpp
===================================================================
--- ps/trunk/source/graphics/MapReader.cpp (revision 23528)
+++ ps/trunk/source/graphics/MapReader.cpp (revision 23529)
@@ -1,1560 +1,1585 @@
-/* Copyright (C) 2019 Wildfire Games.
+/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#include "precompiled.h"
#include "MapReader.h"
#include "graphics/Camera.h"
#include "graphics/CinemaManager.h"
#include "graphics/Entity.h"
#include "graphics/GameView.h"
#include "graphics/MapGenerator.h"
#include "graphics/Patch.h"
#include "graphics/Terrain.h"
#include "graphics/TerrainTextureEntry.h"
#include "graphics/TerrainTextureManager.h"
#include "lib/timer.h"
#include "lib/external_libraries/libsdl.h"
#include "maths/MathUtil.h"
#include "ps/CLogger.h"
#include "ps/Loader.h"
#include "ps/LoaderThunks.h"
#include "ps/World.h"
#include "ps/XML/Xeromyces.h"
#include "renderer/PostprocManager.h"
#include "renderer/SkyManager.h"
#include "renderer/WaterManager.h"
#include "simulation2/Simulation2.h"
#include "simulation2/components/ICmpCinemaManager.h"
+#include "simulation2/components/ICmpGarrisonHolder.h"
#include "simulation2/components/ICmpObstruction.h"
#include "simulation2/components/ICmpOwnership.h"
#include "simulation2/components/ICmpPlayer.h"
#include "simulation2/components/ICmpPlayerManager.h"
#include "simulation2/components/ICmpPosition.h"
#include "simulation2/components/ICmpTerrain.h"
#include "simulation2/components/ICmpVisual.h"
#include "simulation2/components/ICmpWaterManager.h"
#include
CMapReader::CMapReader()
: xml_reader(0), m_PatchesPerSide(0), m_MapGen(0)
{
cur_terrain_tex = 0; // important - resets generator state
}
// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful
void CMapReader::LoadMap(const VfsPath& pathname, JSRuntime* rt, JS::HandleValue settings, CTerrain *pTerrain_,
WaterManager* pWaterMan_, SkyManager* pSkyMan_,
CLightEnv *pLightEnv_, CGameView *pGameView_, CCinemaManager* pCinema_, CTriggerManager* pTrigMan_, CPostprocManager* pPostproc_,
CSimulation2 *pSimulation2_, const CSimContext* pSimContext_, int playerID_, bool skipEntities)
{
pTerrain = pTerrain_;
pLightEnv = pLightEnv_;
pGameView = pGameView_;
pWaterMan = pWaterMan_;
pSkyMan = pSkyMan_;
pCinema = pCinema_;
pTrigMan = pTrigMan_;
pPostproc = pPostproc_;
pSimulation2 = pSimulation2_;
pSimContext = pSimContext_;
m_PlayerID = playerID_;
m_SkipEntities = skipEntities;
m_StartingCameraTarget = INVALID_ENTITY;
m_ScriptSettings.init(rt, settings);
filename_xml = pathname.ChangeExtension(L".xml");
// In some cases (particularly tests) we don't want to bother storing a large
// mostly-empty .pmp file, so we let the XML file specify basic terrain instead.
// If there's an .xml file and no .pmp, then we're probably in this XML-only mode
only_xml = false;
if (!VfsFileExists(pathname) && VfsFileExists(filename_xml))
{
only_xml = true;
}
file_format_version = CMapIO::FILE_VERSION; // default if there's no .pmp
if (!only_xml)
{
// [25ms]
unpacker.Read(pathname, "PSMP");
file_format_version = unpacker.GetVersion();
}
// check oldest supported version
if (file_format_version < FILE_READ_VERSION)
throw PSERROR_Game_World_MapLoadFailed("Could not load terrain file - too old version!");
// delete all existing entities
if (pSimulation2)
pSimulation2->ResetState();
// reset post effects
if (pPostproc)
pPostproc->SetPostEffect(L"default");
// load map or script settings script
if (settings.isUndefined())
RegMemFun(this, &CMapReader::LoadScriptSettings, L"CMapReader::LoadScriptSettings", 50);
else
RegMemFun(this, &CMapReader::LoadRMSettings, L"CMapReader::LoadRMSettings", 50);
// load player settings script (must be done before reading map)
RegMemFun(this, &CMapReader::LoadPlayerSettings, L"CMapReader::LoadPlayerSettings", 50);
// unpack the data
if (!only_xml)
RegMemFun(this, &CMapReader::UnpackMap, L"CMapReader::UnpackMap", 1200);
// read the corresponding XML file
RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 50);
// apply terrain data to the world
RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5);
// read entities
RegMemFun(this, &CMapReader::ReadXMLEntities, L"CMapReader::ReadXMLEntities", 5800);
// apply misc data to the world
RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5);
// load map settings script (must be done after reading map)
RegMemFun(this, &CMapReader::LoadMapSettings, L"CMapReader::LoadMapSettings", 5);
}
// LoadRandomMap: try to load the map data; reinitialise the scene to new data if successful
void CMapReader::LoadRandomMap(const CStrW& scriptFile, JSRuntime* rt, JS::HandleValue settings, CTerrain *pTerrain_,
WaterManager* pWaterMan_, SkyManager* pSkyMan_,
CLightEnv *pLightEnv_, CGameView *pGameView_, CCinemaManager* pCinema_, CTriggerManager* pTrigMan_, CPostprocManager* pPostproc_,
CSimulation2 *pSimulation2_, int playerID_)
{
m_ScriptFile = scriptFile;
pSimulation2 = pSimulation2_;
pSimContext = pSimulation2 ? &pSimulation2->GetSimContext() : NULL;
m_ScriptSettings.init(rt, settings);
pTerrain = pTerrain_;
pLightEnv = pLightEnv_;
pGameView = pGameView_;
pWaterMan = pWaterMan_;
pSkyMan = pSkyMan_;
pCinema = pCinema_;
pTrigMan = pTrigMan_;
pPostproc = pPostproc_;
m_PlayerID = playerID_;
m_SkipEntities = false;
m_StartingCameraTarget = INVALID_ENTITY;
// delete all existing entities
if (pSimulation2)
pSimulation2->ResetState();
only_xml = false;
// copy random map settings (before entity creation)
RegMemFun(this, &CMapReader::LoadRMSettings, L"CMapReader::LoadRMSettings", 50);
// load player settings script (must be done before reading map)
RegMemFun(this, &CMapReader::LoadPlayerSettings, L"CMapReader::LoadPlayerSettings", 50);
// load map generator with random map script
RegMemFun(this, &CMapReader::GenerateMap, L"CMapReader::GenerateMap", 20000);
// parse RMS results into terrain structure
RegMemFun(this, &CMapReader::ParseTerrain, L"CMapReader::ParseTerrain", 500);
// parse RMS results into environment settings
RegMemFun(this, &CMapReader::ParseEnvironment, L"CMapReader::ParseEnvironment", 5);
// parse RMS results into camera settings
RegMemFun(this, &CMapReader::ParseCamera, L"CMapReader::ParseCamera", 5);
// apply terrain data to the world
RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5);
// parse RMS results into entities
RegMemFun(this, &CMapReader::ParseEntities, L"CMapReader::ParseEntities", 1000);
// apply misc data to the world
RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5);
// load map settings script (must be done after reading map)
RegMemFun(this, &CMapReader::LoadMapSettings, L"CMapReader::LoadMapSettings", 5);
}
// UnpackMap: unpack the given data from the raw data stream into local variables
int CMapReader::UnpackMap()
{
return UnpackTerrain();
}
// UnpackTerrain: unpack the terrain from the end of the input data stream
// - data: map size, heightmap, list of textures used by map, texture tile assignments
int CMapReader::UnpackTerrain()
{
// yield after this time is reached. balances increased progress bar
// smoothness vs. slowing down loading.
const double end_time = timer_Time() + 200e-3;
// first call to generator (this is skipped after first call,
// i.e. when the loop below was interrupted)
if (cur_terrain_tex == 0)
{
m_PatchesPerSide = (ssize_t)unpacker.UnpackSize();
// unpack heightmap [600us]
size_t verticesPerSide = m_PatchesPerSide*PATCH_SIZE+1;
m_Heightmap.resize(SQR(verticesPerSide));
unpacker.UnpackRaw(&m_Heightmap[0], SQR(verticesPerSide)*sizeof(u16));
// unpack # textures
num_terrain_tex = unpacker.UnpackSize();
m_TerrainTextures.reserve(num_terrain_tex);
}
// unpack texture names; find handle for each texture.
// interruptible.
while (cur_terrain_tex < num_terrain_tex)
{
CStr texturename;
unpacker.UnpackString(texturename);
ENSURE(CTerrainTextureManager::IsInitialised()); // we need this for the terrain properties (even when graphics are disabled)
CTerrainTextureEntry* texentry = g_TexMan.FindTexture(texturename);
m_TerrainTextures.push_back(texentry);
cur_terrain_tex++;
LDR_CHECK_TIMEOUT(cur_terrain_tex, num_terrain_tex);
}
// unpack tile data [3ms]
ssize_t tilesPerSide = m_PatchesPerSide*PATCH_SIZE;
m_Tiles.resize(size_t(SQR(tilesPerSide)));
unpacker.UnpackRaw(&m_Tiles[0], sizeof(STileDesc)*m_Tiles.size());
// reset generator state.
cur_terrain_tex = 0;
return 0;
}
int CMapReader::ApplyTerrainData()
{
if (m_PatchesPerSide == 0)
{
// we'll probably crash when trying to use this map later
throw PSERROR_Game_World_MapLoadFailed("Error loading map: no terrain data.\nCheck application log for details.");
}
if (!only_xml)
{
// initialise the terrain
pTerrain->Initialize(m_PatchesPerSide, &m_Heightmap[0]);
// setup the textures on the minipatches
STileDesc* tileptr = &m_Tiles[0];
for (ssize_t j=0; jGetPatch(i,j)->m_MiniPatches[m][k]; // can't fail
mp.Tex = m_TerrainTextures[tileptr->m_Tex1Index];
mp.Priority = tileptr->m_Priority;
tileptr++;
}
}
}
}
}
CmpPtr cmpTerrain(*pSimContext, SYSTEM_ENTITY);
if (cmpTerrain)
cmpTerrain->ReloadTerrain();
return 0;
}
// ApplyData: take all the input data, and rebuild the scene from it
int CMapReader::ApplyData()
{
// copy over the lighting parameters
if (pLightEnv)
*pLightEnv = m_LightEnv;
CmpPtr cmpPlayerManager(*pSimContext, SYSTEM_ENTITY);
if (pGameView && cmpPlayerManager)
{
// Default to global camera (with constraints)
pGameView->ResetCameraTarget(pGameView->GetCamera()->GetFocus());
// TODO: Starting rotation?
CmpPtr cmpPlayer(*pSimContext, cmpPlayerManager->GetPlayerByID(m_PlayerID));
if (cmpPlayer && cmpPlayer->HasStartingCamera())
{
// Use player starting camera
CFixedVector3D pos = cmpPlayer->GetStartingCameraPos();
pGameView->ResetCameraTarget(CVector3D(pos.X.ToFloat(), pos.Y.ToFloat(), pos.Z.ToFloat()));
}
else if (m_StartingCameraTarget != INVALID_ENTITY)
{
// Point camera at entity
CmpPtr cmpPosition(*pSimContext, m_StartingCameraTarget);
if (cmpPosition)
{
CFixedVector3D pos = cmpPosition->GetPosition();
pGameView->ResetCameraTarget(CVector3D(pos.X.ToFloat(), pos.Y.ToFloat(), pos.Z.ToFloat()));
}
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
PSRETURN CMapSummaryReader::LoadMap(const VfsPath& pathname)
{
VfsPath filename_xml = pathname.ChangeExtension(L".xml");
CXeromyces xmb_file;
if (xmb_file.Load(g_VFS, filename_xml, "scenario") != PSRETURN_OK)
return PSRETURN_File_ReadFailed;
// Define all the relevant elements used in the XML file
#define EL(x) int el_##x = xmb_file.GetElementID(#x)
#define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
EL(scenario);
EL(scriptsettings);
#undef AT
#undef EL
XMBElement root = xmb_file.GetRoot();
ENSURE(root.GetNodeName() == el_scenario);
XERO_ITER_EL(root, child)
{
int child_name = child.GetNodeName();
if (child_name == el_scriptsettings)
{
m_ScriptSettings = child.GetText();
}
}
return PSRETURN_OK;
}
void CMapSummaryReader::GetMapSettings(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret)
{
JSContext* cx = scriptInterface.GetContext();
JSAutoRequest rq(cx);
ScriptInterface::CreateObject(cx, ret);
if (m_ScriptSettings.empty())
return;
JS::RootedValue scriptSettingsVal(cx);
scriptInterface.ParseJSON(m_ScriptSettings, &scriptSettingsVal);
scriptInterface.SetProperty(ret, "settings", scriptSettingsVal, false);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Holds various state data while reading maps, so that loading can be
// interrupted (e.g. to update the progress display) then later resumed.
class CXMLReader
{
NONCOPYABLE(CXMLReader);
public:
CXMLReader(const VfsPath& xml_filename, CMapReader& mapReader)
: m_MapReader(mapReader), nodes(NULL, 0, NULL)
{
Init(xml_filename);
}
CStr ReadScriptSettings();
// read everything except for entities
void ReadXML();
// return semantics: see Loader.cpp!LoadFunc.
int ProgressiveReadEntities();
private:
CXeromyces xmb_file;
CMapReader& m_MapReader;
int el_entity;
int el_tracks;
int el_template, el_player;
int el_position, el_orientation, el_obstruction;
+ int el_garrison;
int el_actor;
int at_x, at_y, at_z;
int at_group, at_group2;
int at_angle;
int at_uid;
int at_seed;
XMBElementList nodes; // children of root
// loop counters
size_t node_idx;
size_t entity_idx;
// # entities+nonentities processed and total (for progress calc)
int completed_jobs, total_jobs;
// maximum used entity ID, so we can safely allocate new ones
entity_id_t max_uid;
void Init(const VfsPath& xml_filename);
void ReadTerrain(XMBElement parent);
void ReadEnvironment(XMBElement parent);
void ReadCamera(XMBElement parent);
void ReadPaths(XMBElement parent);
void ReadTriggers(XMBElement parent);
int ReadEntities(XMBElement parent, double end_time);
};
void CXMLReader::Init(const VfsPath& xml_filename)
{
// must only assign once, so do it here
node_idx = entity_idx = 0;
if (xmb_file.Load(g_VFS, xml_filename, "scenario") != PSRETURN_OK)
throw PSERROR_Game_World_MapLoadFailed("Could not read map XML file!");
// define the elements and attributes that are frequently used in the XML file,
// so we don't need to do lots of string construction and comparison when
// reading the data.
// (Needs to be synchronised with the list in CXMLReader - ugh)
#define EL(x) el_##x = xmb_file.GetElementID(#x)
#define AT(x) at_##x = xmb_file.GetAttributeID(#x)
EL(entity);
EL(tracks);
EL(template);
EL(player);
EL(position);
+ EL(garrison);
EL(orientation);
EL(obstruction);
EL(actor);
AT(x); AT(y); AT(z);
AT(group); AT(group2);
AT(angle);
AT(uid);
AT(seed);
#undef AT
#undef EL
XMBElement root = xmb_file.GetRoot();
ENSURE(xmb_file.GetElementString(root.GetNodeName()) == "Scenario");
nodes = root.GetChildNodes();
// find out total number of entities+nonentities
// (used when calculating progress)
completed_jobs = 0;
total_jobs = 0;
for (XMBElement node : nodes)
total_jobs += node.GetChildNodes().size();
// Find the maximum entity ID, so we can safely allocate new IDs without conflicts
max_uid = SYSTEM_ENTITY;
XMBElement ents = nodes.GetFirstNamedItem(xmb_file.GetElementID("Entities"));
XERO_ITER_EL(ents, ent)
{
CStr uid = ent.GetAttributes().GetNamedItem(at_uid);
max_uid = std::max(max_uid, (entity_id_t)uid.ToUInt());
}
}
CStr CXMLReader::ReadScriptSettings()
{
XMBElement root = xmb_file.GetRoot();
ENSURE(xmb_file.GetElementString(root.GetNodeName()) == "Scenario");
nodes = root.GetChildNodes();
XMBElement settings = nodes.GetFirstNamedItem(xmb_file.GetElementID("ScriptSettings"));
return settings.GetText();
}
void CXMLReader::ReadTerrain(XMBElement parent)
{
#define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
AT(patches);
AT(texture);
AT(priority);
AT(height);
#undef AT
ssize_t patches = 9;
CStr texture = "grass1_spring";
int priority = 0;
u16 height = 16384;
XERO_ITER_ATTR(parent, attr)
{
if (attr.Name == at_patches)
patches = attr.Value.ToInt();
else if (attr.Name == at_texture)
texture = attr.Value;
else if (attr.Name == at_priority)
priority = attr.Value.ToInt();
else if (attr.Name == at_height)
height = (u16)attr.Value.ToInt();
}
m_MapReader.m_PatchesPerSide = patches;
// Load the texture
ENSURE(CTerrainTextureManager::IsInitialised()); // we need this for the terrain properties (even when graphics are disabled)
CTerrainTextureEntry* texentry = g_TexMan.FindTexture(texture);
m_MapReader.pTerrain->Initialize(patches, NULL);
// Fill the heightmap
u16* heightmap = m_MapReader.pTerrain->GetHeightMap();
ssize_t verticesPerSide = m_MapReader.pTerrain->GetVerticesPerSide();
for (ssize_t i = 0; i < SQR(verticesPerSide); ++i)
heightmap[i] = height;
// Fill the texture map
for (ssize_t pz = 0; pz < patches; ++pz)
{
for (ssize_t px = 0; px < patches; ++px)
{
CPatch* patch = m_MapReader.pTerrain->GetPatch(px, pz); // can't fail
for (ssize_t z = 0; z < PATCH_SIZE; ++z)
{
for (ssize_t x = 0; x < PATCH_SIZE; ++x)
{
patch->m_MiniPatches[z][x].Tex = texentry;
patch->m_MiniPatches[z][x].Priority = priority;
}
}
}
}
}
void CXMLReader::ReadEnvironment(XMBElement parent)
{
#define EL(x) int el_##x = xmb_file.GetElementID(#x)
#define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
EL(posteffect);
EL(skyset);
EL(suncolor);
EL(sunelevation);
EL(sunrotation);
EL(terrainambientcolor);
EL(unitsambientcolor);
EL(water);
EL(waterbody);
EL(type);
EL(color);
EL(tint);
EL(height);
EL(waviness);
EL(murkiness);
EL(windangle);
EL(fog);
EL(fogcolor);
EL(fogfactor);
EL(fogthickness);
EL(postproc);
EL(brightness);
EL(contrast);
EL(saturation);
EL(bloom);
AT(r); AT(g); AT(b);
#undef AT
#undef EL
XERO_ITER_EL(parent, element)
{
int element_name = element.GetNodeName();
XMBAttributeList attrs = element.GetAttributes();
if (element_name == el_skyset)
{
if (m_MapReader.pSkyMan)
m_MapReader.pSkyMan->SetSkySet(element.GetText().FromUTF8());
}
else if (element_name == el_suncolor)
{
m_MapReader.m_LightEnv.m_SunColor = RGBColor(
attrs.GetNamedItem(at_r).ToFloat(),
attrs.GetNamedItem(at_g).ToFloat(),
attrs.GetNamedItem(at_b).ToFloat());
}
else if (element_name == el_sunelevation)
{
m_MapReader.m_LightEnv.m_Elevation = attrs.GetNamedItem(at_angle).ToFloat();
}
else if (element_name == el_sunrotation)
{
m_MapReader.m_LightEnv.m_Rotation = attrs.GetNamedItem(at_angle).ToFloat();
}
else if (element_name == el_terrainambientcolor)
{
m_MapReader.m_LightEnv.m_TerrainAmbientColor = RGBColor(
attrs.GetNamedItem(at_r).ToFloat(),
attrs.GetNamedItem(at_g).ToFloat(),
attrs.GetNamedItem(at_b).ToFloat());
}
else if (element_name == el_unitsambientcolor)
{
m_MapReader.m_LightEnv.m_UnitsAmbientColor = RGBColor(
attrs.GetNamedItem(at_r).ToFloat(),
attrs.GetNamedItem(at_g).ToFloat(),
attrs.GetNamedItem(at_b).ToFloat());
}
else if (element_name == el_fog)
{
XERO_ITER_EL(element, fog)
{
int element_name = fog.GetNodeName();
if (element_name == el_fogcolor)
{
XMBAttributeList attrs = fog.GetAttributes();
m_MapReader.m_LightEnv.m_FogColor = RGBColor(
attrs.GetNamedItem(at_r).ToFloat(),
attrs.GetNamedItem(at_g).ToFloat(),
attrs.GetNamedItem(at_b).ToFloat());
}
else if (element_name == el_fogfactor)
{
m_MapReader.m_LightEnv.m_FogFactor = fog.GetText().ToFloat();
}
else if (element_name == el_fogthickness)
{
m_MapReader.m_LightEnv.m_FogMax = fog.GetText().ToFloat();
}
}
}
else if (element_name == el_postproc)
{
XERO_ITER_EL(element, postproc)
{
int element_name = postproc.GetNodeName();
if (element_name == el_brightness)
{
m_MapReader.m_LightEnv.m_Brightness = postproc.GetText().ToFloat();
}
else if (element_name == el_contrast)
{
m_MapReader.m_LightEnv.m_Contrast = postproc.GetText().ToFloat();
}
else if (element_name == el_saturation)
{
m_MapReader.m_LightEnv.m_Saturation = postproc.GetText().ToFloat();
}
else if (element_name == el_bloom)
{
m_MapReader.m_LightEnv.m_Bloom = postproc.GetText().ToFloat();
}
else if (element_name == el_posteffect)
{
if (m_MapReader.pPostproc)
m_MapReader.pPostproc->SetPostEffect(postproc.GetText().FromUTF8());
}
}
}
else if (element_name == el_water)
{
XERO_ITER_EL(element, waterbody)
{
ENSURE(waterbody.GetNodeName() == el_waterbody);
XERO_ITER_EL(waterbody, waterelement)
{
int element_name = waterelement.GetNodeName();
if (element_name == el_height)
{
CmpPtr cmpWaterManager(*m_MapReader.pSimContext, SYSTEM_ENTITY);
ENSURE(cmpWaterManager);
cmpWaterManager->SetWaterLevel(entity_pos_t::FromString(waterelement.GetText()));
continue;
}
// The rest are purely graphical effects, and should be ignored if
// graphics are disabled
if (!m_MapReader.pWaterMan)
continue;
if (element_name == el_type)
{
if (waterelement.GetText() == "default")
m_MapReader.pWaterMan->m_WaterType = L"ocean";
else
m_MapReader.pWaterMan->m_WaterType = waterelement.GetText().FromUTF8();
}
#define READ_COLOR(el, out) \
else if (element_name == el) \
{ \
XMBAttributeList attrs = waterelement.GetAttributes(); \
out = CColor( \
attrs.GetNamedItem(at_r).ToFloat(), \
attrs.GetNamedItem(at_g).ToFloat(), \
attrs.GetNamedItem(at_b).ToFloat(), \
1.f); \
}
#define READ_FLOAT(el, out) \
else if (element_name == el) \
{ \
out = waterelement.GetText().ToFloat(); \
} \
READ_COLOR(el_color, m_MapReader.pWaterMan->m_WaterColor)
READ_COLOR(el_tint, m_MapReader.pWaterMan->m_WaterTint)
READ_FLOAT(el_waviness, m_MapReader.pWaterMan->m_Waviness)
READ_FLOAT(el_murkiness, m_MapReader.pWaterMan->m_Murkiness)
READ_FLOAT(el_windangle, m_MapReader.pWaterMan->m_WindAngle)
#undef READ_FLOAT
#undef READ_COLOR
else
debug_warn(L"Invalid map XML data");
}
}
}
else
debug_warn(L"Invalid map XML data");
}
m_MapReader.m_LightEnv.CalculateSunDirection();
}
void CXMLReader::ReadCamera(XMBElement parent)
{
// defaults if we don't find player starting camera
#define EL(x) int el_##x = xmb_file.GetElementID(#x)
#define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
EL(declination);
EL(rotation);
EL(position);
AT(angle);
AT(x); AT(y); AT(z);
#undef AT
#undef EL
float declination = DEGTORAD(30.f), rotation = DEGTORAD(-45.f);
CVector3D translation = CVector3D(100, 150, -100);
XERO_ITER_EL(parent, element)
{
int element_name = element.GetNodeName();
XMBAttributeList attrs = element.GetAttributes();
if (element_name == el_declination)
{
declination = attrs.GetNamedItem(at_angle).ToFloat();
}
else if (element_name == el_rotation)
{
rotation = attrs.GetNamedItem(at_angle).ToFloat();
}
else if (element_name == el_position)
{
translation = CVector3D(
attrs.GetNamedItem(at_x).ToFloat(),
attrs.GetNamedItem(at_y).ToFloat(),
attrs.GetNamedItem(at_z).ToFloat());
}
else
debug_warn(L"Invalid map XML data");
}
if (m_MapReader.pGameView)
{
m_MapReader.pGameView->GetCamera()->m_Orientation.SetXRotation(declination);
m_MapReader.pGameView->GetCamera()->m_Orientation.RotateY(rotation);
m_MapReader.pGameView->GetCamera()->m_Orientation.Translate(translation);
m_MapReader.pGameView->GetCamera()->UpdateFrustum();
}
}
void CXMLReader::ReadPaths(XMBElement parent)
{
#define EL(x) int el_##x = xmb_file.GetElementID(#x)
#define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
EL(path);
EL(rotation);
EL(node);
EL(position);
EL(target);
AT(name);
AT(timescale);
AT(orientation);
AT(mode);
AT(style);
AT(x);
AT(y);
AT(z);
AT(deltatime);
#undef EL
#undef AT
CmpPtr cmpCinemaManager(*m_MapReader.pSimContext, SYSTEM_ENTITY);
XERO_ITER_EL(parent, element)
{
int elementName = element.GetNodeName();
if (elementName == el_path)
{
CCinemaData pathData;
XMBAttributeList attrs = element.GetAttributes();
CStrW pathName(attrs.GetNamedItem(at_name).FromUTF8());
pathData.m_Name = pathName;
pathData.m_Timescale = fixed::FromString(attrs.GetNamedItem(at_timescale));
pathData.m_Orientation = attrs.GetNamedItem(at_orientation).FromUTF8();
pathData.m_Mode = attrs.GetNamedItem(at_mode).FromUTF8();
pathData.m_Style = attrs.GetNamedItem(at_style).FromUTF8();
TNSpline positionSpline, targetSpline;
fixed lastPositionTime = fixed::Zero();
fixed lastTargetTime = fixed::Zero();
XERO_ITER_EL(element, pathChild)
{
elementName = pathChild.GetNodeName();
attrs = pathChild.GetAttributes();
// Load node data used for spline
if (elementName == el_node)
{
lastPositionTime += fixed::FromString(attrs.GetNamedItem(at_deltatime));
lastTargetTime += fixed::FromString(attrs.GetNamedItem(at_deltatime));
XERO_ITER_EL(pathChild, nodeChild)
{
elementName = nodeChild.GetNodeName();
attrs = nodeChild.GetAttributes();
if (elementName == el_position)
{
CFixedVector3D position(fixed::FromString(attrs.GetNamedItem(at_x)),
fixed::FromString(attrs.GetNamedItem(at_y)),
fixed::FromString(attrs.GetNamedItem(at_z)));
positionSpline.AddNode(position, CFixedVector3D(), lastPositionTime);
lastPositionTime = fixed::Zero();
}
else if (elementName == el_rotation)
{
// TODO: Implement rotation slerp/spline as another object
}
else if (elementName == el_target)
{
CFixedVector3D targetPosition(fixed::FromString(attrs.GetNamedItem(at_x)),
fixed::FromString(attrs.GetNamedItem(at_y)),
fixed::FromString(attrs.GetNamedItem(at_z)));
targetSpline.AddNode(targetPosition, CFixedVector3D(), lastTargetTime);
lastTargetTime = fixed::Zero();
}
else
LOGWARNING("Invalid cinematic element for node child");
}
}
else
LOGWARNING("Invalid cinematic element for path child");
}
// Construct cinema path with data gathered
CCinemaPath path(pathData, positionSpline, targetSpline);
if (path.Empty())
{
LOGWARNING("Path with name '%s' is empty", pathName.ToUTF8());
return;
}
if (!cmpCinemaManager)
continue;
if (!cmpCinemaManager->HasPath(pathName))
cmpCinemaManager->AddPath(path);
else
LOGWARNING("Path with name '%s' already exists", pathName.ToUTF8());
}
else
LOGWARNING("Invalid path child with name '%s'", element.GetText());
}
}
void CXMLReader::ReadTriggers(XMBElement UNUSED(parent))
{
}
int CXMLReader::ReadEntities(XMBElement parent, double end_time)
{
XMBElementList entities = parent.GetChildNodes();
ENSURE(m_MapReader.pSimulation2);
CSimulation2& sim = *m_MapReader.pSimulation2;
CmpPtr cmpPlayerManager(sim, SYSTEM_ENTITY);
while (entity_idx < entities.size())
{
// all new state at this scope and below doesn't need to be
// wrapped, since we only yield after a complete iteration.
XMBElement entity = entities[entity_idx++];
ENSURE(entity.GetNodeName() == el_entity);
XMBAttributeList attrs = entity.GetAttributes();
CStr uid = attrs.GetNamedItem(at_uid);
ENSURE(!uid.empty());
int EntityUid = uid.ToInt();
CStrW TemplateName;
int PlayerID = 0;
+ std::vector Garrison;
CFixedVector3D Position;
CFixedVector3D Orientation;
long Seed = -1;
// Obstruction control groups.
entity_id_t ControlGroup = INVALID_ENTITY;
entity_id_t ControlGroup2 = INVALID_ENTITY;
XERO_ITER_EL(entity, setting)
{
int element_name = setting.GetNodeName();
//
if (element_name == el_template)
{
TemplateName = setting.GetText().FromUTF8();
}
//
else if (element_name == el_player)
{
PlayerID = setting.GetText().ToInt();
}
//
else if (element_name == el_position)
{
XMBAttributeList attrs = setting.GetAttributes();
Position = CFixedVector3D(
fixed::FromString(attrs.GetNamedItem(at_x)),
fixed::FromString(attrs.GetNamedItem(at_y)),
fixed::FromString(attrs.GetNamedItem(at_z)));
}
//
else if (element_name == el_orientation)
{
XMBAttributeList attrs = setting.GetAttributes();
Orientation = CFixedVector3D(
fixed::FromString(attrs.GetNamedItem(at_x)),
fixed::FromString(attrs.GetNamedItem(at_y)),
fixed::FromString(attrs.GetNamedItem(at_z)));
// TODO: what happens if some attributes are missing?
}
//
else if (element_name == el_obstruction)
{
XMBAttributeList attrs = setting.GetAttributes();
ControlGroup = attrs.GetNamedItem(at_group).ToInt();
ControlGroup2 = attrs.GetNamedItem(at_group2).ToInt();
}
+ //
+ else if (element_name == el_garrison)
+ {
+ XMBElementList garrison = setting.GetChildNodes();
+ Garrison.reserve(garrison.size());
+ for (const XMBElement& garr_ent : garrison)
+ {
+ XMBAttributeList attrs = garr_ent.GetAttributes();
+ Garrison.push_back(attrs.GetNamedItem(at_uid).ToInt());
+ }
+ }
//
else if (element_name == el_actor)
{
XMBAttributeList attrs = setting.GetAttributes();
CStr seedStr = attrs.GetNamedItem(at_seed);
if (!seedStr.empty())
{
Seed = seedStr.ToLong();
ENSURE(Seed >= 0);
}
}
else
debug_warn(L"Invalid map XML data");
}
entity_id_t ent = sim.AddEntity(TemplateName, EntityUid);
entity_id_t player = cmpPlayerManager->GetPlayerByID(PlayerID);
if (ent == INVALID_ENTITY || player == INVALID_ENTITY)
{ // Don't add entities with invalid player IDs
LOGERROR("Failed to load entity template '%s'", utf8_from_wstring(TemplateName));
}
else
{
CmpPtr cmpPosition(sim, ent);
if (cmpPosition)
{
cmpPosition->JumpTo(Position.X, Position.Z);
cmpPosition->SetYRotation(Orientation.Y);
// TODO: other parts of the position
}
CmpPtr cmpOwnership(sim, ent);
if (cmpOwnership)
cmpOwnership->SetOwner(PlayerID);
+ if (!Garrison.empty())
+ {
+ CmpPtr cmpGarrisonHolder(sim, ent);
+ if (cmpGarrisonHolder)
+ cmpGarrisonHolder->SetInitEntities(Garrison);
+ else
+ LOGERROR("CXMLMapReader::ReadEntities() entity '%d' of player '%d' has no GarrisonHolder component and thus cannot garrison units.", ent, PlayerID);
+ Garrison.clear();
+ }
+
CmpPtr cmpObstruction(sim, ent);
if (cmpObstruction)
{
if (ControlGroup != INVALID_ENTITY)
cmpObstruction->SetControlGroup(ControlGroup);
if (ControlGroup2 != INVALID_ENTITY)
cmpObstruction->SetControlGroup2(ControlGroup2);
cmpObstruction->ResolveFoundationCollisions();
}
CmpPtr cmpVisual(sim, ent);
if (cmpVisual)
{
if (Seed != -1)
cmpVisual->SetActorSeed((u32)Seed);
// TODO: variation/selection strings
}
if (PlayerID == m_MapReader.m_PlayerID && (boost::algorithm::ends_with(TemplateName, L"civil_centre") || m_MapReader.m_StartingCameraTarget == INVALID_ENTITY))
{
// Focus on civil centre or first entity owned by player
m_MapReader.m_StartingCameraTarget = ent;
}
}
completed_jobs++;
LDR_CHECK_TIMEOUT(completed_jobs, total_jobs);
}
return 0;
}
void CXMLReader::ReadXML()
{
for (XMBElement node : nodes)
{
CStr name = xmb_file.GetElementString(node.GetNodeName());
if (name == "Terrain")
{
ReadTerrain(node);
}
else if (name == "Environment")
{
ReadEnvironment(node);
}
else if (name == "Camera")
{
ReadCamera(node);
}
else if (name == "ScriptSettings")
{
// Already loaded - this is to prevent an assertion
}
else if (name == "Entities")
{
// Handled by ProgressiveReadEntities instead
}
else if (name == "Paths")
{
ReadPaths(node);
}
else if (name == "Triggers")
{
ReadTriggers(node);
}
else if (name == "Script")
{
if (m_MapReader.pSimulation2)
m_MapReader.pSimulation2->SetStartupScript(node.GetText());
}
else
{
debug_printf("Invalid XML element in map file: %s\n", name.c_str());
debug_warn(L"Invalid map XML data");
}
}
}
int CXMLReader::ProgressiveReadEntities()
{
// yield after this time is reached. balances increased progress bar
// smoothness vs. slowing down loading.
const double end_time = timer_Time() + 200e-3;
int ret;
while (node_idx < nodes.size())
{
XMBElement node = nodes[node_idx];
CStr name = xmb_file.GetElementString(node.GetNodeName());
if (name == "Entities")
{
if (!m_MapReader.m_SkipEntities)
{
ret = ReadEntities(node, end_time);
if (ret != 0) // error or timed out
return ret;
}
}
node_idx++;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// load script settings from map
int CMapReader::LoadScriptSettings()
{
if (!xml_reader)
xml_reader = new CXMLReader(filename_xml, *this);
// parse the script settings
if (pSimulation2)
pSimulation2->SetMapSettings(xml_reader->ReadScriptSettings());
return 0;
}
// load player settings script
int CMapReader::LoadPlayerSettings()
{
if (pSimulation2)
pSimulation2->LoadPlayerSettings(true);
return 0;
}
// load map settings script
int CMapReader::LoadMapSettings()
{
if (pSimulation2)
pSimulation2->LoadMapSettings();
return 0;
}
int CMapReader::ReadXML()
{
if (!xml_reader)
xml_reader = new CXMLReader(filename_xml, *this);
xml_reader->ReadXML();
return 0;
}
// progressive
int CMapReader::ReadXMLEntities()
{
if (!xml_reader)
xml_reader = new CXMLReader(filename_xml, *this);
int ret = xml_reader->ProgressiveReadEntities();
// finished or failed
if (ret <= 0)
{
SAFE_DELETE(xml_reader);
}
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int CMapReader::LoadRMSettings()
{
// copy random map settings over to sim
ENSURE(pSimulation2);
pSimulation2->SetMapSettings(m_ScriptSettings);
return 0;
}
int CMapReader::GenerateMap()
{
JSContext* cx = pSimulation2->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
if (!m_MapGen)
{
// Initialize map generator
m_MapGen = new CMapGenerator();
VfsPath scriptPath;
if (m_ScriptFile.length())
scriptPath = L"maps/random/"+m_ScriptFile;
// Stringify settings to pass across threads
std::string scriptSettings = pSimulation2->GetScriptInterface().StringifyJSON(&m_ScriptSettings);
// Try to generate map
m_MapGen->GenerateMap(scriptPath, scriptSettings);
}
// Check status
int progress = m_MapGen->GetProgress();
if (progress < 0)
{
// RMS failed - return to main menu
throw PSERROR_Game_World_MapLoadFailed("Error generating random map.\nCheck application log for details.");
}
else if (progress == 0)
{
// Finished, get results as StructuredClone object, which must be read to obtain the JS::Value
shared_ptr results = m_MapGen->GetResults();
// Parse data into simulation context
JS::RootedValue data(cx);
pSimulation2->GetScriptInterface().ReadStructuredClone(results, &data);
if (data.isUndefined())
{
// RMS failed - return to main menu
throw PSERROR_Game_World_MapLoadFailed("Error generating random map.\nCheck application log for details.");
}
else
{
m_MapData.init(cx, data);
}
}
else
{
// Still working
// Sleep for a while, slowing down the rendering thread
// to allow more CPU for the map generator thread
SDL_Delay(100);
}
// return progress
return progress;
};
int CMapReader::ParseTerrain()
{
TIMER(L"ParseTerrain");
JSContext* cx = pSimulation2->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
// parse terrain from map data
// an error here should stop the loading process
#define GET_TERRAIN_PROPERTY(val, prop, out)\
if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\
{ LOGERROR("CMapReader::ParseTerrain() failed to get '%s' property", #prop);\
throw PSERROR_Game_World_MapLoadFailed("Error parsing terrain data.\nCheck application log for details"); }
u32 size;
GET_TERRAIN_PROPERTY(m_MapData, size, size)
m_PatchesPerSide = size / PATCH_SIZE;
// flat heightmap of u16 data
GET_TERRAIN_PROPERTY(m_MapData, height, m_Heightmap)
// load textures
std::vector textureNames;
GET_TERRAIN_PROPERTY(m_MapData, textureNames, textureNames)
num_terrain_tex = textureNames.size();
while (cur_terrain_tex < num_terrain_tex)
{
ENSURE(CTerrainTextureManager::IsInitialised()); // we need this for the terrain properties (even when graphics are disabled)
CTerrainTextureEntry* texentry = g_TexMan.FindTexture(textureNames[cur_terrain_tex]);
m_TerrainTextures.push_back(texentry);
cur_terrain_tex++;
}
// build tile data
m_Tiles.resize(SQR(size));
JS::RootedValue tileData(cx);
GET_TERRAIN_PROPERTY(m_MapData, tileData, &tileData)
// parse tile data object into flat arrays
std::vector tileIndex;
std::vector tilePriority;
GET_TERRAIN_PROPERTY(tileData, index, tileIndex);
GET_TERRAIN_PROPERTY(tileData, priority, tilePriority);
ENSURE(SQR(size) == tileIndex.size() && SQR(size) == tilePriority.size());
// reorder by patches and store
for (size_t x = 0; x < size; ++x)
{
size_t patchX = x / PATCH_SIZE;
size_t offX = x % PATCH_SIZE;
for (size_t y = 0; y < size; ++y)
{
size_t patchY = y / PATCH_SIZE;
size_t offY = y % PATCH_SIZE;
STileDesc tile;
tile.m_Tex1Index = tileIndex[y*size + x];
tile.m_Tex2Index = 0xFFFF;
tile.m_Priority = tilePriority[y*size + x];
m_Tiles[(patchY * m_PatchesPerSide + patchX) * SQR(PATCH_SIZE) + (offY * PATCH_SIZE + offX)] = tile;
}
}
// reset generator state
cur_terrain_tex = 0;
#undef GET_TERRAIN_PROPERTY
return 0;
}
int CMapReader::ParseEntities()
{
TIMER(L"ParseEntities");
JSContext* cx = pSimulation2->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
// parse entities from map data
std::vector entities;
if (!pSimulation2->GetScriptInterface().GetProperty(m_MapData, "entities", entities))
LOGWARNING("CMapReader::ParseEntities() failed to get 'entities' property");
CSimulation2& sim = *pSimulation2;
CmpPtr cmpPlayerManager(sim, SYSTEM_ENTITY);
size_t entity_idx = 0;
size_t num_entities = entities.size();
Entity currEnt;
while (entity_idx < num_entities)
{
// Get current entity struct
currEnt = entities[entity_idx];
entity_id_t ent = pSimulation2->AddEntity(currEnt.templateName, currEnt.entityID);
entity_id_t player = cmpPlayerManager->GetPlayerByID(currEnt.playerID);
if (ent == INVALID_ENTITY || player == INVALID_ENTITY)
{ // Don't add entities with invalid player IDs
LOGERROR("Failed to load entity template '%s'", utf8_from_wstring(currEnt.templateName));
}
else
{
CmpPtr cmpPosition(sim, ent);
if (cmpPosition)
{
cmpPosition->JumpTo(currEnt.position.X * (int)TERRAIN_TILE_SIZE, currEnt.position.Z * (int)TERRAIN_TILE_SIZE);
cmpPosition->SetYRotation(currEnt.rotation.Y);
// TODO: other parts of the position
}
CmpPtr cmpOwnership(sim, ent);
if (cmpOwnership)
cmpOwnership->SetOwner(currEnt.playerID);
// Detect and fix collisions between foundation-blocking entities.
// This presently serves to copy wall tower control groups to wall
// segments, allowing players to expand RMS-generated walls.
CmpPtr cmpObstruction(sim, ent);
if (cmpObstruction)
cmpObstruction->ResolveFoundationCollisions();
if (currEnt.playerID == m_PlayerID && (boost::algorithm::ends_with(currEnt.templateName, L"civil_centre") || m_StartingCameraTarget == INVALID_ENTITY))
{
// Focus on civil centre or first entity owned by player
m_StartingCameraTarget = currEnt.entityID;
}
}
entity_idx++;
}
return 0;
}
int CMapReader::ParseEnvironment()
{
// parse environment settings from map data
JSContext* cx = pSimulation2->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
#define GET_ENVIRONMENT_PROPERTY(val, prop, out)\
if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\
LOGWARNING("CMapReader::ParseEnvironment() failed to get '%s' property", #prop);
JS::RootedValue envObj(cx);
GET_ENVIRONMENT_PROPERTY(m_MapData, Environment, &envObj)
if (envObj.isUndefined())
{
LOGWARNING("CMapReader::ParseEnvironment(): Environment settings not found");
return 0;
}
if (pPostproc)
pPostproc->SetPostEffect(L"default");
std::wstring skySet;
GET_ENVIRONMENT_PROPERTY(envObj, SkySet, skySet)
if (pSkyMan)
pSkyMan->SetSkySet(skySet);
CColor sunColor;
GET_ENVIRONMENT_PROPERTY(envObj, SunColor, sunColor)
m_LightEnv.m_SunColor = RGBColor(sunColor.r, sunColor.g, sunColor.b);
GET_ENVIRONMENT_PROPERTY(envObj, SunElevation, m_LightEnv.m_Elevation)
GET_ENVIRONMENT_PROPERTY(envObj, SunRotation, m_LightEnv.m_Rotation)
CColor terrainAmbientColor;
GET_ENVIRONMENT_PROPERTY(envObj, TerrainAmbientColor, terrainAmbientColor)
m_LightEnv.m_TerrainAmbientColor = RGBColor(terrainAmbientColor.r, terrainAmbientColor.g, terrainAmbientColor.b);
CColor unitsAmbientColor;
GET_ENVIRONMENT_PROPERTY(envObj, UnitsAmbientColor, unitsAmbientColor)
m_LightEnv.m_UnitsAmbientColor = RGBColor(unitsAmbientColor.r, unitsAmbientColor.g, unitsAmbientColor.b);
// Water properties
JS::RootedValue waterObj(cx);
GET_ENVIRONMENT_PROPERTY(envObj, Water, &waterObj)
JS::RootedValue waterBodyObj(cx);
GET_ENVIRONMENT_PROPERTY(waterObj, WaterBody, &waterBodyObj)
// Water level - necessary
float waterHeight;
GET_ENVIRONMENT_PROPERTY(waterBodyObj, Height, waterHeight)
CmpPtr cmpWaterManager(*pSimulation2, SYSTEM_ENTITY);
ENSURE(cmpWaterManager);
cmpWaterManager->SetWaterLevel(entity_pos_t::FromFloat(waterHeight));
// If we have graphics, get rest of settings
if (pWaterMan)
{
GET_ENVIRONMENT_PROPERTY(waterBodyObj, Type, pWaterMan->m_WaterType)
if (pWaterMan->m_WaterType == L"default")
pWaterMan->m_WaterType = L"ocean";
GET_ENVIRONMENT_PROPERTY(waterBodyObj, Color, pWaterMan->m_WaterColor)
GET_ENVIRONMENT_PROPERTY(waterBodyObj, Tint, pWaterMan->m_WaterTint)
GET_ENVIRONMENT_PROPERTY(waterBodyObj, Waviness, pWaterMan->m_Waviness)
GET_ENVIRONMENT_PROPERTY(waterBodyObj, Murkiness, pWaterMan->m_Murkiness)
GET_ENVIRONMENT_PROPERTY(waterBodyObj, WindAngle, pWaterMan->m_WindAngle)
}
JS::RootedValue fogObject(cx);
GET_ENVIRONMENT_PROPERTY(envObj, Fog, &fogObject);
GET_ENVIRONMENT_PROPERTY(fogObject, FogFactor, m_LightEnv.m_FogFactor);
GET_ENVIRONMENT_PROPERTY(fogObject, FogThickness, m_LightEnv.m_FogMax);
CColor fogColor;
GET_ENVIRONMENT_PROPERTY(fogObject, FogColor, fogColor);
m_LightEnv.m_FogColor = RGBColor(fogColor.r, fogColor.g, fogColor.b);
JS::RootedValue postprocObject(cx);
GET_ENVIRONMENT_PROPERTY(envObj, Postproc, &postprocObject);
std::wstring postProcEffect;
GET_ENVIRONMENT_PROPERTY(postprocObject, PostprocEffect, postProcEffect);
if (pPostproc)
pPostproc->SetPostEffect(postProcEffect);
GET_ENVIRONMENT_PROPERTY(postprocObject, Brightness, m_LightEnv.m_Brightness);
GET_ENVIRONMENT_PROPERTY(postprocObject, Contrast, m_LightEnv.m_Contrast);
GET_ENVIRONMENT_PROPERTY(postprocObject, Saturation, m_LightEnv.m_Saturation);
GET_ENVIRONMENT_PROPERTY(postprocObject, Bloom, m_LightEnv.m_Bloom);
m_LightEnv.CalculateSunDirection();
#undef GET_ENVIRONMENT_PROPERTY
return 0;
}
int CMapReader::ParseCamera()
{
JSContext* cx = pSimulation2->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
// parse camera settings from map data
// defaults if we don't find player starting camera
float declination = DEGTORAD(30.f), rotation = DEGTORAD(-45.f);
CVector3D translation = CVector3D(100, 150, -100);
#define GET_CAMERA_PROPERTY(val, prop, out)\
if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\
LOGWARNING("CMapReader::ParseCamera() failed to get '%s' property", #prop);
JS::RootedValue cameraObj(cx);
GET_CAMERA_PROPERTY(m_MapData, Camera, &cameraObj)
if (!cameraObj.isUndefined())
{ // If camera property exists, read values
CFixedVector3D pos;
GET_CAMERA_PROPERTY(cameraObj, Position, pos)
translation = pos;
GET_CAMERA_PROPERTY(cameraObj, Rotation, rotation)
GET_CAMERA_PROPERTY(cameraObj, Declination, declination)
}
#undef GET_CAMERA_PROPERTY
if (pGameView)
{
pGameView->GetCamera()->m_Orientation.SetXRotation(declination);
pGameView->GetCamera()->m_Orientation.RotateY(rotation);
pGameView->GetCamera()->m_Orientation.Translate(translation);
pGameView->GetCamera()->UpdateFrustum();
}
return 0;
}
CMapReader::~CMapReader()
{
// Cleaup objects
delete xml_reader;
delete m_MapGen;
}
Index: ps/trunk/source/graphics/MapWriter.cpp
===================================================================
--- ps/trunk/source/graphics/MapWriter.cpp (revision 23528)
+++ ps/trunk/source/graphics/MapWriter.cpp (revision 23529)
@@ -1,478 +1,492 @@
-/* Copyright (C) 2019 Wildfire Games.
+/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#include "precompiled.h"
#include "Camera.h"
#include "CinemaManager.h"
#include "GameView.h"
#include "LightEnv.h"
#include "MapReader.h"
#include "MapWriter.h"
#include "Patch.h"
#include "Terrain.h"
#include "TerrainTextureEntry.h"
#include "TerrainTextureManager.h"
#include "maths/MathUtil.h"
#include "maths/NUSpline.h"
#include "ps/CLogger.h"
#include "ps/Loader.h"
#include "ps/Filesystem.h"
#include "ps/XML/XMLWriter.h"
#include "renderer/PostprocManager.h"
#include "renderer/SkyManager.h"
#include "renderer/WaterManager.h"
#include "simulation2/Simulation2.h"
#include "simulation2/components/ICmpCinemaManager.h"
+#include "simulation2/components/ICmpGarrisonHolder.h"
#include "simulation2/components/ICmpObstruction.h"
#include "simulation2/components/ICmpOwnership.h"
#include "simulation2/components/ICmpPosition.h"
#include "simulation2/components/ICmpTemplateManager.h"
#include "simulation2/components/ICmpVisual.h"
#include "simulation2/components/ICmpWaterManager.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
// CMapWriter constructor: nothing to do at the minute
CMapWriter::CMapWriter()
{
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// SaveMap: try to save the current map to the given file
void CMapWriter::SaveMap(const VfsPath& pathname, CTerrain* pTerrain,
WaterManager* pWaterMan, SkyManager* pSkyMan,
CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* UNUSED(pCinema),
CPostprocManager* pPostproc,
CSimulation2* pSimulation2)
{
CFilePacker packer(FILE_VERSION, "PSMP");
// build necessary data
PackMap(packer, pTerrain);
try
{
// write it out
packer.Write(pathname);
}
catch (PSERROR_File_WriteFailed&)
{
LOGERROR("Failed to write map '%s'", pathname.string8());
return;
}
VfsPath pathnameXML = pathname.ChangeExtension(L".xml");
WriteXML(pathnameXML, pWaterMan, pSkyMan, pLightEnv, pCamera, pPostproc, pSimulation2);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// GetHandleIndex: return the index of the given handle in the given list; or 0xFFFF if
// handle isn't in list
static u16 GetEntryIndex(const CTerrainTextureEntry* entry, const std::vector& entries)
{
const size_t limit = std::min(entries.size(), size_t(0xFFFEu)); // paranoia
for (size_t i=0;i& textures,
std::vector& tiles)
{
// the list of all handles in use
std::vector entries;
// resize tile array to required size
tiles.resize(SQR(pTerrain->GetVerticesPerSide()-1));
STileDesc* tileptr=&tiles[0];
// now iterate through all the tiles
const ssize_t patchesPerSide=pTerrain->GetPatchesPerSide();
for (ssize_t j=0;jGetPatch(i,j)->m_MiniPatches[m][k]; // can't fail
u16 index=u16(GetEntryIndex(mp.GetTextureEntry(),entries));
if (index==0xFFFF) {
index=(u16)entries.size();
entries.push_back(mp.GetTextureEntry());
}
tileptr->m_Tex1Index=index;
tileptr->m_Tex2Index=0xFFFF;
tileptr->m_Priority=mp.GetPriority();
tileptr++;
}
}
}
}
// now find the texture names for each handle
for (size_t i=0;iGetTag();
}
textures.push_back(texturename);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// PackMap: pack the current world into a raw data stream
void CMapWriter::PackMap(CFilePacker& packer, CTerrain* pTerrain)
{
// now pack everything up
PackTerrain(packer, pTerrain);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// PackTerrain: pack the terrain onto the end of the output data stream
// - data: map size, heightmap, list of textures used by map, texture tile assignments
void CMapWriter::PackTerrain(CFilePacker& packer, CTerrain* pTerrain)
{
// pack map size
const ssize_t mapsize = pTerrain->GetPatchesPerSide();
packer.PackSize(mapsize);
// pack heightmap
packer.PackRaw(pTerrain->GetHeightMap(),sizeof(u16)*SQR(pTerrain->GetVerticesPerSide()));
// the list of textures used by map
std::vector terrainTextures;
// descriptions of each tile
std::vector tiles;
// build lists by scanning through the terrain
EnumTerrainTextures(pTerrain, terrainTextures, tiles);
// pack texture names
const size_t numTextures = terrainTextures.size();
packer.PackSize(numTextures);
for (size_t i=0;i(FILE_VERSION));
ENSURE(pSimulation2);
CSimulation2& sim = *pSimulation2;
if (!sim.GetStartupScript().empty())
{
XMLWriter_Element scriptTag(xmlMapFile, "Script");
scriptTag.Text(sim.GetStartupScript().c_str(), true);
}
{
XMLWriter_Element environmentTag(xmlMapFile, "Environment");
environmentTag.Setting("SkySet", pSkyMan->GetSkySet());
{
XMLWriter_Element sunColorTag(xmlMapFile, "SunColor");
sunColorTag.Attribute("r", pLightEnv->m_SunColor.X); // yes, it's X/Y/Z...
sunColorTag.Attribute("g", pLightEnv->m_SunColor.Y);
sunColorTag.Attribute("b", pLightEnv->m_SunColor.Z);
}
{
XMLWriter_Element SunElevationTag(xmlMapFile, "SunElevation");
SunElevationTag.Attribute("angle", pLightEnv->m_Elevation);
}
{
XMLWriter_Element sunRotationTag(xmlMapFile, "SunRotation");
sunRotationTag.Attribute("angle", pLightEnv->m_Rotation);
}
{
XMLWriter_Element terrainAmbientColorTag(xmlMapFile, "TerrainAmbientColor");
terrainAmbientColorTag.Attribute("r", pLightEnv->m_TerrainAmbientColor.X);
terrainAmbientColorTag.Attribute("g", pLightEnv->m_TerrainAmbientColor.Y);
terrainAmbientColorTag.Attribute("b", pLightEnv->m_TerrainAmbientColor.Z);
}
{
XMLWriter_Element unitsAmbientColorTag(xmlMapFile, "UnitsAmbientColor");
unitsAmbientColorTag.Attribute("r", pLightEnv->m_UnitsAmbientColor.X);
unitsAmbientColorTag.Attribute("g", pLightEnv->m_UnitsAmbientColor.Y);
unitsAmbientColorTag.Attribute("b", pLightEnv->m_UnitsAmbientColor.Z);
}
{
XMLWriter_Element fogTag(xmlMapFile, "Fog");
fogTag.Setting("FogFactor", pLightEnv->m_FogFactor);
fogTag.Setting("FogThickness", pLightEnv->m_FogMax);
{
XMLWriter_Element fogColorTag(xmlMapFile, "FogColor");
fogColorTag.Attribute("r", pLightEnv->m_FogColor.X);
fogColorTag.Attribute("g", pLightEnv->m_FogColor.Y);
fogColorTag.Attribute("b", pLightEnv->m_FogColor.Z);
}
}
{
XMLWriter_Element waterTag(xmlMapFile, "Water");
{
XMLWriter_Element waterBodyTag(xmlMapFile, "WaterBody");
CmpPtr cmpWaterManager(sim, SYSTEM_ENTITY);
ENSURE(cmpWaterManager);
waterBodyTag.Setting("Type", pWaterMan->m_WaterType);
{
XMLWriter_Element colorTag(xmlMapFile, "Color");
colorTag.Attribute("r", pWaterMan->m_WaterColor.r);
colorTag.Attribute("g", pWaterMan->m_WaterColor.g);
colorTag.Attribute("b", pWaterMan->m_WaterColor.b);
}
{
XMLWriter_Element tintTag(xmlMapFile, "Tint");
tintTag.Attribute("r", pWaterMan->m_WaterTint.r);
tintTag.Attribute("g", pWaterMan->m_WaterTint.g);
tintTag.Attribute("b", pWaterMan->m_WaterTint.b);
}
waterBodyTag.Setting("Height", cmpWaterManager->GetExactWaterLevel(0, 0));
waterBodyTag.Setting("Waviness", pWaterMan->m_Waviness);
waterBodyTag.Setting("Murkiness", pWaterMan->m_Murkiness);
waterBodyTag.Setting("WindAngle", pWaterMan->m_WindAngle);
}
}
{
XMLWriter_Element postProcTag(xmlMapFile, "Postproc");
{
postProcTag.Setting("Brightness", pLightEnv->m_Brightness);
postProcTag.Setting("Contrast", pLightEnv->m_Contrast);
postProcTag.Setting("Saturation", pLightEnv->m_Saturation);
postProcTag.Setting("Bloom", pLightEnv->m_Bloom);
postProcTag.Setting("PostEffect", pPostproc->GetPostEffect());
}
}
}
{
XMLWriter_Element cameraTag(xmlMapFile, "Camera");
{
XMLWriter_Element positionTag(xmlMapFile, "Position");
CVector3D pos = pCamera->GetOrientation().GetTranslation();
positionTag.Attribute("x", pos.X);
positionTag.Attribute("y", pos.Y);
positionTag.Attribute("z", pos.Z);
}
CVector3D in = pCamera->GetOrientation().GetIn();
// Convert to spherical coordinates
float rotation = atan2(in.X, in.Z);
float declination = atan2(sqrt(in.X*in.X + in.Z*in.Z), in.Y) - static_cast(M_PI / 2);
{
XMLWriter_Element rotationTag(xmlMapFile, "Rotation");
rotationTag.Attribute("angle", rotation);
}
{
XMLWriter_Element declinationTag(xmlMapFile, "Declination");
declinationTag.Attribute("angle", declination);
}
}
{
std::string settings = sim.GetMapSettingsString();
if (!settings.empty())
{
XMLWriter_Element scriptSettingsTag(xmlMapFile, "ScriptSettings");
scriptSettingsTag.Text(("\n" + settings + "\n").c_str(), true);
}
}
{
XMLWriter_Element entitiesTag(xmlMapFile, "Entities");
CmpPtr cmpTemplateManager(sim, SYSTEM_ENTITY);
ENSURE(cmpTemplateManager);
// This will probably need to be changed in the future, but for now we'll
// just save all entities that have a position
CSimulation2::InterfaceList ents = sim.GetEntitiesWithInterface(IID_Position);
for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it)
{
entity_id_t ent = it->first;
// Don't save local entities (placement previews etc)
if (ENTITY_IS_LOCAL(ent))
continue;
XMLWriter_Element entityTag(xmlMapFile, "Entity");
entityTag.Attribute("uid", ent);
entityTag.Setting("Template", cmpTemplateManager->GetCurrentTemplateName(ent));
CmpPtr cmpOwnership(sim, ent);
if (cmpOwnership)
entityTag.Setting("Player", static_cast(cmpOwnership->GetOwner()));
+ CmpPtr cmpGarrisonHolder(sim, ent);
+ if (cmpGarrisonHolder)
+ {
+ XMLWriter_Element garrisonTag(xmlMapFile, "Garrison");
+ std::vector garrison = cmpGarrisonHolder->GetEntities();
+ for (const entity_id_t garr_ent_id : garrison)
+ {
+ XMLWriter_Element garrisonedEntityTag(xmlMapFile, "GarrisonedEntity");
+ garrisonedEntityTag.Attribute("uid", static_cast(garr_ent_id));
+ // ToDo: We can store turret position as well.
+ }
+ }
+
CmpPtr cmpPosition(sim, ent);
if (cmpPosition)
{
CFixedVector3D pos;
if (cmpPosition->IsInWorld())
pos = cmpPosition->GetPosition();
CFixedVector3D rot = cmpPosition->GetRotation();
{
XMLWriter_Element positionTag(xmlMapFile, "Position");
positionTag.Attribute("x", pos.X);
positionTag.Attribute("z", pos.Z);
// TODO: height offset etc
}
{
XMLWriter_Element orientationTag(xmlMapFile, "Orientation");
orientationTag.Attribute("y", rot.Y);
// TODO: X, Z maybe
}
}
CmpPtr cmpObstruction(sim, ent);
if (cmpObstruction)
{
// TODO: Currently only necessary because Atlas
// does not set up control groups for its walls.
cmpObstruction->ResolveFoundationCollisions();
entity_id_t group = cmpObstruction->GetControlGroup();
entity_id_t group2 = cmpObstruction->GetControlGroup2();
// Don't waste space writing the default control groups.
if (group != ent || group2 != INVALID_ENTITY)
{
XMLWriter_Element obstructionTag(xmlMapFile, "Obstruction");
if (group != ent)
obstructionTag.Attribute("group", group);
if (group2 != INVALID_ENTITY)
obstructionTag.Attribute("group2", group2);
}
}
CmpPtr cmpVisual(sim, ent);
if (cmpVisual)
{
entity_id_t seed = static_cast(cmpVisual->GetActorSeed());
if (seed != ent)
{
XMLWriter_Element actorTag(xmlMapFile, "Actor");
actorTag.Attribute("seed",seed);
}
// TODO: variation/selection strings
}
}
}
CmpPtr cmpCinemaManager(sim, SYSTEM_ENTITY);
if (cmpCinemaManager)
{
const std::map& paths = cmpCinemaManager->GetPaths();
std::map::const_iterator it = paths.begin();
XMLWriter_Element pathsTag(xmlMapFile, "Paths");
for ( ; it != paths.end(); ++it )
{
fixed timescale = it->second.GetTimescale();
const std::vector& position_nodes = it->second.GetAllNodes();
const std::vector& target_nodes = it->second.GetTargetSpline().GetAllNodes();
const CCinemaData* data = it->second.GetData();
XMLWriter_Element pathTag(xmlMapFile, "Path");
pathTag.Attribute("name", data->m_Name);
pathTag.Attribute("timescale", timescale);
pathTag.Attribute("orientation", data->m_Orientation);
pathTag.Attribute("mode", data->m_Mode);
pathTag.Attribute("style", data->m_Style);
struct SEvent
{
fixed time;
const char* type;
CFixedVector3D value;
SEvent(fixed time, const char* type, CFixedVector3D value)
: time(time), type(type), value(value)
{}
bool operator<(const SEvent& another) const
{
return time < another.time;
}
};
// All events of a manipulating of camera (position/rotation/target)
std::vector events;
events.reserve(position_nodes.size() + target_nodes.size());
fixed last_position = fixed::Zero();
for (size_t i = 0; i < position_nodes.size(); ++i)
{
fixed distance = i > 0 ? position_nodes[i - 1].Distance : fixed::Zero();
last_position += distance;
events.emplace_back(last_position, "Position", position_nodes[i].Position);
}
fixed last_target = fixed::Zero();
for (size_t i = 0; i < target_nodes.size(); ++i)
{
fixed distance = i > 0 ? target_nodes[i - 1].Distance : fixed::Zero();
last_target += distance;
events.emplace_back(last_target, "Target", target_nodes[i].Position);
}
std::sort(events.begin(), events.end());
for (size_t i = 0; i < events.size();)
{
XMLWriter_Element nodeTag(xmlMapFile, "Node");
fixed deltatime = i > 0 ? (events[i].time - events[i - 1].time) : fixed::Zero();
nodeTag.Attribute("deltatime", deltatime);
size_t j = i;
for (; j < events.size() && events[j].time == events[i].time; ++j)
{
// Types: Position/Rotation/Target
XMLWriter_Element eventTypeTag(xmlMapFile, events[j].type);
eventTypeTag.Attribute("x", events[j].value.X);
eventTypeTag.Attribute("y", events[j].value.Y);
eventTypeTag.Attribute("z", events[j].value.Z);
}
i = j;
}
}
}
}
if (!xmlMapFile.StoreVFS(g_VFS, filename))
LOGERROR("Failed to write map '%s'", filename.string8());
}
Index: ps/trunk/source/simulation2/TypeList.h
===================================================================
--- ps/trunk/source/simulation2/TypeList.h (revision 23528)
+++ ps/trunk/source/simulation2/TypeList.h (revision 23529)
@@ -1,205 +1,208 @@
-/* Copyright (C) 2019 Wildfire Games.
+/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
// MESSAGE: message types
// INTERFACE: component interface types
// COMPONENT: component types
// Components intended only for use in test cases:
// (The tests rely on the enum IDs, so don't change the order of these)
INTERFACE(Test1)
COMPONENT(Test1A)
COMPONENT(Test1B)
COMPONENT(Test1Scripted)
INTERFACE(Test2)
COMPONENT(Test2A)
COMPONENT(Test2Scripted)
// Message types:
MESSAGE(TurnStart)
MESSAGE(Update)
MESSAGE(Update_MotionFormation)
MESSAGE(Update_MotionUnit)
MESSAGE(Update_Final)
MESSAGE(Interpolate) // non-deterministic (use with caution)
MESSAGE(RenderSubmit) // non-deterministic (use with caution)
MESSAGE(ProgressiveLoad) // non-deterministic (use with caution)
MESSAGE(Deserialized) // non-deterministic (use with caution)
MESSAGE(Create)
MESSAGE(Destroy)
MESSAGE(OwnershipChanged)
MESSAGE(PositionChanged)
MESSAGE(InterpolatedPositionChanged)
MESSAGE(TerritoryPositionChanged)
MESSAGE(MotionUpdate)
MESSAGE(RangeUpdate)
MESSAGE(TerrainChanged)
MESSAGE(VisibilityChanged)
MESSAGE(WaterChanged)
MESSAGE(ObstructionMapShapeChanged)
MESSAGE(TerritoriesChanged)
MESSAGE(PathResult)
MESSAGE(ValueModification)
MESSAGE(TemplateModification)
MESSAGE(VisionRangeChanged)
MESSAGE(VisionSharingChanged)
MESSAGE(MinimapPing)
MESSAGE(CinemaPathEnded)
MESSAGE(CinemaQueueEnded)
MESSAGE(PlayerColorChanged)
// TemplateManager must come before all other (non-test) components,
// so that it is the first to be (de)serialized
INTERFACE(TemplateManager)
COMPONENT(TemplateManager)
// Special component for script component types with no native interface
INTERFACE(UnknownScript)
COMPONENT(UnknownScript)
// In alphabetical order:
INTERFACE(AIInterface)
COMPONENT(AIInterfaceScripted)
INTERFACE(AIManager)
COMPONENT(AIManager)
INTERFACE(CinemaManager)
COMPONENT(CinemaManager)
INTERFACE(CommandQueue)
COMPONENT(CommandQueue)
INTERFACE(Decay)
COMPONENT(Decay)
INTERFACE(Fogging)
COMPONENT(FoggingScripted)
// Note: The VisualActor component relies on this component being initialized before itself, in order to support using
// an entity's footprint shape for the selection boxes. This dependency is not strictly necessary, but it does avoid
// some extra plumbing code to set up on-demand initialization. If you find yourself forced to break this dependency,
// see VisualActor's Init method for a description of how you can avoid it.
INTERFACE(Footprint)
COMPONENT(Footprint)
+INTERFACE(GarrisonHolder)
+COMPONENT(GarrisonHolderScripted)
+
INTERFACE(GuiInterface)
COMPONENT(GuiInterfaceScripted)
INTERFACE(Identity)
COMPONENT(IdentityScripted)
INTERFACE(Minimap)
COMPONENT(Minimap)
INTERFACE(Mirage)
COMPONENT(MirageScripted)
INTERFACE(Motion)
COMPONENT(MotionBall)
COMPONENT(MotionScripted)
INTERFACE(Obstruction)
COMPONENT(Obstruction)
INTERFACE(ObstructionManager)
COMPONENT(ObstructionManager)
INTERFACE(OverlayRenderer)
COMPONENT(OverlayRenderer)
INTERFACE(Ownership)
COMPONENT(Ownership)
INTERFACE(ParticleManager)
COMPONENT(ParticleManager)
INTERFACE(Pathfinder)
COMPONENT(Pathfinder)
INTERFACE(Player)
COMPONENT(PlayerScripted)
INTERFACE(PlayerManager)
COMPONENT(PlayerManagerScripted)
INTERFACE(Position)
COMPONENT(Position) // must be before VisualActor
INTERFACE(ProjectileManager)
COMPONENT(ProjectileManager)
INTERFACE(RallyPoint)
COMPONENT(RallyPointScripted)
INTERFACE(RallyPointRenderer)
COMPONENT(RallyPointRenderer)
INTERFACE(RangeManager)
COMPONENT(RangeManager)
INTERFACE(RangeOverlayRenderer)
COMPONENT(RangeOverlayRenderer)
INTERFACE(Selectable)
COMPONENT(Selectable)
INTERFACE(Settlement)
COMPONENT(SettlementScripted)
INTERFACE(Sound)
COMPONENT(SoundScripted)
INTERFACE(SoundManager)
COMPONENT(SoundManager)
INTERFACE(ValueModificationManager)
COMPONENT(ValueModificationManagerScripted)
INTERFACE(Terrain)
COMPONENT(Terrain)
INTERFACE(TerritoryDecayManager)
COMPONENT(TerritoryDecayManagerScripted)
INTERFACE(TerritoryInfluence)
COMPONENT(TerritoryInfluence)
INTERFACE(TerritoryManager)
COMPONENT(TerritoryManager)
INTERFACE(UnitMotion)
COMPONENT(UnitMotion) // must be after Obstruction
COMPONENT(UnitMotionScripted)
INTERFACE(UnitRenderer)
COMPONENT(UnitRenderer)
INTERFACE(Visibility)
COMPONENT(VisibilityScripted)
INTERFACE(Vision)
COMPONENT(Vision)
// Note: this component relies on the Footprint component being initialized before itself. See the comments above for
// the Footprint component to find out why.
INTERFACE(Visual)
COMPONENT(VisualActor) // must be after Ownership (dependency in Deserialize) and Vision (dependency in Init)
INTERFACE(WaterManager)
COMPONENT(WaterManager)
Index: ps/trunk/source/simulation2/components/ICmpGarrisonHolder.cpp
===================================================================
--- ps/trunk/source/simulation2/components/ICmpGarrisonHolder.cpp (nonexistent)
+++ ps/trunk/source/simulation2/components/ICmpGarrisonHolder.cpp (revision 23529)
@@ -0,0 +1,44 @@
+/* Copyright (C) 2020 Wildfire Games.
+* This file is part of 0 A.D.
+*
+* 0 A.D. is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* (at your option) any later version.
+*
+* 0 A.D. is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with 0 A.D. If not, see .
+*/
+
+#include "precompiled.h"
+
+#include "ICmpGarrisonHolder.h"
+
+#include "simulation2/scripting/ScriptComponent.h"
+#include "simulation2/system/InterfaceScripted.h"
+
+BEGIN_INTERFACE_WRAPPER(GarrisonHolder)
+END_INTERFACE_WRAPPER(GarrisonHolder)
+
+class CCmpGarrisonHolderScripted : public ICmpGarrisonHolder
+{
+public:
+ DEFAULT_SCRIPT_WRAPPER(GarrisonHolderScripted)
+
+ virtual std::vector GetEntities() const
+ {
+ return m_Script.Call >("GetEntities");
+ }
+
+ virtual void SetInitEntities(std::vector entities)
+ {
+ m_Script.CallVoid("SetInitGarrison", entities);
+ }
+};
+
+REGISTER_COMPONENT_SCRIPT_WRAPPER(GarrisonHolderScripted)
Index: ps/trunk/source/simulation2/components/ICmpGarrisonHolder.h
===================================================================
--- ps/trunk/source/simulation2/components/ICmpGarrisonHolder.h (nonexistent)
+++ ps/trunk/source/simulation2/components/ICmpGarrisonHolder.h (revision 23529)
@@ -0,0 +1,35 @@
+/* Copyright (C) 2020 Wildfire Games.
+* This file is part of 0 A.D.
+*
+* 0 A.D. is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* (at your option) any later version.
+*
+* 0 A.D. is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with 0 A.D. If not, see .
+*/
+
+#ifndef INCLUDED_ICMPGARRISONHOLDER
+#define INCLUDED_ICMPGARRISONHOLDER
+
+#include "simulation2/system/Interface.h"
+
+#include
+
+class ICmpGarrisonHolder : public IComponent
+{
+public:
+ virtual std::vector GetEntities() const = 0;
+
+ virtual void SetInitEntities(const std::vector entities) = 0;
+
+ DECLARE_INTERFACE_TYPE(GarrisonHolder)
+};
+
+#endif // INCLUDED_ICMPGARRISONHOLDER