anchor.diff:    if gGameCursor.Mode = cmHouses then
       ResetCursorMode;
   end;
  -
  -
  -procedure TKMapEdInterface.MouseUp(Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
  -var
  -  DP: TAIDefencePosition;
  -  Marker: TKMMapEdMarker;
  -  G: TKMUnitGroup;
  -  U: TKMUnit;
  -  H: TKMHouse;
  -begin
  -  if fIsDraggingObject then
  -  begin
  -    DragHouseMoveModeEnd; //In case we started house move mode (with cursor mode cmHouse) have to end it on Mouse move
  -    ResetObjectDrag;
  -  end;
  -
  -  if fDragScrolling then
  -  begin
  -    if Button = mbMiddle then
  -    begin
  -      fDragScrolling := False;
  -      gRes.Cursors.Cursor := kmc_Default; //Reset cursor
  -      fMain.ApplyCursorRestriction;
  -    end;
  -    Exit;
  -  end;
  -
  -  if fMyControls.CtrlOver <> nil then
  -  begin
  -    //Still need to make checkpoint if painting and released over controls
  -    if fMouseDownOnMap then
  -    begin
  -      gGame.MapEditor.MouseUp(Button, False);
  -      fMouseDownOnMap := False;
  -    end;
  -    fMyControls.MouseUp(X,Y,Shift,Button);
  -    Exit; //We could have caused fGame reinit, so exit at once
  -  end;
  -
  -  fMouseDownOnMap := False;
  -
  -  case Button of
  -    mbLeft:   if gGameCursor.Mode = cmNone then
  -              begin
  -                //If there are some additional layers we first HitTest them
  -                //since they are rendered ontop of Houses/Objects
  -                Marker := gGame.MapEditor.HitTest(gGameCursor.Cell.X, gGameCursor.Cell.Y);
  -                if Marker.MarkerType <> mtNone then
  -                begin
  -                  ShowMarkerInfo(Marker);
  -                  gMySpectator.Selected := nil; //We might have had a unit/group/house selected
  -                end
  -                else
  -                begin
  -                  UpdateSelection;
  -                end;
  -              end;
  -    mbRight:  begin
  -                //Right click performs some special functions and shortcuts
  -                if gGameCursor.Mode = cmTiles then
  -                  gGameCursor.MapEdDir := (gGameCursor.MapEdDir + 1) mod 4; //Rotate tile direction
  -
  -                if gMySpectator.Selected is TKMUnitGroup then
  -                begin
  -                  G := TKMUnitGroup(gMySpectator.Selected);
  -                  //Use Shift to set group order
  -                  if ssShift in gGameCursor.SState then
  -                  begin
  -                    U := gTerrain.UnitsHitTest(gGameCursor.Cell.X, gGameCursor.Cell.Y);
  -                    H := gHands.HousesHitTest(gGameCursor.Cell.X, gGameCursor.Cell.Y);
  -                    //If there's any enemy unit or house on specified tile - set attack target
  +
  +
  +procedure TKMapEdInterface.MouseUp(Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
  +var
  +  DP: TAIDefencePosition;
  +  Marker: TKMMapEdMarker;
  +  G: TKMUnitGroup;
  +  U: TKMUnit;
  +  H: TKMHouse;
  +begin
  +  if fIsDraggingObject then
  +  begin
  +    DragHouseMoveModeEnd; //In case we started house move mode (with cursor mode cmHouse) have to end it on Mouse move
  +    ResetObjectDrag;
  +  end;
  +
  +  if fDragScrolling then
  +  begin
  +    if Button = mbMiddle then
  +    begin
  +      fDragScrolling := False;
  +      gRes.Cursors.Cursor := kmc_Default; //Reset cursor
  +      fMain.ApplyCursorRestriction;
  +    end;
  +    Exit;
  +  end;
  +
  +  if fMyControls.CtrlOver <> nil then
  +  begin
  +    //Still need to make checkpoint if painting and released over controls
  +    if fMouseDownOnMap then
  +    begin
  +      gGame.MapEditor.MouseUp(Button, False);
  +      fMouseDownOnMap := False;
  +    end;
  +    fMyControls.MouseUp(X,Y,Shift,Button);
  +    Exit; //We could have caused fGame reinit, so exit at once
  +  end;
  +
  +  fMouseDownOnMap := False;
  +
  +  case Button of
  +    mbLeft:   if gGameCursor.Mode = cmNone then
  +              begin
  +                //If there are some additional layers we first HitTest them
  +                //since they are rendered ontop of Houses/Objects
  +                Marker := gGame.MapEditor.HitTest(gGameCursor.Cell.X, gGameCursor.Cell.Y);
  +                if Marker.MarkerType <> mtNone then
  +                begin
  +                  ShowMarkerInfo(Marker);
  +                  gMySpectator.Selected := nil; //We might have had a unit/group/house selected
  +                end
  +                else
  +                begin
  +                  UpdateSelection;
  +                end;
  +              end;
  +    mbRight:  begin
  +                //Right click performs some special functions and shortcuts
  +                if gGameCursor.Mode = cmTiles then
  +                  gGameCursor.MapEdDir := (gGameCursor.MapEdDir + 1) mod 4; //Rotate tile direction
  +
  +                if gMySpectator.Selected is TKMUnitGroup then
  +                begin
  +                  G := TKMUnitGroup(gMySpectator.Selected);
  +                  //Use Shift to set group order
  +                  if ssShift in gGameCursor.SState then
  +                  begin
  +                    U := gTerrain.UnitsHitTest(gGameCursor.Cell.X, gGameCursor.Cell.Y);
  +                    H := gHands.HousesHitTest(gGameCursor.Cell.X, gGameCursor.Cell.Y);
  +                    //If there's any enemy unit or house on specified tile - set attack target
                       if ((U <> nil) and (gHands[U.Owner].Alliances[G.Owner] = at_Enemy))
                       or ((H <> nil) and (gHands[H.Owner].Alliances[G.Owner] = at_Enemy)) then
                         G.MapEdOrder.Order := ioAttackPosition
  
positive.code:       gRes.Cursors.Cursor := kmc_Drag;
      end;
    end;
  
    if (Button = mbMiddle) and (fMyControls.CtrlOver = nil) then
    begin
       fDragScrolling := True;
       //Restrict the cursor to the window, for now.
       //TODO: Allow one to drag out of the window, and still capture.
       {$IFDEF MSWindows}
         MyRect := fMain.ClientRect;
         ClipCursor(@MyRect);
       {$ENDIF}
       fDragScrollingCursorPos.X := X;
       fDragScrollingCursorPos.Y := Y;
       fDragScrollingViewportPos.X := fViewport.Position.X;
       fDragScrollingViewportPos.Y := fViewport.Position.Y;
       gRes.Cursors.Cursor := kmc_Drag;
       Exit;
    end;
  
    if Button = mbRight then
      RightClick_Cancel;
  
    //So terrain brushes start on mouse down not mouse move
    UpdateGameCursor(X, Y, Shift);
  
    gGame.MapEditor.MouseDown(Button);
  end;
  
  
  procedure TKMapEdInterface.MouseMove(Shift: TShiftState; X,Y: Integer);
  var
    Marker: TKMMapEdMarker;
    VP: TKMPointF;
  begin
  
    if fDragScrolling then
    begin
      VP.X := fDragScrollingViewportPos.X + (fDragScrollingCursorPos.X - X) / (CELL_SIZE_PX * fViewport.Zoom);
      VP.Y := fDragScrollingViewportPos.Y + (fDragScrollingCursorPos.Y - Y) / (CELL_SIZE_PX * fViewport.Zoom);
      fViewport.Position := VP;
      Exit;
    end;
  
    fMyControls.MouseMove(X,Y,Shift);
  
    if fMyControls.CtrlOver <> nil then
    begin
      //kmc_Edit and kmc_DragUp are handled by Controls.MouseMove (it will reset them when required)
      if not fViewport.Scrolling and not (gRes.Cursors.Cursor in [kmc_Edit,kmc_DragUp]) then
        gRes.Cursors.Cursor := kmc_Default;
      gGameCursor.SState := []; //Don't do real-time elevate when the mouse is over controls, only terrain
      Exit;
    end
    else
      DisplayHint(nil); //Clear shown hint
  
    if (ssLeft in Shift) or (ssRight in Shift) then
      fMouseDownOnMap := True;
  
    UpdateGameCursor(X,Y,Shift);
    Label_Coordinates.Caption := Format('X: %d, Y: %d', [gGameCursor.Cell.X, gGameCursor.Cell.Y]);
  
    if fIsDraggingObject and (ssLeft in Shift) then
    begin
      //Cursor can be reset to default, when moved to menu panel while dragging, so set it to drag cursor again
      gRes.Cursors.Cursor := kmc_Drag;
      MoveObjectToCursorCell(fDragObject);
    end else
    if gGameCursor.Mode = cmNone then
    begin
      Marker := gGame.MapEditor.HitTest(gGameCursor.Cell.X, gGameCursor.Cell.Y);
      if Marker.MarkerType <> mtNone then
        gRes.Cursors.Cursor := kmc_Info
      else
      if gMySpectator.HitTestCursor <> nil then
        gRes.Cursors.Cursor := kmc_Info
      else
      if not fViewport.Scrolling then
        gRes.Cursors.Cursor := kmc_Default;
    end;
  
    Label_Coordinates.Caption := Format('X: %d, Y: %d', [gGameCursor.Cell.X, gGameCursor.Cell.Y]);
  
    gGame.MapEditor.MouseMove;
  end;
  
  
  procedure TKMapEdInterface.ResetCursorMode;
  begin
    gGameCursor.Mode := cmNone;
    gGameCursor.Tag1 := 0;
    gGameCursor.CellAdjustment := ZERO_POINT;
  end;
  
  
  //Start drag house move mode (with cursor mode cmHouse)
  procedure TKMapEdInterface.DragHouseMoveModeStart(aHouseNewPos: TKMPoint; aHouseOldPos: TKMPoint);
    procedure SetCursorModeHouse(aHouseType: THouseType);
    begin
      gGameCursor.Mode := cmHouses;
      gGameCursor.Tag1 := Byte(aHouseType);
      //Update cursor CellAdjustment to render house markups at proper positions
      gGameCursor.CellAdjustment := KMPoint(fDragHouseGrabPntAdjustment.X + gRes.Houses[aHouseType].EntranceOffsetX, fDragHouseGrabPntAdjustment.Y);
    end;
  var H: TKMHouse;
  begin
    if fDragObject is TKMHouse then
    begin
      H := TKMHouse(fDragObject);
      //Temporarily remove house from terrain to render house markups as there is no current house (we want to move it)
      gTerrain.SetHouse(H.GetPosition, H.HouseType, hsNone, H.Owner);
      //Stop minimap from updatting, because moving house will dissapear on it, while moving in cmHouse cursor mode
      fStopMinimapUpdate := True;
      SetCursorModeHouse(H.HouseType); //Update cursor mode to cmHouse
    end;
  end;
  
  
  //Drag house move mode end (with cursor mode cmHouse)
  procedure TKMapEdInterface.DragHouseMoveModeEnd;
  var H: TKMHouse;
  begin
    //Restore minimap update
    fStopMinimapUpdate := False;
  
    if (fDragObject is TKMHouse) then
    begin
      H := TKMHouse(fDragObject);
      //Restore house on terrain, just in case we were in house move mode (with cursor mode cmHouse)
      gTerrain.SetHouse(H.GetPosition, H.HouseType, hsBuilt, H.Owner);
      ResetCursorMode;
    end;
  end;
  
  
  procedure TKMapEdInterface.MoveObjectToCursorCell(aObjectToMove: TObject);
  var H: TKMHouse;
      HouseNewPos, HouseOldPos, HouseNewEntrance, HouseOldEntrance: TKMPoint;
      TileOverlayToSave: TTileOverlay;
      IsHouseMovedToNewPos: Boolean;
  begin
    if aObjectToMove = nil then Exit;
  
    TileOverlayToSave := to_None; //Lets make compiler happy, even if this initialization is not necessary
  
    //House move
    if aObjectToMove is TKMHouse then
    begin
      H := TKMHouse(aObjectToMove);
  
      HouseOldPos := H.GetPosition;
      HouseOldEntrance := KMPoint(HouseOldPos.X + gRes.Houses[H.HouseType].EntranceOffsetX, HouseOldPos.Y);
  
      HouseNewPos := KMVectorSum(gGameCursor.Cell, fDragHouseGrabPntAdjustment);
      HouseNewEntrance := KMPoint(HouseNewPos.X + gRes.Houses[H.HouseType].EntranceOffsetX, HouseNewPos.Y);
  
      if not fIsDraggingObject then
        H.SetPosition(HouseNewPos)  //handles Right click, when house is selected
      else begin
        IsHouseMovedToNewPos := not KMSamePoint(HouseNewPos, HouseOldPos);
        if IsHouseMovedToNewPos then
          //Save tile overlay under new house entrance
          TileOverlayToSave := gTerrain.Land[HouseNewEntrance.Y, HouseNewEntrance.X].TileOverlay;
  
        if H.SetPosition(HouseNewPos, False) then
        begin
          DragHouseMoveModeEnd;
          if IsHouseMovedToNewPos then
          begin
            //If we actually moved house to new pos, then restore tile overlay at old house entrance position
            gTerrain.Land[HouseOldEntrance.Y, HouseOldEntrance.X].TileOverlay := fDragHouseEntranceTileOverlay;
            //and store old tile overlay under house entrance
            fDragHouseEntranceTileOverlay := TileOverlayToSave;
          end
        end else
          DragHouseMoveModeStart(HouseNewPos, HouseOldPos);
      end;
    end;
  
    //Unit move
    if aObjectToMove is TKMUnit then
      if aObjectToMove is TKMUnitWarrior then
        aObjectToMove := gHands.GetGroupByMember(TKMUnitWarrior(aObjectToMove))
      else
        TKMUnit(aObjectToMove).SetPosition(gGameCursor.Cell);
  
    //Unit group move
    if aObjectToMove is TKMUnitGroup then
    begin
      //Just move group to specified location
      TKMUnitGroup(aObjectToMove).Position := gGameCursor.Cell;
    end;
  end;
  
  
  procedure TKMapEdInterface.UpdateSelection;
  begin
    gMySpectator.UpdateSelect;
  
    if gMySpectator.Selected is TKMHouse then
    begin
      HidePages;
      Player_SetActive(TKMHouse(gMySpectator.Selected).Owner);
      fGuiHouse.Show(TKMHouse(gMySpectator.Selected));
    end;
    if gMySpectator.Selected is TKMUnit then
    begin
      HidePages;
      Player_SetActive(TKMUnit(gMySpectator.Selected).Owner);
      fGuiUnit.Show(TKMUnit(gMySpectator.Selected));
    end;
    if gMySpectator.Selected is TKMUnitGroup then
    begin
      HidePages;
      Player_SetActive(TKMUnitGroup(gMySpectator.Selected).Owner);
      fGuiUnit.Show(TKMUnitGroup(gMySpectator.Selected));
    end;
  end;
  
  
  procedure TKMapEdInterface.ResetObjectDrag;
  begin
    fIsDraggingObject := False;
    fDragHouseGrabPntAdjustment := ZERO_POINT;
    fDragObject := nil;
  
negative.code:                     G.MapEdOrder.Pos.Dir := G.Direction;
                      //Update group GUI
                      fGuiUnit.Show(G);
                    end else
                      MoveObjectToCursorCell(gMySpectator.Selected);
                  end else
                    MoveObjectToCursorCell(gMySpectator.Selected);
  
                  if fGuiMarkerDefence.Visible then
                  begin
                    DP := gHands[fGuiMarkerDefence.Owner].AI.General.DefencePositions[fGuiMarkerDefence.Index];
                    DP.Position := KMPointDir(gGameCursor.Cell, DP.Position.Dir);
                  end;
  
                  if fGuiMarkerReveal.Visible then
                    gGame.MapEditor.Revealers[fGuiMarkerReveal.Owner][fGuiMarkerReveal.Index] := gGameCursor.Cell;
                end;
    end;
  
    UpdateGameCursor(X, Y, Shift); //Updates the shift state
  
    gGame.MapEditor.MouseUp(Button, True);
  
    //Update the XY coordinates of the Center Screen button
    if (gGameCursor.Mode = cmMarkers) and (gGameCursor.Tag1 = MARKER_CENTERSCREEN) then
      fGuiPlayer.ChangePlayer; //Forces an update
  end;
  
  
  procedure TKMapEdInterface.Resize(X,Y: Word);
  begin
    inherited;
  
    fViewport.Resize(X, Y);
  end;
  
  
  procedure TKMapEdInterface.SetLoadMode(aMultiplayer:boolean);
  begin
    fGuiMenu.SetLoadMode(aMultiplayer);
  end;
  
  
  //UI should paint only controls
  procedure TKMapEdInterface.Paint;
    procedure PaintTextInShape(aText: string; X,Y: SmallInt; aLineColor: Cardinal; aTextColor: Cardinal);
    var
      W: Integer;
    begin
      //Paint the background
      W := 10 + 10 * Length(aText);
      TKMRenderUI.WriteShape(X - W div 2, Y - 10, W, 20, $80000000);
      TKMRenderUI.WriteOutline(X - W div 2, Y - 10, W, 20, 2, aLineColor);
  
      //Paint the label on top of the background
      TKMRenderUI.WriteText(X, Y - 7, 0, aText, fnt_Metal, taCenter, aTextColor);
    end;
  const
    DefenceLine: array [TAIDefencePosType] of Cardinal = ($FF80FF00, $FFFF8000);
  var
    I, K: Integer;
    R: TRawDeposit;
    DP: TAIDefencePosition;
    LocF: TKMPointF;
    ScreenLoc: TKMPoint;
  begin
    if mlDeposits in gGame.MapEditor.VisibleLayers then
    begin
      for R := Low(TRawDeposit) to High(TRawDeposit) do
        for I := 0 to gGame.MapEditor.Deposits.Count[R] - 1 do
        //Ignore water areas with 0 fish in them
        if gGame.MapEditor.Deposits.Amount[R, I] > 0 then
        begin
          LocF := gTerrain.FlatToHeight(gGame.MapEditor.Deposits.Location[R, I]);
          ScreenLoc := fViewport.MapToScreen(LocF);
  
          //At extreme zoom coords may become out of range of SmallInt used in controls painting
          if KMInRect(ScreenLoc, fViewport.ViewRect) then
            PaintTextInShape(IntToStr(gGame.MapEditor.Deposits.Amount[R, I]), ScreenLoc.X, ScreenLoc.Y, DEPOSIT_COLORS[R], $FFFFFFFF);
        end;
    end;
  
    if mlDefences in gGame.MapEditor.VisibleLayers then
    begin
      for I := 0 to gHands.Count - 1 do
        for K := 0 to gHands[I].AI.General.DefencePositions.Count - 1 do
        begin
          DP := gHands[I].AI.General.DefencePositions[K];
          LocF := gTerrain.FlatToHeight(KMPointF(DP.Position.Loc.X-0.5, DP.Position.Loc.Y-0.5));
          ScreenLoc := fViewport.MapToScreen(LocF);
  
          if KMInRect(ScreenLoc, fViewport.ViewRect) then
          begin
            PaintTextInShape(IntToStr(K+1), ScreenLoc.X, ScreenLoc.Y - 22, DefenceLine[DP.DefenceType], FlagColorToTextColor(gHands[I].FlagColor));
            TKMRenderUI.WritePicture(ScreenLoc.X, ScreenLoc.Y, 0, 0, [], rxGui, GROUP_IMG[DP.GroupType]);
          end;
        end;
    end;
  
    inherited;
  end;
  
  
  end.
  