FIFE
2008.0
|
00001 /*************************************************************************** 00002 * Copyright (C) 2005-2008 by the FIFE team * 00003 * http://www.fifengine.de * 00004 * This file is part of FIFE. * 00005 * * 00006 * FIFE is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Lesser General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2.1 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00014 * Lesser General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Lesser General Public * 00017 * License along with this library; if not, write to the * 00018 * Free Software Foundation, Inc., * 00019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 00020 ***************************************************************************/ 00021 00022 // Standard C++ library includes 00023 00024 // 3rd party library includes 00025 #include <SDL.h> 00026 00027 // FIFE includes 00028 // These includes are split up in two parts, separated by one empty line 00029 // First block: files included from the FIFE root src directory 00030 // Second block: files included from the same folder 00031 #include "util/log/logger.h" 00032 #include "util/structures/purge.h" 00033 00034 #include "layer.h" 00035 #include "instance.h" 00036 #include "map.h" 00037 #include "instancetree.h" 00038 00039 namespace FIFE { 00040 00041 static Logger _log(LM_STRUCTURES); 00042 00043 Layer::Layer(const std::string& identifier, Map* map, CellGrid* grid) 00044 : m_id(identifier), 00045 m_map(map), 00046 m_instances_visibility(true), 00047 m_transparency(0), 00048 m_instanceTree(new InstanceTree()), 00049 m_grid(grid), 00050 m_pathingstrategy(CELL_EDGES_ONLY), 00051 m_changelisteners(), 00052 m_changedinstances(), 00053 m_changed(false) { 00054 } 00055 00056 Layer::~Layer() { 00057 purge(m_instances); 00058 delete m_instanceTree; 00059 } 00060 00061 bool Layer::hasInstances() const { 00062 return !m_instances.empty(); 00063 } 00064 00065 Instance* Layer::createInstance(Object* object, const ModelCoordinate& p, const std::string& id) { 00066 ExactModelCoordinate emc(static_cast<double>(p.x), static_cast<double>(p.y), static_cast<double>(p.z)); 00067 return createInstance(object, emc, id); 00068 } 00069 00070 Instance* Layer::createInstance(Object* object, const ExactModelCoordinate& p, const std::string& id) { 00071 Location location; 00072 location.setLayer(this); 00073 location.setExactLayerCoordinates(p); 00074 00075 Instance* instance = new Instance(object, location, id); 00076 if(instance->isActive()) { 00077 setInstanceActivityStatus(instance, instance->isActive()); 00078 } 00079 m_instances.push_back(instance); 00080 m_instanceTree->addInstance(instance); 00081 00082 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin(); 00083 while (i != m_changelisteners.end()) { 00084 (*i)->onInstanceCreate(this, instance); 00085 ++i; 00086 } 00087 m_changed = true; 00088 return instance; 00089 } 00090 00091 bool Layer::addInstance(Instance* instance, const ExactModelCoordinate& p){ 00092 if( !instance ){ 00093 FL_ERR(_log, "Tried to add an instance to layer, but given instance is invalid"); 00094 return false; 00095 } 00096 00097 Location location; 00098 location.setLayer(this); 00099 location.setExactLayerCoordinates(p); 00100 instance->setLocation(location); 00101 00102 m_instances.push_back(instance); 00103 m_instanceTree->addInstance(instance); 00104 if(instance->isActive()) { 00105 setInstanceActivityStatus(instance, instance->isActive()); 00106 } 00107 00108 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin(); 00109 while (i != m_changelisteners.end()) { 00110 (*i)->onInstanceCreate(this, instance); 00111 ++i; 00112 } 00113 m_changed = true; 00114 return true; 00115 } 00116 00117 void Layer::deleteInstance(Instance* instance) { 00118 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin(); 00119 while (i != m_changelisteners.end()) { 00120 (*i)->onInstanceDelete(this, instance); 00121 ++i; 00122 } 00123 setInstanceActivityStatus(instance, false); 00124 std::vector<Instance*>::iterator it = m_instances.begin(); 00125 for(; it != m_instances.end(); ++it) { 00126 if(*it == instance) { 00127 m_instanceTree->removeInstance(*it); 00128 delete *it; 00129 m_instances.erase(it); 00130 break; 00131 } 00132 } 00133 m_changed = true; 00134 } 00135 00136 void Layer::setInstanceActivityStatus(Instance* instance, bool active) { 00137 if(active) { 00138 m_active_instances.insert(instance); 00139 } else { 00140 m_active_instances.erase(instance); 00141 } 00142 } 00143 00144 Instance* Layer::getInstance(const std::string& id) { 00145 std::vector<Instance*>::iterator it = m_instances.begin(); 00146 for(; it != m_instances.end(); ++it) { 00147 if((*it)->getId() == id) 00148 return *it; 00149 } 00150 00151 return 0; 00152 } 00153 00154 std::vector<Instance*> Layer::getInstances(const std::string& id) { 00155 std::vector<Instance*> matching_instances; 00156 std::vector<Instance*>::iterator it = m_instances.begin(); 00157 for(; it != m_instances.end(); ++it) { 00158 if((*it)->getId() == id) 00159 matching_instances.push_back(*it); 00160 } 00161 return matching_instances; 00162 } 00163 00164 std::vector<Instance*> Layer::getInstancesAt(Location& loc, bool use_exactcoordinates) { 00165 std::vector<Instance*> matching_instances; 00166 std::vector<Instance*>::iterator it = m_instances.begin(); 00167 00168 for(; it != m_instances.end(); ++it) { 00169 if (use_exactcoordinates) { 00170 if ((*it)->getLocationRef().getExactLayerCoordinatesRef() == loc.getExactLayerCoordinatesRef()) { 00171 matching_instances.push_back(*it); 00172 } 00173 } else { 00174 if ((*it)->getLocationRef().getLayerCoordinates() == loc.getLayerCoordinates()) { 00175 matching_instances.push_back(*it); 00176 } 00177 } 00178 } 00179 00180 return matching_instances; 00181 } 00182 00183 void Layer::getMinMaxCoordinates(ModelCoordinate& min, ModelCoordinate& max, const Layer* layer) const { 00184 if (!layer) { 00185 layer = this; 00186 } 00187 00188 bool first_found = false; 00189 for (std::vector<Instance*>::const_iterator i = m_instances.begin(); i != m_instances.end(); ++i) { 00190 if (!first_found) { 00191 min = m_instances.front()->getLocationRef().getLayerCoordinates(layer); 00192 max = min; 00193 first_found = true; 00194 } else { 00195 ModelCoordinate coord = (*i)->getLocationRef().getLayerCoordinates(layer); 00196 00197 if(coord.x < min.x) { 00198 min.x = coord.x; 00199 } 00200 00201 if(coord.x > max.x) { 00202 max.x = coord.x; 00203 } 00204 00205 if(coord.y < min.y) { 00206 min.y = coord.y; 00207 } 00208 00209 if(coord.y > max.y) { 00210 max.y = coord.y; 00211 } 00212 } 00213 } 00214 if (!first_found) { 00215 min = ModelCoordinate(); 00216 max = min; 00217 } 00218 } 00219 00220 void Layer::setInstancesVisible(bool vis) { 00221 m_instances_visibility = vis; 00222 } 00223 00224 void Layer::setLayerTransparency(uint8_t transparency) { 00225 m_transparency = transparency; 00226 } 00227 00228 uint8_t Layer::getLayerTransparency() { 00229 return m_transparency; 00230 } 00231 00232 void Layer::toggleInstancesVisible() { 00233 m_instances_visibility = !m_instances_visibility; 00234 } 00235 00236 bool Layer::cellContainsBlockingInstance(const ModelCoordinate& cellCoordinate) { 00237 std::list<Instance*> adjacentInstances; 00238 m_instanceTree->findInstances(cellCoordinate, 0, 0, adjacentInstances); 00239 bool blockingInstance = false; 00240 for(std::list<Instance*>::const_iterator j = adjacentInstances.begin(); j != adjacentInstances.end(); ++j) { 00241 if((*j)->isBlocking() && (*j)->getLocationRef().getLayerCoordinates() == cellCoordinate) { 00242 blockingInstance = true; 00243 } 00244 } 00245 return blockingInstance; 00246 } 00247 00248 bool Layer::update() { 00249 m_changedinstances.clear(); 00250 std::set<Instance*>::iterator it = m_active_instances.begin(); 00251 for(; it != m_active_instances.end(); ++it) { 00252 if ((*it)->update() != ICHANGE_NO_CHANGES) { 00253 m_changedinstances.push_back(*it); 00254 m_changed = true; 00255 } 00256 } 00257 if (!m_changedinstances.empty()) { 00258 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin(); 00259 while (i != m_changelisteners.end()) { 00260 (*i)->onLayerChanged(this, m_changedinstances); 00261 ++i; 00262 } 00263 //std::cout << "Layer named " << Id() << " changed = 1\n"; 00264 } 00265 //std::cout << "Layer named " << Id() << " changed = 0\n"; 00266 bool retval = m_changed; 00267 m_changed = false; 00268 return retval; 00269 } 00270 00271 void Layer::addChangeListener(LayerChangeListener* listener) { 00272 m_changelisteners.push_back(listener); 00273 } 00274 00275 void Layer::removeChangeListener(LayerChangeListener* listener) { 00276 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin(); 00277 while (i != m_changelisteners.end()) { 00278 if ((*i) == listener) { 00279 m_changelisteners.erase(i); 00280 return; 00281 } 00282 ++i; 00283 } 00284 } 00285 } // FIFE