# Add inputs and outputs from these tool invocations to the build variables 
 CPP_SRCS += \
+../src/common/GameConfig.cpp \
 ../src/common/GameState.cpp \
 ../src/common/Hero.cpp \
 ../src/common/Ikari.cpp \
 ../src/common/TargetingMode.cpp 
 
 OBJS += \
+./src/common/GameConfig.o \
 ./src/common/GameState.o \
 ./src/common/Hero.o \
 ./src/common/Ikari.o \
 ./src/common/TargetingMode.o 
 
 CPP_DEPS += \
+./src/common/GameConfig.d \
 ./src/common/GameState.d \
 ./src/common/Hero.d \
 ./src/common/Ikari.d \
 
 
 # Add inputs and outputs from these tool invocations to the build variables 
 CPP_SRCS += \
+../src/common/GameConfig.cpp \
 ../src/common/GameState.cpp \
 ../src/common/Hero.cpp \
 ../src/common/Ikari.cpp \
 ../src/common/TargetingMode.cpp 
 
 OBJS += \
+./src/common/GameConfig.o \
 ./src/common/GameState.o \
 ./src/common/Hero.o \
 ./src/common/Ikari.o \
 ./src/common/TargetingMode.o 
 
 CPP_DEPS += \
+./src/common/GameConfig.d \
 ./src/common/GameState.d \
 ./src/common/Hero.d \
 ./src/common/Ikari.d \
 
 #include "states/PerformAttacks.h"
 #include "../app/Application.h"
 #include "../app/Input.h"
