323 lines
9.8 KiB
C#
323 lines
9.8 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
public class TargetCursor : MonoBehaviour
|
|
{
|
|
public GameManager gameManager;
|
|
public GameObject cursorVisual;
|
|
public CursorAnimator cursorAnimator;
|
|
|
|
private CameraController cameraController;
|
|
|
|
private bool isShootingInProgress = false;
|
|
public bool isPlacingShips = false;
|
|
public GamePole ownField;
|
|
|
|
private int x;
|
|
private int y;
|
|
private int width;
|
|
private int height;
|
|
|
|
private Direction currentDirection = Direction.Right;
|
|
|
|
|
|
// áèíäèíã êíîïîê
|
|
private PlayerKeySet player1Keys = new PlayerKeySet
|
|
{
|
|
Up = ButtonPinMapping.up1,
|
|
Down = ButtonPinMapping.down1,
|
|
Left = ButtonPinMapping.left1,
|
|
Right = ButtonPinMapping.right1,
|
|
Fire = ButtonPinMapping.action1,
|
|
TurnLeft = ButtonPinMapping.turnLeft1,
|
|
TurnRight = ButtonPinMapping.turnRight1
|
|
};
|
|
|
|
private PlayerKeySet player2Keys = new PlayerKeySet
|
|
{
|
|
Up = ButtonPinMapping.up2,
|
|
Down = ButtonPinMapping.down2,
|
|
Left = ButtonPinMapping.left2,
|
|
Right = ButtonPinMapping.right2,
|
|
Fire = ButtonPinMapping.action2,
|
|
TurnLeft = ButtonPinMapping.turnLeft2,
|
|
TurnRight = ButtonPinMapping.turnRight2
|
|
};
|
|
|
|
private PlayerKeySet activeKeys;
|
|
|
|
// Òåêóùèé êâàäðàíò êàìåðû: 0=âïåð¸ä, 1=âïðàâî, 2=íàçàä, 3=âëåâî
|
|
private int cameraQuadrant = 0;
|
|
|
|
// Âîçâðàùàåò ôèçè÷åñêóþ êíîïêó êîòîðóþ íóæíî íàæàòü ÷òîáû ñäâèíóòü êóðñîð â íóæíîì íàïðàâëåíèè
|
|
// dx,dy — ëîãè÷åñêîå íàïðàâëåíèå äâèæåíèÿ êóðñîðà íà ïîëå
|
|
private ButtonPinMapping GetKeyForDirection(int dx, int dy)
|
|
{
|
|
// Ïîâîðîò êàìåðû íà 90° âïðàâî: ôèçè÷åñêàÿ îñü ïîâîðà÷èâàåòñÿ
|
|
// q=0: âïåð¸ä=ââåðõ, âïðàâî=âïðàâî, íàçàä=âíèç, âëåâî=âëåâî
|
|
// q=1: âïåð¸ä=âïðàâî, âïðàâî=âíèç, íàçàä=âëåâî, âëåâî=ââåðõ
|
|
// q=2: âïåð¸ä=âíèç, âïðàâî=âëåâî, íàçàä=ââåðõ, âëåâî=âïðàâî
|
|
// q=3: âïåð¸ä=âëåâî, âïðàâî=ââåðõ, íàçàä=âïðàâî, âëåâî=âíèç
|
|
|
|
int rotDx = dx;
|
|
int rotDy = dy;
|
|
|
|
for (int i = 0; i < cameraQuadrant; i++)
|
|
{
|
|
// Ïîâîðîò âåêòîðà íà -90° (êàìåðà ïîâåðíóëàñü âïðàâî — âåêòîð ïîâîðà÷èâàåì âëåâî)
|
|
int tmp = rotDx;
|
|
rotDx = rotDy;
|
|
rotDy = -tmp;
|
|
}
|
|
|
|
// Òåïåðü rotDx/rotDy — ýòî êàêóþ ôèçè÷åñêóþ êíîïêó íàæàòü
|
|
if (rotDx == 0 && rotDy == -1) return activeKeys.Up;
|
|
if (rotDx == 0 && rotDy == 1) return activeKeys.Down;
|
|
if (rotDx == 1 && rotDy == 0) return activeKeys.Right;
|
|
if (rotDx == -1 && rotDy == 0) return activeKeys.Left;
|
|
|
|
return activeKeys.Up; // fallback
|
|
}
|
|
|
|
// êíîïî÷êè (òîëüêî fire è ïîâîðîò êîðàáëÿ — îíè íå çàâèñÿò îò êàìåðû)
|
|
private ButtonPinMapping fireKey;
|
|
private ButtonPinMapping turnLeftKey;
|
|
private ButtonPinMapping turnRightKey;
|
|
|
|
|
|
public Transform cameraPivot;
|
|
|
|
private int playerId;
|
|
|
|
public void Initialize(GameManager gm, Transform pivotTransform, int playerId = 1, bool isPlacingShips = false)
|
|
{
|
|
this.isPlacingShips = isPlacingShips;
|
|
gameManager = gm;
|
|
|
|
if (isPlacingShips)
|
|
ownField = gm.playerField;
|
|
else
|
|
ownField = gm.enemyField;
|
|
|
|
// Ðàçìåðû è íà÷àëüíàÿ ïîçèöèÿ — èç òåêóùåé êîíôèãóðàöèè ïîëÿ
|
|
width = ownField.LengPole;
|
|
height = ownField.LengPole;
|
|
x = width / 2;
|
|
y = height / 2;
|
|
|
|
BindKeys(playerId);
|
|
|
|
cameraPivot = pivotTransform;
|
|
|
|
|
|
|
|
UpdateCursorPosition();
|
|
|
|
// Ìãíîâåííî âûñòàâèòü ñîñòîÿíèå êóðñîðà ïîä ñòàðòîâîé ïîçèöèåé
|
|
if (cursorAnimator != null)
|
|
{
|
|
bool blocked = isPlacingShips
|
|
? (ownField.FreePole[x, y] != 0)
|
|
: (ownField.PoleShot[x, y] != 0);
|
|
cursorAnimator.RefreshState(blocked);
|
|
}
|
|
}
|
|
|
|
private void BindKeys(int playerId)
|
|
{
|
|
activeKeys = (playerId == 1) ? player1Keys : player2Keys;
|
|
|
|
// Íàïðàâëåíèÿ (up/down/left/right) íå êîïèðóåì — îíè âû÷èñëÿþòñÿ ÷åðåç MapKey + cameraQuadrant
|
|
fireKey = activeKeys.Fire;
|
|
turnLeftKey = activeKeys.TurnLeft;
|
|
turnRightKey = activeKeys.TurnRight;
|
|
}
|
|
|
|
|
|
public void SwitchButton(Vector3 rotate)
|
|
{
|
|
if (activeKeys == null) return; // çàùèòà îò âûçîâà äî Initialize
|
|
|
|
float y = rotate.y;
|
|
if (y > 180) y -= 360;
|
|
|
|
if (y >= -45 && y < 45) cameraQuadrant = 0; // âïåð¸ä
|
|
else if (y >= 45 && y < 135) cameraQuadrant = 1; // âïðàâî
|
|
else if (y >= 135 || y < -135) cameraQuadrant = 2; // íàçàä
|
|
else cameraQuadrant = 3; // âëåâî
|
|
}
|
|
|
|
|
|
|
|
void Update()
|
|
{
|
|
if (isShootingInProgress) return;
|
|
if (gameManager.currentInputMode == GameManager.InputMode.UI) return;
|
|
|
|
|
|
|
|
// --- Ïîâîðîò êîðàáëÿ / êàìåðû â ðåæèìå ðàññòàíîâêè ---
|
|
if (isPlacingShips)
|
|
{
|
|
if (In.GetButtonDown(turnLeftKey))
|
|
currentDirection = (Direction)(((int)currentDirection + 3) % 4);
|
|
else if (In.GetButtonDown(turnRightKey))
|
|
currentDirection = (Direction)(((int)currentDirection + 1) % 4);
|
|
UpdateCursorPosition();
|
|
}
|
|
|
|
// if (In.GetButtonUp(turnRightKey) || In.GetButtonUp(turnLeftKey)) SwitchButton(cameraPivot.rotation.eulerAngles);
|
|
//
|
|
|
|
// --- Òîëüêî â ñâîé õîä ---
|
|
if (!isPlacingShips && (gameManager.currentState != GameState.Playing || !gameManager.isPlayerTurn))
|
|
return;
|
|
|
|
// --- Äâèæåíèå êóðñîðà ---
|
|
|
|
bool anyMove = In.GetButtonDown(activeKeys.Up) ||
|
|
In.GetButtonDown(activeKeys.Down) ||
|
|
In.GetButtonDown(activeKeys.Left) ||
|
|
In.GetButtonDown(activeKeys.Right);
|
|
|
|
if (anyMove)
|
|
SwitchButton(cameraPivot.rotation.eulerAngles); // ?
|
|
|
|
|
|
bool moved = false;
|
|
if (In.GetButtonDown(GetKeyForDirection( 0, -1))) { MoveCursor( 0, -1); moved = true; }
|
|
if (In.GetButtonDown(GetKeyForDirection( 0, 1))) { MoveCursor( 0, 1); moved = true; }
|
|
if (In.GetButtonDown(GetKeyForDirection( 1, 0))) { MoveCursor( 1, 0); moved = true; }
|
|
if (In.GetButtonDown(GetKeyForDirection(-1, 0))) { MoveCursor(-1, 0); moved = true; }
|
|
if (moved)
|
|
{
|
|
UpdateCursorPosition();
|
|
if (!isPlacingShips) gameManager.ResetBattleIdleTimer();
|
|
}
|
|
|
|
// --- Âûñòðåë / óñòàíîâêà ---
|
|
if (In.GetButtonDown(fireKey))
|
|
{
|
|
if (!isPlacingShips)
|
|
{
|
|
gameManager.ResetBattleIdleTimer();
|
|
TryShoot();
|
|
}
|
|
else TryPlaceCurrentShip();
|
|
}
|
|
}
|
|
|
|
void UpdateCursorPosition()
|
|
{
|
|
Cell targetCell = ownField.GetCell(x, y);
|
|
if (targetCell != null)
|
|
{
|
|
cursorVisual.transform.position = targetCell.transform.position + Vector3.back * 0.1f;
|
|
// Ìàñøòàá êóðñîðà = ðàçìåð êëåòêè (â áûñòðûõ ðåæèìàõ êëåòêè êðóïíåå)
|
|
cursorVisual.transform.localScale = Vector3.one * ownField.CellScale;
|
|
}
|
|
|
|
// Îáíîâëÿåì ñîñòîÿíèå àíèìàòîðà
|
|
if (cursorAnimator != null)
|
|
{
|
|
bool blocked;
|
|
if (isPlacingShips)
|
|
// Ïðè ðàññòàíîâêå — êðàñíûé åñëè êëåòêà çàíÿòà èëè ðèô
|
|
blocked = (ownField.FreePole[x, y] != 0);
|
|
else
|
|
// Ïðè ñòðåëüáå — êðàñíûé åñëè óæå ñòðåëÿëè
|
|
blocked = (ownField.PoleShot[x, y] != 0);
|
|
|
|
if (blocked) cursorAnimator.SetStateBlocked();
|
|
else cursorAnimator.SetStateFree();
|
|
}
|
|
|
|
if (isPlacingShips)
|
|
{
|
|
ownField.ClearGhost();
|
|
ownField.ShowShipGhost(x, y, currentDirection);
|
|
}
|
|
}
|
|
|
|
void TryShoot()
|
|
{
|
|
if (isShootingInProgress) return;
|
|
if (ownField.PoleShot[x, y] != 0) return;
|
|
|
|
isShootingInProgress = true;
|
|
|
|
// Àíèìàöèÿ âûñòðåëà — êëåòêà áóäåò çàíÿòà ïîñëå âûñòðåëà
|
|
cursorAnimator?.PlayShot(true);
|
|
|
|
if (gameManager.gameMode == GameMode.PlayerVsPlayer)
|
|
{
|
|
gameManager.opponentManager.enemyBattery.FireShot(
|
|
gameManager.opponentManager.playerField, x, y, (wasHit, wasShipDestroyed) => { // ìèñòð êàñòûëü
|
|
|
|
gameManager.opponentManager.ProcessShotResult(wasHit, false, wasShipDestroyed);
|
|
});
|
|
}
|
|
|
|
gameManager.battery.FireShot(gameManager.enemyField, x, y, (wasHit, wasShipDestroyed) =>
|
|
{
|
|
gameManager.ProcessShotResult(wasHit, true, wasShipDestroyed);
|
|
if (!wasHit)gameManager.EndPlayerTurn();
|
|
isShootingInProgress = false;
|
|
});
|
|
|
|
}
|
|
|
|
void TryPlaceCurrentShip()
|
|
{
|
|
bool placed = ownField.PlaceShipManual(x, y, currentDirection);
|
|
if (placed) gameManager.AddShipPlayer();
|
|
}
|
|
|
|
|
|
|
|
void MoveCursor(int dx, int dy)
|
|
{
|
|
if (isPlacingShips)
|
|
{
|
|
x += dx;
|
|
y += dy;
|
|
|
|
if (x < 0) x = width - 1;
|
|
if (x >= width)
|
|
{
|
|
x = width - 1;
|
|
gameManager.SetInputMode(GameManager.InputMode.UI);
|
|
return;
|
|
}
|
|
|
|
if (y < 0) y = height - 1;
|
|
if (y >= height) y = 0;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
x += dx;
|
|
y += dy;
|
|
|
|
if (x < 0) x = width - 1;
|
|
if (x >= width) x = 0;
|
|
if (y < 0) y = height - 1;
|
|
if (y >= height) y = 0;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class PlayerKeySet
|
|
{
|
|
public ButtonPinMapping Up;
|
|
public ButtonPinMapping Down;
|
|
public ButtonPinMapping Left;
|
|
public ButtonPinMapping Right;
|
|
public ButtonPinMapping Fire;
|
|
public ButtonPinMapping TurnLeft;
|
|
public ButtonPinMapping TurnRight;
|
|
}
|