1 /*
2 * Copyright (C) 2002-2020 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20 #include "logic/map_objects/world/world.h"
21
22 #include <memory>
23
24 #include "base/i18n.h"
25 #include "graphic/graphic.h"
26 #include "graphic/image_io.h"
27 #include "logic/game_data_error.h"
28 #include "logic/map_objects/immovable.h"
29 #include "logic/map_objects/world/critter.h"
30 #include "logic/map_objects/world/editor_category.h"
31 #include "logic/map_objects/world/resource_description.h"
32 #include "logic/map_objects/world/terrain_description.h"
33 #include "scripting/lua_table.h"
34
35 namespace Widelands {
36
World()37 World::World()
38 : critters_(new DescriptionMaintainer<CritterDescr>()),
39 immovables_(new DescriptionMaintainer<ImmovableDescr>()),
40 terrains_(new DescriptionMaintainer<TerrainDescription>()),
41 resources_(new DescriptionMaintainer<ResourceDescription>()),
42 editor_terrain_categories_(new DescriptionMaintainer<EditorCategory>()),
43 editor_critter_categories_(new DescriptionMaintainer<EditorCategory>()),
44 editor_immovable_categories_(new DescriptionMaintainer<EditorCategory>()) {
45 }
46
~World()47 World::~World() {
48 }
49
load_graphics()50 void World::load_graphics() {
51 for (size_t i = 0; i < terrains_->size(); ++i) {
52 TerrainDescription* terrain = terrains_->get_mutable(i);
53 for (size_t j = 0; j < terrain->texture_paths().size(); ++j) {
54 // Set the minimap color on the first loaded image.
55 if (j == 0) {
56 SDL_Surface* sdl_surface = load_image_as_sdl_surface(terrain->texture_paths()[j]);
57 uint8_t top_left_pixel = static_cast<uint8_t*>(sdl_surface->pixels)[0];
58 const SDL_Color top_left_pixel_color =
59 sdl_surface->format->palette->colors[top_left_pixel];
60 terrain->set_minimap_color(
61 RGBColor(top_left_pixel_color.r, top_left_pixel_color.g, top_left_pixel_color.b));
62 SDL_FreeSurface(sdl_surface);
63 }
64 terrain->add_texture(g_gr->images().get(terrain->texture_paths()[j]));
65 }
66 }
67 }
68
postload()69 void World::postload() {
70 const DescriptionIndex nr_t = get_nr_terrains();
71 for (size_t i = 0; i < nr_t; ++i) {
72 const TerrainDescription& t = terrain_descr(i);
73 if (!t.enhancement().empty()) {
74 if (!terrain_descr(t.enhancement())) {
75 throw GameDataError(
76 "Terrain %s: Unknown enhancement %s", t.name().c_str(), t.enhancement().c_str());
77 }
78 }
79 }
80 }
81
terrains() const82 const DescriptionMaintainer<TerrainDescription>& World::terrains() const {
83 return *terrains_;
84 }
85
add_resource_type(const LuaTable & table)86 void World::add_resource_type(const LuaTable& table) {
87 resources_->add(new ResourceDescription(table));
88 }
89
add_terrain_type(const LuaTable & table)90 void World::add_terrain_type(const LuaTable& table) {
91 terrains_->add(new TerrainDescription(table, *this));
92 }
93
add_critter_type(const LuaTable & table)94 void World::add_critter_type(const LuaTable& table) {
95 i18n::Textdomain td("world");
96 critters_->add(new CritterDescr(_(table.get_string("descname")), table, *this));
97 }
98
immovables() const99 const DescriptionMaintainer<ImmovableDescr>& World::immovables() const {
100 return *immovables_;
101 }
102
add_immovable_type(const LuaTable & table)103 void World::add_immovable_type(const LuaTable& table) {
104 i18n::Textdomain td("world");
105 immovables_->add(new ImmovableDescr(_(table.get_string("descname")), table, *this));
106 }
107
add_editor_terrain_category(const LuaTable & table)108 void World::add_editor_terrain_category(const LuaTable& table) {
109 editor_terrain_categories_->add(new EditorCategory(table));
110 }
111
editor_terrain_categories() const112 const DescriptionMaintainer<EditorCategory>& World::editor_terrain_categories() const {
113 return *editor_terrain_categories_;
114 }
115
add_editor_critter_category(const LuaTable & table)116 void World::add_editor_critter_category(const LuaTable& table) {
117 editor_critter_categories_->add(new EditorCategory(table));
118 }
119
editor_critter_categories() const120 const DescriptionMaintainer<EditorCategory>& World::editor_critter_categories() const {
121 return *editor_critter_categories_;
122 }
123
add_editor_immovable_category(const LuaTable & table)124 void World::add_editor_immovable_category(const LuaTable& table) {
125 editor_immovable_categories_->add(new EditorCategory(table));
126 }
127
editor_immovable_categories() const128 const DescriptionMaintainer<EditorCategory>& World::editor_immovable_categories() const {
129 return *editor_immovable_categories_;
130 }
131
safe_resource_index(const char * const resourcename) const132 DescriptionIndex World::safe_resource_index(const char* const resourcename) const {
133 DescriptionIndex const result = resource_index(resourcename);
134
135 if (result == INVALID_INDEX)
136 throw GameDataError("world does not define resource type \"%s\"", resourcename);
137 return result;
138 }
139
terrain_descr(DescriptionIndex const i) const140 TerrainDescription& World::terrain_descr(DescriptionIndex const i) const {
141 return *terrains_->get_mutable(i);
142 }
143
terrain_descr(const std::string & name) const144 const TerrainDescription* World::terrain_descr(const std::string& name) const {
145 DescriptionIndex const i = terrains_->get_index(name);
146 return i != INVALID_INDEX ? terrains_->get_mutable(i) : nullptr;
147 }
148
get_terrain_index(const std::string & name) const149 DescriptionIndex World::get_terrain_index(const std::string& name) const {
150 return terrains_->get_index(name);
151 }
152
get_nr_terrains() const153 DescriptionIndex World::get_nr_terrains() const {
154 return terrains_->size();
155 }
156
get_critter(char const * const l) const157 DescriptionIndex World::get_critter(char const* const l) const {
158 return critters_->get_index(l);
159 }
160
critters() const161 const DescriptionMaintainer<CritterDescr>& World::critters() const {
162 return *critters_;
163 }
164
get_critter_descr(DescriptionIndex index) const165 CritterDescr const* World::get_critter_descr(DescriptionIndex index) const {
166 return critters_->get_mutable(index);
167 }
168
get_critter_descr(const std::string & name) const169 CritterDescr const* World::get_critter_descr(const std::string& name) const {
170 return critters_->exists(name.c_str());
171 }
172
get_immovable_index(const std::string & name) const173 DescriptionIndex World::get_immovable_index(const std::string& name) const {
174 return immovables_->get_index(name);
175 }
176
get_nr_immovables() const177 DescriptionIndex World::get_nr_immovables() const {
178 return immovables_->size();
179 }
180
get_immovable_descr(DescriptionIndex const index) const181 ImmovableDescr const* World::get_immovable_descr(DescriptionIndex const index) const {
182 return immovables_->get_mutable(index);
183 }
184
resource_index(const char * const name) const185 DescriptionIndex World::resource_index(const char* const name) const {
186 return strcmp(name, "none") ? resources_->get_index(name) : Widelands::kNoResource;
187 }
188
189 /***
190 * @return The ResourceDescription for the given index. Returns Nullptr for kNoResource.
191 */
get_resource(DescriptionIndex const res) const192 ResourceDescription const* World::get_resource(DescriptionIndex const res) const {
193 assert(res < resources_->size() || res == Widelands::kNoResource);
194 return resources_->get_mutable(res);
195 }
196
get_nr_resources() const197 DescriptionIndex World::get_nr_resources() const {
198 return resources_->size();
199 }
200
201 } // namespace Widelands
202