diff options
| author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-06-02 12:09:04 -0400 |
|---|---|---|
| committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-06-02 12:09:04 -0400 |
| commit | 91dd78d4c963dbcc596e44bf6991c40bb2df90cb (patch) | |
| tree | 578fb7ae582ea8eb77f7869e71dec6c98ef7d2ef | |
| parent | 06d1fb3ba346d6712206e35a022afcb340b434fd (diff) | |
| download | ether-91dd78d4c963dbcc596e44bf6991c40bb2df90cb.tar.gz ether-91dd78d4c963dbcc596e44bf6991c40bb2df90cb.tar.bz2 ether-91dd78d4c963dbcc596e44bf6991c40bb2df90cb.zip | |
dust now ripples outward
| -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; |
