Ticket #969: ai_territory_support-09282011.patch

File ai_territory_support-09282011.patch, 6.5 KB (added by historic_bruno, 13 years ago)
  • binaries/data/mods/public/simulation/ai/common-api/base.js

     
    7979
    8080    this.entities = new EntityCollection(this, this._rawEntities);
    8181    this.events = state.events;
    82     this.map = state.map;
    8382    this.passabilityClasses = state.passabilityClasses;
     83    this.passabilityMap = state.passabilityMap;
    8484    this.player = this._player;
    8585    this.playerData = state.players[this._player];
    8686    this.templates = this._templates;
     87    this.territoryMap = state.territoryMap;
    8788    this.timeElapsed = state.timeElapsed;
    8889
    8990    Engine.ProfileStop();
     
    9394    // Clean up temporary properties, so they don't disturb the serializer
    9495    delete this.entities;
    9596    delete this.events;
    96     delete this.map;
    9797    delete this.passabilityClasses;
     98    delete this.passabilityMap;
    9899    delete this.player;
    99100    delete this.playerData;
    100101    delete this.templates;
     102    delete this.territoryMap;
    101103    delete this.timeElapsed;
    102104};
    103105
  • source/simulation2/components/CCmpAIManager.cpp

     
    3434#include "simulation2/components/ICmpObstructionManager.h"
    3535#include "simulation2/components/ICmpRangeManager.h"
    3636#include "simulation2/components/ICmpTemplateManager.h"
     37#include "simulation2/components/ICmpTerritoryManager.h"
    3738#include "simulation2/helpers/Grid.h"
    3839#include "simulation2/serialization/DebugSerializer.h"
    3940#include "simulation2/serialization/StdDeserializer.h"
     
    272273        m_PlayerMetadata.clear();
    273274        m_Players.clear();
    274275        m_GameState.reset();
    275         m_GameStateMapVal = CScriptValRooted();
     276        m_PassabilityMapVal = CScriptValRooted();
     277        m_TerritoryMapVal = CScriptValRooted();
    276278    }
    277279
    278280    bool AddPlayer(const std::wstring& aiName, player_id_t player, bool callConstructor)
     
    286288        return true;
    287289    }
    288290
    289     void StartComputation(const shared_ptr<ScriptInterface::StructuredClone>& gameState, const Grid<u16>& map)
     291    void StartComputation(const shared_ptr<ScriptInterface::StructuredClone>& gameState, const Grid<u16>& passabilityMap, const Grid<u8>& territoryMap, bool territoryMapDirty)
    290292    {
    291293        ENSURE(m_CommandsComputed);
    292294
    293295        m_GameState = gameState;
    294296
    295         if (map.m_DirtyID != m_GameStateMap.m_DirtyID)
     297        if (passabilityMap.m_DirtyID != m_PassabilityMap.m_DirtyID)
    296298        {
    297             m_GameStateMap = map;
     299            m_PassabilityMap = passabilityMap;
    298300
    299301            JSContext* cx = m_ScriptInterface.GetContext();
    300             m_GameStateMapVal = CScriptValRooted(cx, ScriptInterface::ToJSVal(cx, m_GameStateMap));
     302            m_PassabilityMapVal = CScriptValRooted(cx, ScriptInterface::ToJSVal(cx, m_PassabilityMap));
    301303        }
    302304
     305        if (territoryMapDirty)
     306        {
     307            m_TerritoryMap = territoryMap;
     308
     309            JSContext* cx = m_ScriptInterface.GetContext();
     310            m_TerritoryMapVal = CScriptValRooted(cx, ScriptInterface::ToJSVal(cx, m_TerritoryMap));
     311        }
     312
    303313        m_CommandsComputed = false;
    304314    }
    305315
     
    432442        {
    433443            PROFILE("AI compute read state");
    434444            state = m_ScriptInterface.ReadStructuredClone(m_GameState);
    435             m_ScriptInterface.SetProperty(state.get(), "map", m_GameStateMapVal, true);
     445            m_ScriptInterface.SetProperty(state.get(), "passabilityMap", m_PassabilityMapVal, true);
     446            m_ScriptInterface.SetProperty(state.get(), "territoryMap", m_TerritoryMapVal, true);
    436447        }
    437448
    438449        // It would be nice to do
     
    467478    std::vector<shared_ptr<CAIPlayer> > m_Players; // use shared_ptr just to avoid copying
    468479
    469480    shared_ptr<ScriptInterface::StructuredClone> m_GameState;
    470     Grid<u16> m_GameStateMap;
    471     CScriptValRooted m_GameStateMapVal;
     481    Grid<u16> m_PassabilityMap;
     482    CScriptValRooted m_PassabilityMapVal;
     483    Grid<u8> m_TerritoryMap;
     484    CScriptValRooted m_TerritoryMapVal;
    472485
    473486    bool m_CommandsComputed;
    474487};
     
    568581        // Get the game state from AIInterface
    569582        CScriptVal state = cmpAIInterface->GetRepresentation();
    570583
    571         // Get the map data
     584        // Get the passability data
    572585        Grid<u16> dummyGrid;
    573         const Grid<u16>* map = &dummyGrid;
     586        const Grid<u16>* passabilityMap = &dummyGrid;
    574587        CmpPtr<ICmpPathfinder> cmpPathfinder(GetSimContext(), SYSTEM_ENTITY);
    575588        if (!cmpPathfinder.null())
    576             map = &cmpPathfinder->GetPassabilityGrid();
     589            passabilityMap = &cmpPathfinder->GetPassabilityGrid();
    577590
     591        // Get the territory data
     592        //  Since getting the territory grid can trigger a recalculation, we check NeedUpdate first
     593        bool territoryMapDirty = false;
     594        Grid<u8> dummyGrid2;
     595        const Grid<u8>* territoryMap = &dummyGrid2;
     596        CmpPtr<ICmpTerritoryManager> cmpTerritoryManager(GetSimContext(), SYSTEM_ENTITY);
     597        if (!cmpTerritoryManager.null() && cmpTerritoryManager->NeedUpdate(&m_TerritoriesDirtyID))
     598        {
     599            territoryMap = &cmpTerritoryManager->GetTerritoryGrid();
     600            territoryMapDirty = true;
     601        }
     602
    578603        LoadPathfinderClasses(state);
    579604
    580         m_Worker.StartComputation(scriptInterface.WriteStructuredClone(state.get()), *map);
     605        m_Worker.StartComputation(scriptInterface.WriteStructuredClone(state.get()), *passabilityMap, *territoryMap, territoryMapDirty);
    581606    }
    582607
    583608    virtual void PushCommands()
     
    605630    std::vector<std::string> m_TemplateNames;
    606631    size_t m_TemplateLoadedIdx;
    607632    std::vector<std::pair<std::string, const CParamNode*> > m_Templates;
     633    size_t m_TerritoriesDirtyID;
    608634
    609635    void StartLoadEntityTemplates()
    610636    {
  • source/simulation2/scripting/EngineScriptConversions.cpp

     
    236236
    237237    return OBJECT_TO_JSVAL(obj);
    238238}
     239
     240template<> jsval ScriptInterface::ToJSVal<Grid<u8> >(JSContext* cx, const Grid<u8>& val)
     241{
     242    JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
     243    if (!obj)
     244        return JSVAL_VOID;
     245
     246    jsuint len = val.m_W * val.m_H;
     247    JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8, len);
     248    if (!darray)
     249        return JSVAL_VOID;
     250
     251    js::TypedArray *tdest = js::TypedArray::fromJSObject(darray);
     252    ENSURE(tdest->byteLength == len*sizeof(u8));
     253
     254    memcpy(tdest->data, val.m_Data, tdest->byteLength);
     255
     256    jsval w = ToJSVal(cx, val.m_W);
     257    jsval h = ToJSVal(cx, val.m_H);
     258    jsval data = OBJECT_TO_JSVAL(darray);
     259
     260    JS_SetProperty(cx, obj, "width", &w);
     261    JS_SetProperty(cx, obj, "height", &h);
     262    JS_SetProperty(cx, obj, "data", &data);
     263
     264    return OBJECT_TO_JSVAL(obj);
     265}