Logo
~Sockets~
~Examples~
~Contact~

Chunk.cpp

Go to the documentation of this file.
00001 // Chunk.cpp
00002 // released 2006-09-25
00003 /*
00004 Copyright (C) 2006  Anders Hedstrom (grymse@alhem.net)
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program 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
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this program; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 // statics
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                 // next line will crash when initing a new world
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 
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4