title: __thiscall already defined in .obj
body: <p>I am getting linker errors which I cannot seem to find the root cause of, having checked for including .cpp files and reading other forums.</p>
  
  <p>The errors are:</p>
  
  <pre><code>1&gt;------ Build started: Project: Penguin_RPG, Configuration: Debug Win32 ------
  1&gt;  main.cpp
  1&gt;c:\users\adam\documents\visual studio 2013\projects\penguin_rpg\penguin_rpg\dialogue.hpp(53): warning C4018: '&lt;=' : signed/unsigned mismatch
  1&gt;c:\users\adam\documents\visual studio 2013\projects\penguin_rpg\penguin_rpg\main.cpp(39): warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
  1&gt;main.obj : error LNK2005: "public: __thiscall Area::Area(class Dialogue,class Inventory,class std::vector&lt;class Creature *,class std::allocator&lt;class Creature *&gt; &gt;)" (??0Area@@QAE@VDialogue@@VInventory@@V?$vector@PAVCreature@@V?$allocator@PAVCreature@@@std@@@std@@@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: __thiscall Creature::Creature(class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;,int,int,int,int,double,unsigned int,class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;)" (??0Creature@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HHHHNI0@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: __thiscall Creature::Creature(void)" (??0Creature@@QAE@XZ) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: __thiscall Dialogue::Dialogue(class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;,class std::vector&lt;class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;,class std::allocator&lt;class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt; &gt; &gt;)" (??0Dialogue@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@2@@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: __thiscall Item::Item(class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;,class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;)" (??0Item@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: __thiscall Weapon::Weapon(class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;,class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;,unsigned int,double)" (??0Weapon@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0IN@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: int __thiscall Dialogue::activate(void)" (?activate@Dialogue@@QAEHXZ) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Inventory::add_armour(class Armour *,int)" (?add_armour@Inventory@@QAEXPAVArmour@@H@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Inventory::add_item(class Item *,int)" (?add_item@Inventory@@QAEXPAVItem@@H@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Inventory::add_weapon(class Weapon *,int)" (?add_weapon@Inventory@@QAEXPAVWeapon@@H@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Inventory::clear(void)" (?clear@Inventory@@QAEXXZ) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Creature::equipArmour(class Armour *)" (?equipArmour@Creature@@QAEXPAVArmour@@@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Creature::equipWeapon(class Weapon *)" (?equipWeapon@Creature@@QAEXPAVWeapon@@@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: unsigned int __thiscall Creature::expToLevel(unsigned int)" (?expToLevel@Creature@@QAEII@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: bool __thiscall Creature::levelUp(void)" (?levelUp@Creature@@QAE_NXZ) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Inventory::merge(class Inventory *)" (?merge@Inventory@@QAEXPAV1@@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Inventory::print(bool)" (?print@Inventory@@QAEX_N@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: int __thiscall Inventory::print_armours(bool)" (?print_armours@Inventory@@QAEH_N@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: int __thiscall Inventory::print_items(bool)" (?print_items@Inventory@@QAEH_N@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: int __thiscall Inventory::print_weapons(bool)" (?print_weapons@Inventory@@QAEH_N@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Inventory::remove_armour(class Armour *,int)" (?remove_armour@Inventory@@QAEXPAVArmour@@H@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Inventory::remove_item(class Item *,int)" (?remove_item@Inventory@@QAEXPAVItem@@H@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Inventory::remove_weapon(class Weapon *,int)" (?remove_weapon@Inventory@@QAEXPAVWeapon@@H@Z) already defined in atlas.obj
  1&gt;main.obj : error LNK2005: "public: void __thiscall Area::search(class Creature &amp;)" (?search@Area@@QAEXAAVCreature@@@Z) already defined in atlas.obj
  1&gt;C:\Users\Adam\Documents\Visual Studio 2013\Projects\Penguin_RPG\Debug\Penguin_RPG.exe : fatal error LNK1169: one or more multiply defined symbols found
  ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
  </code></pre>
  
  <p>atlas.hpp:</p>
  
  <pre><code>#pragma once
  #ifndef ATLAS_HPP
  #define ATLAS_HPP
  
  #include &lt;vector&gt;
  
  #include "creature.hpp"
  #include "item.hpp"
  #include "weapon.hpp"
  #include "armour.hpp"
  #include "area.hpp"
  
  //atlas building functions. Atlases contain vectors of
  //game data that is not modified. Could be replaced with
  //functions that read from config files.
  
  void buildatlas_creature(std::vector&lt;Creature&gt;&amp; atlas);
  void buildatlas_item(std::vector&lt;Item&gt;&amp; atlas);
  void buildatlas_weapon(std::vector&lt;Weapon&gt;&amp; atlas);
  void buildatlas_armours(std::vector&lt;Armour&gt;&amp; atlas);
  void buildatlas_area(std::vector&lt;Area&gt;&amp; atlas,
      std::vector&lt;Item&gt;&amp; items, std::vector&lt;Weapon&gt;&amp; weapons,
      std::vector&lt;Armour&gt;&amp; armours, std::vector&lt;Creature&gt;&amp; creatures);
  
  #endif //ATLAS_HPP
  </code></pre>
  
  <p>atlas.cpp:</p>
  
  <pre><code>#include "atlas.hpp"
  
  void buildatlas_creature(std::vector&lt;Creature&gt;&amp; atlas)
  {
      //fill the atlas
      //Creature(name, health, str, end, dex, hitRate, level)
      atlas.push_back(Creature("Rat", 8, 8, 8, 12, 2.0, 1));
  
      return;
  }
  void buildatlas_item(std::vector&lt;Item&gt;&amp; atlas)
  {
      //Item(name, description)
      atlas.push_back(Item("Gold Coin", 
          "A small disc made of lustrous metal"));
      atlas.push_back(Item("Iron Key",
          "A heavy iron key with a simple cut"));
  
      return;
  }
  void buildatlas_weapon(std::vector&lt;Weapon&gt;&amp; atlas)
  {
      //Weapon(name, description, damage, hitRate)
      atlas.push_back(Weapon("Iron Dagger", 
          "A short blade made of iron with a leather hilt",
          5, 10.0));
      atlas.push_back(Weapon("Excalibur",
          "The legendary blade, bestowed upon you by the lady of the lake",
          35, 35.0));
  
      return;
  }
  void buildatlas_armours(std::vector&lt;Armour&gt;&amp; atlas)
  {
      //Armour(name, description, defence, slot)
      atlas.push_back(Armour("Leather Vest",
          "Torso armour made of tanned hide",
          4, Armour::Slot::TORSO));
  
      return;
  }
  void buildatlas_area(std::vector&lt;Area&gt;&amp; atlas,
      std::vector&lt;Item&gt;&amp; items, std::vector&lt;Weapon&gt;&amp; weapons,
      std::vector&lt;Armour&gt;&amp; armours, std::vector&lt;Creature&gt;&amp; creatures)
  {
      // Area definitions are somewhat more complicated:
      atlas.push_back(Area(Dialogue(        // Standard dialogue definiton
          "You are in room 1",              // Description
          { "Go to room 2", "Search" }),      // Choices
          Inventory(                        // Area inventory
      {
          std::make_pair(&amp;items[0], 5)  // Pair of item and quantity
  
      },
      {
          std::make_pair(&amp;weapons[0], 1)// Pair of weapon and quantity
      },
      {
          std::make_pair(&amp;armours[0], 1) // Pair of armour and quantity
      }),
      {                                 // Creatures
      }));
  
      atlas.push_back(Area(Dialogue(
          "You are in room 2",
          { "Go to room 1", "Search" }),
          Inventory(
      {
          std::make_pair(&amp;items[0], 10),
          std::make_pair(&amp;items[1], 1)
      },
      {
      },
      {
      }),
      {
          &amp;creatures[0]
      }));
  
      return;
  }
  </code></pre>
  
  <p>inventory.hpp:</p>
  
  <pre><code>#pragma once
  #ifndef INVENTORY_HPP
  #define INVENTORY_HPP
  
  #include "item.hpp"
  #include "weapon.hpp"
  #include "armour.hpp"
  
  #include &lt;list&gt;
  #include &lt;utility&gt;
  #include &lt;iostream&gt;
  
  class Inventory
  {
  public:
      //Whilst weapons and armour are items, they have their own 
      //specific properties and can't be stored in the same list.
      //The first element of the pair stores a pointer to the item
      //in the item/weapon/armour atlas, defined in main(), the second
      //if the quantity of the item
  
      std::list&lt;std::pair&lt;Item*, int&gt;&gt; items;
      std::list&lt;std::pair&lt;Weapon*, int&gt;&gt; weapons;
      std::list&lt;std::pair&lt;Armour*, int&gt;&gt; armours;
  
      Inventory(){};
      Inventory(std::list&lt;std::pair&lt;Item*, int&gt;&gt; items,
          std::list&lt;std::pair&lt;Weapon*, int&gt;&gt; weapons,
          std::list&lt;std::pair&lt;Armour*, int&gt;&gt; armours)
      {
          this-&gt;items = items;
          this-&gt;weapons = weapons;
          this-&gt;armours = armours;
      }
  
      void add_item(Item* item, int count);
      void add_weapon(Weapon* weapon, int count);
      void add_armour(Armour* armour, int count);
  
      void remove_item(Item*, int count);
      void remove_weapon(Weapon*, int count);
      void remove_armour(Armour*, int count);
  
      void merge(Inventory* inventory);
      void clear();
  
      int print_items(bool label);
      int print_weapons(bool label);
      int print_armours(bool label);
      void print(bool label);
  };
  
  //add an item to the inventory
  void Inventory::add_item(Item* item, int count)
  {
      // Increase the quantity if the item already exists
      for (auto&amp; it : this-&gt;items)
      {
          if (it.first == item) it.second += count;
          return;
      }
      // If the item doesn't already exist in the inventory, then a
      // pair must be created too
      this-&gt;items.push_back(std::make_pair(item, count));
  }
  void Inventory::add_weapon(Weapon* weapon, int count)
  {
      for (auto&amp; it : this-&gt;weapons)
      {
          if (it.first == weapon)
          {
              it.second += count;
              return;
          }
      }
      this-&gt;weapons.push_back(std::make_pair(weapon, count));
  }
  
  void Inventory::add_armour(Armour* armour, int count)
  {
      for (auto&amp; it : this-&gt;armours)
      {
          if (it.first == armour)
          {
              it.second += count;
              return;
          }
      }
      this-&gt;armours.push_back(std::make_pair(armour, count));
  }
  
  void Inventory::remove_item(Item* item, int count)
  {
      // Iterate through the items, and if they are found then decrease
      // the quantity by the quantity removed
      for (auto&amp; it : this-&gt;items)
      {
          if (it.first == item) it.second -= count;
      }
      // Iterate through the list again, and remove any elements from
      // the list that have zero or less for their quantity
      // We do this in two passes because removing an element from
      // a list during a for loop invalidates the iterators, and the
      // loop stops working
      this-&gt;items.remove_if([](std::pair&lt;Item*, int&gt;&amp; element)
      {
          return element.second &lt; 1;
      });
  }
  
  void Inventory::remove_weapon(Weapon* weapon, int count)
  {
      for (auto&amp; it : this-&gt;weapons)
      {
          if (it.first == weapon) it.second -= count;
      }
      this-&gt;weapons.remove_if([](std::pair&lt;Weapon*, int&gt;&amp; element)
      {
          return element.second &lt; 1;
      });
  }
  
  void Inventory::remove_armour(Armour* armour, int count)
  {
      for (auto&amp; it : this-&gt;armours)
      {
          if (it.first == armour) it.second -= count;
      }
      this-&gt;armours.remove_if([](std::pair&lt;Armour*, int&gt;&amp; element)
      {
          return element.second &lt; 1;
      });
  }
  
  //merge the specified Inventory with the current one
  //adding item quantaties if they exist, creating a new slot if they don't
  void Inventory::merge(Inventory* inventory)
  {
      // You can't merge an inventory with itself!
      if (inventory == this) return;
  
      // Loop through the items to be added, and add them. Our addition
      // function will take care of everything else for us
      for (auto it : inventory-&gt;items)
      {
          this-&gt;add_item(it.first, it.second);
      }
      // Do the same for the weapons
      for (auto it : inventory-&gt;weapons)
      {
          this-&gt;add_weapon(it.first, it.second);
      }
      // Do the same for the armour
      for (auto it : inventory-&gt;armours)
      {
          this-&gt;add_armour(it.first, it.second);
      }
  
      return;
  }
  
  void Inventory::clear()
  {
      this-&gt;items.clear();
      this-&gt;weapons.clear();
      this-&gt;armours.clear();
  }
  
  //output a list of items to stdout, nicely formatted
  int Inventory::print_items(bool label = false)
  {
      unsigned int i = 1;
  
      for(std::list&lt;std::pair&lt;Item*, int&gt;&gt;::iterator it =
          this-&gt;items.begin(); it != this-&gt;items.end(); ++it)
      {
          //number items if asked
          if(label)
          {
              std::cout &lt;&lt; i++ &lt;&lt; ":";
              //output the item name, quantity and description
              std::cout &lt;&lt; it-&gt;first-&gt;name &lt;&lt; " (" &lt;&lt; it-&gt;second &lt;&lt; ") - ";
              std::cout &lt;&lt;it-&gt;first-&gt;description &lt;&lt; std::endl;
          }
      }
      //return number of items outputted, for convienience
      return this-&gt;items.size();
  }
  
  //output a list of weapons to stdout, nicely formatted
  int Inventory::print_weapons(bool label = false)
  {
      unsigned int i = 1;
  
      for (auto it : this-&gt;weapons)
      {
          if (label) std::cout &lt;&lt; i++ &lt;&lt; ": ";
          std::cout &lt;&lt; it.first-&gt;name &lt;&lt; " (" &lt;&lt; it.second &lt;&lt; ") - ";
          std::cout &lt;&lt; it.first-&gt;description &lt;&lt; std::endl;
      }
  
      return this-&gt;weapons.size();
  }
  
  //output a list of armour to stdout, nicely formatted
  int Inventory::print_armours(bool label = false)
  {
      unsigned int i = 1;
  
      for(std::list&lt;std::pair&lt;Armour*, int&gt;&gt;::iterator it =
          this-&gt;armours.begin(); it != this-&gt;armours.end(); ++it)
      {
          //number items if asked
          if(label)
          {
              std::cout &lt;&lt; i++ &lt;&lt; ":";
              //output the item name, quantity and description
              std::cout &lt;&lt; it-&gt;first-&gt;name &lt;&lt; " (" &lt;&lt; it-&gt;second &lt;&lt; ") - ";
              std::cout &lt;&lt;it-&gt;first-&gt;description &lt;&lt; std::endl;
          }
      }
      //return number of items outputted, for convienience
      return this-&gt;armours.size();
  }
  
  //print the entire inventory, unless it is empty
  void Inventory::print(bool label = false)
  {
      if(this-&gt;items.size() == 0 &amp;&amp; 
          this-&gt;weapons.size() == 0 &amp;&amp;
          this-&gt;armours.size() == 0)
      {
          std::cout &lt;&lt; "Empty!" &lt;&lt; std::endl;
      }
      else
      {
          this-&gt;print_items(label);
          this-&gt;print_weapons(label);
          this-&gt;print_armours(label);
      }
      return;
  }
  #endif //INVENTORY_HPP
  </code></pre>
  
  <p>main.cpp:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;vector&gt;
  #include &lt;list&gt;
  #include &lt;utility&gt;
  #include &lt;cstdlib&gt;
  #include &lt;ctime&gt;
  
  #include "area.hpp"
  #include "armour.hpp"
  #include "atlas.hpp"
  #include "creature.hpp"
  #include "dialogue.hpp"
  #include "inventory.hpp"
  #include "item.hpp"
  #include "weapon.hpp"
  
  Creature dialogue_newChar();
  
  int main(void)
  {
      std::vector&lt;Creature&gt; creatureAtlas;
      std::vector&lt;Item&gt; itemAtlas;
      std::vector&lt;Weapon&gt; weaponAtlas;
      std::vector&lt;Armour&gt; armourAtlas;
      std::vector&lt;Area&gt; areaAtlas;
  
      // Build the atlases
      buildatlas_creature(creatureAtlas);
      buildatlas_item(itemAtlas);
      buildatlas_weapon(weaponAtlas);
      buildatlas_armours(armourAtlas);
      buildatlas_area(areaAtlas, itemAtlas, weaponAtlas,
          armourAtlas, creatureAtlas);
  
      Creature player;
  
      //seed rand() with system time, to produce better random numbers
      srand(time(NULL));
  
      //main game menu dialogue
      int result = Dialogue("Welcome to the jungle!", { "New Game" }).activate();
  
      switch (result)
      {
      case 1:
          player = dialogue_newChar();
          break;
      default:
          return 0;
          break;
      }
      // Set the current area to be the first area in the atlas,
      // essentially placing the player there upon game start
      Area* currentArea = &amp;(areaAtlas[0]);
  
      // Play the game until a function breaks the loop and closes it
      while (1)
      {
          // If the player has died then inform them as such and close
          // the program
          if (player.health &lt;= 0)
          {
              std::cout &lt;&lt; "\t----YOU DIED----\n    Game Over\n";
              return 0;
          }
  
          // Activate the current area's dialogue
          result = currentArea-&gt;dialogue.activate();
  
          // These could be moved inside of the area code using an
          // event style system, but that allows for much less
          // flexibility with what happens in each area. Since we're
          // defining the areas in code anyway, sticking with this
          // isn't too much of a problem, and it keeps things easy
          // to understand
          if (currentArea == &amp;(areaAtlas[0]))
          {
              switch (result)
              {
              case 1:
                  // Move to area 1
                  currentArea = &amp;(areaAtlas[1]);
                  break;
              case 2:
                  // Search the area
                  currentArea-&gt;search(player);
                  break;
              default:
                  break;
              }
          }
          else if (currentArea == &amp;(areaAtlas[1]))
          {
              switch (result)
              {
                  // Move to area 0
              case 1:
                  currentArea = &amp;(areaAtlas[0]);
                  break;
                  // Search the area
              case 2:
                  currentArea-&gt;search(player);
                  break;
              default:
                  break;
              }
          }
      }
  
      return 0;
  
  }
  
  //create a new character
  Creature dialogue_newChar()
  {
      //ask for a name and class
      std::cout &lt;&lt; "Choose your name punk!" &lt;&lt; std::endl;
      std::string name;
      std::cin &gt;&gt; name;
  
      int result = Dialogue("Choose your class!", { "Fighter", "Rogue" }).activate();
  
      switch (result)
      {
      case 1:
          //Fighter favours health and strength
          return Creature(name, 35, 20, 10, 5, 10.0, 1, "Fighter");
          break;
      case 2:
          //Rogue favours endurance and dexterity
          return Creature(name, 30, 5, 10, 20, 15.0, 1, "Rogue");
          break;
      default:
          //default should not happen, good to be safe though!
          return Creature(name, 30, 10, 10, 10, 10.0, 1, "Adventurer");
          break;
      }
  }
  </code></pre>
  
  <p>I can add the code for additional files if needed.
  Thanks!</p>