#include <iostream>

class Creature
{
public:
    Creature(const std::string& name) : name(name) {}

    virtual ~Creature() = default;
    virtual void printInfo() const
    {
        std::cout << name;
    };

    std::string name;
};

template <typename T>
class VampiredCreature : T
{
public:
    VampiredCreature(const T& t, float sunlightSensitivity)
    : T(t),
      sunlightSensitivity(sunlightSensitivity) {}

    void printInfo() const override
    {
        T::printInfo();
        std::cout << " vampired: " << sunlightSensitivity;
    };
    float sunlightSensitivity = 0.f;
};

template <typename T>
class WereWolfCreature : T
{
public:
    WereWolfCreature(const T& t, int wolfHours) : T(t), wolfHours(wolfHours) {}

    void printInfo() const override
    {
        T::printInfo();
        
        std::cout << " wereWolf: " << wolfHours;
    }
    int wolfHours;
};

using Vampire = VampiredCreature<Creature>;
using Werewolf = WereWolfCreature<Creature>;
using VampireWerewolf = WereWolfCreature<Vampire>;

int main()
{
    Creature bob("Bob");
    Vampire dracula({"Dracula"}, 0.42f);
    Werewolf wolf({"Mi-Wolf"}, 50);
    VampireWerewolf vampireWereWolf({{"Wolf/Vampire"}, 0.51f}, 36);

    bob.printInfo();
    std::cout << "\n-----------\n";
    dracula.printInfo();
    std::cout << "\n-----------\n";
    wolf.printInfo();
    std::cout << "\n-----------\n";
    vampireWereWolf.printInfo();
    std::cout << "\n-----------\n";
}
