00001 /* 00002 SagaEngine library 00003 Copyright (c) 2002-2006 Skalden Studio AS 00004 00005 This software is provided 'as-is', without any express or implied 00006 warranty. In no event will the authors be held liable for any 00007 damages arising from the use of this software. 00008 00009 Permission is granted to distribute the library under the terms of the 00010 Q Public License version 1.0. Be sure to read and understand the license 00011 before using the library. It should be included here, or you may read it 00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl 00013 00014 The original version of this library can be located at: 00015 http://www.sagaengine.com/ 00016 00017 Rune Myrland 00018 rune@skalden.com 00019 */ 00020 00021 00022 #include "ZoneManager.hpp" 00023 #include "ZoneAreaComponent.hpp" 00024 #include "Exit.hpp" 00025 #include "sim/sim.hpp" 00026 #include "sim/schema/SimSchema.hpp" 00027 #include "comp/list/NodeComponentList.hpp" 00028 #include "util/vecmath/Vector3.hpp" 00029 #include "util/error/Log.hpp" 00030 00031 00032 00033 namespace se_core { 00034 00035 ZoneAreaComponent 00036 ::ZoneAreaComponent(Composite* owner, const ComponentFactory* factory) 00037 : RootChildComponent(sct_ZONE, owner, factory), page_(0, 0, 0, -1), exitCount_(0), exits_(0) { 00038 // 3x3 array to hold self and neighbours 00039 for(short i = 0; i < MAX_NEIGHBOURS; ++i) { 00040 neighbours_[i] = 0; 00041 } 00042 // Add self in center 00043 neighbours_[ 1 + 1 * 3 + 1 * 9 ] = this; 00044 addLink(*this); 00045 } 00046 00047 00048 ZoneAreaComponent 00049 ::~ZoneAreaComponent() { 00050 delete[] exits_; 00051 } 00052 00053 00054 void ZoneAreaComponent 00055 ::setActive(bool state) { 00056 if(state) { 00057 NodeComponent* c = static_cast<NodeComponent*>(CompSchema::activeRoot().component(type_)); 00058 if(c) { 00059 setParent(*c); 00060 } 00061 } 00062 else { 00063 resetParent(); 00064 } 00065 } 00066 00067 00068 void ZoneAreaComponent 00069 ::offset(const ZoneAreaComponent& other, Page& dest) const { 00070 dest.sub(other.page(), page_); 00071 } 00072 00073 00074 bool ZoneAreaComponent 00075 ::offset(const ZoneAreaComponent& other, const Vector3& size, Vector3& dest) const { 00076 Page rel(other.page(), page_); 00077 dest.x_ = rel.x_ * size.x_; 00078 dest.y_ = rel.y_ * size.y_; 00079 dest.z_ = rel.z_ * size.z_; 00080 00081 return (page_.w_ >= 0 && rel.w_ != 0); 00082 } 00083 00084 00085 00086 bool ZoneAreaComponent 00087 ::addNeighbour(ZoneAreaComponent& other) { 00088 if(other.owner() == owner()) 00089 return false; 00090 00091 Page rel(other.page(), page_); 00092 if(!rel.isNeighbourOffset()) { 00093 return false; 00094 } 00095 00096 int index = neighbourIndex(rel); 00097 AssertFatal(other.owner() != owner(), "Grid file for " << owner()->name() << " probably included twice"); 00098 AssertFatal(neighbours_[ index ] == 0, owner()->name() << " -> " << neighbours_[index]->owner()->name() << " (Trying to link " << other.owner()->name() << ")"); 00099 neighbours_[ index ] = &other; 00100 return true; 00101 } 00102 00103 00104 void ZoneAreaComponent 00105 ::addLink(ZoneAreaComponent& link) { 00106 links_.add(link); 00107 } 00108 00109 00110 int ZoneAreaComponent 00111 ::neighbourIndex(const Page& rel) const { 00112 AssertFatal(rel.isNeighbourOffset(), "Clamp to neighbour offset first"); 00113 AssertFatal(rel.w_ == 0, "Neighbours must be in the same grid"); 00114 return (rel.x_ + 1) + 3 * (rel.y_ + 1) + 9 * (rel.z_ + 1); 00115 } 00116 00117 00118 ZoneAreaComponent* ZoneAreaComponent 00119 ::neighbour(int relX, int relY, int relZ) { 00120 Page rel(relX, relY, relZ, 0); 00121 if(!rel.isNeighbourOffset()) { 00122 Page n; 00123 n.clampToNeighbourOffset(rel); 00124 ZoneAreaComponent* via = neighbours_[ neighbourIndex(n) ]; 00125 if(!via) 00126 return 0; 00127 return via->neighbour(rel.x_ - n.x_, rel.y_ - n.y_, rel.z_ - n.z_); 00128 } 00129 return neighbours_[ neighbourIndex(rel) ]; 00130 } 00131 00132 00133 const ZoneAreaComponent* ZoneAreaComponent 00134 ::neighbour(int relX, int relY, int relZ) const { 00135 Page rel(relX, relY, relZ, 0); 00136 if(!rel.isNeighbourOffset()) { 00137 Page n; 00138 n.clampToNeighbourOffset(rel); 00139 const ZoneAreaComponent* via = neighbours_[ neighbourIndex(n) ]; 00140 if(!via) 00141 return 0; 00142 return via->neighbour(rel.x_ - n.x_, rel.y_ - n.y_, rel.z_ - n.z_); 00143 } 00144 00145 return neighbours_[ neighbourIndex(rel) ]; 00146 } 00147 00148 00149 void ZoneAreaComponent 00150 ::setExits(Exit* exits, int count) { 00151 if(exits_) { 00152 LogWarning("Overriding exits in: " << owner()->name()); 00153 delete[] exits_; 00154 exits_ = 0; 00155 } 00156 00157 exits_ = new Exit[ count ]; 00158 for(int i = 0; i < count; ++i) { 00159 exits_[i] = exits[i]; 00160 } 00161 exitCount_ = count; 00162 } 00163 00164 00165 Exit& ZoneAreaComponent 00166 ::exit(int id) { 00167 AssertFatal(id >= 0 && id < exitCount_, owner()->name()); 00168 return exits_[id]; 00169 } 00170 00171 const Exit& ZoneAreaComponent 00172 ::exit(int id) const { 00173 Assert(id >= 0 && id < exitCount_); 00174 return exits_[id]; 00175 } 00176 } 00177
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:12 2007 by Doxygen version 1.3.9.1.