3 * @brief
\83Q
\81[
\83\80\92\86\82Ì
\83t
\83\8d\83A
\82ð
\92è
\8b`
\82·
\82é
15 Field::Field(std::map<TAG, std::shared_ptr<Dungeon>>::iterator dungeonIt, DEPTH depth) : GameInstance()
17 Dungeon *dungeonPtr = &(*dungeonIt->second);
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();
25 if(depth > dungeonPtr->GetMaxDepth() || depth > dungeonPtr->GetMinDepth()) return;
27 squares.resize(this->height);
28 for(y = 0; y < height; y++)
30 for(x = 0; x < width; x++)
32 squares[y].push_back(std::shared_ptr<Square>(new Square()));
33 if(Dice::Cast(1, 4) == 3)
35 squares[y][x]->SetFloor(dungeonPtr->GetInnerWallFloorTag());
39 squares[y][x]->SetFloor(dungeonPtr->GetFloorFloorTag());
46 this->createRectRoom(13, 13, 20, 33);
53 this->generated = true;
61 Field::Field(DEPTH depth)
71 void Field::WipeData(void)
75 this->dungeonTag = "";
82 MAP_LENGTH Field::GetWidth(void)
87 MAP_LENGTH Field::GetHeight(void)
92 bool Field::SetSize(MAP_LENGTH width, MAP_LENGTH height)
95 this->height = height;
99 Square *Field::GetSquare(MAP_LENGTH x, MAP_LENGTH y)
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();
106 Square *Field::GetSquare(Coordinates &coord)
108 return this->GetSquare(coord.GetX(), coord.GetY());
111 bool Field::GenerateTrap(std::map<TAG, std::shared_ptr<TrapBase>>::iterator trapBaseIt, Coordinates *position)
113 traps.emplace(traps.end(), std::make_shared<Trap>(trapBaseIt, position));
117 void Field::UpdateSight(void)
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);
125 for(x = 0; x < updateSizeX * updateSizeY; x++)
127 this->SightPass[x] = false;
128 this->PhysicalPass[x] = false;
131 for(y = 1; y < updateSizeY; y += 2)
133 for(x = 1; x < updateSizeX; x += 2)
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();
140 for(y = 0; y < this->height * 2 + 1; y += 2)
142 for(x = 0; x < this->width * 2 + 1; x += 2)
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))
146 this->SightPass[y * updateSizeX + x] = false;
147 this->PhysicalPass[y * updateSizeX + x] = false;
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()))
151 this->SightPass[y * updateSizeX + x] = true;
152 this->PhysicalPass[y * updateSizeX + x] = true;
156 this->SightPass[y * updateSizeX + x] = false;
157 this->PhysicalPass[y * updateSizeX + x] = false;
162 for(y = 0; y < this->height * 2 + 1; y += 2)
164 for(x = 1; x < this->width * 2 + 1; x += 2)
166 if(!this->GetSquare(x / 2, y / 2 - 1) || !this->GetSquare(x / 2, y / 2))
168 this->SightPass[y * updateSizeX + x] = false;
169 this->PhysicalPass[y * updateSizeX + x] = false;
171 else if(this->GetSquare(x / 2, y / 2 - 1)->IsWall() || this->GetSquare(x / 2, y / 2)->IsWall())
173 this->SightPass[y * updateSizeX + x] = false;
174 this->PhysicalPass[y * updateSizeX + x] = false;
178 this->SightPass[y * updateSizeX + x] = true;
179 this->PhysicalPass[y * updateSizeX + x] = true;
184 for(y = 1; y < updateSizeY; y += 2)
186 for(x = 0; x < updateSizeX; x += 2)
188 if(!this->GetSquare(x / 2 - 1, y / 2) || !this->GetSquare(x / 2, y / 2))
190 this->SightPass[y * updateSizeX + x] = false;
191 this->PhysicalPass[y * updateSizeX + x] = false;
193 else if(this->GetSquare(x / 2 - 1, y / 2)->IsWall() || this->GetSquare(x / 2, y / 2)->IsWall())
195 this->SightPass[y * updateSizeX + x] = false;
196 this->PhysicalPass[y * updateSizeX+ x] = false;
200 this->SightPass[y * updateSizeX + x] = true;
201 this->PhysicalPass[y * updateSizeX + x] = true;
208 void Field::createRectRoom(MAP_LENGTH sx, MAP_LENGTH sy, MAP_LENGTH ex, MAP_LENGTH ey)
211 std::vector<std::shared_ptr<Coordinates>> wallVec;
216 for(y = sy + 1; y < ey; y++)
218 for(x = sx + 1; x < ex; x++)
220 squarePtr = this->GetSquare(x, y);
223 squarePtr->SetFloor(dungeonPtr->GetFloorFloorTag());
228 for(y = sy; y <= ey; y++)
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));
238 for(x = sx + 1; x < ex; x++)
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));
248 this->GetSquare(*wallVec[Dice::Rand0(wallVec.size())].get())->SetFloor(dungeonPtr->GetFloorFloorTag());
251 void Field::createRectRoom(Coordinates& leftTop, Coordinates& rightBottom)
253 this->createRectRoom(leftTop.GetX(), leftTop.GetY(), rightBottom.GetX(), rightBottom.GetY());
256 void Field::GetSight(std::vector<bool> &coordVec, MAP_LENGTH size, MAP_LENGTH baseX, MAP_LENGTH baseY)
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;
265 for(s = 0 ; s < allocSize; s++) coordVec[s] = false;
266 coordVec[size * sideWidth + size] = true;
268 for(s = size; s >= 1; s--)
270 for(x = baseX - s; x <= baseX + s; x++)
276 if(Coordinates::Distance(baseX, baseY, tx, ty1) >= size) continue;
278 if(tx >= 0 && ty1 >= 0 && tx < this->width && ty1 < this->height)
280 if(!coordVec[(ty1 - baseY + size) * sideWidth + tx - baseX + size])
282 Coordinates::LineOfSight(lineVec, baseX, baseY, tx, ty1);
283 if(lineVec[0].GetX() == baseX && lineVec[0].GetY() == baseY)
285 for(lineIt = ++lineVec.begin(); lineIt < lineVec.end(); lineIt++)
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;
295 for(lineRIt = ++lineVec.rbegin(); lineRIt < lineVec.rend(); lineRIt++)
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;
308 if(tx >= 0 && ty2 >= 0 && tx < this->width && ty2 < this->height)
310 if(!coordVec[(ty2 - baseY + size) * sideWidth + tx - baseX + size])
312 Coordinates::LineOfSight(lineVec, baseX, baseY, tx, ty2);
313 if(lineVec[0].GetX() == baseX && lineVec[0].GetY() == baseY)
315 for(lineIt = ++lineVec.begin()++; lineIt < lineVec.end(); lineIt++)
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;
325 for(lineRIt = ++lineVec.rbegin()++; lineRIt < lineVec.rend(); lineRIt++)
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;
340 for(y = baseY - s; y <= baseY + s; y++)
346 if(Coordinates::Distance(baseX, baseY, tx1, ty) >= size) continue;
349 if(tx1 >= 0 && ty >= 0 && tx1 < this->width && ty < this->height)
351 if(!coordVec[(ty - baseY + size) * sideWidth + tx1 - baseX + size])
353 Coordinates::LineOfSight(lineVec, baseX, baseY, tx1, ty);
354 if(lineVec[0].GetX() == baseX && lineVec[0].GetY() == baseY)
356 for(lineIt = ++lineVec.begin(); lineIt < lineVec.end(); lineIt++)
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;
366 for(lineRIt = ++lineVec.rbegin(); lineRIt < lineVec.rend(); lineRIt++)
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;
379 if(tx2 >= 0 && ty >= 0 && tx2 < this->width && ty < this->height)
381 if(!coordVec[(ty - baseY + size) * sideWidth + tx2 - baseX + size])
383 Coordinates::LineOfSight(lineVec, baseX, baseY, tx2, ty);
384 if(lineVec[0].GetX() == baseX && lineVec[0].GetY() == baseY)
386 for(lineIt = ++lineVec.begin(); lineIt < lineVec.end(); lineIt++)
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;
396 for(lineRIt = ++lineVec.rbegin(); lineRIt < lineVec.rend(); lineRIt++)
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;
413 for(y = -size + 1; y < size; y++)
415 for(x = -size + 1; x < size; x++)
417 if(Coordinates::Distance(0, 0, x, y) <= size)
419 if(coordVec[(y+size) * sideWidth + (x+size)] == true && !this->GetSquare(baseX + x, baseY + y)->IsWall())
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;
436 bool Field::HaveSight(MAP_LENGTH bx, MAP_LENGTH by, MAP_LENGTH tx, MAP_LENGTH ty)
438 std::vector<Coordinates> coordVec;
439 std::vector<Coordinates>::iterator coordIt;
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;
444 Coordinates::LineOfSight(coordVec, bx, by, tx, ty);
445 for(coordIt = coordVec.begin(); coordIt != coordVec.end(); coordIt++)
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;
454 bool Field::GetSightPass(MAP_LENGTH x, MAP_LENGTH y)
456 return SightPass[y * (this->width * 2 + 1) + x];
459 Coordinates* Field::Scatter(MAP_LENGTH y, MAP_LENGTH x, MAP_LENGTH distance)
465 bool Field::AddRiver(Floor *floor1_ptr, Floor *floor2_ptr)