WangAreaGrid.cpp

Go to the documentation of this file.
00001 #include "WangAreaGrid.hpp"
00002 #include "sim/stat/DictionaryEntry.hpp"
00003 #include "sim/area/AreaManager.hpp"
00004 #include <cstdio>
00005 
00006 
00007 using namespace se_core;
00008 
00009 namespace se_basic {
00010 
00011     WangAreaGrid
00012     ::WangAreaGrid(int xSize, int zSize, const char* name) 
00013             : xSize_(xSize), zSize_(zSize), definitionCount_(0), defaultBorder_('0') {
00014 
00015         areas_ = new Areas[ xSize_ * zSize_ ];
00016         for(int i = 0; i < xSize_ * zSize_; ++i) {
00017             areas_[ i ].area_ = 0;
00018             areas_[ i ].definitionIndex_ = -2;
00019         }
00020         wangDefinitions_ = new WangDefinition[MAX_DEFINITIONS];
00021         dict_ = new DictionaryEntry(DE_ZONE, name, true);
00022     }
00023 
00024 
00025     WangAreaGrid
00026     ::~WangAreaGrid() {
00027         delete[] areas_;
00028         delete[] wangDefinitions_;
00029     }
00030 
00031 
00032     void WangAreaGrid
00033     ::setArea(int x, int z, int defIndex) {
00034 
00035         areas_[ x + z * xSize_ ].definitionIndex_ = defIndex;
00036         if(defIndex < 0)
00037             return;
00038         char buffer[32];        
00039         sprintf(buffer, "%s/%d.%d", dict_->name_, z, x);
00040         Area* a = SimSchema::areaManager.createArea(buffer, wangDefinitions_[defIndex].areaName_.get(), x, 0, z, dict_->id_);
00041         LogDetail("Grid: " << dict_->name_ << " - " << dict_->id_);
00042 
00043         areas_[ x + z * xSize_ ].area_ = a;
00044     }
00045 
00046 
00047     int WangAreaGrid
00048     ::findMatch(const unsigned char* wanted, int random) {
00049         //LogDetail("Defs: " << definitionCount_);
00050         bool didFind = false;
00051         do {
00052             for(int i = 0; i < definitionCount_; ++i) {
00053                 WangDefinition& w = wangDefinitions_[i];
00054                 bool isMatch = true;
00055 
00056                 for(int j = 0; j < 4; ++j) {
00057                     if(wanted[j] != 0 && wanted[j] != w.wang_[j]) {
00058                         isMatch = false;
00059                     }
00060                 }
00061                 if(isMatch) {
00062                     if(random <= 0) {
00063                         return i;
00064                     }
00065                     --random;
00066                     didFind = true;
00067                 }
00068             }
00069         } while(didFind);
00070 
00071         for(int i = 0; i < 4; ++i) {
00072             if(wanted[i] == '0' || wanted[i] == 0) {
00073                 return -1;
00074             }
00075         }
00076 
00077         char buffer[5];
00078         buffer[0] = (wanted[0] != 0) ? wanted[0] : 'X';
00079         buffer[1] = (wanted[1] != 0) ? wanted[1] : 'X';
00080         buffer[2] = (wanted[2] != 0) ? wanted[2] : 'X';
00081         buffer[3] = (wanted[3] != 0) ? wanted[3] : 'X';
00082         buffer[4] = 0;
00083 
00084 
00085         LogFatal("Didn't find match for: " << buffer);
00086         return 0;
00087     }
00088 
00089 
00090     void WangAreaGrid
00091     ::generate(int seed) {
00092         // (navmesh data)
00093         unsigned char wantedWang[4];
00094         for(int z = 0; z < zSize_; ++z) {
00095             for(int x = 0; x < xSize_; ++x) {
00096                 // Already defined?
00097                 int myDef = getDefinition(x, z);
00098                 if(myDef >= -1)
00099                     continue;
00100 
00101                 //
00102                 wantedWang[0] = getSide(x, z - 1, 2);
00103                 wantedWang[1] = getSide(x + 1, z, 3);
00104                 wantedWang[2] = getSide(x, z + 1, 0);
00105                 wantedWang[3] = getSide(x - 1, z, 1);
00106 
00107                 seed += x * z;
00108                 seed ^= (seed >> 8);
00109                 seed ^= (seed >> 16);
00110                 seed ^= (seed >> 24);
00111                 int def = findMatch(wantedWang, seed % 19);
00112 
00113                 setArea(x, z, def);
00114             }
00115         }
00116     }
00117 
00118 
00119     void WangAreaGrid
00120     ::save(const char* filename) {
00121         char fullPath[256];
00122         sprintf(fullPath, "%s/logic/area/grid/%s.txt", IoSchema::dataPath, filename);
00123         FILE* out = fopen(fullPath, "wt");
00124 
00125         fprintf(out, "XG02\n");
00126         fprintf(out, "%d %d\n", xSize_, zSize_);
00127         for(int i = 0; i < definitionCount_; ++i) {
00128             WangDefinition* w = &wangDefinitions_[i];
00129             fprintf(out, "# %d\n", i);
00130             fprintf(out, "T %s %c%c%c%c\n", w->areaName_.get(), w->wang_[0], w->wang_[1], w->wang_[2], w->wang_[3]);
00131         }
00132         fprintf(out, "\n");
00133 
00134         for(int z = 0; z < zSize_; ++z) {
00135             fprintf(out, "C %d { ", z);
00136             for(int x = 0; x < xSize_; ++x) {
00137                 int myDef = getDefinition(x, z);
00138                 fprintf(out, "%2d ", myDef);
00139             }
00140             fprintf(out, "}\n");
00141         }
00142         fprintf(out, "Q\n");
00143         fclose(out);
00144     }
00145 
00146 }

Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:02 2007 by Doxygen version 1.3.9.1.

SourceForge.net Logo