Source

zorkish / stages / AdventureStage.hpp

/*
 * AdventureStage.hpp
 *
 *  Created on: 20/08/2012
 *      Author: rhys
 */

#ifndef ADVENTURESTAGE_HPP_
#define ADVENTURESTAGE_HPP_

#include <boost/algorithm/string/case_conv.hpp>
#include "HighScoreStage.hpp"
#include "../CommandManager.hpp"
#include "../util.hpp"
#include "../commands/DropCommand.hpp"
#include "../commands/GoCommand.hpp"
#include "../commands/HiScoreCommand.hpp"
#include "../commands/InventoryCommand.hpp"
#include "../commands/LookCommand.hpp"
#include "../commands/TakeCommand.hpp"
#include "../commands/QuitCommand.hpp"

class AdventureStage : public ZorkishStage {
private:
    CommandManager cmgr;
    std::string message;
    std::unique_ptr<World> world;
    Player player;
    int moves;

public:
    AdventureStage(ZorkishGame& game)
            : ZorkishStage(game) {
        this->cmgr.add_command(make_unique<GoCommand>(), "GO");
        this->cmgr.add_command(make_unique<LookCommand>(), "LOOK");
        this->cmgr.add_command(make_unique<QuitCommand>(), "QUIT");
        this->cmgr.add_command(make_unique<HiScoreCommand>(), "HISCORE");
        this->cmgr.add_command(make_unique<InventoryCommand>(),
                { "INV", "INVENTORY" });
        this->cmgr.add_command(make_unique<TakeCommand>(), { "TAKE", "GRAB" });
        this->cmgr.add_command(make_unique<DropCommand>(), "DROP");
    }

    void setup(std::unique_ptr<World> world, int starting_location) {
        auto* start = world->get_location(starting_location);
        this->world.swap(world);
        this->message = start->long_desc();
        this->moves = 0;
        this->player = Player(start);
    }

    virtual Status update(ActiveStageManager& smgr) {
        if (this->player.alive) {
            if (this->cmgr.run(*this->world, this->player)) {
                this->moves++;
            }
            return GameStage::Status::CONTINUE;
        } else {
            if (this->player.score >= 10) {
                auto& hs = this->game.high_score();
                hs->set_score(this->player.score, this->moves,
                        this->world->name);
                smgr.set_next_stage(hs.get());
            }

            return GameStage::Status::FINISH;
        }
    }

    virtual void draw() {
        using std::cout;
        if (!this->message.empty()) {
            cout << this->message << '\n';
            this->message.clear();
        }
        if (this->player.alive) {
            cout << ":> ";
        }
    }
};

#endif /* ADVENTURESTAGE_HPP_ */