Beispiel #1
0
void CUnitDrawProxy::Draw(const CViewport *vp) const
{
	int x = this->IX + vp->Map2ViewportX(this->X);
	int y = this->IY + vp->Map2ViewportY(this->Y);

	/* FIXME: check if we have to push real type here?*/
	if (state == 1 && cframe) {
		DrawConstructionShadow(*Type, cframe, frame, x, y);
	} else {
		if (IsAlive) {
			DrawShadow(*Type, frame, x, y);
		}
	}

	//
	// Show that the unit is selected
	//
	DrawSelectionAt(x, y);

	//
	// Adjust sprite for Harvesters.
	//
	CPlayerColorGraphic *sprite = Type->Sprite;
	if (Type->Harvester && this->CurrentResource) {
		ResourceInfo *resinfo = Type->ResInfo[this->CurrentResource];
		if (this->ResourcesHeld) {
			if (resinfo->SpriteWhenLoaded) {
				sprite = resinfo->SpriteWhenLoaded;
			}
		} else {
			if (resinfo->SpriteWhenEmpty) {
				sprite = resinfo->SpriteWhenEmpty;
			}
		}
	}

	//
	// Now draw!
	// Buildings under construction/upgrade/ready.
	//
	if (state == 1) {
		if (cframe) {
			DrawConstruction(Player->Index, cframe, *Type, frame,
				x + (Type->TileWidth * TileSizeX) / 2,
				y + (Type->TileHeight * TileSizeY) / 2);
		}
	//
	// Draw the future unit type, if upgrading to it.
	//
	} else if (state == 2) {
		// FIXME: this frame is hardcoded!!!
		DrawUnitType(*Type, sprite, Player->Index, frame < 0 ? /*-1*/ - 1 : 1, x, y);
	} else {
		DrawUnitType(*Type, sprite, Player->Index, frame, x, y);
	}

	// Unit's extras not fully supported.. need to be decorations themselves.
	// FIXME: johns: ugly check here, should be removed!
	if (IsAlive /*unit->IsVisible(ThisPlayer)*/) {
		DrawDecorationAt(x, y);
	}

	//DrawInformations(this, type, x, y);
}
Beispiel #2
0
/**
**	Draw unit on map.
**
**	@param unit	Pointer to the unit.
*/
local void DrawUnit(Unit* unit)
{
    int x;
    int y;
    int r;
    UnitType* type;
    UnitStats* stats;

    type=unit->Type;

    x=Map2ScreenX(unit->X)+unit->IX;
    y=Map2ScreenY(unit->Y)+unit->IY;

    if( type->UnitType==UnitTypeFly ) {
	DrawShadow(unit,type,x,y);
    }

    DrawSelectionRectangle(unit,type,x,y);

    PlayerPixels(unit->Player);
    DrawUnitType(type,unit->Frame,x,y);

    stats=unit->Stats;

    //
    //	For debug draw sight, react and attack range!
    //
    if( NumSelected==1 && unit->Selected ) {
	if( ShowSightRange ) {
	    DrawRectangle(ColorGreen
		,x+TileSizeX/2-stats->SightRange*TileSizeX
		,y+TileSizeY/2-stats->SightRange*TileSizeY
		,stats->SightRange*TileSizeX*2
		,stats->SightRange*TileSizeY*2);
	}
	if( type->CanAttack ) {
	    if( ShowReactRange ) {
		r= (unit->Player->Type==PlayerHuman)
			? type->ReactRangeHuman
			: type->ReactRangeComputer;
		if( r ) {
		    DrawRectangle(ColorBlue
			,x+TileSizeX/2-r*TileSizeX
			,y+TileSizeY/2-r*TileSizeY
			,r*TileSizeX*2
			,r*TileSizeY*2);
		}
	    }
	    if( ShowAttackRange && stats->AttackRange ) {
		DrawRectangle(ColorRed
		    ,x+TileSizeX/2-stats->AttackRange*TileSizeX
		    ,y+TileSizeY/2-stats->AttackRange*TileSizeY
		    ,stats->AttackRange*TileSizeX*2
		    ,stats->AttackRange*TileSizeY*2);
	    }
	}
    }

    //
    //	For debug draw destination. FIXME: should become orders
    //
    if( ShowOrders && unit->Selected && (KeyModifiers&ModifierShift)) {
	DrawPath(unit);
    }

    // FIXME: johns: ugly check here should be removed!
    if( unit->Command.Action!=UnitActionDie ) {
	DrawDecoration(unit,type,x,y);
    }
}
Beispiel #3
0
/**
**  Draw unit on map.
*/
void CUnit::Draw(const CViewport *vp) const
{
	int x;
	int y;
	int frame;
	int state;
	int constructed;
	CPlayerColorGraphic *sprite;
	ResourceInfo *resinfo;
	CConstructionFrame *cframe;
	CUnitType *type;

	/*
	 * Since we can draw in parallel to game logic units may be already destroyed
	 * or removed (this->Container != NULL) most dangerus is destroyed state
	 * but due existence of UnitCashe, unit memory is always valid only we need check
	 * Destroyed flag... the hack is that  this->Type == NULL but 'or' logic
	 * should secure this scenario and retir before this->Type->Revealer check
	 */
	if (this->Destroyed || this->Container || this->Type->Revealer) { // Revealers are not drawn
		return;
	}

	bool IsVisible = this->IsVisible(ThisPlayer);

	// Those should have been filtered. Check doesn't make sense with ReplayRevealMap
	Assert(ReplayRevealMap || this->Type->VisibleUnderFog || IsVisible);

	int player = this->RescuedFrom ? this->RescuedFrom->Index : this->Player->Index;
	int action = this->CurrentAction();
	if (ReplayRevealMap || IsVisible) {
		type = this->Type;
		frame = this->Frame;
		y = this->IY;
		x = this->IX;
		x += vp->Map2ViewportX(this->tilePos.x);
		y += vp->Map2ViewportY(this->tilePos.y);
		state = (action == UnitActionBuilt) |
				((action == UnitActionUpgradeTo) << 1);
		constructed = this->Constructed;
		// Reset Type to the type being upgraded to
		if (state == 2) {
			type = this->CurrentOrder()->Arg1.Type;
		}
		// This is trash unless the unit is being built, and that's when we use it.
		cframe = this->Data.Built.Frame;
	} else {
		y = this->Seen.IY;
		x = this->Seen.IX;
		x += vp->Map2ViewportX(this->Seen.X);
		y += vp->Map2ViewportY(this->Seen.Y);
		frame = this->Seen.Frame;
		type = this->Seen.Type;
		constructed = this->Seen.Constructed;
		state = this->Seen.State;
		cframe = this->Seen.CFrame;
	}

#ifdef DYNAMIC_LOAD
	if (!type->Sprite) {
		LoadUnitTypeSprite(*type);
	}
#endif

	if (!IsVisible && frame == UnitNotSeen) {
		DebugPrint("FIXME: Something is wrong, unit %d not seen but drawn time %lu?.\n" _C_
			this->Slot _C_ GameCycle);
		return;
	}


	if (state == 1 && constructed) {
		DrawConstructionShadow(*type, cframe, frame, x, y);
	} else {
		if (action != UnitActionDie) {
			DrawShadow(*type, frame, x, y);
		}
	}

	//
	// Show that the unit is selected
	//
	DrawUnitSelection(vp, *this);

	//
	// Adjust sprite for Harvesters.
	//
	sprite = type->Sprite;
	if (type->Harvester && this->CurrentResource) {
		resinfo = type->ResInfo[this->CurrentResource];
		if (this->ResourcesHeld) {
			if (resinfo->SpriteWhenLoaded) {
				sprite = resinfo->SpriteWhenLoaded;
			}
		} else {
			if (resinfo->SpriteWhenEmpty) {
				sprite = resinfo->SpriteWhenEmpty;
			}
		}
	}

	//
	// Now draw!
	// Buildings under construction/upgrade/ready.
	//
	if (state == 1) {
		if (constructed) {
			DrawConstruction(player, cframe, *type, frame,
				x + (type->TileWidth * TileSizeX) / 2,
				y + (type->TileHeight * TileSizeY) / 2);
		}
	//
	// Draw the future unit type, if upgrading to it.
	//
	} else if (state == 2) {
		// FIXME: this frame is hardcoded!!!
		DrawUnitType(*type, sprite, player, frame < 0 ? /*-1*/ - 1 : 1, x, y);
	} else {
		DrawUnitType(*type, sprite, player, frame, x, y);
	}

	// Unit's extras not fully supported.. need to be decorations themselves.
	DrawInformations(*this, type, x, y);
}
Beispiel #4
0
/**
**	Draw building on map.
**
**	@param unit	Pointer to the building
*/
local void DrawBuilding(Unit* unit)
{
    int x;
    int y;
    UnitType* type;
    int frame;
    int n_frame;

    // FIXME: This should I rewrite, without checks here!!

    type=unit->Type;
    x = unit->X;
    y = unit->Y;

    // FIXME: johns: this isn't 100% correct, building which are partly
    // FIXME: johns: under the fog are shown partly.

    // FIXME: There is already a check in the main loop UnitVisibile!
    if ( !MAPEXPLORED( x, y ) ) {
	return;
    }

    if ( !TheMap.NoFogOfWar && !MAPVISIBLE( x, y ) ) {
	frame = unit->SeenFrame;
	if (frame == 255) {
	    return;
	}
    } else {
	frame = unit->SeenFrame = unit->Frame;
    }

#if 0
    if( type->Type==UnitOilPlatformHuman || type->Type==UnitOilPlatformOrc ) {
	DebugLevel0("%d -> %d\n",unit->Frame,frame);
    }
#endif

    n_frame = 0;
    if ((frame & 128) == 0 && unit->Rs > 50) {
	n_frame = 128; // fancy buildings
    }

    PlayerPixels(unit->Player);
    x=Map2ScreenX(unit->X)+unit->IX;
    y=Map2ScreenY(unit->Y)+unit->IY;

    //
    //	Buildings under construction/upgrade/ready.
    //
    if( unit->Command.Action==UnitActionBuilded ) {
	if( unit->Constructed || type->RleSprite->NumFrames<=1 ) {
	    DrawConstruction(type->OverlapFrame
		,frame
		,x+(type->TileWidth*TileSizeX)/2
		,y+(type->TileHeight*TileSizeY)/2);
	} else {
#if 0
	    DebugLevel0("Remove this %d\n",n_frame);
	    if ( strcmp(type->Ident,"dark-portal") == 0
		||  strcmp(type->Ident,"runestone") == 0 )
	    //FIXME: dark-portal and runestone haven't reqiured frames, so we draw construction instead
	    DrawConstruction(type->OverlapFrame
		,frame
		,x+(type->TileWidth*TileSizeX)/2
		,y+(type->TileHeight*TileSizeY)/2);
	    else
#endif
	    DrawUnitType(type,frame+n_frame,x,y);
	}
    } else if( unit->Command.Action==UnitActionUpgradeTo ) {
	DrawUnitType(unit->Command.Data.UpgradeTo.What,1+n_frame,x,y);
    } else {
	DrawUnitType(type,frame+n_frame,x,y);
    }

    // FIXME: johns: ugly check here should be removed!
    if( unit->Command.Action!=UnitActionDie ) {
	DrawDecoration(unit,type,x,y);
	DrawSelectionRectangle(unit,type,x,y);
    }
}
Beispiel #5
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);
		}
	    }
	}
    }
}
Beispiel #6
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;
	    }
	}
    }
}
/**
**  Draw unit on map.
*/
void CUnit::Draw(const CViewport &vp) const
{
	int frame;
	int state;
	int constructed;
	const CConstructionFrame *cframe;
	const CUnitType *type;

	if (this->Destroyed || this->Container || this->Type->Revealer) { // Revealers are not drawn
		return;
	}

	bool IsVisible = this->IsVisible(*ThisPlayer);

	// Those should have been filtered. Check doesn't make sense with ReplayRevealMap
	Assert(ReplayRevealMap || this->Type->VisibleUnderFog || IsVisible);

	int player = this->RescuedFrom ? this->RescuedFrom->Index : this->Player->Index;
	int action = this->CurrentAction();
	PixelPos screenPos;
	if (ReplayRevealMap || IsVisible) {
		screenPos = vp.MapToScreenPixelPos(this->GetMapPixelPosTopLeft());
		type = this->Type;
		frame = this->Frame;
		state = (action == UnitActionBuilt) | ((action == UnitActionUpgradeTo) << 1);
		constructed = this->Constructed;
		// Reset Type to the type being upgraded to
		if (action == UnitActionUpgradeTo) {
			const COrder_UpgradeTo &order = *static_cast<COrder_UpgradeTo *>(this->CurrentOrder());

			type = &order.GetUnitType();
		}

		if (this->CurrentAction() == UnitActionBuilt) {
			COrder_Built &order = *static_cast<COrder_Built *>(this->CurrentOrder());

			cframe = &order.GetFrame();
		} else {
			cframe = NULL;
		}
	} else {
		screenPos = vp.TilePosToScreen_TopLeft(this->Seen.tilePos);

		screenPos.x += this->Seen.IX;
		screenPos.y += this->Seen.IY;
		frame = this->Seen.Frame;
		type = this->Seen.Type;
		constructed = this->Seen.Constructed;
		state = this->Seen.State;
		cframe = this->Seen.CFrame;
	}

#ifdef DYNAMIC_LOAD
	if (!type->Sprite) {
		LoadUnitTypeSprite(type);
	}
#endif

	if (!IsVisible && frame == UnitNotSeen) {
		DebugPrint("FIXME: Something is wrong, unit %d not seen but drawn time %lu?.\n" _C_
				   UnitNumber(*this) _C_ GameCycle);
		return;
	}


	if (state == 1 && constructed && cframe) {
		DrawConstructionShadow(*type, cframe, frame, screenPos);
	} else {
		if (action != UnitActionDie) {
			DrawShadow(*type, frame, screenPos);
		}
	}

	//
	// Show that the unit is selected
	//
	DrawUnitSelection(vp, *this);

	//
	// Adjust sprite for Harvesters.
	//
	CPlayerColorGraphic *sprite = type->Sprite;
	if (type->Harvester && this->CurrentResource) {
		ResourceInfo *resinfo = type->ResInfo[this->CurrentResource];
		if (this->ResourcesHeld) {
			if (resinfo->SpriteWhenLoaded) {
				sprite = resinfo->SpriteWhenLoaded;
			}
		} else {
			if (resinfo->SpriteWhenEmpty) {
				sprite = resinfo->SpriteWhenEmpty;
			}
		}
	}

	//
	// Now draw!
	// Buildings under construction/upgrade/ready.
	//
	if (state == 1) {
		if (constructed && cframe) {
			const PixelPos pos(screenPos + (type->GetPixelSize()) / 2);
			DrawConstruction(GameSettings.Presets[player].PlayerColor, cframe, *type, frame, pos);
		} else {
			DrawUnitType(*type, sprite, GameSettings.Presets[player].PlayerColor, frame, screenPos);
		}
		//
		// Draw the future unit type, if upgrading to it.
		//
	} else {
		DrawUnitType(*type, sprite, GameSettings.Presets[player].PlayerColor, frame, screenPos);
	}

	// Unit's extras not fully supported.. need to be decorations themselves.
	DrawInformations(*this, *type, screenPos);
}
Beispiel #8
0
/**
**  Draw unit on map.
*/
void CUnit::Draw() const
{
	int x;
	int y;
	int frame;
	int state;
	int constructed;
	CPlayerColorGraphic *sprite;
	ResourceInfo *resinfo;
	CConstructionFrame *cframe;
	CUnitType *type;

	if (this->Type->Revealer) { // Revealers are not drawn
		return;
	}

	// Those should have been filtered. Check doesn't make sense with ReplayRevealMap
	Assert(ReplayRevealMap || this->Type->VisibleUnderFog || this->IsVisible(ThisPlayer));

	if (ReplayRevealMap || this->IsVisible(ThisPlayer)) {
		type = this->Type;
		frame = this->Frame;
		y = this->IY;
		x = this->IX;
		x += CurrentViewport->Map2ViewportX(this->X);
		y += CurrentViewport->Map2ViewportY(this->Y);
		state = (this->Orders[0]->Action == UnitActionBuilt) |
			((this->Orders[0]->Action == UnitActionUpgradeTo) << 1);
		constructed = this->Constructed;
		// Reset Type to the type being upgraded to
		if (state == 2) {
			type = this->Orders[0]->Type;
		}
		// This is trash unless the unit is being built, and that's when we use it.
		cframe = this->Data.Built.Frame;
	} else {
		y = this->Seen.IY;
		x = this->Seen.IX;
		x += CurrentViewport->Map2ViewportX(this->Seen.X);
		y += CurrentViewport->Map2ViewportY(this->Seen.Y);
		frame = this->Seen.Frame;
		type = this->Seen.Type;
		constructed = this->Seen.Constructed;
		state = this->Seen.State;
		cframe = this->Seen.CFrame;
	}

#ifdef DYNAMIC_LOAD
	if (!type->Sprite) {
		LoadUnitTypeSprite(type);
	}
#endif

	if (!this->IsVisible(ThisPlayer) && frame == UnitNotSeen) {
		DebugPrint("FIXME: Something is wrong, unit %d not seen but drawn time %lu?.\n" _C_
			this->Slot _C_ GameCycle);
		return;
	}


	if (state == 1 && constructed) {
		DrawConstructionShadow(this, cframe, frame, x, y);
	} else {
		DrawShadow(this, NULL, frame, x, y);
	}

	//
	// Show that the unit is selected
	//
	DrawUnitSelection(this);

	//
	// Adjust sprite for Harvesters.
	//
	sprite = type->Sprite;
	if (type->Harvester && this->CurrentResource) {
		resinfo = type->ResInfo[this->CurrentResource];
		if (this->ResourcesHeld) {
			if (resinfo->SpriteWhenLoaded) {
				sprite = resinfo->SpriteWhenLoaded;
			}
		} else {
			if (resinfo->SpriteWhenEmpty) {
				sprite = resinfo->SpriteWhenEmpty;
			}
		}
	}

	//
	// Now draw!
	// Buildings under construction/upgrade/ready.
	//
	if (state == 1) {
		if (constructed) {
			DrawConstruction(this, cframe, type, frame,
				x + (type->TileWidth * TileSizeX) / 2,
				y + (type->TileHeight * TileSizeY) / 2);
		}
	//
	// Draw the future unit type, if upgrading to it.
	//
	} else if (state == 2) {
		// FIXME: this frame is hardcoded!!!
		DrawUnitType(type, sprite,
			this->RescuedFrom ? this->RescuedFrom->Index : this->Player->Index,
			frame < 0 ? -1 - 1 : 1, x, y);
	} else {
		DrawUnitType(type, sprite,
			this->RescuedFrom ? this->RescuedFrom->Index : this->Player->Index,
			frame, x, y);
	}

	// Unit's extras not fully supported.. need to be decorations themselves.
	DrawInformations(this, type, x, y);
}