2021-11-14 20:06:09 +00:00
|
|
|
extends Node2D
|
2021-11-08 13:40:11 +00:00
|
|
|
|
2021-11-11 20:38:10 +00:00
|
|
|
# Path to Ship class, for instantiating new Ships in code
|
2021-11-15 07:17:32 +00:00
|
|
|
var Ship = preload("res://scenes/Game/Ship.tscn")
|
2021-11-11 20:38:10 +00:00
|
|
|
|
2021-11-14 20:06:09 +00:00
|
|
|
# Consts and enums
|
|
|
|
const NO_SHIP = -1
|
2021-11-24 08:53:05 +00:00
|
|
|
enum {MISS = -1, READY = 0, HIT = 1, SUNK = 2, LOST = 3}
|
2021-11-08 13:40:11 +00:00
|
|
|
|
2021-11-14 20:06:09 +00:00
|
|
|
var bottom_board:Array # Player board
|
|
|
|
var top_board:Array # Opponent board
|
|
|
|
var ships = [] # list of Ships
|
2021-11-24 18:17:07 +00:00
|
|
|
var ship_data = [] # Data used to generate ships
|
2021-11-14 20:06:09 +00:00
|
|
|
var ship_count = 0 # number of 'active' (un-sunk) ships
|
|
|
|
|
|
|
|
# a board is square. This is its side length
|
2021-11-12 02:45:38 +00:00
|
|
|
var board_len = 10
|
|
|
|
|
2021-11-14 20:06:09 +00:00
|
|
|
# The top board must be marked by textures. This is where they are stored:
|
|
|
|
var sprites = []
|
|
|
|
|
|
|
|
# Here are where the hit/miss textures are loaded, so that they may be used:
|
|
|
|
var hit_texture = preload("res://assets/game/Hit.png")
|
|
|
|
var miss_texture = preload("res://assets/game/Miss.png")
|
|
|
|
|
2021-11-08 13:40:11 +00:00
|
|
|
|
2021-11-11 20:38:10 +00:00
|
|
|
# TODO: What state?
|
2021-11-14 20:06:09 +00:00
|
|
|
func get_state():
|
2021-11-08 13:40:11 +00:00
|
|
|
pass
|
|
|
|
|
2021-11-14 20:06:09 +00:00
|
|
|
# Evaluate being hit by an opponent
|
|
|
|
# pos: board position opponent fired at
|
|
|
|
func hit(pos):
|
|
|
|
var res = MISS
|
|
|
|
# Get the ship-metadata for that location
|
|
|
|
var ship = bottom_board[pos.x][pos.y]
|
2021-11-24 18:17:07 +00:00
|
|
|
# If the ship's already been hit here, don't bother beating it again
|
|
|
|
if ship[1] != READY:
|
|
|
|
return ship[1]
|
|
|
|
if ship[0] > NO_SHIP:
|
|
|
|
# Decide whether HIT or SUNK
|
2021-11-14 20:06:09 +00:00
|
|
|
res = ships[ship[0]].hit(pos)
|
|
|
|
# If ship sunk,
|
|
|
|
if res == SUNK:
|
|
|
|
# remove it from the count
|
|
|
|
ship_count -= 1
|
2021-11-24 18:17:07 +00:00
|
|
|
# If we have no more ships left, we LOST
|
2021-11-24 08:53:05 +00:00
|
|
|
if ship_count == 0:
|
2021-11-24 18:17:07 +00:00
|
|
|
res = LOST
|
|
|
|
# Record the result on the board, and return it
|
|
|
|
ship[1] = res
|
2021-11-14 20:06:09 +00:00
|
|
|
return res
|
|
|
|
|
|
|
|
# fire: Store the results of firing on an opponent
|
|
|
|
# pos: board position fired on
|
|
|
|
# res: result of firing on the opponent
|
|
|
|
func fire(pos, res):
|
2021-11-24 18:17:07 +00:00
|
|
|
if top_board[pos.x][pos.y] == READY:
|
2021-11-14 20:06:09 +00:00
|
|
|
top_board[pos.x][pos.y] = res
|
2021-11-24 18:17:07 +00:00
|
|
|
return res
|
|
|
|
else:
|
|
|
|
return top_board[pos.x][pos.y]
|
2021-11-14 20:06:09 +00:00
|
|
|
|
2021-11-11 20:38:10 +00:00
|
|
|
# Place a ship on the board at board-space coordinates
|
2021-11-14 20:06:09 +00:00
|
|
|
func place_ship(in_position, in_size, in_orientation, in_variant = 0):
|
2021-11-24 18:17:07 +00:00
|
|
|
# Save the ship data
|
|
|
|
ship_data.append([in_position, in_size, in_orientation])
|
|
|
|
# Create a new Ship, and give it some data
|
2021-11-15 07:17:32 +00:00
|
|
|
var ship = Ship.instance()
|
|
|
|
ship._init(in_position, in_size, in_orientation, in_variant)
|
2021-11-24 18:17:07 +00:00
|
|
|
# Mark the ship on the board
|
2021-11-14 20:06:09 +00:00
|
|
|
for pos in ship.get_extent():
|
|
|
|
bottom_board[pos.x][pos.y] = [ships.size(), READY]
|
2021-11-24 18:17:07 +00:00
|
|
|
# Add the ship to the ships array, and keep count
|
2021-11-14 20:06:09 +00:00
|
|
|
ships.append(ship)
|
|
|
|
ship_count += 1
|
2021-11-24 18:17:07 +00:00
|
|
|
# Add the ship to the scene tree
|
2021-11-14 20:06:09 +00:00
|
|
|
add_child(ship)
|
2021-11-08 13:40:11 +00:00
|
|
|
|
2021-11-24 18:17:07 +00:00
|
|
|
|
|
|
|
func query_bottom(pos):
|
|
|
|
return bottom_board[pos.x][pos.y]
|
|
|
|
|
|
|
|
func query_top(pos):
|
|
|
|
return top_board[pos.x][pos.y]
|
2021-11-08 13:40:11 +00:00
|
|
|
|
2021-11-14 20:06:09 +00:00
|
|
|
# Get the number of live ships
|
|
|
|
func get_ship_count():
|
2021-11-12 02:45:38 +00:00
|
|
|
return ship_count
|
2021-11-11 20:38:10 +00:00
|
|
|
|
2021-11-14 20:06:09 +00:00
|
|
|
# _init: Constructor
|
2021-11-11 20:38:10 +00:00
|
|
|
func _init():
|
2021-11-24 18:17:07 +00:00
|
|
|
# Initialize the bottom_board to a len*len array
|
|
|
|
for x in board_len:
|
2021-11-11 21:38:50 +00:00
|
|
|
bottom_board.append([])
|
2021-11-24 18:17:07 +00:00
|
|
|
for y in board_len:
|
|
|
|
bottom_board[x].append([NO_SHIP, READY])
|
|
|
|
# Initialize the top_board to a len*len array
|
|
|
|
for x in board_len:
|
2021-11-11 21:38:50 +00:00
|
|
|
top_board.append([])
|
2021-11-24 18:17:07 +00:00
|
|
|
for y in board_len:
|
|
|
|
top_board[x].append(READY)
|
2021-11-11 20:38:10 +00:00
|
|
|
|
2021-11-11 21:38:50 +00:00
|
|
|
# worldspace_to_boardspace: convert a Vector2 in world-space to board-space
|
2021-11-11 20:38:10 +00:00
|
|
|
func worldspace_to_boardspace(coordinate:Vector2):
|
2021-11-11 21:38:50 +00:00
|
|
|
# subtract 36 to get the position relative to (0,0) on the board, and integer divide by 32
|
|
|
|
return Vector2(int(coordinate.x - 36) >> 5, int(coordinate.y-36) >> 5)
|