mirror of
https://codeberg.org/ProgramSnail/konkr_game_3d.git
synced 2025-12-06 06:38:47 +00:00
213 lines
6.9 KiB
GDScript
213 lines
6.9 KiB
GDScript
extends Spatial
|
|
|
|
var character_scene = preload("res://scenes/character.tscn")
|
|
|
|
onready var map = get_node("/root/Level/Map")
|
|
onready var utils = get_node("/root/Level/Map/Utils")
|
|
|
|
onready var player_characters : Array = [[get_node("/root/Level/Map/Player0")], [], [], [], []]
|
|
onready var rogue_characters = []
|
|
|
|
var current_player = 0
|
|
var current_character = 0
|
|
|
|
var current_player_used_characters = {}
|
|
|
|
func is_current_player_character_used(character : int):
|
|
return current_player_used_characters.has(character)
|
|
|
|
func current_character_obj():
|
|
return player_characters[current_player][current_character]
|
|
|
|
func current_player_characters_count():
|
|
return player_characters[current_player].size()
|
|
|
|
func is_current_character_exist():
|
|
return current_character < current_player_characters_count()
|
|
|
|
func spawn_current_player_character(position : Vector3):
|
|
player_characters[current_player].append( \
|
|
utils.spawn_on_position(character_scene, position))
|
|
|
|
func try_merge_current_character_with(character : int):
|
|
if current_character == character:
|
|
return false
|
|
|
|
if current_player_used_characters.has(current_character) and \
|
|
current_player_used_characters.has(character):
|
|
return false
|
|
|
|
if player_characters[current_player][current_character].level != player_characters[current_player][character].level:
|
|
return false
|
|
|
|
if not player_characters[current_player][current_character].upgrade():
|
|
return false
|
|
|
|
player_characters[current_player][current_character].translation = player_characters[current_player][character].translation
|
|
|
|
var is_active_after_merge = not current_player_used_characters.has(current_character) and \
|
|
not current_player_used_characters.has(character)
|
|
|
|
player_characters[current_player][character].queue_free()
|
|
|
|
if character + 1 != current_player_characters_count():
|
|
player_characters[current_player][character] = player_characters[current_player].back()
|
|
if current_character + 1 == current_player_characters_count():
|
|
current_character = character
|
|
|
|
player_characters[current_player].pop_back()
|
|
|
|
if not is_active_after_merge:
|
|
set_next_character()
|
|
|
|
return true
|
|
|
|
func destroy_characters_on_position(characters : Array, position : Vector3):
|
|
var destroyed_count = 0
|
|
var alive = []
|
|
|
|
for character in characters:
|
|
var character_position = utils.world_to_grid_position(character.translation)
|
|
if character_position.is_equal_approx(position):
|
|
destroyed_count += 1
|
|
character.queue_free()
|
|
else:
|
|
alive.append(character)
|
|
|
|
return [alive, destroyed_count]
|
|
|
|
func destroy_other_player_characters(position : Vector3, skipped_player : int):
|
|
var characters_destroyed_count = 0
|
|
|
|
for player in range(0, player_characters.size()):
|
|
if player == skipped_player:
|
|
continue
|
|
|
|
var player_destruction_result = \
|
|
destroy_characters_on_position(player_characters[player], position)
|
|
|
|
player_characters[player] = player_destruction_result[0]
|
|
characters_destroyed_count += player_destruction_result[1]
|
|
|
|
var rogue_destruction_result = \
|
|
destroy_characters_on_position(rogue_characters, position)
|
|
|
|
rogue_characters = rogue_destruction_result[0]
|
|
characters_destroyed_count += rogue_destruction_result[1]
|
|
|
|
return characters_destroyed_count
|
|
|
|
# not optimal
|
|
func turn_characters_into_rogues():
|
|
var new_rogue_characters = 0
|
|
|
|
for player in range(0, player_characters.size()):
|
|
var alive_characters = []
|
|
for character in player_characters[player]:
|
|
var character_position = utils.world_to_grid_position(character.translation)
|
|
if not map.is_connected_to_house(character_position, map.player_tiles[player]):
|
|
new_rogue_characters += 1
|
|
character.became_rogue()
|
|
rogue_characters.append(character)
|
|
map.set_tile_cell(character_position, map.EMPTY_TILE)
|
|
else:
|
|
alive_characters.append(character)
|
|
|
|
player_characters[player] = alive_characters
|
|
|
|
return new_rogue_characters
|
|
|
|
# =< 1 characters on one position
|
|
func find_character_and_player_ids_on(position : Vector3):
|
|
for player in range(player_characters.size()):
|
|
for character in range(player_characters[player].size()):
|
|
var character_position = \
|
|
utils.world_to_grid_position(player_characters[player][character].translation)
|
|
if character_position.is_equal_approx(position):
|
|
return [player, character]
|
|
|
|
return null
|
|
|
|
# =< 1 characters on one position
|
|
func find_character_on(position : Vector3):
|
|
var character_and_player_ids = find_character_and_player_ids_on(position)
|
|
|
|
if character_and_player_ids == null:
|
|
return null
|
|
|
|
return player_characters[character_and_player_ids[0]][character_and_player_ids[1]]
|
|
|
|
func set_next_character():
|
|
if current_character < current_player_characters_count():
|
|
current_character_obj().active = false
|
|
|
|
current_player_used_characters[current_character] = null
|
|
|
|
if current_player_used_characters.size() < current_player_characters_count():
|
|
for i in range(current_player_characters_count()):
|
|
if not current_player_used_characters.has(i):
|
|
current_character = i
|
|
else:
|
|
if current_character == current_player_characters_count():
|
|
current_character += 1
|
|
else:
|
|
current_character = current_player_characters_count()
|
|
|
|
if current_character >= current_player_characters_count() + 1:
|
|
set_next_player()
|
|
|
|
if current_character < current_player_characters_count():
|
|
current_character_obj().active = true
|
|
|
|
func set_next_player():
|
|
if current_character < current_player_characters_count():
|
|
current_character_obj().active = false
|
|
|
|
map.player_tiles[current_player] = map.DEFAULT_PLAYER_TILES[current_player]
|
|
map.remove_active_player_color(current_player)
|
|
|
|
current_player_used_characters.clear()
|
|
|
|
current_player += 1
|
|
|
|
if current_player >= map.PLAYERS_COUNT:
|
|
current_player %= map.PLAYERS_COUNT
|
|
|
|
map.set_active_player_color(current_player)
|
|
map.player_tiles[current_player] = map.ACTIVE_PLAYER_TILES[current_player]
|
|
|
|
map.start_player_turn(current_player)
|
|
|
|
current_character = 0
|
|
|
|
if current_character < current_player_characters_count():
|
|
current_character_obj().active = true
|
|
|
|
func switch_character_to(player : int, character : int):
|
|
if current_character < current_player_characters_count():
|
|
current_character_obj().active = false
|
|
|
|
current_player = player
|
|
current_character = character
|
|
|
|
if current_character < current_player_characters_count():
|
|
current_character_obj().active = true
|
|
|
|
# not optiomal
|
|
func characters_tile_block_level(position : Vector3, inviding_player : int):
|
|
var block_level = -1
|
|
|
|
for player in range(0, player_characters.size()):
|
|
for character in player_characters[player]:
|
|
var character_position = utils.world_to_grid_position(character.translation)
|
|
if player != inviding_player and \
|
|
(map.is_neighbour_tiles(character_position, position) or \
|
|
character_position.is_equal_approx(position)) and \
|
|
map.get_tile_cell(position) == map.player_tiles[player]:
|
|
block_level = max(block_level, character.level)
|
|
|
|
if player == inviding_player and \
|
|
character_position.is_equal_approx(position):
|
|
block_level = character.MAX_LEVEL
|
|
|
|
return block_level
|