OSDN Git Service

[Modify] boostライブラリに依存した処理をコメントアウトによる一時的措置を含めて完了.
[deeangband/Deeangband-new.git] / Deeangband / Field.cpp
1 /*!
2  * @file Field.cpp
3  * @brief \83Q\81[\83\80\92\86\82Ì\83t\83\8d\83A\82ð\92è\8b`\82·\82é
4  * @date 2013/12/11
5  * @author Deskull
6  * 2013 Sikabane Works.
7  */
8
9 #include "stdafx.h"
10 #include "Field.h"
11
12 namespace Deeangband
13 {
14
15         Field::Field(std::map<TAG, std::shared_ptr<Dungeon>>::iterator dungeonIt, DEPTH depth) : GameInstance()
16         {
17                 Dungeon *dungeonPtr = &(*dungeonIt->second);
18                 int x, y;
19                 this->dungeonTag = dungeonIt->first;
20                 this->width = dungeonPtr->GetBaseSize().GetX();
21                 this->height = dungeonPtr->GetBaseSize().GetY();
22                 this->generated = false;
23                 this->dungeonPtr = dungeonIt->second.get();
24
25                 if(depth > dungeonPtr->GetMaxDepth() || depth > dungeonPtr->GetMinDepth()) return;
26
27                 squares.resize(this->height);
28                 for(y = 0; y < height; y++)
29                 {
30                         for(x = 0; x < width; x++)
31                         {
32                                 squares[y].push_back(std::shared_ptr<Square>(new Square()));
33                                 if(Dice::Cast(1, 4) == 3)
34                                 {
35                                         squares[y][x]->SetFloor(dungeonPtr->GetInnerWallFloorTag());
36                                 }
37                                 else
38                                 {
39                                         squares[y][x]->SetFloor(dungeonPtr->GetFloorFloorTag());
40                                 }
41                         }
42                 }
43
44                 this->UpdateSight();
45
46                 this->createRectRoom(13, 13, 20, 33);
47
48                 creatures.resize(0);
49                 doors.resize(0);
50                 traps.resize(0);
51                 items.resize(0);
52
53                 this->generated = true;
54         }
55
56         Field::Field()
57         {
58                 WipeData();
59         }
60
61         Field::Field(DEPTH depth)
62         {
63
64         }
65
66         Field::~Field()
67         {
68                 WipeData();
69         }
70
71         void Field::WipeData(void)
72         {
73                 this->width = 0;
74                 this->height = 0;
75                 this->dungeonTag = "";
76                 creatures.resize(0);
77                 doors.resize(0);
78                 traps.resize(0);
79                 items.resize(0);
80         }
81
82         MAP_LENGTH Field::GetWidth(void)
83         {
84                 return width;
85         }
86
87         MAP_LENGTH Field::GetHeight(void)
88         {
89                 return height;
90         }
91
92         bool Field::SetSize(MAP_LENGTH width, MAP_LENGTH height)
93         {
94                 this->width = width;
95                 this->height = height;
96                 return true;
97         }
98
99         Square *Field::GetSquare(MAP_LENGTH x, MAP_LENGTH y)
100         {
101                 //! @note \83t\83B\81[\83\8b\83h\82Ì\94Í\88Í\8aO\82Ì\8dÀ\95W\82Ì\8fê\8d\87false\82ð\95Ô\82·\81B
102                 if(x < 0 || y < 0 || x >= this->width || y >= this->height) return NULL;
103                 return squares[y][x].get();
104         }
105
106         Square *Field::GetSquare(Coordinates &coord)
107         {
108                 return this->GetSquare(coord.GetX(), coord.GetY());
109         }
110
111         bool Field::GenerateTrap(std::map<TAG, std::shared_ptr<TrapBase>>::iterator trapBaseIt, Coordinates *position)
112         {
113                 traps.emplace(traps.end(), std::make_shared<Trap>(trapBaseIt, position));
114                 return true;
115         }
116
117         void Field::UpdateSight(void)
118         {
119                 int x, y;
120                 int updateSizeX = this->width * 2 + 1;
121                 int updateSizeY = this->height * 2 + 1;
122                 this->SightPass.resize(updateSizeX * updateSizeY);
123                 this->PhysicalPass.resize(updateSizeX * updateSizeY);
124
125                 for(x = 0; x < updateSizeX * updateSizeY; x++)
126                 {
127                         this->SightPass[x] = false;
128                         this->PhysicalPass[x] = false;
129                 }
130
131                 for(y = 1; y < updateSizeY; y += 2)
132                 {
133                         for(x = 1; x < updateSizeX; x += 2)
134                         {
135                                 this->SightPass[y * updateSizeX + x] = !this->GetSquare(x / 2, y / 2)->IsWall();
136                                 this->PhysicalPass[y * updateSizeX + x] = !this->GetSquare(x / 2, y / 2)->IsWall();
137                         }
138                 }
139
140                 for(y = 0; y < this->height * 2 + 1; y += 2)
141                 {
142                         for(x = 0; x < this->width * 2 + 1; x += 2)
143                         {
144                                 if(!this->GetSquare(x / 2 - 1, y / 2 - 1) || !this->GetSquare(x / 2 - 1, y / 2) || !this->GetSquare(x / 2, y / 2 - 1) || !this->GetSquare(x / 2, y / 2))
145                                 {
146                                         this->SightPass[y * updateSizeX + x] = false;
147                                         this->PhysicalPass[y * updateSizeX + x] = false;
148                                 }
149                                 else if((!this->GetSquare(x / 2 - 1, y / 2 - 1)->IsWall() && !this->GetSquare(x / 2, y / 2 )->IsWall()) || (!this->GetSquare(x / 2, y / 2 - 1)->IsWall() && !this->GetSquare(x / 2 - 1, y / 2)->IsWall()))
150                                 {
151                                         this->SightPass[y * updateSizeX + x] = true;
152                                         this->PhysicalPass[y * updateSizeX + x] = true;
153                                 }
154                                 else
155                                 {
156                                         this->SightPass[y * updateSizeX + x] = false;
157                                         this->PhysicalPass[y * updateSizeX + x] = false;
158                                 }
159                         }
160                 }
161
162                 for(y = 0; y < this->height * 2 + 1; y += 2)
163                 {
164                         for(x = 1; x < this->width * 2 + 1; x += 2)
165                         {
166                                 if(!this->GetSquare(x / 2, y / 2 - 1) || !this->GetSquare(x / 2, y / 2))
167                                 {
168                                         this->SightPass[y * updateSizeX + x] = false;
169                                         this->PhysicalPass[y * updateSizeX + x] = false;
170                                 }
171                                 else if(this->GetSquare(x / 2, y / 2 - 1)->IsWall() || this->GetSquare(x / 2, y / 2)->IsWall())
172                                 {
173                                         this->SightPass[y * updateSizeX + x] = false;
174                                         this->PhysicalPass[y * updateSizeX + x] = false;
175                                 }
176                                 else
177                                 {
178                                         this->SightPass[y * updateSizeX + x] = true;
179                                         this->PhysicalPass[y * updateSizeX + x] = true;
180                                 }
181                         }
182                 }
183
184                 for(y = 1; y < updateSizeY; y += 2)
185                 {
186                         for(x = 0; x < updateSizeX; x += 2)
187                         {
188                                 if(!this->GetSquare(x / 2 - 1, y / 2) || !this->GetSquare(x / 2, y / 2))
189                                 {
190                                         this->SightPass[y * updateSizeX + x] = false;
191                                         this->PhysicalPass[y * updateSizeX + x] = false;
192                                 }
193                                 else if(this->GetSquare(x / 2 - 1, y / 2)->IsWall() || this->GetSquare(x / 2, y / 2)->IsWall())
194                                 {
195                                         this->SightPass[y * updateSizeX + x] = false;
196                                         this->PhysicalPass[y * updateSizeX+ x] = false;
197                                 }
198                                 else
199                                 {
200                                         this->SightPass[y * updateSizeX + x] = true;
201                                         this->PhysicalPass[y * updateSizeX + x] = true;
202                                 }
203                         }
204                 }
205
206         }
207
208         void Field::createRectRoom(MAP_LENGTH sx, MAP_LENGTH sy,  MAP_LENGTH ex, MAP_LENGTH ey)
209         {
210                 Square *squarePtr;
211                 std::vector<std::shared_ptr<Coordinates>> wallVec;
212
213                 MAP_LENGTH x, y;
214                 wallVec.clear();
215
216                 for(y = sy + 1; y < ey; y++)
217                 {
218                         for(x = sx + 1; x < ex; x++)
219                         {
220                                 squarePtr = this->GetSquare(x, y);
221                                 if(squarePtr)
222                                 {
223                                         squarePtr->SetFloor(dungeonPtr->GetFloorFloorTag());
224                                 }
225                         }
226                 }
227                 
228                 for(y = sy; y <= ey; y++)
229                 {
230                         squarePtr = this->GetSquare(sx, y);
231                         squarePtr->SetFloor(dungeonPtr->GetInnerWallFloorTag());
232                         squarePtr = this->GetSquare(ex, y);
233                         squarePtr->SetFloor(dungeonPtr->GetInnerWallFloorTag());
234                         wallVec.push_back(std::make_shared<Coordinates>(sx, y));
235                         wallVec.push_back(std::make_shared<Coordinates>(ex, y));
236                 }
237
238                 for(x = sx + 1; x < ex; x++)
239                 {
240                         squarePtr = this->GetSquare(x, sy);
241                         squarePtr->SetFloor(dungeonPtr->GetInnerWallFloorTag());
242                         squarePtr = this->GetSquare(x, ey);
243                         squarePtr->SetFloor(dungeonPtr->GetInnerWallFloorTag());
244                         wallVec.push_back(std::make_shared<Coordinates>(x, sy));
245                         wallVec.push_back(std::make_shared<Coordinates>(x, ey));
246                 }
247
248                 this->GetSquare(*wallVec[Dice::Rand0(wallVec.size())].get())->SetFloor(dungeonPtr->GetFloorFloorTag());
249         }
250
251         void Field::createRectRoom(Coordinates& leftTop, Coordinates& rightBottom)
252         {
253                 this->createRectRoom(leftTop.GetX(), leftTop.GetY(), rightBottom.GetX(), rightBottom.GetY());
254         }
255
256         void Field::GetSight(std::vector<bool> &coordVec, MAP_LENGTH size, MAP_LENGTH baseX, MAP_LENGTH baseY)
257         {
258                 MAP_LENGTH x, y, s;
259                 int sideWidth = size * 2 + 1;
260                 int allocSize = sideWidth * sideWidth;
261                 std::vector<Coordinates> lineVec;
262                 std::vector<Coordinates>::iterator lineIt;
263                 std::vector<Coordinates>::reverse_iterator lineRIt;
264
265                 for(s = 0 ; s < allocSize; s++) coordVec[s] = false;
266                 coordVec[size * sideWidth + size] = true;
267
268                 for(s = size; s >= 1; s--)
269                 {
270                         for(x = baseX - s; x <= baseX + s; x++)
271                         {
272                                 int tx = x;
273                                 int ty1 = baseY - s;
274                                 int ty2 = baseY + s;
275
276                                 if(Coordinates::Distance(baseX, baseY, tx, ty1) >= size) continue;
277
278                                 if(tx >= 0 && ty1 >= 0 && tx < this->width && ty1 < this->height)
279                                 {
280                                         if(!coordVec[(ty1 - baseY + size) * sideWidth + tx - baseX + size])
281                                         {
282                                                 Coordinates::LineOfSight(lineVec, baseX, baseY, tx, ty1);
283                                                 if(lineVec[0].GetX() == baseX && lineVec[0].GetY() == baseY)
284                                                 {
285                                                         for(lineIt = ++lineVec.begin(); lineIt < lineVec.end(); lineIt++)
286                                                         {
287                                                                 int lsx = lineIt->GetX() - baseX + size;
288                                                                 int lsy = lineIt->GetY() - baseY + size;
289                                                                 coordVec[lsy * sideWidth + lsx] = true;
290                                                                 if(!this->GetSquare(lineIt->GetX(), lineIt->GetY()) || this->GetSquare(lineIt->GetX(), lineIt->GetY())->IsWall()) break;
291                                                         }
292                                                 }
293                                                 else
294                                                 {
295                                                         for(lineRIt = ++lineVec.rbegin(); lineRIt < lineVec.rend(); lineRIt++)
296                                                         {
297                                                                 int lsx = lineRIt->GetX() - baseX + size;
298                                                                 int lsy = lineRIt->GetY() - baseY + size;
299                                                                 coordVec[lsy * sideWidth + lsx] = true;
300                                                                 if(!this->GetSquare(lineRIt->GetX(), lineRIt->GetY()) || this->GetSquare(lineRIt->GetX(), lineRIt->GetY())->IsWall()) break;
301                                                         }
302                                                 }
303                                         }
304                                 }
305
306                                 lineVec.clear();
307
308                                 if(tx >= 0 && ty2 >= 0 && tx < this->width && ty2 < this->height)
309                                 {
310                                         if(!coordVec[(ty2 - baseY + size) * sideWidth + tx - baseX + size])
311                                         {
312                                                 Coordinates::LineOfSight(lineVec, baseX, baseY, tx, ty2);
313                                                 if(lineVec[0].GetX() == baseX && lineVec[0].GetY() == baseY)
314                                                 {
315                                                         for(lineIt = ++lineVec.begin()++; lineIt < lineVec.end(); lineIt++)
316                                                         {
317                                                                 int lsx = lineIt->GetX() - baseX + size;
318                                                                 int lsy = lineIt->GetY() - baseY + size;
319                                                                 coordVec[lsy * sideWidth + lsx] = true;
320                                                                 if(!this->GetSquare(lineIt->GetX(), lineIt->GetY()) || this->GetSquare(lineIt->GetX(), lineIt->GetY())->IsWall()) break;
321                                                         }
322                                                 }
323                                                 else
324                                                 {
325                                                         for(lineRIt = ++lineVec.rbegin()++; lineRIt < lineVec.rend(); lineRIt++)
326                                                         {
327                                                                 int lsx = lineRIt->GetX() - baseX + size;
328                                                                 int lsy = lineRIt->GetY() - baseY + size;
329                                                                 coordVec[lsy * sideWidth + lsx] = true;
330                                                                 if(!this->GetSquare(lineRIt->GetX(), lineRIt->GetY()) || this->GetSquare(lineRIt->GetX(), lineRIt->GetY())->IsWall()) break;
331                                                         }
332                                                 }
333                                         }
334                                 }
335
336                                 lineVec.clear();
337
338                         }
339
340                         for(y = baseY - s; y <= baseY + s; y++)
341                         {
342                                 int tx1 = baseX - s;
343                                 int tx2 = baseX + s;
344                                 int ty = y;
345
346                                 if(Coordinates::Distance(baseX, baseY, tx1, ty) >= size) continue;
347
348
349                                 if(tx1 >= 0 && ty >= 0 && tx1 < this->width && ty < this->height)
350                                 {
351                                         if(!coordVec[(ty - baseY + size) * sideWidth + tx1 - baseX + size])
352                                         {
353                                                 Coordinates::LineOfSight(lineVec, baseX, baseY, tx1, ty);
354                                                 if(lineVec[0].GetX() == baseX && lineVec[0].GetY() == baseY)
355                                                 {
356                                                         for(lineIt = ++lineVec.begin(); lineIt < lineVec.end(); lineIt++)
357                                                         {
358                                                                 int lsx = lineIt->GetX() - baseX + size;
359                                                                 int lsy = lineIt->GetY() - baseY + size;
360                                                                 coordVec[lsy * sideWidth + lsx] = true;
361                                                                 if(!this->GetSquare(lineIt->GetX(), lineIt->GetY()) || this->GetSquare(lineIt->GetX(), lineIt->GetY())->IsWall()) break;
362                                                         }
363                                                 }
364                                                 else
365                                                 {
366                                                         for(lineRIt = ++lineVec.rbegin(); lineRIt < lineVec.rend(); lineRIt++)
367                                                         {
368                                                                 int lsx = lineRIt->GetX() - baseX + size;
369                                                                 int lsy = lineRIt->GetY() - baseY + size;
370                                                                 coordVec[lsy * sideWidth + lsx] = true;
371                                                                 if(!this->GetSquare(lineRIt->GetX(), lineRIt->GetY()) || this->GetSquare(lineRIt->GetX(), lineRIt->GetY())->IsWall()) break;
372                                                         }       
373                                                 }
374                                         }
375                                 }
376
377                                 lineVec.clear();
378
379                                 if(tx2 >= 0 && ty >= 0 && tx2 < this->width && ty < this->height)
380                                 {
381                                         if(!coordVec[(ty - baseY + size) * sideWidth + tx2 - baseX + size])
382                                         {
383                                                 Coordinates::LineOfSight(lineVec, baseX, baseY, tx2, ty);
384                                                 if(lineVec[0].GetX() == baseX && lineVec[0].GetY() == baseY)
385                                                 {
386                                                         for(lineIt = ++lineVec.begin(); lineIt < lineVec.end(); lineIt++)
387                                                         {
388                                                                 int lsx = lineIt->GetX() - baseX + size;
389                                                                 int lsy = lineIt->GetY() - baseY + size;
390                                                                 coordVec[lsy * sideWidth + lsx] = true;
391                                                                 if(!this->GetSquare(lineIt->GetX(), lineIt->GetY()) || this->GetSquare(lineIt->GetX(), lineIt->GetY())->IsWall()) break;
392                                                         }
393                                                 }
394                                                 else
395                                                 {
396                                                         for(lineRIt = ++lineVec.rbegin(); lineRIt < lineVec.rend(); lineRIt++)
397                                                         {
398                                                                 int lsx = lineRIt->GetX() - baseX + size;
399                                                                 int lsy = lineRIt->GetY() - baseY + size;
400                                                                 coordVec[lsy * sideWidth + lsx] = true;
401                                                                 if(!this->GetSquare(lineRIt->GetX(), lineRIt->GetY()) || this->GetSquare(lineRIt->GetX(), lineRIt->GetY())->IsWall()) break;
402                                                         }       
403                                                 }
404                                         }
405                                 }
406
407                                 lineVec.clear();
408
409                         }
410
411                 }
412
413                 for(y = -size + 1; y < size; y++)
414                 {
415                         for(x = -size + 1; x < size; x++)
416                         {
417                                 if(Coordinates::Distance(0, 0, x, y) <= size)
418                                 {
419                                         if(coordVec[(y+size) * sideWidth + (x+size)] == true && !this->GetSquare(baseX + x, baseY + y)->IsWall())
420                                         {
421                                                 if(this->GetSquare(baseX + x - 1, baseY + y - 1) && this->GetSquare(baseX + x - 1, baseY + y - 1)->IsWall()) coordVec[(y+size-1) * sideWidth + (x+size-1)] = true;
422                                                 if(this->GetSquare(baseX + x - 1, baseY + y + 1) && this->GetSquare(baseX + x - 1, baseY + y + 1)->IsWall()) coordVec[(y+size+1) * sideWidth + (x+size-1)] = true;
423                                                 if(this->GetSquare(baseX + x + 1, baseY + y - 1) && this->GetSquare(baseX + x + 1, baseY + y - 1)->IsWall()) coordVec[(y+size-1) * sideWidth + (x+size+1)] = true;
424                                                 if(this->GetSquare(baseX + x + 1, baseY + y + 1) && this->GetSquare(baseX + x + 1, baseY + y + 1)->IsWall()) coordVec[(y+size+1) * sideWidth + (x+size+1)] = true;
425                                                 if(this->GetSquare(baseX + x + 1, baseY + y) && this->GetSquare(baseX + x + 1, baseY + y)->IsWall()) coordVec[(y+size) * sideWidth + (x+size+1)] = true;
426                                                 if(this->GetSquare(baseX + x, baseY + y + 1) && this->GetSquare(baseX + x, baseY + y + 1)->IsWall()) coordVec[(y+size+1) * sideWidth + (x+size)] = true;
427                                                 if(this->GetSquare(baseX + x - 1, baseY + y) && this->GetSquare(baseX + x - 1, baseY + y)->IsWall()) coordVec[(y+size) * sideWidth + (x+size-1)] = true;
428                                                 if(this->GetSquare(baseX + x, baseY + y - 1) && this->GetSquare(baseX + x, baseY + y - 1)->IsWall()) coordVec[(y+size-1) * sideWidth + (x+size)] = true;
429                                         }
430                                 }
431                         }
432                 }
433
434         }
435
436         bool Field::HaveSight(MAP_LENGTH bx, MAP_LENGTH by, MAP_LENGTH tx, MAP_LENGTH ty)
437         {
438                 std::vector<Coordinates> coordVec;
439                 std::vector<Coordinates>::iterator coordIt;
440
441                 if(bx < 0 || by < 0 || tx < 0 || ty < 0) return false;
442                 if(bx >= this->width || by >= this->height || tx >= this->width || ty >= this->height) return false;
443
444                 Coordinates::LineOfSight(coordVec, bx, by, tx, ty);
445                 for(coordIt = coordVec.begin(); coordIt != coordVec.end(); coordIt++)
446                 {
447                         if(bx == coordIt->GetX() && by == coordIt->GetY()) continue;
448                         if(tx == coordIt->GetX() && ty == coordIt->GetY()) continue;
449                         if(this->GetSquare(coordIt->GetX(), coordIt->GetY())->GetFloorTag() == "VANILLA_PERMANENT_WALL") return false;
450                 }
451                 return true;
452         }
453
454         bool Field::GetSightPass(MAP_LENGTH x, MAP_LENGTH y)
455         {
456                 return SightPass[y * (this->width * 2 + 1) + x];
457         }
458
459         Coordinates* Field::Scatter(MAP_LENGTH y, MAP_LENGTH x, MAP_LENGTH distance)
460         {
461                 // TODO
462                 return NULL;
463         }
464
465         bool Field::AddRiver(Floor *floor1_ptr, Floor *floor2_ptr)
466         {
467                 // TODO
468                 return NULL;
469         }
470
471 }