+#include "../common/GameState.h"
 #include "../common/Ikari.h"
 #include "../common/Inventory.h"
 #include "../common/Item.h"
 }
 
 void BattleState::LoadInventory() {
-       const Inventory &inv(*res->inventory);
+       const Inventory &inv(game->state->inventory);
        itemMenu.Clear();
        itemMenu.Reserve(inv.MaxItems());
        for (int i(0); i < inv.MaxItems(); ++i) {
 
 #include "SmallHeroTag.h"
 #include "../app/fwd.h"
 #include "../app/State.h"
+#include "../common/GameConfig.h"
 #include "../common/fwd.h"
 #include "../common/Stats.h"
 #include "../geometry/Vector.h"
 : public app::State {
 
 public:
-       BattleState(SDL_Surface *background, const PartyLayout &monstersLayout, const PartyLayout &heroesLayout, const Resources *res)
-       : background(background)
-       , monstersLayout(&monstersLayout)
-       , heroesLayout(&heroesLayout)
-       , res(res)
+       BattleState(common::GameConfig *game, SDL_Surface *background, const PartyLayout *monstersLayout)
+       : game(game)
+       , background(background)
+       , monstersLayout(monstersLayout)
+       , heroesLayout(game->heroesLayout)
+       , res(game->battleResources)
        , attackTypeMenu(res->attackIcons)
        , moveMenu(res->moveIcons)
        , numHeroes(0)
        , attackCursor(-1)
        , expReward(0)
        , goldReward(0)
-       , ranAway(false) { assert(background && res); }
+       , ranAway(false) { assert(background && monstersLayout && game); }
 
 public:
        void AddMonster(const Monster &);
        Uint16 CalculateDamage(const common::Stats &attacker, const common::Stats &defender) const;
 
 private:
+       common::GameConfig *game;
        SDL_Surface *background;
        const PartyLayout *monstersLayout;
        const PartyLayout *heroesLayout;
 
 
 , spellMenuHeadline("")
 , spellMenuProperties(0)
-, inventory(0)
 , itemMenuHeadline("")
 , itemMenuProperties(0)
 , ikariMenuHeadline("")
 
        const char *spellMenuHeadline;
        graphics::MenuProperties *spellMenuProperties;
 
-       common::Inventory *inventory;
        const char *itemMenuHeadline;
        graphics::MenuProperties *itemMenuProperties;
 
 
--- /dev/null
+/*
+ * GameConfig.cpp
+ *
+ *  Created on: Oct 9, 2012
+ *      Author: holy
+ */
+
+#include "GameConfig.h"
+
+namespace common {
+
+GameConfig::GameConfig()
+: state(0)
+, battleResources(0)
+, heroesLayout(0) {
+
+}
+
+}
 
--- /dev/null
+/*
+ * GameConfig.h
+ *
+ *  Created on: Oct 9, 2012
+ *      Author: holy
+ */
+
+#ifndef COMMON_GAMECONFIG_H_
+#define COMMON_GAMECONFIG_H_
+
+#include "fwd.h"
+#include "../battle/fwd.h"
+
+namespace common {
+
+struct GameConfig {
+
+       GameConfig();
+
+       GameState *state;
+
+       battle::Resources *battleResources;
+       battle::PartyLayout *heroesLayout;
+
+};
+
+}
+
+#endif /* COMMON_GAMECONFIG_H_ */
 
 #define COMMON_GAMESTATE_H_
 
 #include "Hero.h"
+#include "Inventory.h"
 
 #include <SDL.h>
 
        Hero heroes[7];
        Hero *party[4];
 
+       Inventory inventory;
+
        Uint32 money;
 
 };
 
 
 namespace common {
 
+struct GameConfig;
 struct GameState;
 class Hero;
 class HeroGroup;
 
 #include "battle/Monster.h"
 #include "battle/PartyLayout.h"
 #include "battle/Resources.h"
+#include "common/GameConfig.h"
 #include "common/GameState.h"
 #include "common/Hero.h"
 #include "common/Ikari.h"
 using battle::BattleState;
 using battle::Monster;
 using battle::PartyLayout;
+using common::GameConfig;
 using common::GameState;
 using common::Hero;
 using common::Ikari;
                gameState.party[2] = &gameState.heroes[2];
                gameState.party[3] = &gameState.heroes[3];
 
+               GameConfig gameConfig;
+               gameConfig.state = &gameState;
+               gameConfig.heroesLayout = caster.GetPartyLayout("heroesLayout");
+               gameConfig.battleResources = caster.GetBattleResources("battleResources");
+
                // temporary test data
                SDL_Surface *bg(IMG_Load("test-data/battle-bg.png"));
                PartyLayout monstersLayout(*caster.GetPartyLayout("monstersLayout"));
-               PartyLayout heroesLayout(*caster.GetPartyLayout("heroesLayout"));
 
                Monster monster(*caster.GetMonster("lizard"));
 
-               battle::Resources *battleRes(caster.GetBattleResources("battleResources"));
-
                gameState.heroes[0].AddSpell(caster.GetSpell("resetSpell"));
                Spell *strongSpell(caster.GetSpell("strongSpell"));
                gameState.heroes[0].AddSpell(strongSpell);
                gameState.heroes[0].AddSpell(valorSpell);
                gameState.heroes[1].AddSpell(valorSpell);
 
-               Inventory inventory;
-               inventory.Add(caster.GetItem("antidoteItem"), 9);
-               inventory.Add(caster.GetItem("magicJarItem"), 4);
-               inventory.Add(caster.GetItem("hiPotionItem"), 4);
-               inventory.Add(caster.GetItem("powerPotionItem"), 4);
-               inventory.Add(caster.GetItem("escapeItem"), 2);
-               inventory.Add(caster.GetItem("sleepBallItem"), 1);
-               battleRes->inventory = &inventory;
+               gameState.inventory.Add(caster.GetItem("antidoteItem"), 9);
+               gameState.inventory.Add(caster.GetItem("magicJarItem"), 4);
+               gameState.inventory.Add(caster.GetItem("hiPotionItem"), 4);
+               gameState.inventory.Add(caster.GetItem("powerPotionItem"), 4);
+               gameState.inventory.Add(caster.GetItem("escapeItem"), 2);
+               gameState.inventory.Add(caster.GetItem("sleepBallItem"), 1);
 
                gameState.heroes[0].SetWeapon(caster.GetItem("zircoSwordItem"));
                gameState.heroes[0].SetArmor(caster.GetItem("zirconArmorItem"));
                map1.SetTileset(&tileset);
                map1.SetTriggers(triggers1, 1);
                map1.SetWidth(2);
+               map1.SetBattleBackground(bg);
 
                Tile tiles3[64];
 
                map2.SetTileset(&tileset);
                map2.SetTriggers(triggers2, 1);
                map2.SetWidth(1);
+               map2.SetBattleBackground(bg);
 
                triggers1[0].map = &map2;
                triggers1[0].target = Vector<int>(6, 2);
                mapMonster.SetAnimation(&mapMonsterAnimation);
                mapMonster.Position() = Vector<float>(64, 32);
                mapMonster.SetOrientation(Entity::ORIENTATION_SOUTH);
+               mapMonster.SetPartyLayout(&monstersLayout);
+               mapMonster.SetMonsters(&monster, 1);
                map1.SetEntities(&mapMonster, 1);
 
                InitScreen screen(width, height);
                app::State *state(0);
 
                if (battle) {
-                       BattleState *battleState(new BattleState(bg, monstersLayout, heroesLayout, battleRes));
+                       BattleState *battleState(new BattleState(&gameConfig, bg, &monstersLayout));
                        battleState->AddMonster(monster);
                        battleState->AddMonster(monster);
                        battleState->AddMonster(monster);
                        battleState->AddHero(gameState.heroes[3]);
                        state = battleState;
                } else {
-                       MapState *mapState(new MapState(&map1));
+                       MapState *mapState(new MapState(&gameConfig, &map1));
 
                        mapState->ControlEntity(&gameState.heroes[0].MapEntity());
                        mapState->SetWalkingSpeed(walkSpeed);
 
 namespace map {
 
 Area::Area()
-: tiles(0)
+: battlebg(0)
+, tiles(0)
 , numTiles(0)
 , width(0) {
 
 }
 
 
+Tile *Area::TileAt(const geometry::Vector<int> &offset) {
+       int tileIndex(offset.Y() * width + offset.X());
+       if (tileIndex < numTiles) {
+               return tiles +tileIndex;
+       } else {
+               return 0;
+       }
+}
+
 const Tile *Area::TileAt(const geometry::Vector<int> &offset) const {
        int tileIndex(offset.Y() * width + offset.X());
        if (tileIndex < numTiles) {
 
        int Width() const { return width; }
        int Height() const { return numTiles / width + (numTiles % width ? 1 : 0); }
        geometry::Vector<int> Size() const { return geometry::Vector<int>(Width(), Height()); }
+       Tile *TileAt(const geometry::Vector<int> &);
        const Tile *TileAt(const geometry::Vector<int> &) const;
 
+       SDL_Surface *BattleBackground() { return battlebg; }
+
        void Render(SDL_Surface *dest, const graphics::Sprite *tileset, const geometry::Vector<int> &offset) const;
        void RenderDebug(SDL_Surface *dest, const graphics::Sprite *tileset, const geometry::Vector<int> &offset) const;
 
 // temporary setters
 public:
-       void SetTiles(const Tile *t, int num) { tiles = t; numTiles = num; }
+       void SetTiles(Tile *t, int num) { tiles = t; numTiles = num; }
        void SetWidth(int w) { width = w; }
 
 private:
-       const Tile *tiles;
+       SDL_Surface *battlebg;
+       Tile *tiles;
        int numTiles;
        int width;
 
 
 Entity::Entity()
 : follower(0)
 , animation(0)
+, partyLayout(0)
+, monsters(0)
+, numMonsters(0)
 , orientation(ORIENTATION_NORTH)
 , speed(0)
 , flags(0) {
        Entity e;
 
        int animationId(TypeDescription::GetTypeId("Animation"));
+       int monsterId(TypeDescription::GetTypeId("Monster"));
+       int partyLayoutId(TypeDescription::GetTypeId("PartyLayout"));
        int vectorId(TypeDescription::GetTypeId("Vector"));
 
        TypeDescription &td(TypeDescription::CreateOrGet("Entity"));
        td.SetSize(sizeof(Entity));
 
        td.AddField("animation", FieldDescription(((char *)&e.animation) - ((char *)&e), animationId).SetReferenced());
+       td.AddField("partyLayout", FieldDescription(((char *)&e.partyLayout) - ((char *)&e), partyLayoutId).SetReferenced());
+       td.AddField("monsters", FieldDescription(((char *)&e.monsters) - ((char *)&e), monsterId).SetReferenced().SetAggregate());
        td.AddField("spriteOffset", FieldDescription(((char *)&e.spriteOffset) - ((char *)&e), vectorId));
 }
 
 
 #ifndef MAP_ENTITY_H_
 #define MAP_ENTITY_H_
 
+#include "../battle/fwd.h"
+#include "../battle/Monster.h"
 #include "../geometry/Vector.h"
 #include "../graphics/fwd.h"
 #include "../graphics/Animation.h"
 
        void SetFlags(int f) { flags = f; }
        bool Blocking() const { return !(flags & FLAG_NONBLOCKING); }
-       bool Hostile() const {
-               // NOTE: this is a stub for testing!
-               return Blocking();
-       }
+       bool Hostile() const { return partyLayout && numMonsters > 0; }
+
+       void SetPartyLayout(battle::PartyLayout *l) { partyLayout = l; }
+       battle::PartyLayout *PartyLayout() { return partyLayout; }
+
+       void SetMonsters(battle::Monster *m, int num) { monsters = m; numMonsters = num; }
+       battle::Monster *MonstersBegin() { return monsters; }
+       battle::Monster *MonstersEnd() { return monsters + numMonsters; }
 
        Entity *Follower() { return follower; }
        const Entity *Follower() const { return follower; }
 private:
        Entity *follower;
        const graphics::Animation *animation;
+       battle::PartyLayout *partyLayout;
+       battle::Monster *monsters;
+       int numMonsters;
        graphics::AnimationRunner runner;
        geometry::Vector<int> spriteOffset;
        geometry::Vector<float> position;
 
 #include "Map.h"
 
 #include "Area.h"
+#include "Tile.h"
 #include "Trigger.h"
 #include "../graphics/Sprite.h"
 
 
 Map::Map()
 : tileset(0)
+, battlebg(0)
 , areas(0)
 , numAreas(0)
 , triggers(0)
 }
 
 
+Area *Map::AreaAt(const Vector<int> &offset) {
+       if (numAreas > 0) {
+               Vector<int> coords(TileCoordinates(offset));
+               Vector<int> areaOffset(coords / areas[0].Size());
+               int areaIndex(areaOffset.Index(width));
+               if (areaIndex < numAreas) {
+                       return areas + areaIndex;
+               }
+       }
+       return 0;
+}
+
 const Area *Map::AreaAt(const Vector<int> &offset) const {
        if (numAreas > 0) {
                Vector<int> coords(TileCoordinates(offset));
        return 0;
 }
 
+Tile *Map::TileAt(const Vector<int> &offset) {
+       Area *area(AreaAt(offset));
+       if (area) {
+               Vector<int> tileOffset(TileCoordinates(offset) % area->Size());
+               return area->TileAt(tileOffset);
+       } else {
+               return 0;
+       }
+}
+
 const Tile *Map::TileAt(const Vector<int> &offset) const {
        const Area *area(AreaAt(offset));
        if (area) {
        return 0;
 }
 
+SDL_Surface *Map::BattleBackgroundAt(const geometry::Vector<int> &position) {
+       Tile *tile(TileAt(position));
+       if (tile && tile->BattleBackground()) {
+               return tile->BattleBackground();
+       }
+       Area *area(AreaAt(position));
+       if (area && area->BattleBackground()) {
+               return area->BattleBackground();
+       }
+       return battlebg;
+}
+
 Vector<int> Map::TileCoordinates(const Vector<int> &position) const {
        return position / tileset->Size();
 }
 
 
 public:
        const graphics::Sprite *Tileset() const { return tileset; }
+       Area *AreaAt(const geometry::Vector<int> &);
        const Area *AreaAt(const geometry::Vector<int> &) const;
+       Tile *TileAt(const geometry::Vector<int> &);
        const Tile *TileAt(const geometry::Vector<int> &) const;
        Trigger *TriggerAt(const geometry::Vector<int> &);
+       SDL_Surface *BattleBackgroundAt(const geometry::Vector<int> &);
        geometry::Vector<int> TileCoordinates(const geometry::Vector<int> &) const;
 
        Entity **EntitiesBegin() { return &entities; }
 // temporary setters
 public:
        void SetTileset(const graphics::Sprite *t) { tileset = t; }
+       void SetBattleBackground(SDL_Surface *bg) { battlebg = bg; }
        void SetAreas(Area *a, int num) { areas = a; numAreas = num; }
        void SetTriggers(Trigger *t, int num) { triggers = t; numTriggers = num; }
        void SetEntities(Entity *e, int num) { entities = e; numEntities = num; }
 
 private:
        const graphics::Sprite *tileset;
+       SDL_Surface *battlebg;
        Area *areas;
        int numAreas;
        Trigger *triggers;
 
 #include "Trigger.h"
 #include "../app/Application.h"
 #include "../app/Input.h"
+#include "../battle/BattleState.h"
+#include "../common/GameConfig.h"
+#include "../common/GameState.h"
 #include "../graphics/ColorFade.h"
 
 #include <algorithm>
 
 using app::Application;
 using app::Input;
+using battle::BattleState;
+using common::GameConfig;
 using geometry::Vector;
 using graphics::ColorFade;
 
 namespace map {
 
-MapState::MapState(Map *map)
-: ctrl(0)
+MapState::MapState(GameConfig *g, Map *map)
+: game(g)
+, ctrl(0)
 , map(map)
 , controlled(0)
 , tempTarget(20, 20)
        if (moveTimer.Running() && !moveTimer.JustHit()) return;
 
        Vector<int> nowLock(controlled->Position());
+       bool event(false);
        if (nowLock != lastLock) {
-               OnGridLock();
+               event = OnGridLock();
                afterLock = true;
                moveTimer.Clear();
        } else if (moveTimer.JustHit()) {
-               OnGridLock();
+               event = OnGridLock();
                afterLock = true;
        }
 
-       // TODO: halt all activity if lock caused a state/map transition
+       if (event) {
+               return;
+       }
 
        if (nextDirection >= 0) {
                bool blocked(CheckBlocking());
        return false;
 }
 
-void MapState::OnGridLock() {
+bool MapState::OnGridLock() {
        if (skipLock) {
                skipLock = false;
+               return false;
        } else {
                LockEntities();
-               CheckMonster();
-               CheckTrigger();
+               return CheckMonster() || CheckTrigger();
        }
 }
 
        }
 }
 
-void MapState::CheckMonster() {
+bool MapState::CheckMonster() {
        Vector<int> coords(map->TileCoordinates(controlled->Position()));
        Vector<int> neighbor[4];
        neighbor[0] = Vector<int>(coords.X(), coords.Y() - 1); // N
                for (std::vector<Entity *>::iterator e(entities.begin()), end(entities.end()); e != end; ++e) {
                        if ((*e)->Hostile() && map->TileCoordinates((*e)->Position()) == neighbor[i]) {
                                // TODO: check for turn advantage, see #26
-                               // TODO: remove entity, push battle state and transition and halt all other activity
+                               // TODO: other transition
+                               BattleState *battleState(new BattleState(game, map->BattleBackgroundAt((*e)->Position()), (*e)->PartyLayout()));
+                               for (int i(0); i < 4; ++i) {
+                                       if (game->state->party[i]) {
+                                               battleState->AddHero(*game->state->party[i]);
+                                       }
+                               }
+                               for (battle::Monster *monster((*e)->MonstersBegin()); monster != (*e)->MonstersEnd(); ++monster) {
+                                       battleState->AddMonster(*monster);
+                               }
+
+                               ColorFade *fadeIn(new ColorFade(this, 0, 500, true));
+                               fadeIn->SetLeadInTime(500);
+                               ColorFade *fadeOut(new ColorFade(this, 0, 500));
+                               fadeOut->SetLeadOutTime(500);
+
+                               ctrl->PushState(fadeIn);
+                               ctrl->PushState(battleState);
+                               ctrl->PushState(fadeOut);
+                               // TODO: move entity erase to happen after the transition or battle
+                               entities.erase(e);
+                               return true;
                                // needed information here:
-                               //  - battle background (from tile?)
+                               //  - battle background (from tile/area/map)
                                //  - monsters + layout (from entity)
-                               //  - battle resources (from global resources)
                        }
                }
        }
+       return false;
 }
 
-void MapState::CheckTrigger() {
+bool MapState::CheckTrigger() {
        Trigger *trigger(map->TriggerAt(Vector<int>(controlled->Position())));
        if (trigger) {
                // TODO: run trigger script
                        ColorFade *fadeOut(new ColorFade(this, 0, 500, false));
                        fadeOut->SetLeadOutTime(500);
                        ctrl->PushState(fadeOut);
+                       return true;
                }
        }
-
+       return false;
 }
 
 void MapState::OnMove(bool realMove) {
 
 #include "Entity.h"
 #include "fwd.h"
 #include "../app/State.h"
+#include "../common/fwd.h"
 #include "../geometry/Vector.h"
 #include "../graphics/Camera.h"
 
 : public app::State {
 
 public:
-       explicit MapState(Map *);
+       explicit MapState(common::GameConfig *, Map *);
        virtual ~MapState() { }
 
 public:
        bool CheckBlocking() const;
 
        void OnTileLock();
-       void OnGridLock();
+       bool OnGridLock();
        void OnMove(bool);
 
        void UpdateFollower(Entity &);
        void StopFollowers(Entity &);
 
        void LockEntities();
-       void CheckMonster();
-       void CheckTrigger();
+       bool CheckMonster();
+       bool CheckTrigger();
 
 private:
+       common::GameConfig *game;
        app::Application *ctrl;
        Map *map;
        Entity *controlled;
 
 namespace map {
 
 Tile::Tile()
-: flags(0) {
+: battlebg(0)
+, flags(0) {
 
 }
 
 
                BLOCK_WEST = 0x08,
        };
 
+       SDL_Surface *BattleBackground() { return battlebg; }
+
        const geometry::Vector<int> &Offset() const { return offset; }
 
        bool BlocksNorth() const { return flags & BLOCK_NORTH; }
        Tile &SetFlags(Uint32 f) { flags = f; return *this; }
 
 private:
+       SDL_Surface *battlebg;
        geometry::Vector<int> offset;
        Uint32 flags;