Fronter/Main.gd

501 lines
15 KiB
GDScript

#
# Copyright (C) 2018 Sage Vaillancourt, sagev9000@gmail.com
#
# This file is part of Fronter.
#
# Fronter is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Fronter is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Fronter. If not, see <http://www.gnu.org/licenses/>.
#
extends Node
export (PackedScene) var FirstBad
export (PackedScene) var BlobBad
export (PackedScene) var LaserBad
export (PackedScene) var Prison
export (PackedScene) var RectangleBoss
export (PackedScene) var RectangleReturn
export (PackedScene) var BlackHole
var players = {}
var position = Vector2(200, 200)
var bads_this_round = 0
var upgrade_cost = 50
var booting = true
var screen_flashing = false
var rectangle_opacity = 1
var bad_spawning_enabled = true
var player_info
var touchy_shooty = false
var my_info = { name = "sagethesagesage", color = "FFFFFF" }
var mainmenu
var current_round = 1
var spawning_done = false
var not_loading = false
func _ready():
# Prepare black rectangle for fading in
$ColorRect.visible = true
if OS.has_touchscreen_ui_hint():
$HowTos/HowTo.visible = true
else:
$HowTos/HowToDesktop.visible = true
# Launch the main menu on boot and pause the game
mainmenu = preload("res://MainMenu.tscn").instance()
add_child(mainmenu)
mainmenu.connect("multiplayer_menu", self, "_open_multiplayer_menu")
mainmenu.connect("start_game", self, "rounds")
get_tree().paused = true
# Seed randi for randomizing enemy spawn locations
randomize()
updatePoints()
const DEFAULT_SPAWN_SPEED = 5
func rounds(round_number):
$BG.visible = true
##### WEAKER, LESS VALUABLE ENEMIES, AT HIGHER VOLUME, MAY BE MORE ENGAGING
# health, time, bad1s, badblobs, badlasers, badprisons
match round_number:
1:
roundOfEnemies(.6,DEFAULT_SPAWN_SPEED*.75,5,0,0,0) # default
#roundOfEnemies(0.1,DEFAULT_SPAWN_SPEED,1,0,0,0)
rpc("set_wave_name", "Wave 1: Learning to fly")
2:
roundOfEnemies(.6,DEFAULT_SPAWN_SPEED*.75,4,1,0,0)
#if get_tree().is_network_server() == true:
# rpc("bossMode", 0)
#else:
#bossMode(2)
rpc("set_wave_name", "Wave 2: Any colour you like")
3:
roundOfEnemies(.6,DEFAULT_SPAWN_SPEED*.75,8,2,0,0)
rpc("set_wave_name", "Wave 3: Money")
4:
roundOfEnemies(.6,DEFAULT_SPAWN_SPEED*.75,12,3,1,0)
rpc("set_wave_name", "Wave 4: YOU CAN BLOCK ENEMY LASERS WITH YOUR SHIP")
5:
roundOfEnemies(.6,DEFAULT_SPAWN_SPEED*.5,15,3,0,0)
rpc("set_wave_name", "Wave 5: One of These Days")
6:
roundOfEnemies(.7,DEFAULT_SPAWN_SPEED*.5,18,6,1,0)
rpc("set_wave_name", "Wave 6: Seamus")
7:
roundOfEnemies(.8,DEFAULT_SPAWN_SPEED*.5,21,7,1,0)
rpc("set_wave_name", "Wave 7: ")
8:
roundOfEnemies(.8,DEFAULT_SPAWN_SPEED*.75/(8/4),20,6,0,floor(8/8))
rpc("set_wave_name", "Wave 8: Free Four")
9:
roundOfEnemies(.9, DEFAULT_SPAWN_SPEED*(0.5), 9*3, 9, floor(9/4), floor(9/8))
rpc("set_wave_name", str("Wave 9"))
10:
rpc("set_wave_name", "Wave 10: What do you want from me?")
if get_tree().is_network_server() == true:
rpc("bossMode", 0)
else:
bossMode(0)
11:
roundOfEnemies(1,DEFAULT_SPAWN_SPEED*.75/(11/4),11*3,11,floor(11/4),floor(11/8))
$WaveLabel.text = str("Wave ", 11)
$BG/Sun.visible = true
15:
rpc("set_wave_name", "Wave 15: Eclipse")
if get_tree().is_network_server() == true:
rpc("bossMode", 1)
else:
bossMode(1)
20:
roundOfEnemies((1+(20-11)/10), (DEFAULT_SPAWN_SPEED*(0.5)), 20*3, 20, floor(20/4), floor(20/8))
var roundNo:
############### health ##### spawn speed #################### bad1s#### blobs # lasers ######### prisons ######
roundOfEnemies((1+(roundNo-11)/10), (DEFAULT_SPAWN_SPEED*(0.5)), roundNo*3, roundNo, floor(roundNo/4), floor(roundNo/8))
rpc("set_wave_name", str("Wave ", roundNo))
### Wave names ###
### on rectangle's return: The Hero's Return
### on Black boss appearance: Eclipse
sync func set_wave_name(name):
$WaveLabel.text = str(name)
# Open the multiplayer section of the menu and pause the game
func _open_multiplayer_menu():
var multiplayer = preload("res://Networking.tscn").instance()
multiplayer.connect("player_info", self, "_load_players")
multiplayer.connect("start_multiplayer_game", self, "_start_multiplayer_game")
add_child(multiplayer)
multiplayer.setName(my_info.name)
get_tree().paused = true
func _process(delta):
# If L+R+A+Start is pressed on a controller, quit
if (Input.is_action_pressed("ctlr_l")):
if (Input.is_action_pressed("ctlr_r")):
if (Input.is_action_pressed("ctlr_a")):
if (Input.is_action_pressed("ctlr_start")):
get_tree().quit()
# If the quit button is pressed, do it
if (Input.is_action_pressed("ui_quit")):
get_tree().quit()
if Input.is_action_pressed("ui_right") || Input.is_action_pressed("ui_left"):
_on_HideHowTo_pressed()
if Input.is_action_pressed("ui_down") || Input.is_action_pressed("ui_up"):
_on_HideHowTo_pressed()
if Input.is_action_pressed("ui_accept"):
_on_HideHowTo_pressed()
# If you're in multiplayer,
if get_tree().has_network_peer():
# and not the host
if !get_tree().is_network_server():
# Stop spawning bads
#$BaddieTimer.stop()
pass
if (touchy_feely && (abs(touchy_feely.position.x - $Player.position.x) > 1)):
if (touchy_feely.position.x < 800):
$Player.moveto(touchy_feely.position)
if (touchy_shooty && $Player.can_shoot):
$Player.shoot()
# If we're in the booting process, fade out the rectangle
if booting == true:
$ColorRect.color = Color(0, 0, 0, rectangle_opacity)
rectangle_opacity -= delta/1.25
if rectangle_opacity <= 0:
booting = false
$ColorRect.visible = false
$Music.playing = true
# Flash the screen white
if screen_flashing == true:
$ColorRect.color = Color(1, 1, 1, rectangle_opacity)
rectangle_opacity -= delta/3
if rectangle_opacity <= 0:
screen_flashing = false
$ColorRect.visible = false
# When an enemy dies
func _on_bad_death(kill_money):
# Give players appropriate money
$Player.money += kill_money
updatePoints()
print(current_round)
if get_tree().is_network_server() || not get_tree().has_network_peer():
if get_tree().get_nodes_in_group("enemies").size() == 1 && spawning_done == true:
rpc("openPlayerMenu")
current_round +=1
sync func openPlayerMenu():
$Player.upgradeMenu()
func startNextRound():
if get_tree().is_network_server() || not get_tree().has_network_peer():
rounds(current_round)
func roundOfEnemies(bad_health_multi, spawn_time, bad1s, badblobs, badlasers, badprisons):
spawning_done = false
# each enemy type comes in as an integer
# randomly dole out enemies until each is at 0
yield(get_tree().create_timer(1), "timeout")
var enemiesToBeSpawned = bad1s+badblobs+badlasers+badprisons
if enemiesToBeSpawned == 0:
return false
var bad_type
var badposition = Vector2()
while enemiesToBeSpawned > 0:
var nextEnemy = randi()%5
if (nextEnemy == 0 || nextEnemy == 4) && bad1s > 0 && get_tree().paused == false:
bad_type = 0
bad1s -= 1
yield(get_tree().create_timer(spawn_time), "timeout")
elif (nextEnemy == 1) && badblobs > 0 && get_tree().paused == false:
bad_type = 1
badblobs -= 1
yield(get_tree().create_timer(spawn_time), "timeout")
elif (nextEnemy == 2) && badlasers > 0 && get_tree().paused == false:
bad_type = 2
badlasers -= 1
yield(get_tree().create_timer(spawn_time), "timeout")
elif (nextEnemy == 3) && badprisons > 0 && get_tree().paused == false:
bad_type = 3
badprisons -= 1
yield(get_tree().create_timer(spawn_time), "timeout")
else: bad_type = 50000
enemiesToBeSpawned = bad1s+badblobs+badlasers+badprisons
if get_tree().paused == true:
yield(get_tree().create_timer(1), "timeout")
if bad_type < 50000:
badposition.x = 1100
badposition.y = (randi()%410) + 50
rpc("spawnBad", bad_type, badposition, bad_health_multi)
spawning_done = true
#$Player.upgradeMenu()
func upgradeTurret(position):
print("upgradeTurret()")
rpc("remoteUpgradeTurret", position)
####################
# UPGRADE A TURRET #
remote func remoteUpgradeTurret(position):
for child in get_children():
if "turret" in child.get_name():
print("turret")
if child.position == position:
child.upgradeTurret()
#child.damage = damage
#child.get_node("Range").scale = t_range
#child.get_node("ReloadTimer").wait_time = reload_time
print(child.damage, child.get_node("Range").scale, child.get_node("ReloadTimer").wait_time)
break
# UPGRADE A TURRET #
####################
#########################
# ENEMY SPAWNING SCRIPT #
#########################
var bad_health_multi = 1.5
sync func spawnBad(bad_type, badposition, health_multi):
var bad
if bad_type == 0:
bad = FirstBad.instance()
if bad_type == 1:
bad = BlobBad.instance()
if bad_type == 2:
bad = LaserBad.instance()
if bad_type == 3:
bad = Prison.instance()
# Increase BG speed with each enemy spawned
$BG.fly_speed *= 1.01
add_child(bad)
bad.connect("dead", self, "_on_bad_death")
if bad_type == 3:
bad.connect("health_up", self, "_on_health_up")
bad.health_multi = health_multi
bad.position = badposition
func _on_health_up(hp_increase):
$Mothership.health += hp_increase
$Mothership._update_health_bar()
func _on_PauseButton_pressed():
$Player.pauseMenu()
$ColorRect.visible = false
func updatePoints():
$MoneyDisplay.text = str("$", $Player.money)
#$MoneyDisplay.text = str($Player.money, " points")
func _on_Mothership_game_over():
for child in self.get_children():
print(child, child.name)
if ("Bad" in child.name):
child.queue_free()
elif (child.has_method("bossHealth")):
child.queue_free()
$Player.gameOver()
func _on_Player_restart_game():
print("_on_Player_restart_game()")
"""
for child in self.get_children():
print(child, child.name)
if ("Bad" in child.name):
child.queue_free()
elif (child.has_method("bossHealth")):
child.queue_free()"""
current_round = 1
spawning_done = true
updatePoints()
if get_tree().is_network_server() || not get_tree().has_network_peer():
rpc("hideGameOver")
rpc("openPlayerMenu")
remote func hideGameOver():
$Player.restart_game()
var touchy_feely
var touchscreen_on = false
func _input(event):
if (event is InputEventScreenTouch || event is InputEventScreenDrag):
touchscreen_on = true
if event.position.x < 800:
$Player.position.x = event.position.x + 100*(event.position.x/800)
$Player.position.y = event.position.y - 100
else:
touchy_shooty = true
func other_shooting_upgrade(id, other_bullet_delay):
prints("Other player shooting speed upgrade")
get_node(str(id)).timer.set_wait_time(other_bullet_delay)
func other_damage_upgrade(id, other_laser_damage):
get_node(str(id)).laser_damage = other_laser_damage
func other_laser_penetration_upgrade(id, other_laser_penetration):
get_node(str(id)).laser_penetration = other_laser_penetration
func other_ship_color_change(id, other_color):
prints("Other player color change")
get_node(str(id)).modulate(other_color)
func double_laser_upgrade(id):
prints("Double laser upgrade for", id)
get_node(str(id)).double_laser = true
# Show other player's movement
func _on_Player_multiplayer_movement(id, pos, other_is_shooting):
get_node(str(id)).position = pos
get_node(str(id)).is_shooting = other_is_shooting
# BOSS MODE #
# Disable enemy spawning
# Wait a few seconds for enemies to clear
# Call for boss launch
var bosstimer = null
sync func bossMode(boss_type):
prints("bossMode()")
bosstimer = Timer.new()
"""bosstimer.connect("timeout",self,"_launch_boss", boss_type)
add_child(bosstimer) #to process
bosstimer.wait_time = 3
bosstimer.one_shot = true
bosstimer.start() #to start"""
yield(get_tree().create_timer(3), "timeout")
prints("_launch_boss(",boss_type,")")
var bad
if boss_type == 0:
bad = RectangleBoss.instance()
elif boss_type == 1:
bad = BlackHole.instance()
elif boss_type == 2:
bad = RectangleReturn.instance()
$Music.volume_db = -40
add_child(bad)
# Flash screen when signalled
bad.connect("flash", self, "_flash_screen")
bad.show_behind_parent = true
# Boss death functions the same as regular death
bad.connect("dead", self, "_on_boss_death")
# Get boss health
bad.connect("boss_health", self, "getBossHealth")
"""
# Spawn the first boss
func _launch_boss(boss_type):
prints("_launch_boss(",boss_type,")")
var bad
if boss_type == 0:
bad = RectangleBoss.instance()
elif boss_type == 1:
bad = BlackHole.instance()
$Music.volume_db = -20
add_child(bad)
# Flash screen when signalled
bad.connect("flash", self, "_flash_screen")
bad.show_behind_parent = true
# Boss death functions the same as regular death
bad.connect("dead", self, "_on_boss_death")
# Get boss health
bad.connect("boss_health", self, "getBossHealth")
"""
func getBossHealth(currentHealth, totalHealth):
totalHealth = float(totalHealth)
var health_bar = Vector2(((currentHealth/totalHealth)*800)+100, 50)
$BossHealth.set_point_position(1, health_bar)
$BossHealth.default_color.a = 1
if currentHealth <= 0:
$BossHealth.default_color.a = 0
pass
# Currently same as regular enemy death
func _on_boss_death(kill_money):
# Give players appropriate money, and restart spawns
$Player.money += kill_money
updatePoints()
bad_spawning_enabled = true
bosstimer.stop()
rpc("openPlayerMenu")
current_round +=1
$Music.volume_db = 0
# Begins screen-flashing process
func _flash_screen():
prints("_flash_screen")
screen_flashing = true
rectangle_opacity = 1
$ColorRect.visible = true
func _load_players(id, info):
player_info = info
prints("_load_players", player_info)
func _start_multiplayer_game():
print(player_info)
mainmenu.now_quitting = true
for peer_id in player_info:
if peer_id != get_tree().get_network_unique_id():
var player = preload("res://OtherPlayer.tscn").instance()
player.set_name(str(peer_id))
prints(str(peer_id), "yeetert")
add_child(player)
player.setUsername(player_info[peer_id].name)
if get_tree().is_network_server():
rounds(1)
func _on_HideHowTo_pressed():
$HowTos.visible = false
func _on_Player_other_ship_enable_rainbow(id):
prints("Other player entered rainbow mode")
get_node(str(id)).enable_the_rainbow()
func _on_Player_buy_turret(id, turret_position):
print("Main:buyTurret", turret_position)
var turret = preload("res://Turret.tscn").instance()
turret.connect("upgrade_turret", self, "upgradeTurret")
turret.set_name(str(id,"turret"))
add_child(turret)
turret.position = turret_position
turret.scale.x = 0.25
turret.scale.y = 0.25