/**
 *  zeichnet den Kartenausschnitt.
 *
 *  @author OLiver
 *  @author FloSoft
 */
void TerrainRenderer::Draw(const GameWorldView& gwv, unsigned int* water)
{
    assert(!gl_vertices.empty());
    assert(!borders.empty());

    /*  if ((gwv.GetXOffset() == gwv.terrain_last_xoffset) && (gwv.GetYOffset() == gwv.terrain_last_yoffset) && (gwv.terrain_list != 0) && (GAMECLIENT.GetGlobalAnimation(4, 5, 4, 0) == gwv.terrain_last_global_animation))
        {
            glCallList(gwv.terrain_list);
            *water = gwv.terrain_last_water;
            return;
        }

        gwv.terrain_last_xoffset = gwv.GetXOffset();
        gwv.terrain_last_yoffset = gwv.GetYOffset();
        gwv.terrain_last_global_animation = GAMECLIENT.GetGlobalAnimation(4, 5, 4, 0);

        if (gwv.terrain_list == 0)
            gwv.terrain_list = glGenLists(1);

        glNewList(gwv.terrain_list, GL_COMPILE_AND_EXECUTE);*/

    // nach Texture in Listen sortieren
    boost::array< std::vector<MapTile>, TT_COUNT> sorted_textures;
    boost::array< std::vector<BorderTile>, 5> sorted_borders;
    PreparedRoads sorted_roads;

    Point<int> lastOffset(0, 0);
 
    // Beim zeichnen immer nur beginnen, wo man auch was sieht
    for(int y = gwv.GetFirstPt().y; y < gwv.GetLastPt().y; ++y)
    {
        unsigned char lastTerrain = 255;
        unsigned char lastBorder  = 255;

        for(int x = gwv.GetFirstPt().x; x < gwv.GetLastPt().x; ++x)
        {
            Point<int> posOffset;
            MapPoint tP = ConvertCoords(Point<int>(x, y), &posOffset);

            TerrainType t = gwv.GetGameWorldViewer().GetNode(tP).t1;
            if(posOffset != lastOffset)
                lastTerrain = 255;

            if(t == lastTerrain && tP != MapPoint(0, 0))
                ++sorted_textures[t].back().count;
            else
            {
                MapTile tmp(GetTriangleIdx(tP), posOffset);
                sorted_textures[t].push_back(tmp);
                lastTerrain = t;
            }

            t = gwv.GetGameWorldViewer().GetNode(tP).t2;

            if(t == lastTerrain)
                ++sorted_textures[t].back().count;
            else
            {
                MapTile tmp(GetTriangleIdx(tP) + 1, posOffset);
                sorted_textures[t].push_back(tmp);
            }

            lastTerrain = t;

            const Borders& curBorders = borders[GetVertexIdx(tP)];
            boost::array<unsigned char, 6> tiles =
            {{
                curBorders.left_right[0],
                curBorders.left_right[1],
                curBorders.right_left[0],
                curBorders.right_left[1],
                curBorders.top_down[0],
                curBorders.top_down[1]
            }};

            // Offsets into gl_* arrays
            boost::array<unsigned, 6> offsets = 
            {{
                curBorders.left_right_offset[0],
                curBorders.left_right_offset[1],
                curBorders.right_left_offset[0],
                curBorders.right_left_offset[1],
                curBorders.top_down_offset[0],
                curBorders.top_down_offset[1]
            }};

            for(unsigned char i = 0; i < 6; ++i)
            {
                if(!tiles[i])
                    continue;
                if(tiles[i] == lastBorder)
                {
                    BorderTile& curTile = sorted_borders[lastBorder - 1].back();
                    // Check that we did not wrap around the map and the expected offset matches
                    if(curTile.tileOffset + curTile.count == offsets[i])
                    {
                        ++curTile.count;
                        continue;
                    }
                }
                lastBorder = tiles[i];
                BorderTile tmp(offsets[i], posOffset);
                sorted_borders[lastBorder - 1].push_back(tmp);
            }

            PrepareWaysPoint(sorted_roads, gwv, tP, posOffset);

            lastOffset = posOffset;
        }
    }

    if (water)
    {
        unsigned water_count = 0;

        for(unsigned char t = 0; t < TT_COUNT; ++t){
            if(!TerrainData::IsWater(TerrainType(t)))
                continue;
            for(std::vector<MapTile>::iterator it = sorted_textures[t].begin(); it != sorted_textures[t].end(); ++it)
            {
                water_count += it->count;
            }
        }

        PointI diff = gwv.GetLastPt() - gwv.GetFirstPt();
        if( diff.x && diff.y )
            *water = 50 * water_count / ( diff.x * diff.y );
        else
            *water = 0;
    }

    lastOffset = PointI(0, 0);

    if(vboBuffersUsed)
    {
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_vertices);
        glVertexPointer(2, GL_FLOAT, 0, NULL);

        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_texcoords);
        glTexCoordPointer(2, GL_FLOAT, 0, NULL);

        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors);
        glColorPointer(3, GL_FLOAT, 0, NULL);
    }
    else
    {
        glVertexPointer(2, GL_FLOAT, 0, &gl_vertices.front());
        glTexCoordPointer(2, GL_FLOAT, 0, &gl_texcoords.front());
        glColorPointer(3, GL_FLOAT, 0, &gl_colors.front());
    }

    // Arrays aktivieren
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    // Modulate2x
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
    glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f);

    // Verschieben gem#ß x und y offset
    glTranslatef( float(-gwv.GetXOffset()), float(-gwv.GetYOffset()), 0.0f);

    // Alphablending aus
    glDisable(GL_BLEND);

    for(unsigned char t = 0; t < TT_COUNT; ++t)
    {
        if(sorted_textures[t].empty())
            continue;
        unsigned animationFrame;
        TerrainType tt = TerrainType(t);
        if(TerrainData::IsLava(tt))
            animationFrame = GAMECLIENT.GetGlobalAnimation(TerrainData::GetFrameCount(tt), 5, 4, 0);
        else if(TerrainData::IsWater(tt))
            animationFrame = GAMECLIENT.GetGlobalAnimation(TerrainData::GetFrameCount(tt), 5, 2, 0);
        else
            animationFrame = 0;

        VIDEODRIVER.BindTexture(LOADER.GetTerrainTexture(tt, animationFrame).GetTexture());

        for(std::vector<MapTile>::iterator it = sorted_textures[t].begin(); it != sorted_textures[t].end(); ++it)
        {
            if(it->posOffset != lastOffset)
            {
                PointI trans = it->posOffset - lastOffset;
                glTranslatef( float(trans.x), float(trans.y), 0.0f);
                lastOffset = it->posOffset;
            }

            assert(it->tileOffset + it->count <= width * height * 2u);
            glDrawArrays(GL_TRIANGLES, it->tileOffset * 3, it->count * 3); // Arguments are in Elements. 1 triangle has 3 values
        }
    }

    glEnable(GL_BLEND);

    glLoadIdentity();
    glTranslatef( float(-gwv.GetXOffset()), float(-gwv.GetYOffset()), 0.0f);

    lastOffset = PointI(0, 0);
    for(unsigned short i = 0; i < 5; ++i)
    {
        if(sorted_borders[i].empty())
            continue;
        VIDEODRIVER.BindTexture(GetImage(borders, i)->GetTexture());

        for(std::vector<BorderTile>::iterator it = sorted_borders[i].begin(); it != sorted_borders[i].end(); ++it)
        {
            if(it->posOffset != lastOffset)
            {
                PointI trans = it->posOffset - lastOffset;
                glTranslatef( float(trans.x), float(trans.y), 0.0f);
                lastOffset = it->posOffset;
            }
            assert(it->tileOffset + it->count <= gl_vertices.size());
            glDrawArrays(GL_TRIANGLES, it->tileOffset * 3, it->count * 3); // Arguments are in Elements. 1 triangle has 3 values
        }
    }
    glLoadIdentity();

    DrawWays(sorted_roads);

    // Wieder zurück ins normale modulate
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
Beispiel #2
0
void noFigure::WalkToGoal()
{
    // Kein Ziel mehr --> Rumirren
    if(!goal)
    {
        StartWandering();
        Wander();
        return;
    }

    // Straße abgelaufen oder noch gar keine Straße vorhanden?
    if(((cur_rs) ? (rs_pos == cur_rs->GetLength()) : true))
    {
        // Ziel erreicht?
        // Bei dem Träger können das beide Flaggen sein!
        MapPoint goal1, goal2;
        if(GetGOT() == GOT_NOF_CARRIER && fs == FS_GOTOGOAL)
        {
            goal1 = static_cast<nofCarrier*>(this)->GetFirstFlag() ?
                static_cast<nofCarrier*>(this)->GetFirstFlag()->GetPos() : MapPoint(0xFFFF, 0xFFFF);
            goal2 = static_cast<nofCarrier*>(this)->GetSecondFlag() ?
                static_cast<nofCarrier*>(this)->GetSecondFlag()->GetPos() : MapPoint(0xFFFF, 0xFFFF);
        }
        else
        {
            goal1 = goal->GetPos();
            goal2 = MapPoint(0xFFFF, 0xFFFF);
        }

        if(goal1 == pos || goal2 == pos)
        {
            if(fs == FS_GOHOME)
            {
                // Mann im Lagerhaus angekommen
                gwg->RemoveFigure(this, pos);
                static_cast<nobBaseWarehouse*>(goal)->AddFigure(this);
            }
            else
            {
                // Zeug nullen
                cur_rs = NULL;
                rs_dir = 0;
                rs_pos = 0;
                goal = NULL;


                // abgeleiteter Klasse sagen, dass das Ziel erreicht wurde
                fs = FS_JOB;
                GoalReached();
            }

        }
        else
        {
            MapPoint next_harbor;
            // Neuen Weg berechnen
            unsigned char route = gwg->FindHumanPathOnRoads(gwg->GetSpecObj<noRoadNode>(pos), goal, NULL, &next_harbor);
            // Kein Weg zum Ziel... nächstes Lagerhaus suchen
            if(route == 0xFF)
            {
                // Arbeisplatz oder Laghaus Bescheid sagen
                Abrogate();
                // Wir gehen jetzt nach Hause
                GoHome();
                // Evtl wurde kein Lagerhaus gefunden und wir sollen rumirren, dann tun wir das gleich
                if(fs == FS_WANDER)
                {
                    Wander();
                    return;
                }

                // Nach Hause laufen...
                WalkToGoal();
                return;
            }
            // Oder müssen wir das Schiff nehmen?
            else if(route == SHIP_DIR)
            {
                // Uns in den Hafen einquartieren
                noBase* nob;
                if((nob = gwg->GetNO(pos))->GetGOT() != GOT_NOB_HARBORBUILDING)
                {
                    // Es gibt keinen Hafen mehr -> nach Hause gehen

                    // Arbeisplatz oder Laghaus Bescheid sagen
                    Abrogate();
                    // Wir gehen jetzt nach Hause
                    GoHome();
                    // Evtl wurde kein Lagerhaus gefunden und wir sollen rumirren, dann tun wir das gleich
                    if(fs == FS_WANDER)
                    {
                        Wander();
                        return;
                    }

                    // Nach Hause laufen...
                    WalkToGoal();
                    return;
                }

                // Uns in den Hafen einquartieren
                cur_rs = NULL; // wir laufen nicht mehr auf einer Straße
                gwg->RemoveFigure(this, pos);
                static_cast<nobHarborBuilding*>(nob)->AddFigureForShip(this, next_harbor);

                return;
            }


            // Nächste Straße wollen, auf der man geht
            cur_rs = gwg->GetSpecObj<noRoadNode>(pos)->routes[route];
            StartWalking(route);
            rs_pos = 0;
            rs_dir = (gwg->GetSpecObj<noRoadNode>(pos) == cur_rs->GetF1()) ? false : true;
        }

    }
    else
    {
        StartWalking(cur_rs->GetDir(rs_dir, rs_pos));
    }
}
Beispiel #3
0
void MapAnalysis::BeginTurn()
{
    MapPoint pos;
    Army army;
    Unit city;
    Unit unit;
    sint32 i;

    m_piracyIncomeMatrix.assign(m_piracyIncomeMatrix.size(), 0);

    m_cityOnContinent.Reset(FALSE);
    m_armyOnContinent.Reset(FALSE);

    m_worldPopulation = 0;

    ComputeHandicapRatios();

    size_t player;
    for (player = 0; player < m_threatGrid.size(); ++player)
    {
        m_threatGrid       [player].Clear();
        m_attackGrid       [player].Clear();
        m_defenseGrid      [player].Clear();
        m_rangedGrid       [player].Clear();
        m_bombardLandGrid  [player].Clear();
        m_bombardSeaGrid   [player].Clear();
        m_bombardAirGrid   [player].Clear();
        m_valueGrid        [player].Clear();
        m_tradeAtRiskGrid  [player].Clear();
        m_piracyLossGrid   [player].Clear();

        m_minCityThreat    [player] = std::numeric_limits<sint32>::max();
        m_maxCityThreat    [player] = std::numeric_limits<sint32>::min();

        m_movementTypeUnion[player] = 0x0;

        m_nuclearWeapons   [player] = 0;
        m_bioWeapons       [player] = 0;
        m_nanoWeapons      [player] = 0;
        m_specialAttackers [player] = 0;
        m_continentSize    [player] = 0;

        m_totalPopulation  [player] = 0;
        m_landArea         [player] = 0;
        m_totalTrade       [player] = 0;

        Player * player_ptr = g_player[player];
        if (player_ptr == NULL)
            continue;

        RecalcCityRanks(player);

        m_projectedScience[player] =
            player_ptr->m_advances->GetProjectedScience();

        m_totalPopulation[player] = static_cast<sint16>(player_ptr->GetTotalPopulation());
        m_landArea[player] = static_cast<sint16>(player_ptr->GetLandArea());
        m_worldPopulation += m_totalPopulation[player];

        sint32 num_units = player_ptr->m_all_units->Num();
        for (i = 0; i < num_units; i++)
        {
            unit = player_ptr->m_all_units->Access(i);
            Assert(unit.IsValid());

            if (    unit.IsValid()
                 && unit.GetDBRec()
                 && unit.GetDBRec()->GetNumSpecialAttacks() > 0
               )
            {
                m_specialAttackers[player]++;
            }
        }

        sint32 num_armies = player_ptr->m_all_armies->Num();
        for (i = 0; i < num_armies; i++)
        {
            army = player_ptr->m_all_armies->Access(i);
            Assert(army.IsValid());
            army->GetPos(pos);

            sint8 defense_count;
            sint8 ranged_count;
            float attack_strength;
            float defense_strength;
            float ranged_strength;
            float bombard_land_strength;
            float bombard_sea_strength;
            float bombard_air_strength;
            float total_value;
			army->ComputeStrength(attack_strength,
			                      defense_strength,
			                      ranged_strength,
			                      defense_count,
			                      ranged_count,
			                      bombard_land_strength,
			                      bombard_sea_strength,
			                      bombard_air_strength,
			                      total_value,
			                      false
			                     );

			Assert(total_value >= 0);

			m_nuclearWeapons[player] += army->CountNuclearUnits();
			m_bioWeapons[player]     += army->CountBioUnits();
			m_nanoWeapons[player]    += army->CountNanoUnits();


			if(m_empireCenter[player] == MapPoint())
			{
				CalcEmpireCenter(player);
			}

			if(!m_empireBoundingRect[player].IsValid())
			{
				UpdateBoundingRectangle(army);
			}

			m_threatGrid      [player].AddValue(pos, static_cast<sint32>(attack_strength + ranged_strength));
			m_attackGrid      [player].AddValue(pos, static_cast<sint32>(attack_strength));
			m_defenseGrid     [player].AddValue(pos, static_cast<sint32>(defense_strength));
			m_rangedGrid      [player].AddValue(pos, static_cast<sint32>(ranged_strength));
			m_bombardLandGrid [player].AddValue(pos, static_cast<sint32>(bombard_land_strength));
			m_bombardSeaGrid  [player].AddValue(pos, static_cast<sint32>(bombard_sea_strength));
			m_bombardAirGrid  [player].AddValue(pos, static_cast<sint32>(bombard_air_strength));
			m_valueGrid       [player].AddValue(pos, static_cast<sint32>(total_value));

			bool    is_land;
			sint16  cont;
			g_theWorld->GetContinent(pos, cont, is_land);

			if(is_land)
			{
				bool is_military = (attack_strength > 0 || ranged_strength > 0)
				                && !army->IsCivilian();
				if(is_military)
				{
					m_armyOnContinent.Set(player, cont, TRUE);
				}
			}


            m_movementTypeUnion[player] |= army.GetMovementType();

            Assert(m_threatGrid      [player].GetTotalValue()  >= 0);
            Assert(m_attackGrid      [player].GetTotalValue()  >= 0);
            Assert(m_defenseGrid     [player].GetTotalValue()  >= 0);
            Assert(m_rangedGrid      [player].GetTotalValue()  >= 0);
            Assert(m_bombardLandGrid [player].GetTotalValue()  >= 0);
            Assert(m_bombardSeaGrid  [player].GetTotalValue()  >= 0);
            Assert(m_bombardAirGrid  [player].GetTotalValue()  >= 0);
            Assert(m_valueGrid       [player].GetTotalValue()  >= 0);
            Assert(m_nuclearWeapons  [player]                  >= 0);
            Assert(m_bioWeapons      [player]                  >= 0);
            Assert(m_nanoWeapons     [player]                  >= 0);
            Assert(m_specialAttackers[player]                  >= 0);
            Assert(m_continentSize   [player]                  >= 0);
            Assert(m_totalPopulation [player]                  >= 0);
            Assert(m_landArea        [player]                  >= 0);
            Assert(m_totalTrade      [player]                  >= 0);
        }


        sint32 num_cities = player_ptr->m_all_cities->Num();
        for (i = 0; i < num_cities; i++)
        {
            city = player_ptr->m_all_cities->Access(i);
            Assert(city.IsValid() && city->GetCityData());
            city.GetPos(pos);
            sint32 total_value = city->GetCityData()->GetValue();


            m_totalTrade[player] += city->GetCityData()->GetGoldFromTradeRoutes();


            m_valueGrid[player].AddValue(pos, total_value);

            TradeDynamicArray * trade_routes = city.CD()->GetTradeSourceList();
            Assert(trade_routes != NULL);

            sint32 tradeRouteCount  = trade_routes ? trade_routes->Num() : 0;
            for (sint32 j = 0; j < tradeRouteCount; j++)
            {
                sint32 route_value = trade_routes->Get(j)->GetValue();
                Army pirate_army = trade_routes->Get(j)->GetPiratingArmy();
                if (pirate_army.IsValid())
                {
                    m_piracyLossGrid[player].
                    AddValue(pirate_army->RetPos(), route_value);

                    AddPiracyIncome(pirate_army.GetOwner(), player, static_cast<sint16>(route_value));

                    m_valueGrid[pirate_army.GetOwner()].
                    AddValue(pirate_army->RetPos(), route_value);
                }


                const DynamicArray < MapPoint > * path = trade_routes->Get(j)->GetPath();
                sint32 per_cell_value =
                            (sint32)(((double)route_value / path->Num()) * 1000.0);
                for (sint32 k = 0; k < path->Num(); k++)
                {
                    m_tradeAtRiskGrid[player].AddValue(path->Get(k),
                    per_cell_value);
                }
            }

            bool    is_land;
            sint16  cont;
            g_theWorld->GetContinent(pos, cont, is_land);
            if (is_land)
            {
                m_cityOnContinent.Set(player, cont, TRUE);


                m_continentSize[player] += g_theWorld->GetLandContinentSize(cont) / num_cities;
            }

        }
    }

    DPRINTF(k_DBG_MAPANALYSIS, ("BEFORE RELAX:\n"));
    DebugLog();
    DPRINTF(k_DBG_MAPANALYSIS, ("\n"));

    const sint8 cycles = 1;
    const float coef = 0.95f;
    for (player = 0; player < m_threatGrid.size(); player++)
    {
        m_threatGrid      [player].Relax(cycles, coef);
        m_attackGrid      [player].Relax(cycles, coef);
        m_defenseGrid     [player].Relax(cycles, coef);
        m_rangedGrid      [player].Relax(cycles, coef);
        m_bombardLandGrid [player].Relax(cycles, coef);
        m_bombardSeaGrid  [player].Relax(cycles, coef);
        m_bombardAirGrid  [player].Relax(cycles, coef);
        m_valueGrid       [player].Relax(cycles, coef);
    }

	for (player = 0; player < m_threatGrid.size(); player++)
	{
		if(Diplomat::HasDiplomat(player))
		{
			Diplomat::GetDiplomat(player).ComputeAllDesireWarWith();
			Diplomat::GetDiplomat(player).ComputeIncursionPermission();
		}
	}

    for (player = 0; player < m_threatGrid.size(); player++)
    {
        Player * player_ptr = g_player[player];
        if (player_ptr == NULL)
            continue;

        sint32 num_cities = player_ptr->m_all_cities->Num();
        for (i = 0; i < num_cities; i++)
        {
            city = player_ptr->m_all_cities->Access(i);
            // Threat has to be calculated after relax
            sint32 threat = GetThreat(player, city.RetPos());

            if (threat < m_minCityThreat[player])
                m_minCityThreat[player] = threat;

            if (threat > m_maxCityThreat[player])
                m_maxCityThreat[player] = threat;
        }
    }

    DPRINTF(k_DBG_MAPANALYSIS, ("RELAXED:\n"));
    DebugLog();
    DPRINTF(k_DBG_MAPANALYSIS, ("\n"));
}
void editMap (MapPoint point, int button)
{
    if( !getGameView()->inCity( point ) ){
        return;
    }
   
    int x = point.x;
    int y = point.y;
    int selected_module_group = get_group_of_type(selected_module_type);
    
    int size;
    //  int x, y; /* mappoint */
    int mod_x, mod_y; /* upper left coords of module clicked on */
    int mps_result;
    
    if (MP_TYPE(x,y) == CST_USED) {
        mod_x = MP_INFO(x,y).int_1;
        mod_y = MP_INFO(x,y).int_2;
    } else {
        mod_x = x;
        mod_y = y;
    }

    /* Bring up mappoint_stats for any right mouse click */
    if (button == SDL_BUTTON_RIGHT) {
        mps_set( x, y, MPS_ENV);
        return;
    }

    /* Handle bulldozing */
    if (selected_module_type == CST_GREEN && button != SDL_BUTTON_RIGHT) {
        check_bulldoze_area (x, y);
        mps_result = mps_set( mod_x, mod_y, MPS_MAP ); // Update mps on bulldoze
#ifdef DEBUG
        DBG_TileInfo(x, y);
#endif
        return;
    }

    /* Bring up mappoint_stats for certain left mouse clicks */
    /* Check market and port double-clicks here */
    /* Check rocket launches */
    if( !GROUP_IS_BARE(MP_GROUP( x,y )) ) {
        if(mapMPS)
            mapMPS->playBuildingSound( mod_x, mod_y );
        mps_result = mps_set( mod_x, mod_y, MPS_MAP ); //query Tool
#ifdef DEBUG
        DBG_TileInfo(x, y);
#endif
        if( mps_result >= 1 ){
            if( MP_GROUP( mod_x,mod_y ) == GROUP_MARKET ){
                clicked_market_cb (mod_x, mod_y);
                return;
            } else if (MP_GROUP(mod_x,mod_y) == GROUP_PORT) {
                clicked_port_cb (mod_x, mod_y);
                return;
            } else if (MP_TYPE(mod_x,mod_y) >= CST_ROCKET_5 &&
                         MP_TYPE(mod_x,mod_y) <= CST_ROCKET_7){
                //Dialogs delete themself
                new Dialog( ASK_LAUNCH_ROCKET, mod_x,mod_y );
                return;
            }
        }
        //to be here we are not in bulldoze-mode and the tile
        //under the cursor is not empty. 
        //to allow up/downgrading of Tracks,Roads,Rails and bridges we can't always return.
        if( ( selected_module_type != CST_TRACK_LR ) && 
            ( selected_module_type != CST_ROAD_LR ) && 
            ( selected_module_type != CST_RAIL_LR ) ) {
            return; //not building a transport
        }
        
        if( ( MP_GROUP(x,y) != GROUP_WATER ) && ( !( MP_INFO(x,y).flags & FLAG_IS_TRANSPORT ))){
            return; //target area is neither water not a transport
	}    

        if( selected_module_type == CST_TRACK_LR ) {
            if( MP_GROUP( x, y ) == GROUP_TRACK || MP_GROUP( x, y ) == GROUP_TRACK_BRIDGE ||
                    MP_GROUP( x, y ) == GROUP_ROAD || MP_GROUP( x, y ) == GROUP_ROAD_BRIDGE ||
                    MP_GROUP( x, y ) == GROUP_RAIL || MP_GROUP( x, y ) == GROUP_RAIL_BRIDGE )
           return;
        } else if( selected_module_type == CST_ROAD_LR ) {
            if ( MP_GROUP( x, y ) == GROUP_ROAD || MP_GROUP( x, y ) == GROUP_ROAD_BRIDGE ||
                    MP_GROUP( x, y ) == GROUP_RAIL || MP_GROUP( x, y ) == GROUP_RAIL_BRIDGE )
                return;
        } else if( selected_module_type == CST_RAIL_LR ) {
            if( MP_GROUP( x, y ) == GROUP_RAIL || MP_GROUP( x, y ) == GROUP_RAIL_BRIDGE )
                return;
        } 
    }

    //query Tool 
    if(selected_module_type==CST_NONE) {
        if (mapMPS) {
            mapMPS->playBuildingSound( mod_x, mod_y );
            mapMPS->setView(MapPoint( mod_x, mod_y ));
        }
        mps_result = mps_set( mod_x, mod_y, MPS_MAP ); //query Tool on CST_NONE
#ifdef DEBUG
        DBG_TileInfo(x, y);
#endif
        return;
    }

    /* OK, by now we are certain that the user wants to place the item.
       Set the origin based on the size of the selected_module_type, and 
       see if the selected item will fit. */
    size = main_groups[selected_module_group].size;
    /*  if (px > (mw->x + mw->w) - size*16)
        px = (mw->x + mw->w) - size*16;
        if (py > (mw->y + mw->h) - size*16)
        py = (mw->y + mw->h) - size*16;
        pixel_to_mappoint(px, py, &x, &y);
    */
    //Check if we are too close to the border
    if( x + size > WORLD_SIDE_LEN - 1 || y + size > WORLD_SIDE_LEN - 1 || x < 1 || y < 1 )
        return;
    
    if (size >= 2) {
        if (!GROUP_IS_BARE(MP_GROUP(x + 1,y))
            || !GROUP_IS_BARE(MP_GROUP(x,y + 1))
            || !GROUP_IS_BARE(MP_GROUP(x + 1,y + 1)))
            return;
    }
    if (size >= 3) {
        if (!GROUP_IS_BARE(MP_GROUP(x + 2,y))
            || !GROUP_IS_BARE(MP_GROUP(x + 2,y + 1))
            || !GROUP_IS_BARE(MP_GROUP(x + 2,y + 2))
            || !GROUP_IS_BARE(MP_GROUP(x + 1,y + 2))
            || !GROUP_IS_BARE(MP_GROUP(x,y + 2)))
            return;
    }
    if (size == 4) {
        if (!GROUP_IS_BARE(MP_GROUP(x + 3,y))
            || !GROUP_IS_BARE(MP_GROUP(x + 3,y + 1))
            || !GROUP_IS_BARE(MP_GROUP(x + 3,y + 2))
            || !GROUP_IS_BARE(MP_GROUP(x + 3,y + 3))
            || !GROUP_IS_BARE(MP_GROUP(x + 2,y + 3))
            || !GROUP_IS_BARE(MP_GROUP(x + 1,y + 3))
            || !GROUP_IS_BARE(MP_GROUP(x,y + 3)))
            return;
    }
    
    //how to build a lake in the park?
    //just hold 'W' key on build ;-)
    if( selected_module_group == GROUP_PARKLAND ){
        Uint8 *keystate = SDL_GetKeyState(NULL);
        if ( keystate[SDLK_w] )
            selected_module_type = CST_PARKLAND_LAKE;
        else
            selected_module_type = CST_PARKLAND_PLANE;
    }

    /* Place the selected item . Warning messages are managed by place_item(...) */
    last_message_group = place_item (x, y, selected_module_type);
    switch (last_message_group)
    {
        case 0:
            /* Success */
            getSound()->playSound( "Build" );
            mps_result = mps_set( mod_x, mod_y, MPS_MAP ); // Update mps on well-built
#ifdef DEBUG
            DBG_TileInfo(x, y);
#endif
            break;
        case -1000:
            /* ouch group does not exist */
        case -1:
            /* Not enough money */
        case -2:
            /* Improper port placement */
        case -3:
            /* too many windmills/substations */
        case -4:
            /* too many market */
        case -5:
            /* previous tip here, cannot build tip here */
        case -6:
            /* previous tip here, cannot build oremine */
        case -7:
            /* no ore reserve. cannot build oremine here */
        default:
            /* warning messages are managed by place item */
            last_message_group = 0;
    }
}
Beispiel #5
0
void GameWorld::Scan(glArchivItem_Map* map)
{
    width = map->getHeader().getWidth();
    height = map->getHeader().getHeight();
    lt = LandscapeType(map->getHeader().getGfxSet());

    Init();

    // Dummy-Hafenpos für Index 0 einfügen // ask Oliverr why!
    // -> I just did, the dummy is so that the harbor "0" might be used for ships with no particular destination
    // poc: if you ever remove this dummy go to GameWorldBase::CalcDistanceToNearestHarbor and fix the loop to include the first harbor again (think Ive seen other instances of dummyadjusted loops as well...)
    GameWorldBase::HarborPos dummy(MapPoint(0, 0));
    
    harbor_pos.push_back(dummy);

    // Andere Sachen setzen
	MapPoint pt(0, 0);
	
    for(pt.y = 0; pt.y < height; ++pt.y)
    {
        for(pt.x = 0; pt.x < width; ++pt.x)
        {
        	MapNode& node = GetNode(pt);

            node.roads[2] = node.roads[1] = node.roads[0] = 0;
            node.roads_real[2] = node.roads_real[1] = node.roads_real[0] = false;
            node.altitude = map->GetMapDataAt(MAP_ALTITUDE, pt.x, pt.y);
            // Aufpassen, dass die Terrainindizes im Rahmen liegen, ansonsten 0 nehmen, unbekanntes Terrain (Bsp.
            // Karte "Drachenebene")
            unsigned char t1 = map->GetMapDataAt(MAP_TERRAIN1, pt.x, pt.y), t2 = map->GetMapDataAt(MAP_TERRAIN2, pt.x, pt.y);

            // Hafenplatz?
            if(t1 >= 0x40 && t1 <= 0x54)
            {
                t1 -= 0x40;
				
				GameWorldBase::HarborPos p(pt);
                node.harbor_id = harbor_pos.size();
                harbor_pos.push_back(p);
            }
            else
                node.harbor_id = 0;



            node.t1 = (t1 < 20) ? TERRAIN_INDIZES[t1] : 0;
            node.t2 = (t2 < 20) ? TERRAIN_INDIZES[t2] : 0;

            node.resources = map->GetMapDataAt(MAP_RESOURCES, pt.x, pt.y);

            // Wasser?
            if(node.resources == 0x20 || node.resources == 0x21)
            {
                // TODO: Berge hatten komische Wasserbeeinflussung
                // ggf 0-4 Wasser setzen
                if( (node.t1 == TT_DESERT || node.t2 == TT_DESERT) ||
                        (node.t1 == TT_WATER || node.t2 == TT_WATER) )
                    node.resources = 0; // Kein Wasser, in der Wüste, da isses trocken!
                else if( (node.t1 == TT_STEPPE || node.t2 == TT_STEPPE) )
                    node.resources = 0x23; // 2 Wasser
                else if( (node.t1 == TT_SAVANNAH || node.t2 == TT_SAVANNAH) )
                    node.resources = 0x25; // 4 Wasser
                else
                    node.resources = 0x27; // 7 Wasser
            }

            node.reserved = false;
            node.owner = 0;
            for(unsigned i = 0; i < 4; ++i)
                node.boundary_stones[i] = 0;
            node.sea_id = 0;

            // FOW-Zeug initialisieren
            for(unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i)
            {
                switch(GAMECLIENT.GetGGS().exploration)
                {
                    case GlobalGameSettings::EXP_DISABLED:
                    {
                        node.fow[i].visibility = VIS_VISIBLE;
                    } break;
                    case GlobalGameSettings::EXP_CLASSIC:
                    {
                        node.fow[i].visibility = VIS_INVISIBLE;
                    } break;
                    case GlobalGameSettings::EXP_FOGOFWAR:
                    {
                        node.fow[i].visibility = VIS_INVISIBLE;
                    } break;
                    case GlobalGameSettings::EXP_FOGOFWARE_EXPLORED:
                    {
                        node.fow[i].visibility = VIS_FOW;
                    } break;
                }

                node.fow[i].last_update_time = 0;
                node.fow[i].object = NULL;
                node.fow[i].roads[0] = node.fow[i].roads[1] =
                                           node.fow[i].roads[2] = 0;
                node.fow[i].owner = 0;
                for(unsigned z = 0; z < 4; ++z)
                    node.fow[i].boundary_stones[z] = 0;
            }
        }
    }

    std::vector< MapPoint > headquarter_positions;

    // Objekte auslesen
    for(pt.y = 0; pt.y < height; ++pt.y)
    {
        for(pt.x = 0; pt.x < width; ++pt.x)
        {
            unsigned int pos = GetIdx(pt);
            unsigned char lc = map->GetMapDataAt(MAP_LANDSCAPE, pt.x, pt.y);

            switch(map->GetMapDataAt(MAP_TYPE, pt.x, pt.y))
            {
                    // Player Startpos (provisorisch)
                case 0x80:
                {
                    headquarter_positions.push_back(pt);

                    if(lc < GAMECLIENT.GetPlayerCount())
                    {
                        GetPlayer(lc)->hqPos = pt;
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Baum 1-4
                case 0xC4:
                {
                    if(lc >= 0x30 && lc <= 0x3D)
                        nodes[pos].obj = new noTree(pt, 0, 3);
                    else if(lc >= 0x70 && lc <= 0x7D)
                        nodes[pos].obj = new noTree(pt, 1, 3);
                    else if(lc >= 0xB0 && lc <= 0xBD)
                        nodes[pos].obj = new noTree(pt, 2, 3);
                    else if(lc >= 0xF0 && lc <= 0xFD)
                        nodes[pos].obj = new noTree(pt, 3, 3);
                    else
                    {
                        LOG.lprintf("Unbekannter Baum1-4 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Baum 5-8
                case 0xC5:
                {
                    if(lc >= 0x30 && lc <= 0x3D)
                        nodes[pos].obj = new noTree(pt, 4, 3);
                    else if(lc >= 0x70 && lc <= 0x7D)
                        nodes[pos].obj = new noTree(pt, 5, 3);
                    else if(lc >= 0xB0 && lc <= 0xBD)
                        nodes[pos].obj = new noTree(pt, 6, 3);
                    else if(lc >= 0xF0 && lc <= 0xFD)
                        nodes[pos].obj = new noTree(pt, 7, 3);
                    else
                    {
                        LOG.lprintf("Unbekannter Baum5-8 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Baum 9
                case 0xC6:
                {
                    if(lc >= 0x30 && lc <= 0x3D)
                        nodes[pos].obj = new noTree(pt, 8, 3);
                    else
                    {
                        LOG.lprintf("Unbekannter Baum9 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Sonstiges Naturzeug ohne Funktion, nur zur Dekoration
                case 0xC8:
                {
                    /// @todo mis0bobs unvollständig (dieses lagerzelt), 4 und 5 überhaupt nicht erwähnt
                    // mis1bobs, 2 und 3 sind vollständig eingebaut

                    // Objekte aus der map_?_z.lst
                    if(lc <= 0x0A)
                        nodes[pos].obj = new noEnvObject(pt, 500 + lc);

                    // "wasserstein" aus der map_?_z.lst
                    else if(lc == 0x0B)
                        nodes[pos].obj = new noStaticObject(pt, 500 + lc);

                    // Objekte aus der map_?_z.lst
                    else if(lc >= 0x0C && lc <= 0x0F)
                        nodes[pos].obj = new noEnvObject(pt, 500 + lc);

                    // Objekte aus der map.lst
                    else if(lc >= 0x10 && lc <= 0x14)
                        nodes[pos].obj = new noEnvObject(pt, 542 + lc - 0x10);

                    // gestrandetes Schiff (mis0bobs, unvollständig)
                    else if(lc == 0x15)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x15) * 2, 0, 1);

                    // das Tor aus der map_?_z.lst
                    else if(lc == 0x16)
                        nodes[pos].obj = new noStaticObject(pt, 560, 0xFFFF, 2);

                    // das geöffnete Tor aus map_?_z.lst
                    else if(lc == 0x17)
                        nodes[pos].obj = new noStaticObject(pt, 561, 0xFFFF, 2);

                    // Stalagmiten (mis1bobs)
                    else if(lc >= 0x18 && lc <= 0x1E)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x18) * 2, 1);

                    // toter Baum (mis1bobs)
                    else if(lc >= 0x1F && lc <= 0x20)
                        nodes[pos].obj = new noStaticObject(pt, 20 + (lc - 0x1F) * 2, 1);

                    // Gerippe (mis1bobs)
                    else if(lc == 0x21)
                        nodes[pos].obj = new noEnvObject(pt, 30, 1);

                    // Objekte aus der map.lst
                    else if(lc >= 0x22 && lc <= 0x27)
                        nodes[pos].obj = new noEnvObject(pt, 550 + lc - 0x22);

                    // Objekte aus der map.lst
                    else if(lc >= 0x28 && lc <= 0x2B)
                        nodes[pos].obj = new noEnvObject(pt, 556 + lc - 0x28);

                    // die "kaputten" Gebäuderuinen usw (mis2bobs)
                    else if(lc >= 0x2C && lc <= 0x2D)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x2C) * 2, 2);
                    else if(lc == 0x2E)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x2C) * 2, 2, 1);
                    else if(lc == 0x2F)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x2C) * 2, 2, 2);
                    else if(lc == 0x30)
                        nodes[pos].obj = new noEnvObject(pt, (lc - 0x2C) * 2, 2);

                    // der Wikinger (mis3bobs)
                    else if(lc == 0x31)
                        nodes[pos].obj = new noStaticObject(pt, 0, 2);

                    else
                    {
                        LOG.lprintf("Unbekanntes Naturzeug auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }

                } break;

                // Granit Typ 1
                case 0xCC:
                {
                    if(lc >= 0x01 && lc <= 0x06)
                        nodes[pos].obj = new noGranite(GT_1, lc - 1);
                    else
                    {
                        LOG.lprintf("Unbekannter Granit1 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Granit Typ 2
                case 0xCD:
                {
                    if(lc >= 0x01 && lc <= 0x06)
                        nodes[pos].obj = new noGranite(GT_2, lc - 1);
                    else
                    {
                        LOG.lprintf("Unbekannter Granit2 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Nichts
                case 0:
                {
                    nodes[pos].obj = NULL;
                } break;

                default:
                {
                    /*LOG.lprintf("Unbekanntes Objekt %d (0x%0X) auf x=%d, y=%d: id=%d (0x%0X)\n", map->map_type[y*width+x], map->map_type[y*width+x], x, y, lc, lc);
                    */         nodes[pos].obj = NULL;
                } break;
            }
        }
    }

    // BQ mit nichts erstmal inititalisieren (HQ-Setzen berechnet diese neu und braucht sie)
    for(pt.y = 0; pt.y < height; ++pt.y)
    {
        for(pt.x = 0; pt.x < width; ++pt.x)
        {
            SetBQ(pt, BQ_NOTHING);
        }
    }

    //random locations? -> randomize them :)
    if (GAMECLIENT.GetGGS().random_location)
    {
        ptrdiff_t (*p_myrandom)(ptrdiff_t) = myRandom;
        std::random_shuffle(headquarter_positions.begin(), headquarter_positions.end(), p_myrandom);

        for (unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i)
        {
            GetPlayer(i)->hqPos = headquarter_positions.at(i);
        }
    }

    // HQ setzen
    for(unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i)
    {
        // Existiert überhaupt ein HQ?
        if(GetPlayer(i)->hqPos.x != 0xFFFF)
        {
            if(GetPlayer(i)->ps == PS_OCCUPIED || GetPlayer(i)->ps == PS_KI)
            {
                nobHQ* hq = new nobHQ(GetPlayer(i)->hqPos, i, GetPlayer(i)->nation);
                SetNO(hq, GetPlayer(i)->hqPos);
                GetPlayer(i)->AddWarehouse(reinterpret_cast<nobBaseWarehouse*>(hq));
            }
            /*else
                GetNode(GetPlayer(i)->hqx,GetPlayer(i)->hqy).obj = 0;*/
        }
    }

    // Tiere auslesen
    for(pt.y = 0; pt.y < height; ++pt.y)
    {
        for(pt.x = 0; pt.x < width; ++pt.x)
        {
            unsigned pos = GetIdx(pt);
            // Tiere setzen
            Species species;
            switch(map->GetMapDataAt(MAP_ANIMALS, pt.x, pt.y))
            {
                    // TODO: Welche ID ist Polarbär?
                case 1: species = Species(SPEC_RABBITWHITE+RANDOM.Rand(__FILE__, __LINE__, 0, 2)); break; // zufällige Hasenart nehmen
                case 2: species = SPEC_FOX; break;
                case 3: species = SPEC_STAG; break;
                case 4: species = SPEC_DEER; break;
                case 5: species = SPEC_DUCK; break;
                case 6: species = SPEC_SHEEP; break;
                default: species = SPEC_NOTHING; break;
            }

            if(species != SPEC_NOTHING)
            {
                noAnimal* animal = new noAnimal(species, pt);
                AddFigure(animal, pt);
                // Loslaufen
                animal->StartLiving();
            }

            /// 4 Fische setzen
            if(map->GetMapDataAt(MAP_RESOURCES, pos) > 0x80 && map->GetMapDataAt(MAP_RESOURCES, pos)  < 0x90)
                GetNode(pt).resources = 0x84;
        }
    }

    /// Weltmeere vermessen
    for(pt.y = 0; pt.y < height; ++pt.y)
    {
        for(pt.x = 0; pt.x < width; ++pt.x)
        {
            // Noch kein Meer an diesem Punkt?
            if(!GetNode(pt).sea_id)
            {
                // Aber trotzdem Teil eines noch nicht vermessenen Meeres?
                if(IsSeaPoint(pt))
                {
                    unsigned sea_size = MeasureSea(pt, seas.size());
                    seas.push_back(Sea(sea_size));
                }
            }
        }
    }

    /// Die Meere herausfinden, an die die Hafenpunkte grenzen
    for(unsigned i = 0; i < harbor_pos.size(); ++i)
    {
        for(unsigned z = 0; z < 6; ++z)
            harbor_pos[i].cps[z].sea_id = IsCoastalPoint(GetNeighbour(harbor_pos[i].pos, z));
    }

    // Nachbarn der einzelnen Hafenplätze ermitteln
    CalcHarborPosNeighbors();

    /// Schatten und BQ berechnen
    for(pt.y = 0; pt.y < height; ++pt.y)
    {
        for(pt.x = 0; pt.x < width; ++pt.x)
        {
            RecalcShadow(pt);
            SetBQ(pt, GAMECLIENT.GetPlayerID());
        }
    }

    /// Bei FoW und aufgedeckt müssen auch die ersten FoW-Objekte erstellt werden
    if(GAMECLIENT.GetGGS().exploration == GlobalGameSettings::EXP_FOGOFWARE_EXPLORED)
    {
        for(pt.y = 0; pt.y < height; ++pt.y)
        {
            for(pt.x = 0; pt.x < width; ++pt.x)
            {
                // Alle Spieler durchgehen
                for(unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i)
                {
                    // An der Stelle FOW für diesen Spieler?
                    if(GetNode(pt).fow[i].visibility == VIS_FOW)
                        SaveFOWNode(pt, i);
                }
            }
        }
    }

}
Beispiel #6
0
void TerrainRenderer::UpdateBorderTriangleColor(const MapPoint pt, const GameWorldViewer* gwv, const bool update)
{
    unsigned int pos = GetTRIdx(pt);

    // Für VBO-Aktualisierung:
    // Erzeugte Ränder zählen
    unsigned count_borders = 0;
    // Erstes Offset merken
    unsigned first_offset = 0;


    // Rand links - rechts
    for(unsigned char i = 0; i < 2; ++i)
    {
        if(borders[pos].left_right[i])
        {
            unsigned int offset = borders[pos].left_right_offset[i];

            if(!first_offset)
                first_offset = offset;

            gl_colors[offset].colors[i ? 0 : 2].r = gl_colors[offset].colors[i ? 0 : 2].g = gl_colors[offset].colors[i ? 0 : 2].b = GetColor(pt);
            gl_colors[offset].colors[1        ].r = gl_colors[offset].colors[1        ].g = gl_colors[offset].colors[1        ].b = GetColor(gwv->GetNeighbour(pt, 4));
            gl_colors[offset].colors[i ? 2 : 0].r = gl_colors[offset].colors[i ? 2 : 0].g = gl_colors[offset].colors[i ? 2 : 0].b = GetBColor(pt, i);

            ++count_borders;
        }
    }

    // Rand rechts - links
    for(unsigned char i = 0; i < 2; ++i)
    {
        if(borders[pos].right_left[i])
        {
            unsigned int offset = borders[pos].right_left_offset[i];

            if(!first_offset)
                first_offset = offset;

            gl_colors[offset].colors[i ? 2 : 0].r = gl_colors[offset].colors[i ? 2 : 0].g = gl_colors[offset].colors[i ? 2 : 0].b = GetColor(gwv->GetNeighbour(pt, 4));
            gl_colors[offset].colors[1        ].r = gl_colors[offset].colors[1        ].g = gl_colors[offset].colors[1        ].b = GetColor(gwv->GetNeighbour(pt, 3));
            gl_colors[offset].colors[i ? 0 : 2].r = gl_colors[offset].colors[i ? 0 : 2].g = gl_colors[offset].colors[i ? 0 : 2].b = GetBColor(MapPoint(pt.x + i, pt.y), i ? 0 : 1);

            ++count_borders;
        }
    }

    // Rand oben - unten
    for(unsigned char i = 0; i < 2; ++i)
    {
        if(borders[pos].top_down[i])
        {
            unsigned int offset = borders[pos].top_down_offset[i];

            if(!first_offset)
                first_offset = offset;

            gl_colors[offset].colors[i ? 2 : 0].r = gl_colors[offset].colors[i ? 2 : 0].g = gl_colors[offset].colors[i ? 2 : 0].b = GetColor(gwv->GetNeighbour(pt, 5));
            gl_colors[offset].colors[1        ].r = gl_colors[offset].colors[1        ].g = gl_colors[offset].colors[1        ].b = GetColor(gwv->GetNeighbour(pt, 4));

            if(i == 0)
                gl_colors[offset].colors[2].r = gl_colors[offset].colors[2].g = gl_colors[offset].colors[2].b = GetBColor(pt, i);
            else
                gl_colors[offset].colors[0].r = gl_colors[offset].colors[0].g = gl_colors[offset].colors[0].b = GetBColor(gwv->GetNeighbour(pt, 5), i);

            ++count_borders;
        }
    }

    /// Bei Vertexbuffern das die Daten aktualisieren
    if(update && SETTINGS.video.vbo)
    {
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors);
        glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, first_offset * 3 * 3 * sizeof(float),
                           count_borders * 3 * 3 * sizeof(float), &gl_colors[first_offset]);
    }
}
Beispiel #7
0
void GameWorld::Deserialize(SerializedGameData* sgd)
{
    // Headinformationen
    width = sgd->PopUnsignedShort();
    height = sgd->PopUnsignedShort();
    lt = LandscapeType(sgd->PopUnsignedChar());

    // Initialisierungen
    Init();

    // Obj-ID-Counter setzen
    GameObject::SetObjIDCounter(sgd->PopUnsignedInt());

    // Trade graphs
    // Only if trade is enabled
    if(GAMECLIENT.GetGGS().isEnabled(ADDON_TRADE))
    {
        tgs.resize(sgd->PopUnsignedChar());
        for(unsigned i = 0; i < tgs.size(); ++i)
            tgs[i] = new TradeGraph(sgd, this);
    }

    // Alle Weltpunkte serialisieren
    for(unsigned i = 0; i < map_size; ++i)
    {
        for(unsigned z = 0; z < 3; ++z)
        {
            nodes[i].roads[z] = sgd->PopUnsignedChar();
            nodes[i].roads_real[z] = nodes[i].roads[z] ? true : false;
        }


        nodes[i].altitude = sgd->PopUnsignedChar();
        nodes[i].shadow = sgd->PopUnsignedChar();
        nodes[i].t1 = sgd->PopUnsignedChar();
        nodes[i].t2 = sgd->PopUnsignedChar();
        nodes[i].resources = sgd->PopUnsignedChar();
        nodes[i].reserved = sgd->PopBool();
        nodes[i].owner = sgd->PopUnsignedChar();
        for(unsigned b = 0; b < 4; ++b)
            nodes[i].boundary_stones[b] = sgd->PopUnsignedChar();
        nodes[i].bq = BuildingQuality(sgd->PopUnsignedChar());
        for(unsigned z = 0; z < GAMECLIENT.GetPlayerCount(); ++z)
        {
            nodes[i].fow[z].visibility = Visibility(sgd->PopUnsignedChar());
            // Nur im FoW können FOW-Objekte stehen
            if(nodes[i].fow[z].visibility == VIS_FOW)
            {
                nodes[i].fow[z].last_update_time = sgd->PopUnsignedInt();
                nodes[i].fow[z].object = sgd->PopFOWObject();
                for(unsigned r = 0; r < 3; ++r)
                    nodes[i].fow[z].roads[r] = sgd->PopUnsignedChar();
                nodes[i].fow[z].owner = sgd->PopUnsignedChar();
                for(unsigned b = 0; b < 4; ++b)
                    nodes[i].fow[z].boundary_stones[b] = sgd->PopUnsignedChar();
            }
            else
            {
                nodes[i].fow[z].last_update_time = 0;
                nodes[i].fow[z].object = NULL;
                for(unsigned r = 0; r < 3; ++r)
                    nodes[i].fow[z].roads[r] = 0;
                nodes[i].fow[z].owner = 0;
                for(unsigned b = 0; b < 4; ++b)
                    nodes[i].fow[z].boundary_stones[b] = 0;
            }
        }
        nodes[i].obj = sgd->PopObject<noBase>(GOT_UNKNOWN);
        sgd->PopObjectList<noBase>(nodes[i].figures, GOT_UNKNOWN);
        nodes[i].sea_id = sgd->PopUnsignedShort();
        nodes[i].harbor_id = sgd->PopUnsignedInt();

        if (nodes[i].harbor_id)
        {
            GameWorldBase::HarborPos p(MapPoint((MapCoord) (i % width), (MapCoord) (i / width)));
            harbor_pos.push_back(p);
        }
    }

    // Katapultsteine deserialisieren
    sgd->PopObjectList(catapult_stones, GOT_CATAPULTSTONE);

    // Meeresinformationen deserialisieren
    seas.resize(sgd->PopUnsignedInt());
    for(unsigned i = 0; i < seas.size(); ++i)
    {
        seas[i].nodes_count = sgd->PopUnsignedInt();
    }

    // Hafenpositionen serialisieren
    harbor_pos.resize(sgd->PopUnsignedInt());
    for(unsigned i = 0; i < harbor_pos.size(); ++i)
    {
        harbor_pos[i].pos = sgd->PopMapPoint();
        for(unsigned z = 0; z < 6; ++z)
            harbor_pos[i].cps[z].sea_id = sgd->PopUnsignedShort();
        for(unsigned z = 0; z < 6; ++z)
        {
            harbor_pos[i].neighbors[z].resize(sgd->PopUnsignedInt());
            for(unsigned c = 0; c < harbor_pos[i].neighbors[z].size(); ++c)
            {
                harbor_pos[i].neighbors[z][c].id = sgd->PopUnsignedInt();
                harbor_pos[i].neighbors[z][c].distance = sgd->PopUnsignedInt();
            }
        }
    }

    sgd->PopObjectList<noBuildingSite>(harbor_building_sites_from_sea, GOT_BUILDINGSITE);

    // BQ neu berechnen
    for(unsigned y = 0; y < height; ++y)
    {
        for(unsigned x = 0; x < width; ++x)
        {
            SetBQ(MapPoint(x, y), GAMECLIENT.GetPlayerID());
        }
    }

    tr.GenerateOpenGL(this);

    // Zum HQ am Anfang springen, falls dieses existiert
    if(GetPlayer(GAMECLIENT.GetPlayerID())->hqPos.x != 0xFFFF)
        this->MoveToMapObject(GetPlayer(GAMECLIENT.GetPlayerID())->hqPos);
}
Beispiel #8
0
void nobMilitary::Capture(const unsigned char new_owner)
{
    RTTR_Assert(IsCaptured());

    captured_not_built = true;
    mAutoTrain = false;
    mAutoTrainVirtual = false;

    // Goldmünzen in der Inventur vom alten Spieler abziehen und dem neuen hinzufügen
    gwg->GetPlayer(player).DecreaseInventoryWare(GD_COINS, coins);
    gwg->GetPlayer(new_owner).IncreaseInventoryWare(GD_COINS, coins);

    // Soldaten, die auf Mission sind, Bescheid sagen
    for(std::list<nofActiveSoldier*>::iterator it = troops_on_mission.begin(); it != troops_on_mission.end(); ++it)
        (*it)->HomeDestroyed();

    // Bestellungen die hierher unterwegs sind canceln
    CancelOrders();

    // Aggressiv-Verteidigenden Soldaten Bescheid sagen, dass sie nach Hause gehen können
    for(std::list<nofAggressiveDefender*>::iterator it = aggressive_defenders.begin(); it != aggressive_defenders.end(); ++it)
        (*it)->AttackedGoalDestroyed();

    troops_on_mission.clear();
    aggressive_defenders.clear();

    // In der Wirtschaftsverwaltung dieses Gebäude jetzt zum neuen Spieler zählen und beim alten raushauen
    gwg->GetPlayer(player).RemoveMilitaryBuilding(this);
    gwg->GetPlayer(new_owner).AddMilitaryBuilding(this);

    // Alten Besitzer merken
    unsigned char old_player = player;

    // neuer Spieler
    player = new_owner;

    // Flagge davor auch übernehmen
    GetFlag()->Capture(new_owner);

    // Territorium neu berechnen
    gwg->RecalcTerritory(*this, false, false);

    // Sichtbarkeiten berechnen für alten Spieler
    gwg->RecalcVisibilitiesAroundPoint(pos, GetMilitaryRadius() + VISUALRANGE_MILITARY + 1, old_player, NULL);

    // Grenzflagge entsprechend neu setzen von den Feinden
    LookForEnemyBuildings();
    // und von den Verbündeten (da ja ein Feindgebäude weg ist)!
    sortedMilitaryBlds buildings = gwg->LookForMilitaryBuildings(pos, 4);
    for(sortedMilitaryBlds::iterator it = buildings.begin(); it != buildings.end(); ++it)
    {
        // verbündetes Gebäude?
        if(gwg->GetPlayer((*it)->GetPlayer()).IsPlayerAttackable(old_player)
                && (*it)->GetBuildingType() >= BLD_BARRACKS && (*it)->GetBuildingType() <= BLD_FORTRESS)
            // Grenzflaggen von dem neu berechnen
            static_cast<nobMilitary*>(*it)->LookForEnemyBuildings();
    }

    // ehemalige Leute dieses Gebäudes nach Hause schicken, die ggf. grad auf dem Weg rein/raus waren
    MapPoint coords[2] = {pos, MapPoint(gwg->GetNeighbour(pos, 4))};
    for(unsigned short i = 0; i < 2; ++i)
    {
        const std::list<noBase*>& figures = gwg->GetFigures(coords[i]);
        for(std::list<noBase*>::const_iterator it = figures.begin(); it != figures.end(); ++it)
        {
            if((*it)->GetType() == NOP_FIGURE)
            {
                if(static_cast<noFigure*>(*it)->GetCurrentRoad() == routes[4] && static_cast<noFigure*>(*it)->GetPlayer() != new_owner)
                {
                    static_cast<noFigure*>(*it)->Abrogate();
                    static_cast<noFigure*>(*it)->StartWandering();
                }
            }
        }
    }

    // Send all allied aggressors home (we own the building now!)
    for(std::list<nofAttacker*>::iterator it = aggressors.begin(); it != aggressors.end();)
    {
        nofAttacker* attacker = *it;
        // dont remove attackers owned by players not allied with the new owner!
        unsigned char attPlayer = attacker->GetPlayer();
        if(attPlayer != player && !gwg->GetPlayer(attPlayer).IsPlayerAttackable(player))
        {
            it = aggressors.erase(it);
            attacker->CapturedBuildingFull();
        }else
            ++it;
    }

    // Fanfarensound abspieln, falls das Militärgebäude im Sichtbereich ist und unseres ist
    gwg->MilitaryBuildingCaptured(pos, player);

    // Post verschicken, an den alten Besitzer und an den neuen Besitzer
    SendPostMessage(old_player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), _("Military building lost"), PMC_MILITARY, *this));
    SendPostMessage(player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), _("Military building captured"), PMC_MILITARY, *this));

    // ggf. Fenster schließen vom alten Spieler
    gwg->ImportantObjectDestroyed(pos);
    gwg->GetNotifications().publish(BuildingNote(BuildingNote::Captured, player, pos, type_));
    gwg->GetNotifications().publish(BuildingNote(BuildingNote::Lost, old_player, pos, type_));
}
Beispiel #9
0
void GameWorldView::Draw(const RoadBuildState& rb, const bool draw_selected, const MapPoint selected, unsigned* water)
{
    SetNextZoomFactor();

    int shortestDistToMouse = 100000;
    Point<int> mousePos(VIDEODRIVER.GetMouseX(), VIDEODRIVER.GetMouseY());
    mousePos -= Point<int>(pos);

    glScissor(pos.x, VIDEODRIVER.GetScreenHeight() - pos.y - height, width, height);
    if(zoomFactor_ != 1.f)
    {
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glScalef(zoomFactor_, zoomFactor_, 1);
        // Offset to center view
        Point<float> diff(width - width / zoomFactor_, height - height / zoomFactor_);
        diff = diff / 2.f;
        glTranslatef(-diff.x, -diff.y, 0.f);
        // Also adjust mouse
        mousePos = Point<int>(Point<float>(mousePos) / zoomFactor_ + diff);
        glMatrixMode(GL_MODELVIEW);
    }

    glTranslatef(static_cast<GLfloat>(pos.x) / zoomFactor_, static_cast<GLfloat>(pos.y) / zoomFactor_, 0.0f);

    glTranslatef(static_cast<GLfloat>(-offset.x), static_cast<GLfloat>(-offset.y), 0.0f);
    const TerrainRenderer& terrainRenderer = gwv.GetTerrainRenderer();
    terrainRenderer.Draw(GetFirstPt(), GetLastPt(), gwv, water);
    glTranslatef(static_cast<GLfloat>(offset.x), static_cast<GLfloat>(offset.y), 0.0f);

    for(int y = firstPt.y; y <= lastPt.y; ++y)
    {
        // Figuren speichern, die in dieser Zeile gemalt werden müssen
        // und sich zwischen zwei Zeilen befinden, da sie dazwischen laufen
        std::vector<ObjectBetweenLines> between_lines;

        for(int x = firstPt.x; x <= lastPt.x; ++x)
        {
            Point<int> curOffset;
            const MapPoint curPt = terrainRenderer.ConvertCoords(Point<int>(x, y), &curOffset);
            DrawPoint curPos = GetWorld().GetNodePos(curPt) - offset + curOffset;

            const Point<int> mouseDist = mousePos - curPos;
            if(std::abs(mouseDist.x) + std::abs(mouseDist.y) < shortestDistToMouse)
            {
                selPt = curPt;
                selPtOffset = curOffset;
                shortestDistToMouse = std::abs(mouseDist.x) + std::abs(mouseDist.y);
            }

            Visibility visibility = gwv.GetVisibility(curPt);

            DrawBoundaryStone(curPt, curPos, visibility);

            if(visibility == VIS_VISIBLE)
            {
                DrawObject(curPt, curPos);

                DrawFigures(curPt, curPos, between_lines);

                //Construction aid mode
                if(show_bq)
                    DrawConstructionAid(curPt, curPos);
            } else if(visibility == VIS_FOW)
            {
                const FOWObject* fowobj = gwv.GetYoungestFOWObject(MapPoint(curPt));
                if(fowobj)
                    fowobj->Draw(curPos);
            }

            if(debugNodePrinter)
                debugNodePrinter->print(curPt, curPos);

            if (d_active)
                DrawAIDebug(curPt, curPos);
        }

        // Figuren zwischen den Zeilen zeichnen
        for(unsigned i = 0; i < between_lines.size(); ++i)
            between_lines[i].obj->Draw(between_lines[i].pos);
    }

    if(show_names || show_productivity)
        DrawNameProductivityOverlay(terrainRenderer);

    DrawGUI(rb, terrainRenderer, draw_selected, selected);

    // Umherfliegende Katapultsteine zeichnen
    for(std::list<CatapultStone*>::const_iterator it = GetWorld().catapult_stones.begin(); it != GetWorld().catapult_stones.end(); ++it)
    {
        if(gwv.GetVisibility((*it)->dest_building) == VIS_VISIBLE || gwv.GetVisibility((*it)->dest_map) == VIS_VISIBLE)
            (*it)->Draw(offset);
    }

    if(zoomFactor_ != 1.f)
    {
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
    }
    glTranslatef(-static_cast<GLfloat>(pos.x) / zoomFactor_, -static_cast<GLfloat>(pos.y) / zoomFactor_, 0.0f);

    glScissor(0, 0, VIDEODRIVER.GetScreenWidth(), VIDEODRIVER.GetScreenWidth());
}
Beispiel #10
0
    // Weglängen schätzen für beide Punkte,  indem man den bisherigen Weg mit der Luftlinie vom aktullen
    // Punkt zum Ziel addiert und auf diese Weise den kleinsten Weg auswählt
    unsigned way1 = pf_nodes[id].way + distance;
    unsigned way2 = pf_nodes[two.id].way + two.distance;

    // Wenn die Wegkosten gleich sind,  vergleichen wir die Koordinaten,  da wir für std::set eine streng
    // monoton steigende Folge brauchen
    if(way1 == way2)
        return (id < two.id);
    else
        return (way1 < way2);
}


/// Definitionen siehe oben
MapPoint PathfindingPoint::dst = MapPoint();
const GameWorldBase* PathfindingPoint::gwb = NULL;

/// Wegfinden ( A* ),  O(v lg v) --> Wegfindung auf allgemeinen Terrain (ohne Straßen),  für Wegbau und frei herumlaufende Berufe
bool GameWorldBase::FindFreePath(const MapPoint start, 
                                 const MapPoint dest,  const bool random_route, 
                                 const unsigned max_route,  std::vector<unsigned char>* route,  unsigned* length, 
                                 unsigned char* first_dir,   FP_Node_OK_Callback IsNodeOK,  FP_Node_OK_Callback IsNodeToDestOk,  const void* param,  const bool record) const
{
    // increase currentVisit,  so we don't have to clear the visited-states at every run
    currentVisit++;

    // if the counter reaches its maxium,  tidy up
    if (currentVisit == std::numeric_limits<unsigned>::max() - 1)
    {
        for (unsigned i = 0; i < (maxMapSize * maxMapSize); ++i)
Beispiel #11
0
void PropColumnMenu::onTouchEnded(Touch *pTouch, Event *pEvent)
{
    Point point = pTouch->getLocation();
    
    Rect rect = Rect::ZERO;
    rect.origin = m_propColumn->convertToWorldSpace(Point::ZERO);
    rect.size = m_propColumn->getContentSize();
    
    if (rect.containsPoint(point))
    {
        point = m_propColumn->convertToNodeSpace(point);
        int x = (int)point.x / GRID_WIDTH;
        int y = (int)point.y / GRID_HEIGHT;
        y = ROW - y - 1;
        m_propVec[m_editProp->getTag()]->setVisible(true);
        this->swapProp(m_editProp->getTag(), y*COL+x);
    }
    else
    {
        if (m_editProp->getOpacity() == 255)
        {
            GAME_UILAYER->getOperationMenu()->addDrugs(2001);
            ControlButton* btn = GAME_UILAYER->getOperationMenu()->getDrugsBtn();
            btn->stopAllActions();
            ScaleTo* scaleTo = ScaleTo::create(0.1f, 1.0f);
            btn->runAction(scaleTo);
            m_propVec[m_editProp->getTag()]->removeFromParent();
            m_propVec[m_editProp->getTag()] = NULL;
        }
        else
        {
            float r = CCRANDOM_0_1();
            if (r ==1)
                r = 0;
            
            BgMap* bgMap = GAME_SCENE->getCurrBgMap();
            MapPoint playerPosition = MapPoint(Player::sharePlayer()->getPosition());
            
            MapPoint point = MapPointZero;
            std::vector<MapPoint> mapVec;
            M_INT lenght = 1;
            do
            {
                mapVec = playerPosition.getMapPointVectorForDistance(lenght);
                unsigned int index = 0;
                for (; index<mapVec.size(); index++)
                {
                    if (GAME_SCENE->getMapPointForProp(MapPoint(mapVec.at(index))) == NULL)
                    {
                        point = MapPoint(mapVec.at(index));
                    }
                }
                
                CC_BREAK_IF(!point.equals(MapPointZero));
                
                lenght++;
            }
            while (1);

            
            PropIconShow* show = m_propVec[m_editProp->getTag()];
            m_propVec[m_editProp->getTag()] = NULL;
            show->setVisible(true);
            show->retain();
            show->removeFromParent();
            show->setPosition(point.getCCPointValue());
            bgMap->addChild(show, BgMap::getZOrderZero(bgMap));
            show->release();
            show->setScale(0.8f);

            GAME_SCENE->insterMapPointForProp(show, point);
            
            show->setOpacity(0);
            FadeIn* fadeIn = FadeIn::create(0.1f);
            JumpBy* jumpBy = JumpBy::create(0.3f, Point::ZERO, 30, 1);
            Spawn* spawn = Spawn::create(fadeIn, jumpBy, NULL);
            show->runAction(spawn);
            
        }
    }
    m_editProp->removeFromParent();
    m_editProp = NULL;
}