Пример #1
0
/**
**  Can build unit-type at this point.
**
**  @param unit  Worker that want to build the building or NULL.
**  @param type  Building unit-type.
**  @param pos   tile map position.
**  @param real  Really build, or just placement
**
**  @return      OnTop, parent unit, builder on true, NULL false.
**
*/
CUnit *CanBuildUnitType(const CUnit *unit, const CUnitType &type, const Vec2i &pos, int real)
{
	// Terrain Flags don't matter if building on top of a unit.
	CUnit *ontop = CanBuildHere(unit, type, pos);
	if (ontop == NULL) {
		return NULL;
	}
	if (ontop != (CUnit *)1 && ontop != unit) {
		return ontop;
	}

	//  Remove unit that is building!
	if (unit) {
		UnmarkUnitFieldFlags(*unit);
	}

	CPlayer *player = NULL;

	if (unit && unit->Player->Type == PlayerPerson) {
		player = unit->Player;
	}
	int testmask;
	unsigned int index = pos.y * Map.Info.MapWidth;
	for (int h = 0; h < type.TileHeight; ++h) {
		for (int w = type.TileWidth; w--;) {
			/* first part of if (!CanBuildOn(x + w, y + h, testmask)) */
			if (!Map.Info.IsPointOnMap(pos.x + w, pos.y + h)) {
				h = type.TileHeight;
				ontop = NULL;
				break;
			}
			if (player && !real) {
				//testmask = MapFogFilterFlags(player, x + w, y + h, type.MovementMask);
				testmask = MapFogFilterFlags(*player,
											 index + pos.x + w, type.MovementMask);
			} else {
				testmask = type.MovementMask;
			}
			/*secound part of if (!CanBuildOn(x + w, y + h, testmask)) */
			const CMapField &mf = *Map.Field(index + pos.x + w);
			if (mf.CheckMask(testmask)) {
				h = type.TileHeight;
				ontop = NULL;
				break;
			}
			if (player && !mf.playerInfo.IsExplored(*player)) {
				h = type.TileHeight;
				ontop = NULL;
				break;
			}
		}
		index += Map.Info.MapWidth;
	}
	if (unit) {
		MarkUnitFieldFlags(*unit);
	}
	// We can build here: check distance to gold mine/oil patch!
	return ontop;
}
Пример #2
0
/**
**	Draw cursor for selecting building position.
*/
local void DrawBuildingCursor(void)
{
    int x;
    int y;
    int x1;
    int y1;
    int mx;
    int my;
    int color;
    int f;
    int w;
    int w0;
    int h;
    int mask;

    x=((CursorX-MAP_X)/TileSizeX)*TileSizeX+MAP_X;	// Align to grid
    y=((CursorY-MAP_Y)/TileSizeY)*TileSizeY+MAP_Y;
    mx=Screen2MapX(x);
    my=Screen2MapY(y);

    //
    //	Draw building
    //
    PlayerPixels(ThisPlayer);
    SetClipping(MAP_X,MAP_Y,MAP_X+MapWidth*TileSizeX,MAP_Y+MapHeight*TileSizeY);
    DrawUnitType(CursorBuilding,0,x,y);
    // FIXME: This is dangerous here
    SetClipping(0,0,VideoWidth,VideoHeight);

    //
    //	Draw the allow overlay
    //
    f=CanBuildHere(CursorBuilding,mx,my);
    // FIXME: Should be moved into unittype structure, and allow more types.
    if( CursorBuilding->ShoreBuilding ) {
	mask=MapFieldLandUnit
		| MapFieldSeaUnit
		| MapFieldBuilding	// already occuppied
		| MapFieldWall
		| MapFieldRocks
		| MapFieldForest	// wall,rock,forest not 100% clear?
		| MapFieldLandAllowed	// can't build on this
		//| MapFieldUnpassable	// FIXME: I think shouldn't be used
		| MapFieldNoBuilding;
    } else switch( CursorBuilding->UnitType ) {
	case UnitTypeLand:
	    mask=MapFieldLandUnit
		| MapFieldBuilding	// already occuppied
		| MapFieldWall
		| MapFieldRocks
		| MapFieldForest	// wall,rock,forest not 100% clear?
		| MapFieldCoastAllowed
		| MapFieldWaterAllowed	// can't build on this
		| MapFieldUnpassable	// FIXME: I think shouldn't be used
		| MapFieldNoBuilding;
	    break;
	case UnitTypeNaval:
	    mask=MapFieldSeaUnit
		| MapFieldBuilding	// already occuppied
		| MapFieldCoastAllowed
		| MapFieldLandAllowed	// can't build on this
		| MapFieldUnpassable	// FIXME: I think shouldn't be used
		| MapFieldNoBuilding;
	    break;
	case UnitTypeFly:
	default:
	    DebugLevel1(__FUNCTION__": Were moves this unit?\n");
	    return;
    }

    h=CursorBuilding->TileHeight;
    if( my+h>MapY+MapHeight ) {		// reduce to view limits
	h=MapY+MapHeight-my;
    }
    w0=CursorBuilding->TileWidth;	// reduce to view limits
    if( mx+w0>MapX+MapWidth ) {
	w0=MapX+MapWidth-mx;
    }
    while( h-- ) {
	w=w0;
	while( w-- ) {
	    if( f && (CanBuildOn(mx+w,my+h,mask) ||
		    (Selected[0]->X==mx+w && Selected[0]->Y==my+h))
                  && (TheMap.Fields[mx+w+(my+h)*TheMap.Width].Flags
			&MapFieldExplored) ) {
		color=ColorGreen;
	    } else {
		color=ColorRed;
	    }
	    // FIXME: Could do this faster+better
	    for( y1=0; y1<TileSizeY; ++y1 ) {
		for( x1=y1&1; x1<TileSizeX; x1+=2 ) {
		    DrawPointUnclipped(color
			    ,x+w*TileSizeX+x1,y+h*TileSizeY+y1);
		}
	    }
	}
    }
}
Пример #3
0
/**
**	Draw cursor for selecting building position.
*/
local void DrawBuildingCursor(void)
{
    int x;
    int y;
    int x1;
    int y1;
    int mx;
    int my;
    int color;
    int f;
    int w;
    int w0;
    int h;
    int mask;
    const Viewport* vp;

    // Align to grid
    vp = TheUI.MouseViewport;
    x=CursorX-(CursorX - vp->X)%TileSizeX;
    y=CursorY-(CursorY - vp->Y)%TileSizeY;
    BuildingCursorSX = mx = Viewport2MapX(vp, x);
    BuildingCursorSY = my = Viewport2MapY(vp, y);

    //
    //	Draw building
    //
    PushClipping();
    SetClipping(vp->X, vp->Y, vp->EndX, vp->EndY);
    GraphicPlayerPixels(ThisPlayer,CursorBuilding->Sprite);
    if( VideoGraphicFrames(CursorBuilding->Sprite)>5 ) {
	DrawUnitType(CursorBuilding,4,x,y);
    } else {
	DrawUnitType(CursorBuilding,0,x,y);
    }
    PopClipping();

    //
    //	Draw the allow overlay
    //
    f=CanBuildHere(CursorBuilding,mx,my);

    mask = CursorBuilding->MovementMask;
    h=CursorBuilding->TileHeight;
    BuildingCursorEY=my+h-1;
    if (my+h > vp->MapY + vp->MapHeight) {	// reduce to view limits
	h = vp->MapY + vp->MapHeight - my;
    }
    w0 = CursorBuilding->TileWidth;	// reduce to view limits
    BuildingCursorEX=mx+w0-1;
    if (mx+w0 > vp->MapX + vp->MapWidth) {
	w0 = vp->MapX + vp->MapWidth - mx;
    }
    while( h-- ) {
	w=w0;
	while( w-- ) {
	    int basex, basey;
	    // FIXME: The field is covered by fog of war!
	    if( f && CanBuildOn(mx+w,my+h,mask &
		    ((Selected[0]
			    && Selected[0]->X==mx+w && Selected[0]->Y==my+h)
			? ~(MapFieldLandUnit|MapFieldSeaUnit) : -1))
		  && IsMapFieldExplored(ThisPlayer,mx+w,my+h) ) {
		color=ColorGreen;
	    } else {
		color=ColorRed;
	    }
	    // FIXME: I could do this faster+better
	    /* latimerius: I'm not sure what you have in mind but I can
	     * at least move invariants out of the loops. */
	    basex = x + w*TileSizeX;
	    basey = y + h*TileSizeY;
	    for( y1=0; y1<TileSizeY; ++y1 ) {
		int j = basey+y1;
		for( x1=y1&1; x1<TileSizeX; x1+=2 ) {
		    int i = basex+x1;
		    if (i > vp->EndX)
			break;
		    VideoDrawPixel (color, i, j);
		}
		if (j > vp->EndY)
		    break;
	    }
	}
    }
}