00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <libfuture.h>
00021 #include <Utility.h>
00022
00023 #include "Chunk.h"
00024 #include "InSocket.h"
00025 #include "Player.h"
00026 #include "FutureHandler.h"
00027 #include "Area.h"
00028 #include "Terrain.h"
00029 #include "Chunkinfo.h"
00030 #include "Portal.h"
00031
00032
00033
00034 chunks_t Chunk::m_chunks;
00035
00036
00037 Chunk::Chunk(Database& db,Area& a,long num) : Object(db), m_area(a)
00038 , m_chunk(Chunk::GetChunk(db, a, num))
00039 {
00040 GetInfo();
00041 }
00042
00043
00044 Chunk::Chunk(Database& db,Area& a,int x,int y,int z) : Object(db), m_area(a)
00045 , m_chunk(Chunk::GetChunk(db, a, x, y, z))
00046 {
00047 GetInfo();
00048 }
00049
00050
00051 Chunk::~Chunk()
00052 {
00053 }
00054
00055
00056 void Chunk::Init(InSocket *from,int x,int y,int z,char tchar)
00057 {
00058 {
00059 db::Chunk chunk(&m_db);
00060 chunk.area = m_area.GetNum();
00061 chunk.x = x;
00062 chunk.y = y;
00063 chunk.z = z;
00064 if (from)
00065 {
00066 Database& db = from -> GetDatabase();
00067 Player pl(db, from -> GetAccountName());
00068 chunk.created_by = pl.GetNum();
00069 }
00070 else
00071 {
00072 chunk.created_by = 0;
00073 }
00074
00075 chunk.created_date = static_cast<FutureHandler&>(from -> Handler()).GetDateTime();
00076 while (chunk.terrain.size() < (size_t)m_area.GetWidth() * m_area.GetHeight())
00077 chunk.terrain += tchar;
00078 chunk.save();
00079 }
00080 Chunk::RemoveObject(m_area, x, y, z);
00081 m_chunk = Chunk::GetChunk(m_db, m_area, x, y, z);
00082
00083 Chunk cnorth(m_db, m_area, x, y + 1, z);
00084 if (cnorth.Exists())
00085 {
00086 for (int x = 0; x < m_area.GetWidth(); x++)
00087 Set(x, 0, cnorth.Get(x, m_area.GetHeight() - 1));
00088 }
00089
00090 Chunk csouth(m_db, m_area, x, y - 1, z);
00091 if (csouth.Exists())
00092 {
00093 for (int x = 0; x < m_area.GetWidth(); x++)
00094 Set(x, m_area.GetHeight() - 1, csouth.Get(x, 0));
00095 }
00096
00097 Chunk ceast(m_db, m_area, x + 1, y, z);
00098 if (ceast.Exists())
00099 {
00100 for (int y = 0; y < m_area.GetHeight(); y++)
00101 Set(m_area.GetWidth() - 1, y, ceast.Get(0, y));
00102 }
00103
00104 Chunk cwest(m_db, m_area, x - 1, y, z);
00105 if (cwest.Exists())
00106 {
00107 for (int y = 0; y < m_area.GetHeight(); y++)
00108 Set(0, y, cwest.Get(m_area.GetWidth() - 1, y));
00109 }
00110 }
00111
00112
00113 void Chunk::Set(int x,int y,char tchar)
00114 {
00115 if (m_chunk)
00116 m_chunk -> terrain[x + y * m_area.GetWidth()] = tchar;
00117 }
00118
00119
00120 char Chunk::Get(int x,int y)
00121 {
00122 if (m_chunk)
00123 return m_chunk -> terrain[x + y * m_area.GetWidth()];
00124 return ' ';
00125 }
00126
00127
00128 bool Chunk::Exists()
00129 {
00130 if (m_chunk && m_chunk -> num)
00131 return true;
00132 return false;
00133 }
00134
00135
00136 void Chunk::Save()
00137 {
00138 if (m_chunk)
00139 m_chunk -> save();
00140 }
00141
00142
00143 long Chunk::GetNum()
00144 {
00145 if (m_chunk)
00146 return m_chunk -> num;
00147 return 0;
00148 }
00149
00150
00151 void Chunk::Fill(int x,int y,char fromchar,char tochar)
00152 {
00153 Set(x,y,tochar);
00154 if (y > 0 && Get(x,y - 1) == fromchar)
00155 Fill(x, y - 1, fromchar, tochar);
00156 if (y < m_area.GetHeight() - 1 && Get(x,y + 1) == fromchar)
00157 Fill(x, y + 1, fromchar, tochar);
00158 if (x < m_area.GetWidth() - 1 && Get(x + 1,y) == fromchar)
00159 Fill(x + 1, y, fromchar, tochar);
00160 if (x > 0 && Get(x - 1,y) == fromchar)
00161 Fill(x - 1, y, fromchar, tochar);
00162 }
00163
00164
00165 db::Chunk *Chunk::GetChunk(Database& db,Area& area,int x,int y,int z)
00166 {
00167 std::list<db::Chunk *>& ref = m_chunks[area.GetNum()];
00168 for (std::list<db::Chunk *>::iterator it = ref.begin(); it != ref.end(); it++)
00169 {
00170 db::Chunk *p = *it;
00171 if (p -> x == x && p -> y == y && p -> z == z)
00172 {
00173 return p;
00174 }
00175 }
00176 db::Chunk *p = new db::Chunk(db, area.GetNum(), x, y, z);
00177 p -> area = area.GetNum();
00178 p -> x = x;
00179 p -> y = y;
00180 p -> z = z;
00181 ref.push_back(p);
00182 return p;
00183 }
00184
00185
00186 db::Chunk *Chunk::GetChunk(Database& db,Area& area,long num)
00187 {
00188 std::list<db::Chunk *>& ref = m_chunks[area.GetNum()];
00189 for (std::list<db::Chunk *>::iterator it = ref.begin(); it != ref.end(); it++)
00190 {
00191 db::Chunk *p = *it;
00192 if (p -> num == num)
00193 {
00194 return p;
00195 }
00196 }
00197 db::Chunk *p = new db::Chunk(db, num);
00198 p -> area = area.GetNum();
00199 ref.push_back(p);
00200 return p;
00201 }
00202
00203
00204 void Chunk::RemoveObject(Area& area,int x,int y,int z)
00205 {
00206 std::list<db::Chunk *>& ref = m_chunks[area.GetNum()];
00207 for (std::list<db::Chunk *>::iterator it = ref.begin(); it != ref.end(); it++)
00208 {
00209 db::Chunk *p = *it;
00210 if (p -> x == x && p -> y == y && p -> z == z)
00211 {
00212 delete p;
00213 ref.erase(it);
00214 return;
00215 }
00216 }
00217 }
00218
00219
00220 int Chunk::GetX()
00221 {
00222 return m_chunk -> x;
00223 }
00224
00225
00226 int Chunk::GetY()
00227 {
00228 return m_chunk -> y;
00229 }
00230
00231
00232 int Chunk::GetZ()
00233 {
00234 return m_chunk -> z;
00235 }
00236
00237
00238 void Chunk::Edge(Terrain& t,int width)
00239 {
00240 if (width < m_area.GetWidth() && width < m_area.GetHeight())
00241 {
00242 for (int w = 0; w < width; w++)
00243 {
00244 for (int x = 0; x < m_area.GetWidth(); x++)
00245 {
00246 Set(x, w, t.GetChar());
00247 Set(x, m_area.GetHeight() - w - 1, t.GetChar());
00248 }
00249 for (int y = 0; y < m_area.GetHeight(); y++)
00250 {
00251 Set(w, y, t.GetChar());
00252 Set(m_area.GetWidth() - w - 1, y, t.GetChar());
00253 }
00254 }
00255 }
00256 }
00257
00258
00259 void Chunk::GetInfo()
00260 {
00261 if (!Exists())
00262 return;
00263 Query q(m_db);
00264 q.get_result("select * from chunkinfo where chunk=" + Utility::l2string(GetNum()));
00265 while (q.fetch_row())
00266 {
00267 db::Chunkinfo info(&m_db, &q);
00268 Chunkinfo x(m_db, *this, info.x, info.y, (Chunkinfo::infotype_t)info.type);
00269 }
00270 q.free_result();
00271 }
00272
00273
00274 void Chunk::AddPortal(int x,int y,Area& to_area,Chunk& to_chunk,int to_x,int to_y)
00275 {
00276 Portal info(m_db, *this);
00277 info.SetX(x);
00278 info.SetY(y);
00279 info.SetType(Chunkinfo::TYPE_PORTAL);
00280 info.SetToArea(to_area.GetNum());
00281 info.SetToChunk(to_chunk.GetNum());
00282 info.SetToX(to_x);
00283 info.SetToY(to_y);
00284 info.Save();
00285 Set(x, y, 'P');
00286 Save();
00287 }
00288
00289
00290 void Chunk::Show(InSocket *from)
00291 {
00292 Database& db = from -> GetDatabase();
00293 Player pl(db, from -> GetAccountName());
00294 std::list<db::Chunkinfo *>& ref = Chunkinfo::GetChunkinfo(*this);
00295 for (std::list<db::Chunkinfo *>::iterator it = ref.begin(); it != ref.end(); it++)
00296 {
00297 db::Chunkinfo *p = *it;
00298 if (p -> x == pl.GetChunkX() && p -> y == pl.GetChunkY())
00299 {
00300 Chunkinfo *info = Chunkinfo::GetInstance(db, *this, p -> x, p -> y, (Chunkinfo::infotype_t)p -> type);
00301 info -> Display(from);
00302 delete info;
00303 }
00304 }
00305 }
00306
00307