diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 96 |
1 files changed, 63 insertions, 33 deletions
diff --git a/src/main.cpp b/src/main.cpp index 77c4510..67be361 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -6,6 +6,8 @@ | |||
6 | #include <random> | 6 | #include <random> |
7 | #include <fov.h> | 7 | #include <fov.h> |
8 | #include <iostream> | 8 | #include <iostream> |
9 | #include <tuple> | ||
10 | #include <set> | ||
9 | #include "util.h" | 11 | #include "util.h" |
10 | #include "map.h" | 12 | #include "map.h" |
11 | 13 | ||
@@ -80,12 +82,16 @@ struct Input { | |||
80 | bool down = false; | 82 | bool down = false; |
81 | }; | 83 | }; |
82 | 84 | ||
85 | using coord = std::tuple<int, int>; | ||
86 | |||
83 | struct Kickup { | 87 | struct Kickup { |
84 | int x; | 88 | int x; |
85 | int y; | 89 | int y; |
86 | size_t cur; | 90 | size_t cur; |
87 | size_t radius; | 91 | size_t radius; |
88 | size_t chain; | 92 | size_t chain; |
93 | std::set<coord> done; | ||
94 | std::set<coord> front; | ||
89 | }; | 95 | }; |
90 | 96 | ||
91 | struct MapData { | 97 | struct MapData { |
@@ -93,6 +99,7 @@ struct MapData { | |||
93 | bool lit = false; | 99 | bool lit = false; |
94 | bool wasLit = false; | 100 | bool wasLit = false; |
95 | double visibility = 0.0; | 101 | double visibility = 0.0; |
102 | size_t dustLife = 0; | ||
96 | }; | 103 | }; |
97 | 104 | ||
98 | class Game { | 105 | class Game { |
@@ -319,6 +326,7 @@ void movePlayer(Game& game, int x, int y) | |||
319 | if (game.map.at(game.player_x, game.player_y).tile == Tile::Floor) | 326 | if (game.map.at(game.player_x, game.player_y).tile == Tile::Floor) |
320 | { | 327 | { |
321 | game.map.at(game.player_x, game.player_y).tile = Tile::Dust; | 328 | game.map.at(game.player_x, game.player_y).tile = Tile::Dust; |
329 | game.map.at(game.player_x, game.player_y).dustLife = 1; | ||
322 | game.numDust++; | 330 | game.numDust++; |
323 | } | 331 | } |
324 | 332 | ||
@@ -430,6 +438,8 @@ void kickUpDust(Game& game, int x, int y, size_t chain) | |||
430 | dk.chain = chain; | 438 | dk.chain = chain; |
431 | dk.cur = 0; | 439 | dk.cur = 0; |
432 | dk.radius = RADIUS + (chain + 1) * (chain + 1); | 440 | dk.radius = RADIUS + (chain + 1) * (chain + 1); |
441 | dk.front.emplace(x, y); | ||
442 | dk.done.emplace(x, y); | ||
433 | 443 | ||
434 | game.kickups.push_back(dk); | 444 | game.kickups.push_back(dk); |
435 | } | 445 | } |
@@ -442,6 +452,7 @@ void popLamp(Game& game, int x, int y, size_t chain) | |||
442 | } | 452 | } |
443 | 453 | ||
444 | game.map.at(x,y).tile = Tile::Dust; | 454 | game.map.at(x,y).tile = Tile::Dust; |
455 | game.map.at(x,y).dustLife = 2; | ||
445 | game.numDust++; | 456 | game.numDust++; |
446 | game.dirtyLighting = true; | 457 | game.dirtyLighting = true; |
447 | 458 | ||
@@ -454,32 +465,24 @@ void processKickup(Game& game) | |||
454 | { | 465 | { |
455 | kickup.cur++; | 466 | kickup.cur++; |
456 | 467 | ||
457 | if (game.map.at(kickup.x, kickup.y).tile == Tile::Floor) | 468 | std::set<coord> newFront; |
469 | for (const coord& xy : kickup.front) | ||
458 | { | 470 | { |
459 | game.map.at(kickup.x, kickup.y).tile = Tile::Dust; | 471 | auto processDir = [&] (int x, int y) { |
460 | game.numDust++; | 472 | coord c {x,y}; |
461 | } | ||
462 | |||
463 | std::unique_ptr<fov_settings_type> dusty(new fov_settings_type); | ||
464 | fov_settings_set_opacity_test_function( | ||
465 | dusty.get(), | ||
466 | [] (void* data, int x, int y) { | ||
467 | Game& game = *static_cast<Game*>(data); | ||
468 | 473 | ||
469 | return game.map.inBounds(x,y) && game.map.at(x,y).tile == Tile::Wall; | 474 | if (game.map.inBounds(x,y) && |
470 | }); | 475 | (game.map.at(x,y).tile == Tile::Floor || |
471 | 476 | game.map.at(x,y).tile == Tile::Lamp) && | |
472 | fov_settings_set_apply_lighting_function( | 477 | !kickup.done.count(c)) |
473 | dusty.get(), | ||
474 | [] (void* data, int x, int y, int, int, void* source) { | ||
475 | Game& game = *static_cast<Game*>(data); | ||
476 | Kickup& kickup = *static_cast<Kickup*>(source); | ||
477 | |||
478 | if (game.map.inBounds(x,y)) | ||
479 | { | 478 | { |
479 | newFront.insert(c); | ||
480 | kickup.done.insert(c); | ||
481 | |||
480 | if (game.map.at(x,y).tile == Tile::Floor) | 482 | if (game.map.at(x,y).tile == Tile::Floor) |
481 | { | 483 | { |
482 | game.map.at(x,y).tile = Tile::Dust; | 484 | game.map.at(x,y).tile = Tile::Dust; |
485 | game.map.at(x,y).dustLife = 2; | ||
483 | game.numDust++; | 486 | game.numDust++; |
484 | game.dirtyLighting = true; | 487 | game.dirtyLighting = true; |
485 | } else if (game.map.at(x,y).tile == Tile::Lamp) | 488 | } else if (game.map.at(x,y).tile == Tile::Lamp) |
@@ -487,15 +490,35 @@ void processKickup(Game& game) | |||
487 | popLamp(game, x, y, kickup.chain + 1); | 490 | popLamp(game, x, y, kickup.chain + 1); |
488 | } | 491 | } |
489 | } | 492 | } |
490 | }); | 493 | }; |
491 | 494 | ||
492 | fov_circle( | 495 | processDir(std::get<0>(xy) - 1, std::get<1>(xy) ); |
493 | dusty.get(), | 496 | processDir(std::get<0>(xy) + 1, std::get<1>(xy) ); |
494 | static_cast<void*>(&game), | 497 | processDir(std::get<0>(xy) , std::get<1>(xy) - 1); |
495 | static_cast<void*>(&kickup), | 498 | processDir(std::get<0>(xy) , std::get<1>(xy) + 1); |
496 | kickup.x, | 499 | |
497 | kickup.y, | 500 | if (std::bernoulli_distribution(0.5)(game.rng)) |
498 | kickup.cur); | 501 | { |
502 | processDir(std::get<0>(xy) - 1, std::get<1>(xy) - 1); | ||
503 | } | ||
504 | |||
505 | if (std::bernoulli_distribution(0.5)(game.rng)) | ||
506 | { | ||
507 | processDir(std::get<0>(xy) - 1, std::get<1>(xy) + 1); | ||
508 | } | ||
509 | |||
510 | if (std::bernoulli_distribution(0.5)(game.rng)) | ||
511 | { | ||
512 | processDir(std::get<0>(xy) + 1, std::get<1>(xy) - 1); | ||
513 | } | ||
514 | |||
515 | if (std::bernoulli_distribution(0.5)(game.rng)) | ||
516 | { | ||
517 | processDir(std::get<0>(xy) + 1, std::get<1>(xy) + 1); | ||
518 | } | ||
519 | } | ||
520 | |||
521 | kickup.front.swap(newFront); | ||
499 | } | 522 | } |
500 | 523 | ||
501 | erase_if( | 524 | erase_if( |
@@ -716,17 +739,24 @@ int main(int, char**) | |||
716 | 739 | ||
717 | while (dustAcc >= dustDt) | 740 | while (dustAcc >= dustDt) |
718 | { | 741 | { |
742 | game.numDust = 0; | ||
743 | |||
719 | for (MapData& md : game.map.data()) | 744 | for (MapData& md : game.map.data()) |
720 | { | 745 | { |
721 | if (md.tile == Tile::Dust) | 746 | if (md.tile == Tile::Dust) |
722 | { | 747 | { |
723 | md.tile = Tile::Floor; | 748 | md.dustLife--; |
724 | game.dirtyLighting = true; | 749 | |
750 | if (md.dustLife <= 0) | ||
751 | { | ||
752 | md.tile = Tile::Floor; | ||
753 | game.dirtyLighting = true; | ||
754 | } else { | ||
755 | game.numDust++; | ||
756 | } | ||
725 | } | 757 | } |
726 | } | 758 | } |
727 | 759 | ||
728 | game.numDust = 0; | ||
729 | |||
730 | processKickup(game); | 760 | processKickup(game); |
731 | 761 | ||
732 | dustAcc -= dustDt; | 762 | dustAcc -= dustDt; |