summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp96
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
85using coord = std::tuple<int, int>;
86
83struct Kickup { 87struct 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
91struct MapData { 97struct 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
98class Game { 105class 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;