diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c872d52
--- /dev/null
+++ b/README.md
@@ -0,0 +1,53 @@
+SFMechSimulator
+===============
+
+_A pseudo 3D Mech Simulator created with C++ and SFML_
+
+Pilot a giant robot and battle other giant robots in a psuedo 3D environment.
+Repair and upgrade your mech between missions.
+Carefully select upgrades and develop winning strategies in combat.
+
+
+
+**Compiling**
+
+_Windows:_
+
+Download SFML and GCC here https://www.sfml-dev.org/download/sfml/2.5.1/
+You will need 'MinGW Builds 7.3.0 (64-bit)' and SFML 'GCC 7.3.0 MinGW (SEH) - 64-bit'
+For 32 bit systems you will need 'MinGW Builds 7.3.0 (32-bit)' and 'GCC 7.3.0 MinGW (DW2) - 32-bit'
+
+Clone this repository to C:\ so the source code is present at C:\SFMechSimulator
+Extract the downloaded SFML package to C:\ so SFML is present at C:\SFML-2.5.1
+Run the compile_windows.bat script
+Run SFMechSimulator.exe to play the game
+To run the game in a window, use the command line argument '-window'
+ie: 'SFMechSimulator.exe -window 1280 720'
+The window cannot be smaller than 1280x720
+
+_Mac:_
+
+Clone this repository.
+Install g++ as described here http://www.edparrish.net/common/macgpp.php#installg++
+Download SFML here https://www.sfml-dev.org/download/sfml/2.5.1/
+Copy the contents of the SFML Frameworks and extlibs directories to /Library/Frameworks
+Run the compile_mac.sh script
+Run the SFMechSimulator executable to play the game
+To run the game in a window, use the command line argument '-window'
+ie: './SFMechSimulator -window 1280 720'
+The window cannot be smaller than 1280x720
+
+_Linux:_
+
+Clone this repository.
+Install SFML, ie: 'sudo apt-get install libsfml-dev'
+Run the compile_linux.sh script
+Run the SFMechSimulator executable to play the game
+To run the game in a window, use the command line argument '-window'
+ie: './SFMechSimulator -window 1280 720'
+The window cannot be smaller than 1280x720
+
+**Playing the Game**
+
+Click the 'NEW GAME' button at the main menu
+Press F1 to start the tutorial
diff --git a/assets/Exoplanetaria-gxxJ5.ttf b/assets/Exoplanetaria-gxxJ5.ttf
new file mode 100644
index 0000000..a2a07c6
Binary files /dev/null and b/assets/Exoplanetaria-gxxJ5.ttf differ
diff --git a/assets/Orbitron Medium.ttf b/assets/Orbitron Medium.ttf
new file mode 100644
index 0000000..88499ff
Binary files /dev/null and b/assets/Orbitron Medium.ttf differ
diff --git a/assets/sounds/cannon.ogg b/assets/sounds/cannon.ogg
new file mode 100644
index 0000000..f60b7d4
Binary files /dev/null and b/assets/sounds/cannon.ogg differ
diff --git a/assets/sounds/crash.ogg b/assets/sounds/crash.ogg
new file mode 100644
index 0000000..36d0a0f
Binary files /dev/null and b/assets/sounds/crash.ogg differ
diff --git a/assets/sounds/explosion.ogg b/assets/sounds/explosion.ogg
new file mode 100644
index 0000000..1756a73
Binary files /dev/null and b/assets/sounds/explosion.ogg differ
diff --git a/assets/sounds/guns.ogg b/assets/sounds/guns.ogg
new file mode 100644
index 0000000..6bb1030
Binary files /dev/null and b/assets/sounds/guns.ogg differ
diff --git a/assets/sounds/hydraulic.ogg b/assets/sounds/hydraulic.ogg
new file mode 100644
index 0000000..2d73d5c
Binary files /dev/null and b/assets/sounds/hydraulic.ogg differ
diff --git a/assets/sounds/impact.ogg b/assets/sounds/impact.ogg
new file mode 100644
index 0000000..7ef6c47
Binary files /dev/null and b/assets/sounds/impact.ogg differ
diff --git a/assets/sounds/intermission_menu.ogg b/assets/sounds/intermission_menu.ogg
new file mode 100644
index 0000000..3d7e2d9
Binary files /dev/null and b/assets/sounds/intermission_menu.ogg differ
diff --git a/assets/sounds/main_menu.ogg b/assets/sounds/main_menu.ogg
new file mode 100644
index 0000000..4d6cb03
Binary files /dev/null and b/assets/sounds/main_menu.ogg differ
diff --git a/assets/sounds/mission.ogg b/assets/sounds/mission.ogg
new file mode 100644
index 0000000..dd05ccb
Binary files /dev/null and b/assets/sounds/mission.ogg differ
diff --git a/assets/sounds/power_down.ogg b/assets/sounds/power_down.ogg
new file mode 100644
index 0000000..e30698b
Binary files /dev/null and b/assets/sounds/power_down.ogg differ
diff --git a/assets/sounds/power_up.ogg b/assets/sounds/power_up.ogg
new file mode 100644
index 0000000..a4e213e
Binary files /dev/null and b/assets/sounds/power_up.ogg differ
diff --git a/assets/sounds/purchase.ogg b/assets/sounds/purchase.ogg
new file mode 100644
index 0000000..8cb70e1
Binary files /dev/null and b/assets/sounds/purchase.ogg differ
diff --git a/assets/sounds/stomp.ogg b/assets/sounds/stomp.ogg
new file mode 100644
index 0000000..1fd7889
Binary files /dev/null and b/assets/sounds/stomp.ogg differ
diff --git a/assets/sounds/victory.ogg b/assets/sounds/victory.ogg
new file mode 100644
index 0000000..2c04c4e
Binary files /dev/null and b/assets/sounds/victory.ogg differ
diff --git a/assets/textures/buttons/cancel_button.png b/assets/textures/buttons/cancel_button.png
new file mode 100644
index 0000000..f71cba5
Binary files /dev/null and b/assets/textures/buttons/cancel_button.png differ
diff --git a/assets/textures/buttons/cancel_button_hover.png b/assets/textures/buttons/cancel_button_hover.png
new file mode 100644
index 0000000..4edf747
Binary files /dev/null and b/assets/textures/buttons/cancel_button_hover.png differ
diff --git a/assets/textures/buttons/create_new_button.png b/assets/textures/buttons/create_new_button.png
new file mode 100644
index 0000000..614b8f3
Binary files /dev/null and b/assets/textures/buttons/create_new_button.png differ
diff --git a/assets/textures/buttons/create_new_button_hover.png b/assets/textures/buttons/create_new_button_hover.png
new file mode 100644
index 0000000..a3346e7
Binary files /dev/null and b/assets/textures/buttons/create_new_button_hover.png differ
diff --git a/assets/textures/buttons/exit_game_button.png b/assets/textures/buttons/exit_game_button.png
new file mode 100644
index 0000000..dd1e6b5
Binary files /dev/null and b/assets/textures/buttons/exit_game_button.png differ
diff --git a/assets/textures/buttons/exit_game_button_hover.png b/assets/textures/buttons/exit_game_button_hover.png
new file mode 100644
index 0000000..0036648
Binary files /dev/null and b/assets/textures/buttons/exit_game_button_hover.png differ
diff --git a/assets/textures/buttons/load_button.png b/assets/textures/buttons/load_button.png
new file mode 100644
index 0000000..e2a3bfe
Binary files /dev/null and b/assets/textures/buttons/load_button.png differ
diff --git a/assets/textures/buttons/load_button_hover.png b/assets/textures/buttons/load_button_hover.png
new file mode 100644
index 0000000..ec11f6b
Binary files /dev/null and b/assets/textures/buttons/load_button_hover.png differ
diff --git a/assets/textures/buttons/main_menu_button.png b/assets/textures/buttons/main_menu_button.png
new file mode 100644
index 0000000..34985cb
Binary files /dev/null and b/assets/textures/buttons/main_menu_button.png differ
diff --git a/assets/textures/buttons/main_menu_button_hover.png b/assets/textures/buttons/main_menu_button_hover.png
new file mode 100644
index 0000000..b810022
Binary files /dev/null and b/assets/textures/buttons/main_menu_button_hover.png differ
diff --git a/assets/textures/buttons/market_button.png b/assets/textures/buttons/market_button.png
new file mode 100644
index 0000000..2625193
Binary files /dev/null and b/assets/textures/buttons/market_button.png differ
diff --git a/assets/textures/buttons/market_button_hover.png b/assets/textures/buttons/market_button_hover.png
new file mode 100644
index 0000000..465743a
Binary files /dev/null and b/assets/textures/buttons/market_button_hover.png differ
diff --git a/assets/textures/buttons/next_mission_button.png b/assets/textures/buttons/next_mission_button.png
new file mode 100644
index 0000000..e490899
Binary files /dev/null and b/assets/textures/buttons/next_mission_button.png differ
diff --git a/assets/textures/buttons/next_mission_button_hover.png b/assets/textures/buttons/next_mission_button_hover.png
new file mode 100644
index 0000000..dd81920
Binary files /dev/null and b/assets/textures/buttons/next_mission_button_hover.png differ
diff --git a/assets/textures/buttons/options_button.png b/assets/textures/buttons/options_button.png
new file mode 100644
index 0000000..394867d
Binary files /dev/null and b/assets/textures/buttons/options_button.png differ
diff --git a/assets/textures/buttons/options_button_hover.png b/assets/textures/buttons/options_button_hover.png
new file mode 100644
index 0000000..7e0c466
Binary files /dev/null and b/assets/textures/buttons/options_button_hover.png differ
diff --git a/assets/textures/buttons/repair_button.png b/assets/textures/buttons/repair_button.png
new file mode 100644
index 0000000..523fd84
Binary files /dev/null and b/assets/textures/buttons/repair_button.png differ
diff --git a/assets/textures/buttons/repair_button_hover.png b/assets/textures/buttons/repair_button_hover.png
new file mode 100644
index 0000000..2f33c0e
Binary files /dev/null and b/assets/textures/buttons/repair_button_hover.png differ
diff --git a/assets/textures/buttons/save_button.png b/assets/textures/buttons/save_button.png
new file mode 100644
index 0000000..32e731c
Binary files /dev/null and b/assets/textures/buttons/save_button.png differ
diff --git a/assets/textures/buttons/save_button_hover.png b/assets/textures/buttons/save_button_hover.png
new file mode 100644
index 0000000..f4c4f90
Binary files /dev/null and b/assets/textures/buttons/save_button_hover.png differ
diff --git a/assets/textures/buttons/start_game_button.png b/assets/textures/buttons/start_game_button.png
new file mode 100644
index 0000000..3ae1132
Binary files /dev/null and b/assets/textures/buttons/start_game_button.png differ
diff --git a/assets/textures/buttons/start_game_button_hover.png b/assets/textures/buttons/start_game_button_hover.png
new file mode 100644
index 0000000..f24afd8
Binary files /dev/null and b/assets/textures/buttons/start_game_button_hover.png differ
diff --git a/assets/textures/cockpit/cockpit.bmp b/assets/textures/cockpit/cockpit.bmp
new file mode 100644
index 0000000..c8e3573
Binary files /dev/null and b/assets/textures/cockpit/cockpit.bmp differ
diff --git a/assets/textures/cockpit/cockpit_cannon.bmp b/assets/textures/cockpit/cockpit_cannon.bmp
new file mode 100644
index 0000000..94e0d76
Binary files /dev/null and b/assets/textures/cockpit/cockpit_cannon.bmp differ
diff --git a/assets/textures/cockpit/cockpit_cannon_left.bmp b/assets/textures/cockpit/cockpit_cannon_left.bmp
new file mode 100644
index 0000000..fb86b4a
Binary files /dev/null and b/assets/textures/cockpit/cockpit_cannon_left.bmp differ
diff --git a/assets/textures/cockpit/cockpit_cannon_right.bmp b/assets/textures/cockpit/cockpit_cannon_right.bmp
new file mode 100644
index 0000000..9a1193f
Binary files /dev/null and b/assets/textures/cockpit/cockpit_cannon_right.bmp differ
diff --git a/assets/textures/cockpit/cockpit_destroyed.bmp b/assets/textures/cockpit/cockpit_destroyed.bmp
new file mode 100644
index 0000000..416448b
Binary files /dev/null and b/assets/textures/cockpit/cockpit_destroyed.bmp differ
diff --git a/assets/textures/cockpit/cockpit_fire.bmp b/assets/textures/cockpit/cockpit_fire.bmp
new file mode 100644
index 0000000..5efd6d7
Binary files /dev/null and b/assets/textures/cockpit/cockpit_fire.bmp differ
diff --git a/assets/textures/cockpit/cockpit_fire_left.bmp b/assets/textures/cockpit/cockpit_fire_left.bmp
new file mode 100644
index 0000000..1853644
Binary files /dev/null and b/assets/textures/cockpit/cockpit_fire_left.bmp differ
diff --git a/assets/textures/cockpit/cockpit_fire_right.bmp b/assets/textures/cockpit/cockpit_fire_right.bmp
new file mode 100644
index 0000000..d465c37
Binary files /dev/null and b/assets/textures/cockpit/cockpit_fire_right.bmp differ
diff --git a/assets/textures/cockpit/cockpit_impact.bmp b/assets/textures/cockpit/cockpit_impact.bmp
new file mode 100644
index 0000000..de5448f
Binary files /dev/null and b/assets/textures/cockpit/cockpit_impact.bmp differ
diff --git a/assets/textures/crosshair.png b/assets/textures/crosshair.png
new file mode 100644
index 0000000..2383545
Binary files /dev/null and b/assets/textures/crosshair.png differ
diff --git a/assets/textures/ground.bmp b/assets/textures/ground.bmp
new file mode 100644
index 0000000..48ca6f6
Binary files /dev/null and b/assets/textures/ground.bmp differ
diff --git a/assets/textures/ground_2.bmp b/assets/textures/ground_2.bmp
new file mode 100644
index 0000000..6ae18c4
Binary files /dev/null and b/assets/textures/ground_2.bmp differ
diff --git a/assets/textures/gui_background.png b/assets/textures/gui_background.png
new file mode 100644
index 0000000..a0fc4c9
Binary files /dev/null and b/assets/textures/gui_background.png differ
diff --git a/assets/textures/gui_background_2.png b/assets/textures/gui_background_2.png
new file mode 100644
index 0000000..7ac9a0e
Binary files /dev/null and b/assets/textures/gui_background_2.png differ
diff --git a/assets/textures/mech/explosion.png b/assets/textures/mech/explosion.png
new file mode 100644
index 0000000..a9f280a
Binary files /dev/null and b/assets/textures/mech/explosion.png differ
diff --git a/assets/textures/mech/mech.bmp b/assets/textures/mech/mech.bmp
new file mode 100644
index 0000000..c1b75a5
Binary files /dev/null and b/assets/textures/mech/mech.bmp differ
diff --git a/assets/textures/mech/mech_cannon_fire.bmp b/assets/textures/mech/mech_cannon_fire.bmp
new file mode 100644
index 0000000..e2f5c31
Binary files /dev/null and b/assets/textures/mech/mech_cannon_fire.bmp differ
diff --git a/assets/textures/mech/mech_cannon_left.bmp b/assets/textures/mech/mech_cannon_left.bmp
new file mode 100644
index 0000000..3f77b16
Binary files /dev/null and b/assets/textures/mech/mech_cannon_left.bmp differ
diff --git a/assets/textures/mech/mech_cannon_right.bmp b/assets/textures/mech/mech_cannon_right.bmp
new file mode 100644
index 0000000..e8940b9
Binary files /dev/null and b/assets/textures/mech/mech_cannon_right.bmp differ
diff --git a/assets/textures/mech/mech_fire.bmp b/assets/textures/mech/mech_fire.bmp
new file mode 100644
index 0000000..7f12a1e
Binary files /dev/null and b/assets/textures/mech/mech_fire.bmp differ
diff --git a/assets/textures/mech/mech_fire_left.bmp b/assets/textures/mech/mech_fire_left.bmp
new file mode 100644
index 0000000..218950b
Binary files /dev/null and b/assets/textures/mech/mech_fire_left.bmp differ
diff --git a/assets/textures/mech/mech_fire_right.bmp b/assets/textures/mech/mech_fire_right.bmp
new file mode 100644
index 0000000..8474994
Binary files /dev/null and b/assets/textures/mech/mech_fire_right.bmp differ
diff --git a/assets/textures/mech/mech_hit.bmp b/assets/textures/mech/mech_hit.bmp
new file mode 100644
index 0000000..1e67764
Binary files /dev/null and b/assets/textures/mech/mech_hit.bmp differ
diff --git a/assets/textures/mech/mech_hit_center.bmp b/assets/textures/mech/mech_hit_center.bmp
new file mode 100644
index 0000000..1e67764
Binary files /dev/null and b/assets/textures/mech/mech_hit_center.bmp differ
diff --git a/assets/textures/mech/mech_hit_cockpit.bmp b/assets/textures/mech/mech_hit_cockpit.bmp
new file mode 100644
index 0000000..6e70a7d
Binary files /dev/null and b/assets/textures/mech/mech_hit_cockpit.bmp differ
diff --git a/assets/textures/mech/mech_hit_left_arm.bmp b/assets/textures/mech/mech_hit_left_arm.bmp
new file mode 100644
index 0000000..7118085
Binary files /dev/null and b/assets/textures/mech/mech_hit_left_arm.bmp differ
diff --git a/assets/textures/mech/mech_hit_left_leg.bmp b/assets/textures/mech/mech_hit_left_leg.bmp
new file mode 100644
index 0000000..476ba7c
Binary files /dev/null and b/assets/textures/mech/mech_hit_left_leg.bmp differ
diff --git a/assets/textures/mech/mech_hit_right_arm.bmp b/assets/textures/mech/mech_hit_right_arm.bmp
new file mode 100644
index 0000000..beb62ed
Binary files /dev/null and b/assets/textures/mech/mech_hit_right_arm.bmp differ
diff --git a/assets/textures/mech/mech_hit_right_leg.bmp b/assets/textures/mech/mech_hit_right_leg.bmp
new file mode 100644
index 0000000..69702a2
Binary files /dev/null and b/assets/textures/mech/mech_hit_right_leg.bmp differ
diff --git a/assets/textures/mech_repair.png b/assets/textures/mech_repair.png
new file mode 100644
index 0000000..27c1bbc
Binary files /dev/null and b/assets/textures/mech_repair.png differ
diff --git a/assets/textures/mech_repair_spark_1.png b/assets/textures/mech_repair_spark_1.png
new file mode 100644
index 0000000..75f5276
Binary files /dev/null and b/assets/textures/mech_repair_spark_1.png differ
diff --git a/assets/textures/mech_repair_spark_2.png b/assets/textures/mech_repair_spark_2.png
new file mode 100644
index 0000000..95220cf
Binary files /dev/null and b/assets/textures/mech_repair_spark_2.png differ
diff --git a/assets/textures/mech_status.bmp b/assets/textures/mech_status.bmp
new file mode 100644
index 0000000..1f8f2ea
Binary files /dev/null and b/assets/textures/mech_status.bmp differ
diff --git a/assets/textures/menu_background.png b/assets/textures/menu_background.png
new file mode 100644
index 0000000..0ddb3fb
Binary files /dev/null and b/assets/textures/menu_background.png differ
diff --git a/assets/textures/mob_icon.png b/assets/textures/mob_icon.png
new file mode 100644
index 0000000..cf0c3af
Binary files /dev/null and b/assets/textures/mob_icon.png differ
diff --git a/assets/textures/player_icon.png b/assets/textures/player_icon.png
new file mode 100644
index 0000000..bbf427e
Binary files /dev/null and b/assets/textures/player_icon.png differ
diff --git a/assets/textures/sky.bmp b/assets/textures/sky.bmp
new file mode 100644
index 0000000..2974e26
Binary files /dev/null and b/assets/textures/sky.bmp differ
diff --git a/assets/textures/sky_2.png b/assets/textures/sky_2.png
new file mode 100644
index 0000000..cc46993
Binary files /dev/null and b/assets/textures/sky_2.png differ
diff --git a/assets/textures/target_gui_background.png b/assets/textures/target_gui_background.png
new file mode 100644
index 0000000..307e930
Binary files /dev/null and b/assets/textures/target_gui_background.png differ
diff --git a/assets/textures/target_icon.png b/assets/textures/target_icon.png
new file mode 100644
index 0000000..867862e
Binary files /dev/null and b/assets/textures/target_icon.png differ
diff --git a/assets/textures/term.bmp b/assets/textures/term.bmp
new file mode 100644
index 0000000..8ff9d72
Binary files /dev/null and b/assets/textures/term.bmp differ
diff --git a/assets/textures/tree.bmp b/assets/textures/tree.bmp
new file mode 100644
index 0000000..b9ee5b7
Binary files /dev/null and b/assets/textures/tree.bmp differ
diff --git a/assets/textures/tree_2.png b/assets/textures/tree_2.png
new file mode 100644
index 0000000..fb56c35
Binary files /dev/null and b/assets/textures/tree_2.png differ
diff --git a/assets/textures/tree_3.png b/assets/textures/tree_3.png
new file mode 100644
index 0000000..35ae26e
Binary files /dev/null and b/assets/textures/tree_3.png differ
diff --git a/assets/textures/tree_4.png b/assets/textures/tree_4.png
new file mode 100644
index 0000000..b06495c
Binary files /dev/null and b/assets/textures/tree_4.png differ
diff --git a/assets/textures/wall.bmp b/assets/textures/wall.bmp
new file mode 100644
index 0000000..64881ab
Binary files /dev/null and b/assets/textures/wall.bmp differ
diff --git a/assets/textures/wall_2.bmp b/assets/textures/wall_2.bmp
new file mode 100644
index 0000000..18a37fa
Binary files /dev/null and b/assets/textures/wall_2.bmp differ
diff --git a/assets/textures/wall_icon.png b/assets/textures/wall_icon.png
new file mode 100644
index 0000000..38eb512
Binary files /dev/null and b/assets/textures/wall_icon.png differ
diff --git a/bindings.list b/bindings.list
new file mode 100644
index 0000000..10f0ae1
--- /dev/null
+++ b/bindings.list
@@ -0,0 +1,16 @@
+throttle_up:W
+throttle_down:S
+turn_left:A
+turn_right:D
+look_left:Left
+look_right:Right
+look_up:Up
+look_down:Down
+fire_guns:Space
+fire_cannon:LControl
+lock_target:T
+select_component:C
+map:M
+show_tutorial:F1
+show_keys:F2
+show_fps:F3
diff --git a/compile_linux.sh b/compile_linux.sh
new file mode 100755
index 0000000..db0ad1d
--- /dev/null
+++ b/compile_linux.sh
@@ -0,0 +1,2 @@
+#! /bin/bash
+g++ main.cpp $PWD/src/settings_menu.cpp $PWD/src/cockpit.cpp $PWD/src/settings.cpp $PWD/src/market_menu.cpp $PWD/src/tutorial.cpp $PWD/src/key_bindings.cpp $PWD/src/assets.cpp $PWD/src/calc_helper.cpp $PWD/src/entity.cpp $PWD/src/file_handler.cpp $PWD/src/hud.cpp $PWD/src/intermission_menu.cpp $PWD/src/main_menu.cpp $PWD/src/mech.cpp $PWD/src/player_controller.cpp $PWD/src/world_generator.cpp -Iinclude -o SFMechSimulator -lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system
diff --git a/compile_mac.sh b/compile_mac.sh
new file mode 100755
index 0000000..15dcd90
--- /dev/null
+++ b/compile_mac.sh
@@ -0,0 +1,3 @@
+#! /bin/bash
+
+g++ -std=c++11 -F/Library/Frameworks -Iinclude -framework sfml-window -framework sfml-graphics -framework sfml-audio -framework sfml-system main.cpp $PWD/src/settings_menu.cpp $PWD/src/cockpit.cpp $PWD/src/settings.cpp $PWD/src/market_menu.cpp $PWD/src/tutorial.cpp $PWD/src/key_bindings.cpp $PWD/src/assets.cpp $PWD/src/calc_helper.cpp $PWD/src/entity.cpp $PWD/src/file_handler.cpp $PWD/src/hud.cpp $PWD/src/intermission_menu.cpp $PWD/src/main_menu.cpp $PWD/src/mech.cpp $PWD/src/player_controller.cpp $PWD/src/world_generator.cpp -o SFMechSimulator
diff --git a/compile_windows.bat b/compile_windows.bat
new file mode 100644
index 0000000..393e0cf
--- /dev/null
+++ b/compile_windows.bat
@@ -0,0 +1,18 @@
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\main.cpp -o obj\Release\main.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\assets.cpp -o obj\Release\src\assets.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\calc_helper.cpp -o obj\Release\src\calc_helper.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\cockpit.cpp -o obj\Release\src\cockpit.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\entity.cpp -o obj\Release\src\entity.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\file_handler.cpp -o obj\Release\src\file_handler.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\hud.cpp -o obj\Release\src\hud.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\intermission_menu.cpp -o obj\Release\src\intermission_menu.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\key_bindings.cpp -o obj\Release\src\key_bindings.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\main_menu.cpp -o obj\Release\src\main_menu.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\market_menu.cpp -o obj\Release\src\market_menu.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\mech.cpp -o obj\Release\src\mech.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\player_controller.cpp -o obj\Release\src\player_controller.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\settings.cpp -o obj\Release\src\settings.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\settings_menu.cpp -o obj\Release\src\settings_menu.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\tutorial.cpp -o obj\Release\src\tutorial.o
+g++.exe -Wall -O2 -IC:\SFML-2.5.1\include -Iinclude -Isrc -c C:\SFMechSimulator\src\world_generator.cpp -o obj\Release\src\world_generator.o
+g++.exe -LC:\SFML-2.5.1\lib -o bin\Release\SFMechSimulator.exe obj\Release\main.o obj\Release\src\assets.o obj\Release\src\calc_helper.o obj\Release\src\cockpit.o obj\Release\src\entity.o obj\Release\src\file_handler.o obj\Release\src\hud.o obj\Release\src\intermission_menu.o obj\Release\src\key_bindings.o obj\Release\src\main_menu.o obj\Release\src\market_menu.o obj\Release\src\mech.o obj\Release\src\player_controller.o obj\Release\src\settings.o obj\Release\src\settings_menu.o obj\Release\src\tutorial.o obj\Release\src\world_generator.o -s -lmingw32 -luser32 -lgdi32 -lwinmm -ldxguid -lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system -mwindows
diff --git a/credits.txt b/credits.txt
new file mode 100644
index 0000000..61c0726
--- /dev/null
+++ b/credits.txt
@@ -0,0 +1,30 @@
+main menu music: https://freesound.org/people/LittleRobotSoundFactory/sounds/274169/
+intermission music: https://freesound.org/people/szegvari/sounds/560746/
+mission music: https://freesound.org/people/FoolBoyMedia/sounds/270366/
+victory sound: https://freesound.org/people/joshuaempyre/sounds/404024/
+
+gun sound: https://freesound.org/people/CJDeets/sounds/476740/
+cannon sound: https://freesound.org/people/Kneeling/sounds/448002/
+power up sound: https://freesound.org/people/Breviceps/sounds/557593/
+power down sound: https://freesound.org/people/qubodup/sounds/222372/
+stomp sound: https://freesound.org/people/studiomandragore/sounds/401628/
+crash sound: https://freesound.org/people/qubodup/sounds/182429/
+impact sound: https://freesound.org/people/Oddworld/sounds/75328/
+hydraulic sound: https://freesound.org/people/eardeer/sounds/385083/
+
+mech sprite: https://opengameart.org/content/unit-666-mech
+dead tree sprites: https://opengameart.org/content/knarled-trees
+green tree sprites: https://opengameart.org/content/tree-collection-v26-bleeds-game-art
+cannon effect: https://opengameart.org/content/blue-fire-effect
+small explosion sprites: https://gaph.artstation.com/
+large explosion sprite: https://www.freepngimg.com/png/31556-atomic-explosion-transparent-background
+menu background and sky: https://free-images.com/lg/5434/planet_earth_moon_science.jpg
+welder: https://opengameart.org/content/16-bit-alien
+welding sparks: https://opengameart.org/content/spark-particles-set-of-8
+skull and bones: https://openclipart.org/image/400px/1010
+sky: https://svs.gsfc.nasa.gov/3895
+moon: https://www.publicdomainpictures.net/en/view-image.php?image=44955&picture=full-moon-at-midnight-close-up
+blue sky: https://www.pexels.com/photo/blue-and-white-sky-with-stars-4737484/
+
+orbitron font: https://www.1001freefonts.com/orbitron.font
+exoplanetaria font: https://www.fontspace.com/exoplanetaria-font-f41401
diff --git a/include/assets.h b/include/assets.h
new file mode 100644
index 0000000..84b5f4c
--- /dev/null
+++ b/include/assets.h
@@ -0,0 +1,182 @@
+#ifndef ASSETS_H
+#define ASSETS_H
+
+#include
+#include
+
+class assets
+{
+ public:
+ // Sounds
+ sf::SoundBuffer gun_sound_buffer;
+ sf::Sound gun_sound;
+
+ sf::SoundBuffer cannon_sound_buffer;
+ sf::Sound cannon_sound;
+
+ sf::SoundBuffer explo_sound_buffer;
+ sf::Sound explosion_sound;
+
+ sf::SoundBuffer hydraulic_sound_buffer;
+ sf::Sound hydraulic_sound;
+
+ sf::SoundBuffer stomp_sound_buffer;
+ sf::Sound stomp_sound;
+
+ sf::SoundBuffer crash_sound_buffer;
+ sf::Sound crash_sound;
+
+ sf::SoundBuffer impact_sound_buffer;
+ sf::Sound impact_sound;
+
+ sf::SoundBuffer power_down_sound_buffer;
+ sf::Sound power_down_sound;
+
+ sf::SoundBuffer power_up_sound_buffer;
+ sf::Sound power_up_sound;
+
+ sf::SoundBuffer purchase_sound_buffer;
+ sf::Sound purchase_sound;
+
+ sf::SoundBuffer main_menu_music_buffer;
+ sf::Sound main_menu_music;
+
+ sf::SoundBuffer intermission_music_buffer;
+ sf::Sound intermission_music;
+
+ sf::SoundBuffer mission_music_buffer;
+ sf::Sound mission_music;
+
+ sf::SoundBuffer victory_sound_buffer;
+ sf::Sound victory_sound;
+
+ // Textures
+ sf::Texture mech_status_texture;
+ sf::Texture mech_texture;
+ sf::Texture mech_fire_guns_texture;
+ sf::Texture mech_fire_guns_left_texture;
+ sf::Texture mech_fire_guns_right_texture;
+ sf::Texture mech_fire_cannons_texture;
+ sf::Texture mech_fire_cannons_left_texture;
+ sf::Texture mech_fire_cannons_right_texture;
+ sf::Texture mech_hit_center_texture;
+ sf::Texture mech_hit_left_leg_texture;
+ sf::Texture mech_hit_right_leg_texture;
+ sf::Texture mech_hit_left_arm_texture;
+ sf::Texture mech_hit_right_arm_texture;
+ sf::Texture mech_hit_cockpit_texture;
+ std::vector mech_textures;
+
+ sf::Texture cockpit_texture;
+ sf::Texture cockpit_fire_texture;
+ sf::Texture cockpit_fire_left_texture;
+ sf::Texture cockpit_fire_right_texture;
+ sf::Texture cockpit_cannon_texture;
+ sf::Texture cockpit_cannon_left_texture;
+ sf::Texture cockpit_cannon_right_texture;
+ sf::Texture cockpit_impact_texture;
+ sf::Texture cockpit_destroyed_texture;
+
+ sf::Texture explosion_texture;
+ sf::Texture crosshair_texture;
+ sf::Texture ground_texture;
+ sf::Texture ground_2_texture;
+ sf::Sprite ground_sprite;
+ sf::Texture sky_texture;
+ sf::Texture sky_2_texture;
+ sf::Texture wall_texture;
+ sf::Texture wall_2_texture;
+ sf::Texture tree_texture;
+ sf::Texture tree_2_texture;
+ sf::Texture tree_3_texture;
+ sf::Texture tree_4_texture;
+ sf::Texture player_icon_texture;
+ sf::Texture mob_icon_texture;
+ sf::Texture target_icon_texture;
+ sf::Texture wall_icon_texture;
+
+ sf::Texture gui_background_texture;
+ sf::Texture gui_background_2_texture;
+ sf::Texture target_gui_background_texture;
+
+ sf::Texture menu_background_texture;
+ sf::Texture menu_mech_texture;
+ sf::Texture menu_mech_spark_1_texture;
+ sf::Texture menu_mech_spark_2_texture;
+ sf::Texture term_texture;
+
+ sf::Texture start_game_button_texture;
+ sf::Texture start_game_button_hover_texture;
+ sf::Texture main_menu_button_texture;
+ sf::Texture main_menu_button_hover_texture;
+ sf::Texture save_game_button_texture;
+ sf::Texture save_game_button_hover_texture;
+ sf::Texture load_game_button_texture;
+ sf::Texture load_game_button_hover_texture;
+ sf::Texture next_mission_button_texture;
+ sf::Texture next_mission_button_hover_texture;
+ sf::Texture repair_button_texture;
+ sf::Texture repair_button_hover_texture;
+ sf::Texture market_button_texture;
+ sf::Texture market_button_hover_texture;
+ sf::Texture exit_game_button_texture;
+ sf::Texture exit_game_button_hover_texture;
+ sf::Texture create_new_button_texture;
+ sf::Texture create_new_button_hover_texture;
+ sf::Texture cancel_button_texture;
+ sf::Texture cancel_button_hover_texture;
+ sf::Texture options_button_texture;
+ sf::Texture options_button_hover_texture;
+
+ // Sprites
+ sf::Sprite cockpit_sprite;
+ sf::Sprite sky_sprite;
+ sf::Sprite map_sprite;
+ sf::Sprite term_sprite;
+ sf::Sprite crosshair_sprite;
+ sf::Sprite player_icon;
+ sf::Sprite mob_icon;
+ sf::Sprite wall_icon;
+ sf::Sprite target_icon;
+
+ sf::Sprite start_game_button_sprite;
+ sf::Sprite main_menu_button_sprite;
+ sf::Sprite save_game_button_sprite;
+ sf::Sprite create_new_button_sprite;
+ sf::Sprite cancel_button_sprite;
+ sf::Sprite load_game_button_sprite;
+ sf::Sprite options_button_sprite;
+ sf::Sprite next_mission_button_sprite;
+ sf::Sprite repair_button_sprite;
+ sf::Sprite market_button_sprite;
+ sf::Sprite exit_game_button_sprite;
+ sf::Sprite menu_background_sprite;
+ sf::Sprite menu_mech_sprite;
+
+ // Fonts
+ sf::Font orbitron;
+ sf::Font exoplanetaria;
+
+ // Text Objects
+ sf::Text notice;
+ sf::Text keys;
+ sf::Text fps_counter;
+ sf::Text throttle_display;
+ sf::Text torso_display;
+ sf::Text input_text;
+ sf::Text mech_status;
+ sf::Text target_status;
+ sf::Text target_info;
+
+ void init(std::string cwd);
+
+ private:
+ void load_sound_buffers(std::string cwd);
+ void load_textures(std::string cwd);
+ void load_fonts(std::string cwd);
+ void init_sounds();
+ void init_sprites();
+ void init_text();
+};
+
+#endif // ASSETS_H
diff --git a/include/calc_helper.h b/include/calc_helper.h
new file mode 100644
index 0000000..bdc7b01
--- /dev/null
+++ b/include/calc_helper.h
@@ -0,0 +1,11 @@
+#ifndef CALC_HELPER_H
+#define CALC_HELPER_H
+
+#include
+
+float get_angle(sf::Vector2f v1, sf::Vector2f v2);
+float get_distance(sf::Vector2f v1, sf::Vector2f v2);
+sf::Vector2f get_midpoint(sf::Vector2f v1, sf::Vector2f v2);
+std::vector x_sort(std::vector vectors, int total);
+
+#endif // CALC_HELPER_H
diff --git a/include/cockpit.h b/include/cockpit.h
new file mode 100644
index 0000000..40eaafa
--- /dev/null
+++ b/include/cockpit.h
@@ -0,0 +1,10 @@
+#ifndef COCKPIT_H
+#define COCKPIT_H
+
+#include
+#include
+#include
+
+void draw_cockpit(sf::RenderWindow &window, assets &resources, player_controller &pc, bool took_damage);
+
+#endif // COCKPIT_H
diff --git a/include/entity.h b/include/entity.h
new file mode 100644
index 0000000..f73754b
--- /dev/null
+++ b/include/entity.h
@@ -0,0 +1,42 @@
+#ifndef ENTITY_H
+#define ENTITY_H
+
+#include
+#include
+#include
+#include
+
+class entity
+{
+ public:
+ float draw_x;
+ float draw_y;
+ float move_x;
+ float move_y;
+ float distance;
+ float old_pos;
+ float think_timer;
+ bool visible;
+ bool firing;
+ bool dying;
+ bool dead;
+ bool init;
+ int id;
+ int targeted_component;
+ sf::Sprite sprite;
+ sf::Sprite icon;
+ sf::Vector2f position;
+ std::string type;
+ std::string sub_type;
+ std::string components [7];
+ entity();
+ mech entity_mech;
+ void fire_weapons(assets &resources);
+ void update(sf::Vector2f camera_pos, bool maze);
+
+ private:
+ bool wall_blocking(sf::Vector2f camera_pos, bool maze);
+ void avoid_walls(bool maze);
+};
+
+#endif // ENTITY_H
diff --git a/include/file_handler.h b/include/file_handler.h
new file mode 100644
index 0000000..d427521
--- /dev/null
+++ b/include/file_handler.h
@@ -0,0 +1,11 @@
+#ifndef FILE_HANDLER_H
+#define FILE_HANDLER_H
+
+#include
+#include
+
+std::string get_file_contents(std::string file_path);
+std::string write_to_file(std::string file_path, std::string data);
+std::string append_file(std::string file_path, std::string data);
+
+#endif
diff --git a/include/hud.h b/include/hud.h
new file mode 100644
index 0000000..25f743f
--- /dev/null
+++ b/include/hud.h
@@ -0,0 +1,24 @@
+#ifndef HUD_H
+#define HUD_H
+
+#include
+#include
+#include
+#include
+
+class hud
+{
+ public:
+ std::string notice;
+ bool show_notice;
+ float notice_timer;
+ void init(assets &resources);
+ void display_notice(sf::RenderWindow &window, std::string notice, float frame_time);
+ void draw_hud(sf::RenderWindow &window, float frame_time, int target_id, float speed, float torso_angle, mech &player_mech, mech &target_mech);
+
+ private:
+ assets resources;
+ void draw_mech(float x_pos, mech &mech_to_draw, sf::RenderWindow &window);
+};
+
+#endif // HUD_H
diff --git a/include/intermission_menu.h b/include/intermission_menu.h
new file mode 100644
index 0000000..923dbb1
--- /dev/null
+++ b/include/intermission_menu.h
@@ -0,0 +1,56 @@
+#ifndef INTERMISSION_MENU_H
+#define INTERMISSION_MENU_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class intermission_menu
+{
+ public:
+ intermission_menu();
+ market_menu market;
+ bool start_game;
+ bool return_to_main;
+ void init(std::string cwd, assets &resources);
+ bool draw_menu(sf::RenderWindow &window, player_controller &pc, float frame_time);
+
+ private:
+ assets resources;
+ settings_menu s_menu;
+ sf::Vector2i mouse_position;
+ sf::String input;
+ std::string cwd;
+ std::string notice;
+ std::string get_save_data(player_controller &pc);
+ std::vector saved_game_buttons;
+ std::vector delete_save_buttons;
+ std::vector delete_save_labels;
+ std::vector saved_game_labels;
+ int kp;
+ float notice_timer;
+ float spark_timer;
+ bool create_save_prompt_open;
+ bool save_prompt_open;
+ bool load_prompt_open;
+ bool repair_prompt_open;
+ bool show_notice;
+ bool prompt_displayed();
+ void create_save(player_controller &pc);
+ void save_game(player_controller &pc, int i);
+ void display_notice(sf::RenderWindow &window, std::string notice, float frame_time);
+ void reset_game(player_controller &pc);
+ void load_game(std::string cwd, std::string file, player_controller &pc);
+ void delete_save_game(int i);
+ void draw_saved_game_buttons(sf::RenderWindow &window);
+ void draw_delete_buttons(sf::RenderWindow &window);
+ void draw_save_menu(sf::RenderWindow &window);
+ void draw_load_menu(sf::RenderWindow &window);
+ void draw_repair_menu(sf::RenderWindow &window, player_controller &pc);
+};
+
+#endif // INTERMISSION_MENU_H
diff --git a/include/key_bindings.h b/include/key_bindings.h
new file mode 100644
index 0000000..946ccaf
--- /dev/null
+++ b/include/key_bindings.h
@@ -0,0 +1,16 @@
+#ifndef KEY_BINDINGS_H
+#define KEY_BINDINGS_H
+
+#include
+#include
+
+class key_bindings
+{
+ public:
+ std::map bindings;
+ void load(std::string cwd);
+ private:
+ std::map keys;
+};
+
+#endif // KEY_BINDINGS_H
diff --git a/include/main_menu.h b/include/main_menu.h
new file mode 100644
index 0000000..8416419
--- /dev/null
+++ b/include/main_menu.h
@@ -0,0 +1,38 @@
+#ifndef MAIN_MENU_H
+#define MAIN_MENU_H
+
+#include
+#include
+#include
+#include
+#include
+
+class main_menu
+{
+ public:
+ bool start_game;
+ bool game_loaded;
+ void init(std::string cwd, assets &resources);
+ bool draw_menu(sf::RenderWindow &window, player_controller &pc, float frame_time);
+
+ private:
+ assets resources;
+ settings_menu s_menu;
+ sf::Vector2i mouse_position;
+ bool load_prompt_open;
+ bool show_load_notice;
+ bool show_delete_notice;
+ float delete_notice_timer;
+ float load_notice_timer;
+ float spark_timer;
+ std::string cwd;
+ std::vector load_game_buttons;
+ std::vector load_game_labels;
+ std::vector delete_save_buttons;
+ std::vector delete_save_labels;
+ void load_game(std::string cwd, std::string file, player_controller &pc);
+ void delete_save_game(int i);
+ void draw_load_menu(sf::RenderWindow &window);
+};
+
+#endif // MAIN_MENU_H
diff --git a/include/market_menu.h b/include/market_menu.h
new file mode 100644
index 0000000..05cc9a6
--- /dev/null
+++ b/include/market_menu.h
@@ -0,0 +1,80 @@
+#ifndef MARKET_MENU_H
+#define MARKET_MENU_H
+
+#include
+#include
+#include
+
+class market_menu
+{
+ public:
+ market_menu();
+
+ struct item
+ {
+ std::string name;
+ std::string type;
+ int level;
+ int modifier;
+ int secondary_modifier;
+ int price;
+ };
+
+ std::vector item_worth;
+ std::string notice;
+ bool visible;
+ bool show_notice;
+ void generate_items();
+ void init(std::string cwd);
+ void handle_events(sf::Event event, player_controller &pc, sf::Vector2i mouse_position);
+ void draw_menu(sf::RenderWindow &window, player_controller &pc, sf::Vector2i mouse_position);
+
+ private:
+ sf::Font market_font;
+ sf::Texture gui_background_texture;
+ sf::VertexArray exit_button;
+
+ sf::SoundBuffer purchase_sound_buffer;
+ sf::Sound purchase_sound;
+
+ std::vector sell_categories;
+
+ std::vector- guns;
+ std::vector
- cannons;
+ std::vector
- reactors;
+ std::vector
- coolers;
+ std::vector
- cockpits;
+ std::vector
- arms;
+ std::vector
- legs;
+
+ std::vector sell_buttons;
+ std::vector gun_buttons;
+ std::vector cannon_buttons;
+ std::vector reactor_buttons;
+ std::vector cooler_buttons;
+ std::vector cockpit_buttons;
+ std::vector arm_buttons;
+ std::vector leg_buttons;
+
+ std::vector sell_button_labels;
+ std::vector gun_button_labels;
+ std::vector cannon_button_labels;
+ std::vector reactor_button_labels;
+ std::vector cooler_button_labels;
+ std::vector cockpit_button_labels;
+ std::vector arm_button_labels;
+ std::vector leg_button_labels;
+
+ std::vector gun_descriptions;
+ std::vector cannon_descriptions;
+ std::vector reactor_descriptions;
+ std::vector cooler_descriptions;
+ std::vector cockpit_descriptions;
+ std::vector arm_descriptions;
+ std::vector leg_descriptions;
+
+ void purchase_item(player_controller &pc, item item_bought);
+ void sell_item(player_controller &pc, std::string category);
+};
+
+#endif // MARKET_MENU_H
diff --git a/include/mech.h b/include/mech.h
new file mode 100644
index 0000000..c139941
--- /dev/null
+++ b/include/mech.h
@@ -0,0 +1,61 @@
+#ifndef MECH_H
+#define MECH_H
+
+#include
+
+class mech
+{
+ public:
+ mech();
+
+ int weapon;
+ int weight;
+
+ int reactor_integrity;
+ int cooler_integrity;
+ int left_leg_integrity;
+ int right_leg_integrity;
+ int left_arm_integrity;
+ int right_arm_integrity;
+ int cockpit_integrity;
+ int total_integrity();
+
+ int cooler_modifier;
+ int guns_modifier;
+ int cannons_modifier;
+ int max_reactor_integrity;
+ int max_cooler_integrity;
+ int max_left_leg_integrity;
+ int max_right_leg_integrity;
+ int max_left_arm_integrity;
+ int max_right_arm_integrity;
+ int max_cockpit_integrity;
+ int max_total_integrity();
+
+ std::string primary_weapon;
+ std::string secondary_weapon;
+ std::string reactor;
+ std::string cooler;
+ std::string left_leg;
+ std::string right_leg;
+ std::string left_arm;
+ std::string right_arm;
+ std::string cockpit;
+
+ float heat;
+ float speed;
+ float damage_timer;
+ bool is_player;
+ bool power_down;
+ bool taking_damage;
+ bool can_move();
+ bool can_fire();
+ bool destroyed();
+ bool left_arm_destroyed();
+ bool right_arm_destroyed();
+ void update();
+ void repair();
+ void take_damage(std::string target, float distance, int weapon);
+};
+
+#endif // MECH_H
diff --git a/include/player_controller.h b/include/player_controller.h
new file mode 100644
index 0000000..5c20280
--- /dev/null
+++ b/include/player_controller.h
@@ -0,0 +1,70 @@
+#ifndef PLAYER_CONTROLLER_H
+#define PLAYER_CONTROLLER_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class player_controller
+{
+ public:
+ player_controller();
+ key_bindings kb;
+ mech player_mech;
+ sf::Vector2f player_pos;
+ sf::Vector2f look_pos;
+ sf::Vector2f back_pos;
+ sf::Vector2f left_pos;
+ sf::Vector2f right_pos;
+ std::vector components;
+ int credits;
+ int credits_earned;
+ int targeted_component;
+ int target_id;
+ int enemy_id;
+ int mission;
+ bool guns_firing;
+ bool cannon_firing;
+ bool player_firing;
+ bool muzzle_flash;
+ bool cannon_flash;
+ bool hit_target;
+ bool turn_left;
+ bool turn_right;
+ bool look_left;
+ bool look_right;
+ bool look_up;
+ bool look_down;
+ float muzzle_flash_timer;
+ float cannon_flash_timer;
+ float look_offset;
+ float torso_angle;
+ void reset();
+ void init(std::string cwd, assets &resources);
+ void collision_check(entity other, float view_range);
+ void fire_guns(std::vector &entities, int entity_count, float window_width);
+ void fire_cannon(std::vector &entities, int entity_count, float window_width);
+ void lock_target(std::vector &entities, int entity_count, float window_width);
+ void update(sf::RenderWindow &window, float frame_time);
+ void handle_events(sf::RenderWindow &window, sf::Event event);
+ void fixed_update(sf::Transformable player);
+
+ private:
+ assets resources;
+ float stomp_timer;
+ float step_timer;
+ float mouse_move_timer;
+ float guns_timer;
+ float cannon_timer;
+ bool move_forward;
+ bool move_back;
+ bool throttle_up;
+ bool throttle_down;
+ bool mouse_moved;
+};
+
+#endif
diff --git a/include/settings.h b/include/settings.h
new file mode 100644
index 0000000..b6cd0fe
--- /dev/null
+++ b/include/settings.h
@@ -0,0 +1,11 @@
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+extern bool music;
+extern bool invert_mouse;
+extern double audio_volume;
+
+void save_settings(std::string cwd);
+void load_settings(std::string cwd);
+
+#endif // SETTINGS_H
diff --git a/include/settings_menu.h b/include/settings_menu.h
new file mode 100644
index 0000000..2561e20
--- /dev/null
+++ b/include/settings_menu.h
@@ -0,0 +1,28 @@
+#ifndef SETTINGS_MENU_H
+#define SETTINGS_MENU_H
+
+#include
+
+class settings_menu
+{
+ public:
+ bool visible;
+ bool in_game;
+ bool abort_mission;
+ bool abort_prompt_open;
+ void init(std::string cwd, assets &resources, bool in_game);
+ void handle_events(sf::Event event, sf::Vector2i mouse_position);
+ void draw_menu(sf::RenderWindow &window, sf::Vector2i mouse_position, float frame_time);
+ private:
+ assets resources;
+ std::string cwd;
+ std::vector buttons;
+ std::vector abort_buttons;
+ std::vector button_labels;
+ std::vector abort_button_labels;
+ std::vector button_values;
+ std::vector button_text;
+ std::vector abort_button_text;
+};
+
+#endif // SETTINGS_MENU_H
diff --git a/include/tutorial.h b/include/tutorial.h
new file mode 100644
index 0000000..01ccafa
--- /dev/null
+++ b/include/tutorial.h
@@ -0,0 +1,23 @@
+#ifndef TUTORIAL_H
+#define TUTORIAL_H
+
+#include
+#include
+#include
+
+class tutorial
+{
+ public:
+ int step;
+ bool visible;
+ tutorial(std::string cwd);
+ void draw_tutorial(sf::RenderWindow &window, bool show_keys, float speed, float torso_angle, float heat);
+
+ private:
+ sf::Texture gui_background_texture;
+ sf::Sprite gui_background_sprite;
+ sf::Text tutorial_text;
+ sf::Font tutorial_font;
+};
+
+#endif // TUTORIAL_H
diff --git a/include/world_generator.h b/include/world_generator.h
new file mode 100644
index 0000000..fe06083
--- /dev/null
+++ b/include/world_generator.h
@@ -0,0 +1,26 @@
+#ifndef WORLD_GENERATOR_H
+#define WORLD_GENERATOR_H
+
+#include
+#include
+
+class world_generator
+{
+ public:
+ int theme;
+ int mission;
+ bool maze;
+ void generate_world(assets &resources, std::vector &entities, int entity_count);
+ void flip_walls_vertical(std::vector &entities, int entity_count, bool inverse);
+ void flip_walls_horizontal(std::vector &entities, int entity_count, bool inverse);
+ world_generator();
+
+ protected:
+
+ private:
+ int wall_count;
+ int mob_count;
+ bool min_npc_spawned;
+};
+
+#endif // WORLD_GENERATOR_H
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..acda394
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,1033 @@
+#ifdef __cplusplus
+ #include
+#else
+ #include
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Class objects
+assets resources;
+player_controller pc;
+world_generator world_gen;
+main_menu m_menu;
+settings_menu s_menu;
+intermission_menu i_menu;
+hud player_hud;
+
+// Player
+sf::Transformable player;
+sf::Transformable camera;
+
+// Graphics
+int view_range = 60;
+int camera_width = 60;
+int ray_count = view_range * camera_width;
+int wall_height = 40;
+float fov_mod = 0;
+float sky_x;
+float sky_y;
+std::vector camera_plane(camera_width);
+std::vector rays(ray_count);
+std::vector origins(ray_count);
+
+// Engine
+int draw_count = 0;
+int entity_count = 2000;
+bool flipped_vertical;
+bool flipped_horizontal;
+bool show_fps;
+float fps;
+float frame_time;
+float frame_timer;
+std::string cwd;
+std::vector entities(entity_count);
+std::vector mobs(entity_count);
+
+
+// Game
+bool show_map = true;
+bool show_keys = false;
+bool bullet_hit = false;
+bool main_menu = true;
+bool intermission_menu = false;
+bool game_started = false;
+bool show_victory_notice = false;
+float victory_timer;
+float game_over_timer;
+float map_scale = 0.25;
+float bullet_delay;
+float damage_timer;
+bool taking_damage;
+bool took_damage;
+
+// Framerate
+std::chrono::high_resolution_clock::time_point fps_start;
+std::chrono::high_resolution_clock::time_point fps_finish;
+
+void start_game()
+{
+ int rand_map = rand() % 100;
+ world_gen.maze = rand_map > 50 ? true : false;
+ int rand_theme = rand() % 100;
+ world_gen.theme = rand_theme > 50 ? 1 : 2;
+ world_gen.mission = pc.mission;
+ world_gen.generate_world(resources, entities, entity_count);
+ player.rotate(90);
+ camera.rotate(90);
+ game_started = true;
+ resources.power_up_sound.setVolume(50 * audio_volume);
+ resources.power_up_sound.play();
+}
+
+void complete_mission()
+{
+ player.setRotation(0);
+ camera.setRotation(0);
+ sky_x = 0;
+ sky_y = 0;
+ s_menu.visible = false;
+ pc.credits += (pc.credits_earned + 20000);
+ pc.reset();
+ pc.mission++;
+ bullet_delay = 0;
+ game_started = false;
+ i_menu.market.generate_items();
+ i_menu.start_game = false;
+ intermission_menu = true;
+}
+
+void abort_mission()
+{
+ resources.mission_music.stop();
+ player.setRotation(0);
+ camera.setRotation(0);
+ sky_x = 0;
+ sky_y = 0;
+ pc.reset();
+ bullet_delay = 0;
+ game_started = false;
+ s_menu.visible = false;
+ intermission_menu = true;
+ i_menu.start_game = false;
+ s_menu.abort_mission = false;
+}
+
+int main(int argc, char * argv[])
+{
+ srand(time(NULL));
+
+ char cwd_char[PATH_MAX];
+ if (getcwd(cwd_char, sizeof(cwd_char)) != NULL)
+ {
+ cwd = cwd_char;
+ }
+
+ tutorial tut(cwd);
+ load_settings(cwd);
+ resources.init(cwd);
+
+ pc.init(cwd, resources);
+ player_hud.init(resources);
+ m_menu.init(cwd, resources);
+ i_menu.init(cwd, resources);
+ s_menu.init(cwd, resources, true);
+ i_menu.market.generate_items();
+
+ sf::RenderWindow window;
+
+ bool windowed = false;
+
+ if (argc > 3)
+ {
+ if (strcmp(argv[1], "-window") == 0)
+ {
+ windowed = true;
+ unsigned int x = std::stoi(argv[2]) < 1280 ? 1280 : std::stoi(argv[2]);
+ unsigned int y = std::stoi(argv[3]) < 720 ? 720 : std::stoi(argv[3]);
+ window.create(sf::VideoMode(x, y), "SF Mech Simulator", sf::Style::Close);
+ }
+ }
+
+ if (windowed == false)
+ {
+ window.create(sf::VideoMode(sf::VideoMode::getDesktopMode().width, sf::VideoMode::getDesktopMode().height), "SF Mech Simulator", sf::Style::Fullscreen);
+ }
+
+ window.setFramerateLimit(60);
+
+ // Start the game loop
+ while (window.isOpen())
+ {
+ fps_start = std::chrono::high_resolution_clock::now();
+
+ if (main_menu == true)
+ {
+ window.setMouseCursorVisible(true);
+ main_menu = m_menu.draw_menu(window, pc, frame_time);
+ }
+ else if (m_menu.game_loaded == true)
+ {
+ m_menu.game_loaded = false;
+ i_menu.market.generate_items();
+ intermission_menu = true;
+ }
+ else if (intermission_menu == true)
+ {
+ if (i_menu.return_to_main == false)
+ {
+ window.setMouseCursorVisible(true);
+ intermission_menu = i_menu.draw_menu(window, pc, frame_time);
+ }
+ else
+ {
+ i_menu.return_to_main = false;
+ m_menu.game_loaded = false;
+ m_menu.start_game = false;
+ intermission_menu = false;
+ game_started = false;
+ main_menu = true;
+ }
+ }
+ else
+ {
+ if (game_started == false)
+ {
+ start_game();
+ }
+
+ if (intermission_menu == false && pc.player_mech.power_down == false && show_victory_notice == false)
+ {
+ resources.mission_music.setVolume(50 * audio_volume);
+
+ if (music == true && resources.mission_music.getStatus() != sf::Sound::Playing)
+ {
+ resources.mission_music.play();
+ }
+ }
+
+ window.setMouseCursorVisible(s_menu.visible);
+
+ // Process events
+ sf::Event event;
+ while (window.pollEvent(event))
+ {
+ if (s_menu.visible == true)
+ {
+ sf::Vector2i mouse_pos = sf::Mouse().getPosition(window);
+ s_menu.handle_events(event, mouse_pos);
+ }
+ else
+ {
+ pc.handle_events(window, event);
+ }
+
+ if (event.type == sf::Event::Closed)
+ {
+ window.close();
+ }
+
+ if(event.type == sf::Event::KeyPressed)
+ {
+ if (pc.player_mech.destroyed() == false)
+ {
+ if(event.key.code == pc.kb.bindings["lock_target"])
+ {
+ int j = 0;
+ for (int i = 0; i < entity_count; i++)
+ {
+ if (entities[i].type == "mob")
+ {
+ mobs[j] = entities[i];
+ j++;
+ }
+ }
+ mobs.resize(j);
+ pc.lock_target(mobs, j, window.getView().getSize().x);
+ }
+
+ if(event.key.code == pc.kb.bindings["map"])
+ {
+ if (show_map == true)
+ {
+ if (map_scale == 0.25)
+ {
+ map_scale = 0.5;
+ }
+ else if (map_scale == 0.5)
+ {
+ map_scale = 0.75;
+ }
+ else if (map_scale == 0.75)
+ {
+ map_scale = 0.25;
+ show_map = !show_map;
+ }
+ }
+ else
+ {
+ show_map = !show_map;
+ }
+ }
+
+ if (event.key.code == pc.kb.bindings["show_keys"])
+ {
+ show_keys = !show_keys;
+ }
+
+ if (event.key.code == pc.kb.bindings["show_tutorial"])
+ {
+ tut.visible = !tut.visible;
+ }
+
+ if (event.key.code == pc.kb.bindings["show_fps"])
+ {
+ show_fps = !show_fps;
+ }
+
+ if (event.key.code == sf::Keyboard::Escape && show_victory_notice == false)
+ {
+ s_menu.visible = !s_menu.visible;
+ }
+
+ if (tut.visible && event.key.code == sf::Keyboard::Return)
+ {
+ tut.step = tut.step < 10 ? tut.step + 1 : 0;
+ }
+ }
+ }
+ }
+
+ if (s_menu.visible == false)
+ {
+ // Walls need to be placed in descending order of distance to the camera
+ if (camera.getRotation() > 0 && camera.getRotation() < 180 && flipped_vertical == false)
+ {
+ world_gen.flip_walls_vertical(entities, entity_count, true);
+ flipped_vertical = true;
+ }
+
+ if (camera.getRotation() >= 180 && flipped_vertical == true)
+ {
+ world_gen.flip_walls_vertical(entities, entity_count, false);
+ flipped_vertical = false;
+ }
+
+ if ((camera.getRotation() >= 270 || camera.getRotation() <= 90) && flipped_horizontal == false)
+ {
+ world_gen.flip_walls_horizontal(entities, entity_count, true);
+ flipped_horizontal = true;
+ }
+
+ if (camera.getRotation() > 90 && camera.getRotation() < 270 && flipped_horizontal == true)
+ {
+ world_gen.flip_walls_horizontal(entities, entity_count, false);
+ flipped_horizontal = false;
+ }
+
+ if(pc.turn_left == true && pc.player_mech.can_move() == true)
+ {
+ player.rotate(-10 * frame_time);
+ camera.rotate(-10 * frame_time);
+ sky_x -= 100 * frame_time;
+ }
+
+ if(pc.turn_right == true && pc.player_mech.can_move() == true)
+ {
+ player.rotate(10 * frame_time);
+ camera.rotate(10 * frame_time);
+ sky_x += 100 * frame_time;
+ }
+
+ if (pc.look_left == true && pc.torso_angle > -89 && pc.player_mech.cockpit_integrity > 0)
+ {
+ camera.rotate(-10 * frame_time);
+ pc.torso_angle -= 10 * frame_time;
+ sky_x -= 100 * frame_time;
+ }
+
+ if (pc.look_right == true && pc.torso_angle < 90 && pc.player_mech.cockpit_integrity > 0)
+ {
+ camera.rotate(10 * frame_time);
+ pc.torso_angle += 10 * frame_time;
+ sky_x += 100 * frame_time;
+ }
+
+ // Vertical cockpit movement
+ if (pc.look_up == true)
+ {
+ if (pc.look_offset < 15 && pc.player_mech.cockpit_integrity > 0)
+ {
+ pc.look_offset += 5 * frame_time;
+ sky_y -= 50 * frame_time;
+ }
+ }
+
+ if (pc.look_down == true && pc.player_mech.cockpit_integrity > 0)
+ {
+ if (pc.look_offset > -27)
+ {
+ pc.look_offset -= 5 * frame_time;
+ sky_y += 50 * frame_time;
+ }
+ }
+
+ pc.update(window, frame_time);
+
+ // Frame rate independent updates
+ frame_timer += frame_time;
+ if (frame_timer >= 0.1)
+ {
+ frame_timer = 0;
+
+ pc.fixed_update(player);
+
+ int mob_count = 0;
+ for (int i = 0; i < entity_count; i++)
+ {
+ if (entities[i].type == "mob" && entities[i].sub_type == "mech" && entities[i].dead == false)
+ {
+ mob_count++;
+ entities[i].update(camera_plane[camera_width / 2], world_gen.maze);
+ if (entities[i].firing == true && pc.player_mech.destroyed() == false && pc.enemy_id == 0)
+ {
+ entities[i].fire_weapons(resources);
+ taking_damage = true;
+ pc.enemy_id = i;
+ }
+ }
+ }
+
+ if (mob_count == 0)
+ {
+ show_victory_notice = true;
+ }
+
+ // Firing weapons
+ if (pc.player_firing == true)
+ {
+ int j = 0;
+ for (int i = 0; i < entity_count; i++)
+ {
+ if (entities[i].type == "mob")
+ {
+ mobs[j] = entities[i];
+ j++;
+ }
+ }
+ mobs.resize(j);
+
+ if (pc.player_mech.weapon == 1 && pc.guns_firing == false)
+ {
+ pc.fire_guns(mobs, j, window.getView().getSize().x);
+ }
+
+ if (pc.player_mech.weapon == 5 && pc.cannon_firing == false)
+ {
+ pc.fire_cannon(mobs, j, window.getView().getSize().x);
+ }
+ }
+
+ // Taking damage
+ if (taking_damage == true)
+ {
+ damage_timer++;
+ if (damage_timer >= 2 && damage_timer < 4)
+ {
+ entities[pc.enemy_id].sprite.setTexture(resources.mech_texture);
+ }
+ else if (damage_timer >= 4 && damage_timer < 6)
+ {
+ if (took_damage == false && pc.player_mech.destroyed() == false)
+ {
+ resources.impact_sound.setVolume(100 * audio_volume);
+ resources.impact_sound.play();
+
+ entity enemy = entities[pc.enemy_id];
+ mech enemy_mech = entities[pc.enemy_id].entity_mech;
+ std::string component = enemy.components[enemy.targeted_component];
+ int modifier = enemy_mech.weapon == 1 ? enemy_mech.guns_modifier : enemy_mech.cannons_modifier;
+ int damage = enemy_mech.weapon + modifier;
+
+ if (enemy_mech.left_arm_destroyed() || enemy_mech.right_arm_destroyed())
+ {
+ damage = damage / 2;
+ }
+
+ pc.player_mech.take_damage(component, enemy.distance, damage);
+ took_damage = true;
+ }
+ }
+ else if (damage_timer >= 6)
+ {
+ taking_damage = false;
+ took_damage = false;
+ pc.enemy_id = 0;
+ damage_timer = 0;
+ }
+ }
+
+ // Dealing damage
+ if (pc.hit_target == true)
+ {
+ bullet_delay++;
+ if (bullet_delay >= 4 && bullet_delay < 6 && bullet_hit == false)
+ {
+ if (entities[pc.target_id].entity_mech.destroyed() == true)
+ {
+ resources.explosion_sound.setVolume(50 * audio_volume);
+ resources.explosion_sound.play();
+ entities[pc.target_id].sprite.setTexture(resources.explosion_texture);
+ }
+ else
+ {
+ resources.impact_sound.setVolume(50 * audio_volume);
+ resources.impact_sound.play();
+ entities[pc.target_id].sprite.setTexture(resources.mech_textures[pc.targeted_component]);
+ }
+ bullet_hit = true;
+ }
+ else if (bullet_delay >= 6)
+ {
+ if (entities[pc.target_id].entity_mech.destroyed() == true)
+ {
+ entities[pc.target_id].visible = false;
+ entities[pc.target_id].dead = true;
+ pc.credits_earned += 10000;
+ }
+ else
+ {
+ entities[pc.target_id].sprite.setTexture(resources.mech_texture);
+ }
+
+ mech player_mech = pc.player_mech;
+ entity target = entities[pc.target_id];
+ std::string component = pc.components[pc.targeted_component];
+ int modifier = player_mech.weapon == 1 ? player_mech.guns_modifier : player_mech.cannons_modifier;
+ int damage = player_mech.weapon + modifier;
+
+ if (player_mech.left_arm_destroyed() || player_mech.right_arm_destroyed())
+ {
+ damage = damage / 2;
+ }
+
+ entities[pc.target_id].entity_mech.take_damage(component, target.distance, damage);
+ pc.hit_target = false;
+ bullet_hit = false;
+ bullet_delay = 0;
+ }
+ }
+
+ if (pc.player_mech.destroyed() == true)
+ {
+ show_keys = false;
+ tut.visible = false;
+ s_menu.visible = false;
+ resources.cockpit_sprite.setTexture(resources.cockpit_destroyed_texture);
+ pc.player_mech.speed = 0;
+
+ if (pc.player_mech.power_down == false)
+ {
+ resources.mission_music.stop();
+ resources.power_down_sound.setVolume(50 * audio_volume);
+ resources.power_down_sound.play();
+ pc.player_mech.power_down = true;
+ }
+
+ game_over_timer++;
+ if (game_over_timer >= 100)
+ {
+ pc.player_mech.power_down = false;
+ game_over_timer = 0;
+ player.setRotation(0);
+ camera.setRotation(0);
+ sky_x = 0;
+ sky_y = 0;
+ pc.reset();
+ bullet_delay = 0;
+ game_started = false;
+ intermission_menu = true;
+ i_menu.start_game = false;
+ }
+ }
+ else
+ {
+ resources.cockpit_sprite.setTexture(resources.cockpit_texture);
+ }
+ }
+ }
+
+ // Camera plane creation
+ sf::Vector2f camera_pos;
+ camera_pos.x = player.getPosition().x + 10 * cos (camera.getRotation() * (3.14 / 180));
+ camera_pos.y = player.getPosition().y + 10 * sin (camera.getRotation() * (3.14 / 180));
+
+ float pos = camera_width / 2;
+ for (int i = 0; i < camera_width / 2; i++)
+ {
+ camera_plane[i].x = camera_pos.x + pos * cos ((camera.getRotation() - 90) * (3.14 / 180));
+ camera_plane[i].y = camera_pos.y + pos * sin ((camera.getRotation() - 90) * (3.14 / 180));
+ pos --;
+ }
+
+ pos = 0;
+ for (int i = camera_width / 2; i < camera_width; i++)
+ {
+ camera_plane[i].x = camera_pos.x + pos * cos ((camera.getRotation() + 90) * (3.14 / 180));
+ camera_plane[i].y = camera_pos.y + pos * sin ((camera.getRotation() + 90) * (3.14 / 180));
+ pos ++;
+ }
+
+ // Raycasting
+ int k = 0;
+ for (int i = 0; i < view_range; i++)
+ {
+ for (int j = 0; j < camera_width; j++)
+ {
+ float angle = j;
+ if (j < camera_width / 2)
+ {
+ angle = (((camera_width / 2) - j) * -1) * fov_mod;
+ }
+ else
+ {
+ angle = (j - (camera_width / 2)) * fov_mod;
+ }
+ rays[k].x = camera_plane[j].x + i * cos ((camera.getRotation() + angle) * (3.14 / 180));
+ rays[k].y = camera_plane[j].y + i * sin ((camera.getRotation() + angle) * (3.14 / 180));
+ origins[k] = camera_plane[j];
+ k++;
+ }
+ }
+
+ // Determine entitites visible to the camera
+ for (int i = 0; i < entity_count; i++)
+ {
+ float distance = get_distance(camera_plane[camera_width / 2], entities[i].position);
+ if (distance < view_range)
+ {
+ int index;
+ float wall_ray = 0;
+ float near_ray = 0;
+ float dist = 100;
+ bool visible = false;
+ bool culling = false;
+
+ for (int j = 0; j < ray_count; j++)
+ {
+ dist = (get_distance(rays[j], entities[i].position));
+ if (dist < 1 && entities[i].dead == false)
+ {
+ pc.collision_check(entities[i], view_range);
+ entities[i].distance = get_distance(entities[i].position, origins[j]);
+ index = j;
+ visible = true;
+
+ if (entities[i].type == "wall")
+ {
+ wall_ray = (float)j / (float)camera_width;
+ wall_ray = wall_ray - floor(wall_ray);
+ wall_ray = wall_ray * camera_width;
+ culling = true;
+ }
+ }
+
+ if (culling == true)
+ {
+ near_ray = (float)j / (float)camera_width;
+ near_ray = near_ray - floor(near_ray);
+ near_ray = near_ray * camera_width;
+ if (near_ray > wall_ray - 5 && near_ray < wall_ray + 5)
+ {
+ rays[j] = origins[j];
+ }
+ }
+ }
+
+ if (visible == true)
+ {
+ // Center the entity between the closest raycasts, for smoother movement
+ float dist_to_left = (get_distance(rays[index - 1], entities[i].position));
+ float dist_to_right = (get_distance(rays[index + 1], entities[i].position));
+ int offset = dist_to_left < dist_to_right ? index - 1 : index + 1;
+ float offset_percent = ((float)offset) / (float)camera_width;
+ offset_percent = offset_percent - floor(offset_percent);
+ float screen_percent = (float)index / (float)camera_width;
+ screen_percent = screen_percent - floor(screen_percent);
+ float final_pos = (offset_percent + screen_percent) / 2;
+ float distance_moved = 0;
+
+ if (entities[i].old_pos > final_pos)
+ {
+ distance_moved = entities[i].old_pos - final_pos;
+ }
+ else
+ {
+ distance_moved = final_pos - entities[i].old_pos;
+ }
+
+ if (distance_moved > 0.02)
+ {
+ final_pos = (final_pos + entities[i].old_pos) / 2;
+ }
+
+ float entity_draw_x = window.getView().getSize().x * final_pos;
+ entities[i].draw_x = entity_draw_x;
+ entities[i].old_pos = final_pos;
+ }
+
+ entities[i].visible = visible;
+ }
+ else
+ {
+ entities[i].visible = false;
+ entities[i].old_pos = 0;
+ }
+ }
+
+ // Position the player in the world
+ player.setPosition(pc.player_pos.x, pc.player_pos.y);
+
+ // Clear screen
+ window.clear();
+
+ // Draw the sky
+ resources.sky_sprite.setTextureRect(sf::IntRect(sky_x, sky_y, window.getView().getSize().x, window.getView().getSize().y));
+ if (world_gen.theme == 1)
+ {
+ resources.sky_sprite.setTexture(resources.sky_texture);
+ }
+ else
+ {
+ resources.sky_sprite.setTexture(resources.sky_2_texture);
+ }
+ window.draw(resources.sky_sprite);
+
+ // Draw the ground
+ resources.ground_sprite.setPosition(0, ((window.getView().getSize().y / 2) + pc.look_offset * 10));
+ float ground_scale_x = window.getView().getSize().x / resources.ground_sprite.getLocalBounds().width;
+ float ground_scale_y = resources.ground_sprite.getLocalBounds().height;
+ resources.ground_sprite.setScale(ground_scale_x, ground_scale_y);
+ if (world_gen.theme == 1)
+ {
+ resources.ground_sprite.setTexture(resources.ground_texture);
+ }
+ else
+ {
+ resources.ground_sprite.setTexture(resources.ground_2_texture);
+ }
+ window.draw(resources.ground_sprite);
+
+ for (int i = 0; i < entity_count; i++)
+ {
+ if (entities[i].visible == true)
+ {
+ draw_count++;
+ }
+ }
+
+ if (draw_count > 0)
+ {
+ std::vector entities_to_draw(draw_count);
+ draw_count = 0;
+
+ // Find all visible objects
+ for (int i = 0; i < entity_count; i++)
+ {
+ if (entities[i].visible == true)
+ {
+ entities_to_draw[draw_count] = entities[i];
+ draw_count++;
+ }
+ }
+
+ // The upper and lower vertices of wall segments
+ std::vector verts_low(draw_count);
+ std::vector verts_high(draw_count);
+
+ // Create sprites and wall segments for drawing to the screen
+ for (int i = 0; i < draw_count; i++)
+ {
+ if (entities_to_draw[i].type == "wall") // Create lines with scaled height for drawing wall quads
+ {
+ float scale = 6 - (entities_to_draw[i].distance * 0.095) - pc.look_offset * 0.005;
+ scale = scale < 0 ? 0 : scale;
+ sf::Vector2f v1;
+ v1.x = entities_to_draw[i].draw_x;
+ v1.y = (window.getView().getSize().y / 2) - (wall_height * scale) + pc.look_offset * 10;
+ sf::Vector2f v2;
+ v2.x = entities_to_draw[i].draw_x;
+ v2.y = (window.getView().getSize().y / 2) + (wall_height * scale) + pc.look_offset * 10;
+ verts_high[i] = v1;
+ verts_low[i] = v2;
+ }
+ else // Prepare sprites for drawing to the screen
+ {
+ float scale = 3 - (entities_to_draw[i].distance * 0.05) - pc.look_offset * 0.005;
+ scale = scale < 0 ? 0 : scale;
+ entities_to_draw[i].sprite.setScale(scale, scale);
+ entities_to_draw[i].sprite.setScale(scale, scale);
+ float window_center = window.getView().getSize().y / 2;
+ float sprite_width = entities_to_draw[i].sprite.getTexture()->getSize().y;
+ float sprite_scale = entities_to_draw[i].sprite.getScale().y;
+ entities_to_draw[i].draw_y = window_center - ((sprite_width * sprite_scale) / 2);
+ entities_to_draw[i].draw_y += (120 - (entities_to_draw[i].distance * 2)) + pc.look_offset * 10;
+ entities_to_draw[i].sprite.setPosition(entities_to_draw[i].draw_x, entities_to_draw[i].draw_y);
+ }
+ }
+
+ // Sort wall segments from left to right on the window's x axis, for drawing quads
+ verts_low = x_sort(verts_low, draw_count);
+ verts_high = x_sort(verts_high, draw_count);
+
+ // Create the quads
+ std::vector walls (draw_count);
+ for (int wall_index = 0; wall_index < draw_count - 1; wall_index++)
+ {
+ if (get_distance(verts_high[wall_index], verts_high[wall_index + 1]) < window.getView().getSize().x * 0.4)
+ {
+ if (verts_low[wall_index].x != 0)
+ {
+ sf::VertexArray quad(sf::Quads, 4);
+ quad[0].position = verts_low[wall_index];
+ quad[1].position = verts_low[wall_index + 1];
+ quad[2].position = verts_high[wall_index + 1];
+ quad[3].position = verts_high[wall_index];
+ quad[0].texCoords = sf::Vector2f(0.f, 512.f);
+ quad[1].texCoords = sf::Vector2f(512.f, 512.f);
+ quad[2].texCoords = sf::Vector2f(512.f, 0.f);
+ quad[3].texCoords = sf::Vector2f(0.f, 0.f);
+ if (world_gen.theme == 1)
+ {
+ window.draw(quad, &resources.wall_texture);
+ }
+ else
+ {
+ window.draw(quad, &resources.wall_2_texture);
+ }
+ }
+ }
+ }
+
+ // Sort sprites by their distance from the camera, so farther sprites are drawn first
+ entity temp;
+ int i, j;
+
+ for(i = 0; i < draw_count; i++)
+ {
+ for(j = i + 1; j < draw_count; j++)
+ {
+ if(entities_to_draw[i].distance < entities_to_draw[j].distance)
+ {
+ temp = entities_to_draw[i];
+ entities_to_draw[i] = entities_to_draw[j];
+ entities_to_draw[j] = temp;
+ }
+ }
+ }
+
+ // Draw sprites
+ for (int i = 0; i < draw_count; i++)
+ {
+ if (entities_to_draw[i].type != "wall")
+ {
+ window.draw(entities_to_draw[i].sprite);
+ if (entities_to_draw[i].type == "mob")
+ {
+ if (pc.target_id == entities_to_draw[i].id)
+ {
+ float scale = 3 - (entities_to_draw[i].distance * 0.05) - pc.look_offset * 0.005;
+ scale = scale < 0 ? 0 : scale;
+ float x = entities_to_draw[i].sprite.getPosition().x;
+ float y = entities_to_draw[i].sprite.getPosition().y;
+ float width = entities_to_draw[i].sprite.getTexture()->getSize().x * scale;
+ float height = entities_to_draw[i].sprite.getTexture()->getSize().y * scale;
+ sf::Vector2f top_left = sf::Vector2f(x - 10, y - 10);
+ sf::Vector2f bottom_left = sf::Vector2f(x - 10, y + height + 10);
+ sf::Vector2f top_right = sf::Vector2f(x + width + 10, y - 10);
+ sf::Vector2f bottom_right = sf::Vector2f(x + width + 10, y + height + 10);
+ sf::VertexArray target_box(sf::LineStrip, 5);
+ target_box[0].position = bottom_left;
+ target_box[1].position = bottom_right;
+ target_box[2].position = top_right;
+ target_box[3].position = top_left;
+ target_box[4].position = bottom_left;
+ for (int j = 0; j < 5; j++)
+ {
+ target_box[j].color = sf::Color::Red;
+ }
+ window.draw(target_box);
+ std::string target_distance = std::to_string((int)entities[pc.target_id].distance * 10);
+ std::string info = "Distance: " + target_distance + " meters\nTargeting: " + pc.components[pc.targeted_component];
+ resources.target_info.setString(info);
+ sf::Vector2f info_pos = sf::Vector2f(top_left.x, top_left.y - 40);
+ resources.target_info.setPosition(info_pos);
+ window.draw(resources.target_info);
+ }
+ }
+ }
+ }
+ }
+
+ // Draw the cockpit
+ draw_cockpit(window, resources, pc, took_damage);
+
+ //Draw the HUD
+ player_hud.draw_hud(window, frame_time, pc.target_id, pc.player_mech.speed, pc.torso_angle, pc.player_mech, entities[pc.target_id].entity_mech);
+
+ // Draw entities on the map
+ for (int i = 0; i < entity_count; i++)
+ {
+ if (show_map == true && pc.player_mech.destroyed() == false)
+ {
+ if (entities[i].type == "mob")
+ {
+ if (pc.target_id == entities[i].id)
+ {
+ entities[i].icon.setTexture(resources.target_icon_texture);
+ }
+ else
+ {
+ entities[i].icon.setTexture(resources.mob_icon_texture);
+ }
+ }
+ if (entities[i].dead == false)
+ {
+ entities[i].icon.setPosition(entities[i].position.x * map_scale, entities[i].position.y * map_scale);
+ window.draw(entities[i].icon);
+ }
+ }
+ }
+
+ // Draw the player on the map
+ if (show_map == true && pc.player_mech.destroyed() == false)
+ {
+ sf::VertexArray line1(sf::LinesStrip, 2);
+ sf::Vector2f map_player_pos = sf::Vector2f(pc.player_pos.x * map_scale, pc.player_pos.y * map_scale);
+ sf::Vector2f map_look_pos = sf::Vector2f(pc.look_pos.x * map_scale, pc.look_pos.y * map_scale);
+ sf::Vector2f map_cam_pos = sf::Vector2f(rays[camera_width / 2 + camera_width * 5].x * map_scale, rays[camera_width / 2 + camera_width * 5].y * map_scale);
+ sf::Vector2f mid = get_midpoint(map_player_pos, map_look_pos);
+
+ resources.player_icon.setPosition(sf::Vector2f((pc.player_pos.x - 16) * map_scale, (pc.player_pos.y - 16) * map_scale));
+ resources.player_icon.setScale(map_scale, map_scale);
+ window.draw(resources.player_icon);
+
+ line1[0].position = map_player_pos;
+ line1[1].position = mid;
+ line1[0].color = sf::Color::Green;
+ line1[1].color = sf::Color::Green;
+ window.draw(line1);
+
+ sf::VertexArray line2(sf::LinesStrip, 2);
+ line2[0].position = map_player_pos;
+ line2[1].position = map_cam_pos;
+ line2[0].color = sf::Color::Red;
+ line2[1].color = sf::Color::Red;
+ window.draw(line2);
+ }
+
+ if (show_keys == true)
+ {
+ sf::Vector2f bg_pos;
+ float x = window.getView().getSize().x - 150;
+ bg_pos.x = x - (resources.keys.getGlobalBounds().width / 2);
+ bg_pos.y = (window.getView().getSize().y / 2) - 175;
+ sf::Sprite bg = sf::Sprite(resources.gui_background_texture);
+ bg.setPosition(bg_pos);
+ bg.setScale(0.1, 1);
+ window.draw(bg);
+
+ std::string bindings = get_file_contents(cwd + "/bindings.list");
+ resources.keys.setString(bindings);
+ resources.keys.setPosition(x - 50, (window.getView().getSize().y / 2) - 150);
+ window.draw(resources.keys);
+ }
+
+ if (tut.visible == true)
+ {
+ tut.draw_tutorial(window, show_keys, pc.player_mech.speed, pc.torso_angle, pc.player_mech.heat);
+ }
+
+ if (show_victory_notice == true)
+ {
+ resources.mission_music.stop();
+ if (resources.victory_sound.getStatus() != sf::Sound::Playing)
+ {
+ resources.victory_sound.setVolume(100 * audio_volume);
+ resources.victory_sound.play();
+ }
+
+ tut.visible = false;
+ s_menu.visible = false;
+ resources.notice.setFont(resources.orbitron);
+ resources.notice.setString("MISSION COMPLETE");
+ sf::Vector2f text_pos;
+ text_pos.x = (window.getView().getSize().x / 2) - (resources.notice.getGlobalBounds().width / 2);
+ text_pos.y = (window.getView().getSize().y / 2) - 150;
+ resources.notice.setPosition(text_pos);
+ window.draw(resources.notice);
+ resources.notice.setFont(resources.exoplanetaria);
+
+ victory_timer += 10 * frame_time;
+ if (victory_timer >= 60)
+ {
+ victory_timer = 0;
+ show_victory_notice = false;
+ complete_mission();
+ }
+ }
+
+ if (s_menu.visible == true)
+ {
+ tut.visible = false;
+ sf::Vector2i mouse_pos = sf::Mouse().getPosition(window);
+ s_menu.draw_menu(window, mouse_pos, frame_time);
+
+ if (s_menu.abort_mission == true)
+ {
+ abort_mission();
+ }
+ }
+
+ // Draw frame rate at the bottom left corner of the screen
+ if (show_fps == true)
+ {
+ sf::String fps_string = "FPS: " + std::to_string(fps);
+ resources.fps_counter.setString(fps_string);
+ resources.fps_counter.setPosition(10, window.getView().getSize().y * 0.96);
+ window.draw(resources.fps_counter);
+ }
+
+ // Display on screen what has been rendered to the window so far
+ window.display();
+ }
+
+ // Calculate framerate
+ fps_finish = std::chrono::high_resolution_clock::now();
+ fps = (float)1e9/(float)std::chrono::duration_cast(fps_finish-fps_start).count();
+ frame_time = 1 / fps;
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/save/saves.list b/save/saves.list
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/save/saves.list
@@ -0,0 +1 @@
+
diff --git a/settings.list b/settings.list
new file mode 100644
index 0000000..76f56f2
--- /dev/null
+++ b/settings.list
@@ -0,0 +1,3 @@
+volume:1.000000
+music:1
+
diff --git a/src/assets.cpp b/src/assets.cpp
new file mode 100644
index 0000000..f299776
--- /dev/null
+++ b/src/assets.cpp
@@ -0,0 +1,647 @@
+#include
+#include
+#include
+
+// Loads sounds from file
+void assets::load_sound_buffers(std::string cwd)
+{
+ if (!main_menu_music_buffer.loadFromFile(cwd + "/assets/sounds/main_menu.ogg"))
+ {
+ std::cout << "Error loading sound file main_menu.ogg";
+ std::cout << "\n";
+ }
+
+ if (!intermission_music_buffer.loadFromFile(cwd + "/assets/sounds/intermission_menu.ogg"))
+ {
+ std::cout << "Error loading sound file intermission_menu.ogg";
+ std::cout << "\n";
+ }
+
+ if (!mission_music_buffer.loadFromFile(cwd + "/assets/sounds/mission.ogg"))
+ {
+ std::cout << "Error loading sound file mission.ogg";
+ std::cout << "\n";
+ }
+
+ if (!power_down_sound_buffer.loadFromFile(cwd + "/assets/sounds/power_down.ogg"))
+ {
+ std::cout << "Error loading sound file power_down.ogg";
+ std::cout << "\n";
+ }
+
+ if (!victory_sound_buffer.loadFromFile(cwd + "/assets/sounds/victory.ogg"))
+ {
+ std::cout << "Error loading sound file victory.ogg";
+ std::cout << "\n";
+ }
+
+ if (!power_up_sound_buffer.loadFromFile(cwd + "/assets/sounds/power_up.ogg"))
+ {
+ std::cout << "Error loading sound file power_up.ogg";
+ std::cout << "\n";
+ }
+
+ if (!hydraulic_sound_buffer.loadFromFile(cwd + "/assets/sounds/hydraulic.ogg"))
+ {
+ std::cout << "Error loading sound file hydraulic.ogg";
+ std::cout << "\n";
+ }
+
+ if (!gun_sound_buffer.loadFromFile(cwd + "/assets/sounds/guns.ogg"))
+ {
+ std::cout << "Error loading sound file guns.ogg";
+ std::cout << "\n";
+ }
+
+ if (!cannon_sound_buffer.loadFromFile(cwd + "/assets/sounds/cannon.ogg"))
+ {
+ std::cout << "Error loading sound file cannon.ogg";
+ std::cout << "\n";
+ }
+
+ if (!explo_sound_buffer.loadFromFile(cwd + "/assets/sounds/explosion.ogg"))
+ {
+ std::cout << "Error loading sound file explosion.ogg";
+ std::cout << "\n";
+ }
+
+ if (!stomp_sound_buffer.loadFromFile(cwd + "/assets/sounds/stomp.ogg"))
+ {
+ std::cout << "Error loading sound file stomp.ogg";
+ std::cout << "\n";
+ }
+
+ if (!crash_sound_buffer.loadFromFile(cwd + "/assets/sounds/crash.ogg"))
+ {
+ std::cout << "Error loading sound file crash.ogg";
+ std::cout << "\n";
+ }
+
+ if (!impact_sound_buffer.loadFromFile(cwd + "/assets/sounds/impact.ogg"))
+ {
+ std::cout << "Error loading sound file impact.ogg";
+ std::cout << "\n";
+ }
+
+ if (!purchase_sound_buffer.loadFromFile(cwd + "/assets/sounds/purchase.ogg"))
+ {
+ std::cout << "Error loading sound file purchase.ogg";
+ std::cout << "\n";
+ }
+}
+
+// Loads textures from file
+void assets::load_textures(std::string cwd)
+{
+ if (!mech_texture.loadFromFile(cwd + "/assets/textures/mech/mech.bmp"))
+ {
+ std::cout << "Error loading image file mech.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_fire_guns_texture.loadFromFile(cwd + "/assets/textures/mech/mech_fire.bmp"))
+ {
+ std::cout << "Error loading image file mech_fire.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_fire_guns_left_texture.loadFromFile(cwd + "/assets/textures/mech/mech_fire_left.bmp"))
+ {
+ std::cout << "Error loading image file mech_fire_left.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_fire_guns_right_texture.loadFromFile(cwd + "/assets/textures/mech/mech_fire_right.bmp"))
+ {
+ std::cout << "Error loading image file mech_fire_right.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_fire_cannons_texture.loadFromFile(cwd + "/assets/textures/mech/mech_cannon_fire.bmp"))
+ {
+ std::cout << "Error loading image file mech_cannon_fire.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_fire_cannons_left_texture.loadFromFile(cwd + "/assets/textures/mech/mech_cannon_left.bmp"))
+ {
+ std::cout << "Error loading image file mech_cannon_fire_left.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_fire_cannons_right_texture.loadFromFile(cwd + "/assets/textures/mech/mech_cannon_right.bmp"))
+ {
+ std::cout << "Error loading image file mech_cannon_fire_right.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_hit_center_texture.loadFromFile(cwd + "/assets/textures/mech/mech_hit_center.bmp"))
+ {
+ std::cout << "Error loading image file mech_hit_center.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_hit_cockpit_texture.loadFromFile(cwd + "/assets/textures/mech/mech_hit_cockpit.bmp"))
+ {
+ std::cout << "Error loading image file mech_hit_cockpit.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_hit_left_leg_texture.loadFromFile(cwd + "/assets/textures/mech/mech_hit_left_leg.bmp"))
+ {
+ std::cout << "Error loading image file mech_hit_left_leg.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_hit_right_leg_texture.loadFromFile(cwd + "/assets/textures/mech/mech_hit_right_leg.bmp"))
+ {
+ std::cout << "Error loading image file mech_hit_right_leg.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_hit_left_arm_texture.loadFromFile(cwd + "/assets/textures/mech/mech_hit_left_arm.bmp"))
+ {
+ std::cout << "Error loading image file mech_hit_left_arm.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_hit_right_arm_texture.loadFromFile(cwd + "/assets/textures/mech/mech_hit_right_arm.bmp"))
+ {
+ std::cout << "Error loading image file mech_hit_right_arm.bmp";
+ std::cout << "\n";
+ }
+
+ if (!explosion_texture.loadFromFile(cwd + "/assets/textures/mech/explosion.png"))
+ {
+ std::cout << "Error loading image file explosion.bmp";
+ std::cout << "\n";
+ }
+
+ if (!crosshair_texture.loadFromFile(cwd + "/assets/textures/crosshair.png"))
+ {
+ std::cout << "Error loading image file crosshair.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cockpit_texture.loadFromFile(cwd + "/assets/textures/cockpit/cockpit.bmp"))
+ {
+ std::cout << "Error loading image file cockpit.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cockpit_fire_texture.loadFromFile(cwd + "/assets/textures/cockpit/cockpit_fire.bmp"))
+ {
+ std::cout << "Error loading image file cockpit_fire.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cockpit_fire_left_texture.loadFromFile(cwd + "/assets/textures/cockpit/cockpit_fire_left.bmp"))
+ {
+ std::cout << "Error loading image file cockpit_fire_left.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cockpit_fire_right_texture.loadFromFile(cwd + "/assets/textures/cockpit/cockpit_fire_right.bmp"))
+ {
+ std::cout << "Error loading image file cockpit_fire_right.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cockpit_cannon_texture.loadFromFile(cwd + "/assets/textures/cockpit/cockpit_cannon.bmp"))
+ {
+ std::cout << "Error loading image file cockpit_cannon.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cockpit_cannon_left_texture.loadFromFile(cwd + "/assets/textures/cockpit/cockpit_cannon_left.bmp"))
+ {
+ std::cout << "Error loading image file cockpit_cannon_left.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cockpit_cannon_right_texture.loadFromFile(cwd + "/assets/textures/cockpit/cockpit_cannon_right.bmp"))
+ {
+ std::cout << "Error loading image file cockpit_cannon_right.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cockpit_impact_texture.loadFromFile(cwd + "/assets/textures/cockpit/cockpit_impact.bmp"))
+ {
+ std::cout << "Error loading image file cockpit_impact.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cockpit_destroyed_texture.loadFromFile(cwd + "/assets/textures/cockpit/cockpit_destroyed.bmp"))
+ {
+ std::cout << "Error loading image file cockpit_destroyed.bmp";
+ std::cout << "\n";
+ }
+
+ if (!ground_texture.loadFromFile(cwd + "/assets/textures/ground.bmp"))
+ {
+ std::cout << "Error loading image file ground.bmp";
+ std::cout << "\n";
+ }
+
+ if (!ground_2_texture.loadFromFile(cwd + "/assets/textures/ground_2.bmp"))
+ {
+ std::cout << "Error loading image file ground_2.bmp";
+ std::cout << "\n";
+ }
+
+ if (!sky_texture.loadFromFile(cwd + "/assets/textures/sky.bmp"))
+ {
+ std::cout << "Error loading image file sky.bmp";
+ std::cout << "\n";
+ }
+
+ if (!sky_2_texture.loadFromFile(cwd + "/assets/textures/sky_2.png"))
+ {
+ std::cout << "Error loading image file sky_2.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mech_status_texture.loadFromFile(cwd + "/assets/textures/mech_status.bmp"))
+ {
+ std::cout << "Error loading image file mech_status.bmp";
+ std::cout << "\n";
+ }
+
+ if (!gui_background_texture.loadFromFile(cwd + "/assets/textures/gui_background.png"))
+ {
+ std::cout << "Error loading image file gui_background.bmp";
+ std::cout << "\n";
+ }
+
+ if (!gui_background_2_texture.loadFromFile(cwd + "/assets/textures/gui_background_2.png"))
+ {
+ std::cout << "Error loading image file gui_background_2.bmp";
+ std::cout << "\n";
+ }
+
+ if (!target_gui_background_texture.loadFromFile(cwd + "/assets/textures/target_gui_background.png"))
+ {
+ std::cout << "Error loading image file target_gui_background.bmp";
+ std::cout << "\n";
+ }
+
+ if (!wall_texture.loadFromFile(cwd + "/assets/textures/wall.bmp"))
+ {
+ std::cout << "Error loading image file wall.bmp";
+ std::cout << "\n";
+ }
+
+ if (!wall_2_texture.loadFromFile(cwd + "/assets/textures/wall_2.bmp"))
+ {
+ std::cout << "Error loading image file wall_2.bmp";
+ std::cout << "\n";
+ }
+
+ if (!tree_texture.loadFromFile(cwd + "/assets/textures/tree.bmp"))
+ {
+ std::cout << "Error loading image file tree.bmp";
+ std::cout << "\n";
+ }
+
+ if (!tree_2_texture.loadFromFile(cwd + "/assets/textures/tree_2.png"))
+ {
+ std::cout << "Error loading image file tree_2.bmp";
+ std::cout << "\n";
+ }
+
+ if (!tree_3_texture.loadFromFile(cwd + "/assets/textures/tree_3.png"))
+ {
+ std::cout << "Error loading image file tree_3.bmp";
+ std::cout << "\n";
+ }
+
+ if (!tree_4_texture.loadFromFile(cwd + "/assets/textures/tree_4.png"))
+ {
+ std::cout << "Error loading image file tree_4.bmp";
+ std::cout << "\n";
+ }
+
+ if (!player_icon_texture.loadFromFile(cwd + "/assets/textures/player_icon.png"))
+ {
+ std::cout << "Error loading image file player_icon.bmp";
+ std::cout << "\n";
+ }
+
+ if (!mob_icon_texture.loadFromFile(cwd + "/assets/textures/mob_icon.png"))
+ {
+ std::cout << "Error loading image file mob_icon.bmp";
+ std::cout << "\n";
+ }
+
+ if (!target_icon_texture.loadFromFile(cwd + "/assets/textures/target_icon.png"))
+ {
+ std::cout << "Error loading image file target_icon.bmp";
+ std::cout << "\n";
+ }
+
+ if (!wall_icon_texture.loadFromFile(cwd + "/assets/textures/wall_icon.png"))
+ {
+ std::cout << "Error loading image file wall_icon.bmp";
+ std::cout << "\n";
+ }
+
+ if (!menu_background_texture.loadFromFile(cwd + "/assets/textures/menu_background.png"))
+ {
+ std::cout << "Error loading image file menu_background.bmp";
+ std::cout << "\n";
+ }
+
+ if (!menu_mech_texture.loadFromFile(cwd + "/assets/textures/mech_repair.png"))
+ {
+ std::cout << "Error loading image file mech_repair.bmp";
+ std::cout << "\n";
+ }
+
+ if (!menu_mech_spark_1_texture.loadFromFile(cwd + "/assets/textures/mech_repair_spark_1.png"))
+ {
+ std::cout << "Error loading image file mech_repair_spark_1.bmp";
+ std::cout << "\n";
+ }
+
+ if (!menu_mech_spark_2_texture.loadFromFile(cwd + "/assets/textures/mech_repair_spark_2.png"))
+ {
+ std::cout << "Error loading image file mech_repair_spark_2.bmp";
+ std::cout << "\n";
+ }
+
+ if (!start_game_button_texture.loadFromFile(cwd + "/assets/textures/buttons/start_game_button.png"))
+ {
+ std::cout << "Error loading image file start_game_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!start_game_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/start_game_button_hover.png"))
+ {
+ std::cout << "Error loading image file start_game_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!main_menu_button_texture.loadFromFile(cwd + "/assets/textures/buttons/main_menu_button.png"))
+ {
+ std::cout << "Error loading image file main_menu_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!main_menu_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/main_menu_button_hover.png"))
+ {
+ std::cout << "Error loading image file main_menu_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!save_game_button_texture.loadFromFile(cwd + "/assets/textures/buttons/save_button.png"))
+ {
+ std::cout << "Error loading image file save_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!save_game_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/save_button_hover.png"))
+ {
+ std::cout << "Error loading image file save_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!load_game_button_texture.loadFromFile(cwd + "/assets/textures/buttons/load_button.png"))
+ {
+ std::cout << "Error loading image file load_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!load_game_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/load_button_hover.png"))
+ {
+ std::cout << "Error loading image file load_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!options_button_texture.loadFromFile(cwd + "/assets/textures/buttons/options_button.png"))
+ {
+ std::cout << "Error loading image file options_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!options_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/options_button_hover.png"))
+ {
+ std::cout << "Error loading image file options_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!repair_button_texture.loadFromFile(cwd + "/assets/textures/buttons/repair_button.png"))
+ {
+ std::cout << "Error loading image file repair_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!market_button_texture.loadFromFile(cwd + "/assets/textures/buttons/market_button.png"))
+ {
+ std::cout << "Error loading image file market_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!market_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/market_button_hover.png"))
+ {
+ std::cout << "Error loading image file market_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!repair_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/repair_button_hover.png"))
+ {
+ std::cout << "Error loading image file repair_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!exit_game_button_texture.loadFromFile(cwd + "/assets/textures/buttons/exit_game_button.png"))
+ {
+ std::cout << "Error loading image file exit_game_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!exit_game_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/exit_game_button_hover.png"))
+ {
+ std::cout << "Error loading image file exit_game_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!next_mission_button_texture.loadFromFile(cwd + "/assets/textures/buttons/next_mission_button.png"))
+ {
+ std::cout << "Error loading image file next_mission_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!next_mission_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/next_mission_button_hover.png"))
+ {
+ std::cout << "Error loading image file next_mission_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!create_new_button_texture.loadFromFile(cwd + "/assets/textures/buttons/create_new_button.png"))
+ {
+ std::cout << "Error loading image file create_new_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!create_new_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/create_new_button_hover.png"))
+ {
+ std::cout << "Error loading image file create_new_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cancel_button_texture.loadFromFile(cwd + "/assets/textures/buttons/cancel_button.png"))
+ {
+ std::cout << "Error loading image file cancel_button.bmp";
+ std::cout << "\n";
+ }
+
+ if (!cancel_button_hover_texture.loadFromFile(cwd + "/assets/textures/buttons/cancel_button_hover.png"))
+ {
+ std::cout << "Error loading image file cancel_button_hover.bmp";
+ std::cout << "\n";
+ }
+
+ if (!term_texture.loadFromFile(cwd + "/assets/textures/term.bmp"))
+ {
+ std::cout << "Error loading image file term.bmp";
+ std::cout << "\n";
+ }
+}
+
+// Loads fonts from file
+void assets::load_fonts(std::string cwd)
+{
+ if (!orbitron.loadFromFile(cwd + "/assets/Orbitron Medium.ttf"))
+ {
+ std::cout << "Error loading font file Orbitron Medium.ttf";
+ std::cout << "\n";
+ }
+
+ if (!exoplanetaria.loadFromFile(cwd + "/assets/Exoplanetaria-gxxJ5.ttf"))
+ {
+ std::cout << "Error loading font file Exoplanetaria-gxxJ5.ttf";
+ std::cout << "\n";
+ }
+}
+
+// Assigns sound buffers
+void assets::init_sounds()
+{
+ main_menu_music.setBuffer(main_menu_music_buffer);
+ intermission_music.setBuffer(intermission_music_buffer);
+ mission_music.setBuffer(mission_music_buffer);
+ power_down_sound.setBuffer(power_down_sound_buffer);
+ victory_sound.setBuffer(victory_sound_buffer);
+ power_up_sound.setBuffer(power_up_sound_buffer);
+ hydraulic_sound.setBuffer(hydraulic_sound_buffer);
+ gun_sound.setBuffer(gun_sound_buffer);
+ cannon_sound.setBuffer(cannon_sound_buffer);
+ explosion_sound.setBuffer(explo_sound_buffer);
+ stomp_sound.setBuffer(stomp_sound_buffer);
+ crash_sound.setBuffer(crash_sound_buffer);
+ impact_sound.setBuffer(impact_sound_buffer);
+ purchase_sound.setBuffer(purchase_sound_buffer);
+}
+
+// Assigns textures to sprites
+void assets::init_sprites()
+{
+ crosshair_sprite.setTexture(crosshair_texture);
+ cockpit_sprite.setTexture(cockpit_texture);
+ ground_sprite.setTexture(ground_texture);
+ sky_sprite.setTexture(sky_texture);
+ player_icon.setTexture(player_icon_texture);
+ mob_icon.setTexture(mob_icon_texture);
+ target_icon.setTexture(target_icon_texture);
+ wall_icon.setTexture(wall_icon_texture);
+ menu_background_sprite.setTexture(menu_background_texture);
+ menu_mech_sprite.setTexture(menu_mech_texture);
+ start_game_button_sprite.setTexture(start_game_button_texture);
+ main_menu_button_sprite.setTexture(main_menu_button_texture);
+ save_game_button_sprite.setTexture(save_game_button_texture);
+ load_game_button_sprite.setTexture(load_game_button_texture);
+ options_button_sprite.setTexture(options_button_texture);
+ repair_button_sprite.setTexture(repair_button_texture);
+ market_button_sprite.setTexture(market_button_texture);
+ exit_game_button_sprite.setTexture(exit_game_button_texture);
+ next_mission_button_sprite.setTexture(next_mission_button_texture);
+ create_new_button_sprite.setTexture(create_new_button_texture);
+ cancel_button_sprite.setTexture(cancel_button_texture);
+ term_sprite.setTexture(term_texture);
+}
+
+// Sets up text objects
+void assets::init_text()
+{
+ fps_counter.setFont(orbitron);
+ fps_counter.setString("0");
+ fps_counter.setCharacterSize(12);
+ fps_counter.setFillColor(sf::Color::White);
+
+ keys.setFont(exoplanetaria);
+ keys.setString("");
+ keys.setCharacterSize(12);
+ keys.setFillColor(sf::Color::White);
+
+ mech_status.setFont(orbitron);
+ mech_status.setString("");
+ mech_status.setCharacterSize(12);
+ mech_status.setFillColor(sf::Color::Green);
+
+ target_status.setFont(orbitron);
+ target_status.setString("");
+ target_status.setCharacterSize(12);
+ target_status.setFillColor(sf::Color::Red);
+
+ throttle_display.setFont(orbitron);
+ throttle_display.setString("0");
+ throttle_display.setCharacterSize(12);
+ throttle_display.setFillColor(sf::Color::Green);
+
+ torso_display.setFont(orbitron);
+ torso_display.setString("0");
+ torso_display.setCharacterSize(12);
+ torso_display.setFillColor(sf::Color::Green);
+
+ target_info.setFont(orbitron);
+ target_info.setString("");
+ target_info.setCharacterSize(12);
+ target_info.setFillColor(sf::Color::Red);
+
+ input_text.setFont(orbitron);
+ input_text.setString("");
+ input_text.setCharacterSize(12);
+ input_text.setFillColor(sf::Color::White);
+
+ notice.setFont(exoplanetaria);
+ notice.setString("");
+ notice.setCharacterSize(24);
+ notice.setFillColor(sf::Color::White);
+}
+
+// Initializes all assets
+void assets::init(std::string cwd)
+{
+ load_sound_buffers(cwd);
+ load_textures(cwd);
+ load_fonts(cwd);
+
+ init_sounds();
+ init_sprites();
+ init_text();
+
+ mech_textures = {mech_hit_center_texture,
+ mech_hit_center_texture,
+ mech_hit_left_arm_texture,
+ mech_hit_right_arm_texture,
+ mech_hit_left_leg_texture,
+ mech_hit_right_leg_texture,
+ mech_hit_cockpit_texture};
+
+ sky_texture.setRepeated(true);
+ sky_2_texture.setRepeated(true);
+
+ unsigned int x = sf::VideoMode::getDesktopMode().width;
+ unsigned int y = sf::VideoMode::getDesktopMode().height;
+ sky_sprite.setTextureRect(sf::IntRect(0, 0, x, y));
+}
diff --git a/src/calc_helper.cpp b/src/calc_helper.cpp
new file mode 100644
index 0000000..b63ead7
--- /dev/null
+++ b/src/calc_helper.cpp
@@ -0,0 +1,49 @@
+#include
+#include
+#include
+#include
+
+// Returns the distance between two vectors
+float get_distance(sf::Vector2f v1, sf::Vector2f v2)
+{
+ float xdif = v2.x - v1.x;
+ float ydif = v2.y - v1.y;
+ float xdifsqrd = xdif * xdif;
+ float ydifsqrd = ydif * ydif;
+ return sqrt(xdifsqrd + ydifsqrd);
+}
+
+// Returns the midpoint between two vectors
+sf::Vector2f get_midpoint(sf::Vector2f v1, sf::Vector2f v2)
+{
+ float xmid = (v1.x + v2.x) / 2;
+ float ymid = (v1.y + v2.y) / 2;
+ sf::Vector2f vmid(xmid, ymid);
+ return vmid;
+}
+
+// Returns the angle between two vectors
+float get_angle(sf::Vector2f v1, sf::Vector2f v2)
+{
+ return atan2(v2.y - v1.y, v2.x - v1.x) * (180 / 3.14);
+}
+
+// Sorts vectors based on their position along the x axis
+std::vector x_sort(std::vector vectors, int total)
+{
+ sf::Vector2f temp_vector;
+ int current_index, next_index;
+ for(current_index = 0; current_index < total; current_index++)
+ {
+ for(next_index = current_index + 1; next_index < total; next_index++)
+ {
+ if(vectors[current_index].x > vectors[next_index].x)
+ {
+ temp_vector = vectors[current_index];
+ vectors[current_index] = vectors[next_index];
+ vectors[next_index] = temp_vector;
+ }
+ }
+ }
+ return vectors;
+}
diff --git a/src/cockpit.cpp b/src/cockpit.cpp
new file mode 100644
index 0000000..69eca9f
--- /dev/null
+++ b/src/cockpit.cpp
@@ -0,0 +1,66 @@
+#include
+
+// Draws the cockpit, muzzle flashes and hit effects
+void draw_cockpit(sf::RenderWindow &window, assets &resources, player_controller &pc, bool took_damage)
+{
+ float cockpit_x = window.getView().getSize().x / resources.cockpit_sprite.getLocalBounds().width;
+ float cockpit_y = window.getView().getSize().y / resources.cockpit_sprite.getLocalBounds().height;
+ resources.cockpit_sprite.setScale(cockpit_x, cockpit_y);
+ resources.cockpit_sprite.setPosition(0, 0);
+ window.draw(resources.cockpit_sprite);
+
+ if (pc.player_mech.destroyed() == false)
+ {
+ if (pc.muzzle_flash == true)
+ {
+ sf::Sprite fire_sprite;
+
+ if (pc.player_mech.left_arm_destroyed())
+ {
+ fire_sprite = sf::Sprite(resources.cockpit_fire_right_texture);
+ }
+ else if (pc.player_mech.right_arm_destroyed())
+ {
+ fire_sprite = sf::Sprite(resources.cockpit_fire_left_texture);
+ }
+ else
+ {
+ fire_sprite = sf::Sprite(resources.cockpit_fire_texture);
+ }
+
+ fire_sprite.setScale(cockpit_x, cockpit_y);
+ fire_sprite.setPosition(0, 0);
+ window.draw(fire_sprite);
+ }
+
+ if (pc.cannon_flash == true)
+ {
+ sf::Sprite fire_sprite;
+
+ if (pc.player_mech.left_arm_destroyed())
+ {
+ fire_sprite = sf::Sprite(resources.cockpit_cannon_right_texture);
+ }
+ else if (pc.player_mech.right_arm_destroyed())
+ {
+ fire_sprite = sf::Sprite(resources.cockpit_cannon_left_texture);
+ }
+ else
+ {
+ fire_sprite = sf::Sprite(resources.cockpit_cannon_texture);
+ }
+
+ fire_sprite.setScale(cockpit_x, cockpit_y);
+ fire_sprite.setPosition(0, 0);
+ window.draw(fire_sprite);
+ }
+
+ if (took_damage == true)
+ {
+ sf::Sprite damage_sprite = sf::Sprite(resources.cockpit_impact_texture);
+ damage_sprite.setScale(cockpit_x, cockpit_y);
+ damage_sprite.setPosition(0, 0);
+ window.draw(damage_sprite);
+ }
+ }
+}
diff --git a/src/entity.cpp b/src/entity.cpp
new file mode 100644
index 0000000..8e40046
--- /dev/null
+++ b/src/entity.cpp
@@ -0,0 +1,269 @@
+#include
+#include
+#include
+#include
+
+entity::entity()
+{
+ id = 0;
+ draw_x = 0;
+ draw_y = 0;
+ move_x = 0;
+ move_y = 0;
+ old_pos = 0;
+ distance = 0;
+ think_timer = 0;
+ targeted_component = 0;
+
+ dead = false;
+ init = false;
+ dying = false;
+ firing = false;
+ visible = false;
+
+ components[0] = "reactor";
+ components[1] = "cooler";
+ components[2] = "left arm";
+ components[3] = "right arm";
+ components[4] = "left leg";
+ components[5] = "right leg";
+ components[6] = "cockpit";
+}
+
+// Prevents mobs from running into walls
+void entity::avoid_walls(bool maze)
+{
+ if (position.x < 65)
+ {
+ position.x += 1;
+ }
+
+ if (position.x > 545)
+ {
+ position.x -= 1;
+ }
+
+ if (position.y < 45)
+ {
+ position.y += 1;
+ }
+
+ if (position.y > 645)
+ {
+ position.y -= 1;
+ }
+
+ if (maze == true)
+ {
+ if (position.x < 300 && position.y > 395)
+ {
+ position.y -= 1;
+ }
+
+ if (position.x > 175 && position.x < 180 && position.y < 280)
+ {
+ position.x -= 1;
+ position.y += 5;
+ }
+
+ if (position.x < 185 && position.x > 180 && position.y < 280)
+ {
+ position.x += 1;
+ position.y += 5;
+ }
+
+ if (position.x > 295 && position.x < 300 && position.y > 150)
+ {
+ position.x -= 1;
+ position.y -= 5;
+ }
+
+ if (position.x > 300 && position.x < 305 && position.y > 150)
+ {
+ position.x += 1;
+ position.y -= 5;
+ }
+
+ if (position.x > 415 && position.x < 420 && position.y < 520)
+ {
+ position.x -= 1;
+ position.y += 5;
+ }
+
+ if (position.x > 420 && position.x < 425 && position.y < 520)
+ {
+ position.x += 1;
+ position.y += 5;
+ }
+ }
+}
+
+// Returns true if there is a wall between this entity and the player
+bool entity::wall_blocking(sf::Vector2f camera_pos, bool maze)
+{
+ if (maze == false)
+ {
+ return false;
+ }
+
+ if (camera_pos.x < 180 && position.x > 180 && position.y < 280)
+ {
+ return true;
+ }
+
+ if (camera_pos.x > 180 && position.x < 180 && position.y < 280)
+ {
+ return true;
+ }
+
+ if (camera_pos.x < 300 && position.x > 300 && position.y > 150)
+ {
+ return true;
+ }
+
+ if (camera_pos.x > 300 && position.x < 300 && position.y > 150)
+ {
+ return true;
+ }
+
+ if (camera_pos.x < 420 && position.x > 420 && position.y < 520)
+ {
+ return true;
+ }
+
+ if (camera_pos.x > 420 && position.x < 420 && position.y < 520)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+// NPC mech weapons firing
+void entity::fire_weapons(assets &resources)
+{
+ if (sprite.getTexture() == &resources.mech_texture)
+ {
+ if (entity_mech.weapon == 1)
+ {
+ if (entity_mech.left_arm_destroyed() == true)
+ {
+ sprite.setTexture(resources.mech_fire_guns_right_texture);
+ }
+ else if (entity_mech.right_arm_destroyed() == true)
+ {
+ sprite.setTexture(resources.mech_fire_guns_left_texture);
+ }
+ else
+ {
+ sprite.setTexture(resources.mech_fire_guns_texture);
+ }
+
+ resources.gun_sound.setVolume(25 * audio_volume);
+ resources.gun_sound.play();
+
+ float heat_gen = entity_mech.heat + 10 + entity_mech.guns_modifier;
+ entity_mech.heat = entity_mech.heat >= 90 ? 100 : heat_gen;
+ }
+ else
+ {
+ if (entity_mech.left_arm_destroyed() == true)
+ {
+ sprite.setTexture(resources.mech_fire_cannons_right_texture);
+ }
+ else if (entity_mech.right_arm_destroyed() == true)
+ {
+ sprite.setTexture(resources.mech_fire_cannons_left_texture);
+ }
+ else
+ {
+ sprite.setTexture(resources.mech_fire_cannons_texture);
+ }
+
+ resources.cannon_sound.setVolume(25 * audio_volume);
+ resources.cannon_sound.play();
+
+ float heat_gen = entity_mech.heat + 50 + entity_mech.cannons_modifier;
+ entity_mech.heat = entity_mech.heat >= 50 ? 100 : heat_gen;
+ }
+ firing = false;
+ }
+}
+
+// Handles npc logic
+void entity::update(sf::Vector2f camera_pos, bool maze)
+{
+ if (type == "mob" && sub_type == "mech")
+ {
+ think_timer++;
+
+ if (think_timer >= 10)
+ {
+ float camera_range = get_distance(camera_pos, position);
+
+ if (entity_mech.can_move() == true)
+ {
+ int leg_integrity = entity_mech.left_leg_integrity + entity_mech.right_leg_integrity;
+ entity_mech.speed = camera_range > 60 ? leg_integrity * 0.00002 : leg_integrity * 0.00001;
+ float dir = entity_mech.speed;
+
+ if (entity_mech.taking_damage == true || entity_mech.heat >= 50)
+ {
+ dir = -entity_mech.speed;
+ }
+
+ if (position.x < camera_pos.x)
+ {
+ move_x = dir;
+ }
+
+ if (position.x > camera_pos.x)
+ {
+ move_x = -dir;
+ }
+
+ if (position.y < camera_pos.y)
+ {
+ move_y = dir;
+ }
+
+ if (position.y > camera_pos.y)
+ {
+ move_y = -dir;
+ }
+ }
+ else
+ {
+ move_x = 0;
+ move_y = 0;
+ }
+
+ if (entity_mech.can_fire() == true && entity_mech.heat <= 50)
+ {
+ if (camera_range < 60 && wall_blocking(camera_pos, maze) == false)
+ {
+ int fire_decision = rand() % 100;
+
+ if (fire_decision > 25)
+ {
+ targeted_component = rand() % 7;
+ int weapon_decision = rand() % 100;
+ entity_mech.weapon = weapon_decision >= 75 ? 5 : 1;
+ firing = true;
+ }
+ else
+ {
+ firing = false;
+ }
+ }
+ }
+
+ think_timer = 0;
+ }
+
+ avoid_walls(maze);
+ entity_mech.update();
+ position.x += move_x;
+ position.y += move_y;
+ }
+}
diff --git a/src/file_handler.cpp b/src/file_handler.cpp
new file mode 100644
index 0000000..da7f819
--- /dev/null
+++ b/src/file_handler.cpp
@@ -0,0 +1,35 @@
+#include
+#include
+#include
+
+// Reads the contents of a file line by line and returns the result
+std::string get_file_contents(std::string file_path)
+{
+ std::ifstream stream;
+ stream.open(file_path);
+ std::string text;
+ std::string result;
+ while(getline(stream, text))
+ {
+ result += text + "\n";
+ }
+ return result;
+}
+
+// Writes the given data to a file, overwriting the existing data
+std::string write_to_file(std::string file_path, std::string data)
+{
+ std::ofstream file;
+ file.open(file_path);
+ file << data << "\n";
+ file.close();
+ return data;
+}
+
+// Gets the contents of a file, adds the given data and overwrites the file
+std::string append_file(std::string file_path, std::string data)
+{
+ std::string current = get_file_contents(file_path);
+ std::string appended = current + data;
+ return write_to_file(file_path, appended);
+}
diff --git a/src/hud.cpp b/src/hud.cpp
new file mode 100644
index 0000000..caf52d3
--- /dev/null
+++ b/src/hud.cpp
@@ -0,0 +1,286 @@
+#include
+#include
+#include
+
+// Initializes reference to main assets class
+void hud::init(assets &resources)
+{
+ this->resources = resources;
+}
+
+// Displays a notice with the given string
+void hud::display_notice(sf::RenderWindow &window, std::string notice, float frame_time)
+{
+ sf::Vector2f notice_pos;
+ notice_pos.x = (window.getView().getSize().x / 2) - (resources.notice.getGlobalBounds().width / 2);
+ notice_pos.y = (window.getView().getSize().y / 2);
+ resources.notice.setString(notice);
+ resources.notice.setPosition(notice_pos);
+ window.draw(resources.notice);
+
+ notice_timer += 10 * frame_time;
+ if (notice_timer >= 30)
+ {
+ notice_timer = 0;
+ show_notice = false;
+ }
+}
+
+// Draws mech status image with color based on damage
+void hud::draw_mech(float x_pos, mech &mech_to_draw, sf::RenderWindow &window)
+{
+ // Right arm
+ sf::VertexArray right_arm_quad(sf::Quads, 4);
+ right_arm_quad[0].position = sf::Vector2f(window.getView().getSize().x * x_pos, window.getView().getSize().y * 0.8 + 65);
+ right_arm_quad[1].position = sf::Vector2f(window.getView().getSize().x * x_pos + 40, window.getView().getSize().y * 0.8 + 65);
+ right_arm_quad[2].position = sf::Vector2f(window.getView().getSize().x * x_pos + 40, window.getView().getSize().y * 0.8);
+ right_arm_quad[3].position = sf::Vector2f(window.getView().getSize().x * x_pos, window.getView().getSize().y * 0.8);
+ right_arm_quad[0].texCoords = sf::Vector2f(0.f, 130.f);
+ right_arm_quad[1].texCoords = sf::Vector2f(76.f, 130.f);
+ right_arm_quad[2].texCoords = sf::Vector2f(76.f, 0.f);
+ right_arm_quad[3].texCoords = sf::Vector2f(0.f, 0.f);
+
+ float right_arm_red = 255 - (255 * ((float)mech_to_draw.right_arm_integrity / (float)mech_to_draw.max_right_arm_integrity));
+ float right_arm_green = 100 * ((float)mech_to_draw.right_arm_integrity / (float)mech_to_draw.max_right_arm_integrity);
+ for (int i = 0; i < 4; i++)
+ {
+ right_arm_quad[i].color = sf::Color(right_arm_red, right_arm_green, 0, 255);
+ }
+ window.draw(right_arm_quad, &resources.mech_status_texture);
+
+ // Cockpit
+ sf::VertexArray cockpit_quad(sf::Quads, 4);
+ cockpit_quad[0].position = sf::Vector2f(window.getView().getSize().x * x_pos + 40, window.getView().getSize().y * 0.8 + 30);
+ cockpit_quad[1].position = sf::Vector2f(window.getView().getSize().x * x_pos + 92, window.getView().getSize().y * 0.8 + 30);
+ cockpit_quad[2].position = sf::Vector2f(window.getView().getSize().x * x_pos + 92, window.getView().getSize().y * 0.8);
+ cockpit_quad[3].position = sf::Vector2f(window.getView().getSize().x * x_pos + 40, window.getView().getSize().y * 0.8);
+ cockpit_quad[0].texCoords = sf::Vector2f(76.f, 59.f);
+ cockpit_quad[1].texCoords = sf::Vector2f(180.f, 59.f);
+ cockpit_quad[2].texCoords = sf::Vector2f(180.f, 0.f);
+ cockpit_quad[3].texCoords = sf::Vector2f(76.f, 0.f);
+
+ float cockpit_red = 255 - (255 * ((float)mech_to_draw.cockpit_integrity / (float)mech_to_draw.max_cockpit_integrity));
+ float cockpit_green = 100 * ((float)mech_to_draw.cockpit_integrity / (float)mech_to_draw.max_cockpit_integrity);
+ for (int i = 0; i < 4; i++)
+ {
+ cockpit_quad[i].color = sf::Color(cockpit_red, cockpit_green, 0, 255);
+ }
+ window.draw(cockpit_quad, &resources.mech_status_texture);
+
+ // Left arm
+ sf::VertexArray left_arm_quad(sf::Quads, 4);
+ left_arm_quad[0].position = sf::Vector2f(window.getView().getSize().x * x_pos + 92, window.getView().getSize().y * 0.8 + 65);
+ left_arm_quad[1].position = sf::Vector2f(window.getView().getSize().x * x_pos + 132, window.getView().getSize().y * 0.8 + 65);
+ left_arm_quad[2].position = sf::Vector2f(window.getView().getSize().x * x_pos + 132, window.getView().getSize().y * 0.8);
+ left_arm_quad[3].position = sf::Vector2f(window.getView().getSize().x * x_pos + 92, window.getView().getSize().y * 0.8);
+ left_arm_quad[0].texCoords = sf::Vector2f(178.f, 130.f);
+ left_arm_quad[1].texCoords = sf::Vector2f(256.f, 130.f);
+ left_arm_quad[2].texCoords = sf::Vector2f(256.f, 0.f);
+ left_arm_quad[3].texCoords = sf::Vector2f(178.f, 0.f);
+
+ float left_arm_red = 255 - (255 * ((float)mech_to_draw.left_arm_integrity / (float)mech_to_draw.max_left_arm_integrity));
+ float left_arm_green = 100 * ((float)mech_to_draw.left_arm_integrity / (float)mech_to_draw.max_left_arm_integrity);
+ for (int i = 0; i < 4; i++)
+ {
+ left_arm_quad[i].color = sf::Color(left_arm_red, left_arm_green, 0, 255);
+ }
+ window.draw(left_arm_quad, &resources.mech_status_texture);
+
+ // Reactor
+ sf::VertexArray reactor_quad(sf::Quads, 4);
+ reactor_quad[0].position = sf::Vector2f(window.getView().getSize().x * x_pos + 45, window.getView().getSize().y * 0.8 + 50);
+ reactor_quad[1].position = sf::Vector2f(window.getView().getSize().x * x_pos + 88, window.getView().getSize().y * 0.8 + 50);
+ reactor_quad[2].position = sf::Vector2f(window.getView().getSize().x * x_pos + 88, window.getView().getSize().y * 0.8 + 30);
+ reactor_quad[3].position = sf::Vector2f(window.getView().getSize().x * x_pos + 45, window.getView().getSize().y * 0.8 + 30);
+ reactor_quad[0].texCoords = sf::Vector2f(85.f, 96.f);
+ reactor_quad[1].texCoords = sf::Vector2f(170.f, 96.f);
+ reactor_quad[2].texCoords = sf::Vector2f(170.f, 56.f);
+ reactor_quad[3].texCoords = sf::Vector2f(85.f, 56.f);
+
+ float reactor_red = 255 - (255 * ((float)mech_to_draw.reactor_integrity / (float)mech_to_draw.max_reactor_integrity));
+ float reactor_green = 100 * ((float)mech_to_draw.reactor_integrity / (float)mech_to_draw.max_reactor_integrity);
+ for (int i = 0; i < 4; i++)
+ {
+ reactor_quad[i].color = sf::Color(reactor_red, reactor_green, 0, 255);
+ }
+ window.draw(reactor_quad, &resources.mech_status_texture);
+
+ // Cooler
+ sf::VertexArray cooler_quad(sf::Quads, 4);
+ cooler_quad[0].position = sf::Vector2f(window.getView().getSize().x * x_pos + 45, window.getView().getSize().y * 0.8 + 70);
+ cooler_quad[1].position = sf::Vector2f(window.getView().getSize().x * x_pos + 88, window.getView().getSize().y * 0.8 + 70);
+ cooler_quad[2].position = sf::Vector2f(window.getView().getSize().x * x_pos + 88, window.getView().getSize().y * 0.8 + 50);
+ cooler_quad[3].position = sf::Vector2f(window.getView().getSize().x * x_pos + 45, window.getView().getSize().y * 0.8 + 50);
+ cooler_quad[0].texCoords = sf::Vector2f(85.f, 134.f);
+ cooler_quad[1].texCoords = sf::Vector2f(170.f, 134.f);
+ cooler_quad[2].texCoords = sf::Vector2f(170.f, 96.f);
+ cooler_quad[3].texCoords = sf::Vector2f(85.f, 96.f);
+
+ float cooler_red = 255 - (255 * ((float)mech_to_draw.cooler_integrity / (float)mech_to_draw.max_cooler_integrity));
+ float cooler_green = 100 * ((float)mech_to_draw.cooler_integrity / (float)mech_to_draw.max_cooler_integrity);
+ for (int i = 0; i < 4; i++)
+ {
+ cooler_quad[i].color = sf::Color(cooler_red, cooler_green, 0, 255);
+ }
+ window.draw(cooler_quad, &resources.mech_status_texture);
+
+ // Right leg
+ sf::VertexArray right_leg_quad(sf::Quads, 4);
+ right_leg_quad[0].position = sf::Vector2f(window.getView().getSize().x * x_pos + 3, window.getView().getSize().y * 0.8 + 133);
+ right_leg_quad[1].position = sf::Vector2f(window.getView().getSize().x * x_pos + 67, window.getView().getSize().y * 0.8 + 133);
+ right_leg_quad[2].position = sf::Vector2f(window.getView().getSize().x * x_pos + 67, window.getView().getSize().y * 0.8 + 69);
+ right_leg_quad[3].position = sf::Vector2f(window.getView().getSize().x * x_pos + 3, window.getView().getSize().y * 0.8 + 69);
+ right_leg_quad[0].texCoords = sf::Vector2f(0.f, 256.f);
+ right_leg_quad[1].texCoords = sf::Vector2f(128.f, 256.f);
+ right_leg_quad[2].texCoords = sf::Vector2f(128.f, 131.f);
+ right_leg_quad[3].texCoords = sf::Vector2f(0.f, 131.f);
+
+ float right_leg_red = 255 - (255 * ((float)mech_to_draw.right_leg_integrity / (float)mech_to_draw.max_right_leg_integrity));
+ float right_leg_green = 100 * ((float)mech_to_draw.right_leg_integrity / (float)mech_to_draw.max_right_leg_integrity);
+ for (int i = 0; i < 4; i++)
+ {
+ right_leg_quad[i].color = sf::Color(right_leg_red, right_leg_green, 0, 255);
+ }
+ window.draw(right_leg_quad, &resources.mech_status_texture);
+
+ // Left leg
+ sf::VertexArray left_leg_quad(sf::Quads, 4);
+ left_leg_quad[0].position = sf::Vector2f(window.getView().getSize().x * x_pos + 67, window.getView().getSize().y * 0.8 + 133);
+ left_leg_quad[1].position = sf::Vector2f(window.getView().getSize().x * x_pos + 131, window.getView().getSize().y * 0.8 + 133);
+ left_leg_quad[2].position = sf::Vector2f(window.getView().getSize().x * x_pos + 131, window.getView().getSize().y * 0.8 + 69);
+ left_leg_quad[3].position = sf::Vector2f(window.getView().getSize().x * x_pos + 67, window.getView().getSize().y * 0.8 + 69);
+ left_leg_quad[0].texCoords = sf::Vector2f(128.f, 256.f);
+ left_leg_quad[1].texCoords = sf::Vector2f(256.f, 256.f);
+ left_leg_quad[2].texCoords = sf::Vector2f(256.f, 131.f);
+ left_leg_quad[3].texCoords = sf::Vector2f(128.f, 131.f);
+
+ float left_leg_red = 255 - (255 * ((float)mech_to_draw.left_leg_integrity / (float)mech_to_draw.max_left_leg_integrity));
+ float left_leg_green = 100 * ((float)mech_to_draw.left_leg_integrity / (float)mech_to_draw.max_left_leg_integrity);
+ for (int i = 0; i < 4; i++)
+ {
+ left_leg_quad[i].color = sf::Color(left_leg_red, left_leg_green, 0, 255);
+ }
+ window.draw(left_leg_quad, &resources.mech_status_texture);
+}
+
+void hud::draw_hud(sf::RenderWindow &window, float frame_time, int target_id, float speed, float torso_angle, mech &player_mech, mech &target_mech)
+{
+ sf::Sprite status_bg = sf::Sprite(resources.gui_background_texture);
+ status_bg.setPosition(0, window.getView().getSize().y * 0.786);
+ status_bg.setScale(window.getView().getSize().x / 2977, window.getView().getSize().y / 1600);
+ window.draw(status_bg);
+
+ // Draw torso angle a the bottom right corner of the screen
+ int torso_angle_int = floor(torso_angle);
+ sf::String torso_string = "TORSO: " + std::to_string(torso_angle_int);
+ resources.torso_display.setString(torso_string);
+ resources.torso_display.setPosition(window.getView().getSize().x * 0.05, window.getView().getSize().y * 0.83);
+ window.draw(resources.torso_display);
+
+ // Draw throttle percentage a the bottom right corner of the screen
+ int throttle = floor((speed) / 0.125 * 100);
+ sf::String throttle_string = "THROTTLE: " + std::to_string(throttle);
+ resources.throttle_display.setString(throttle_string);
+ resources.throttle_display.setPosition(window.getView().getSize().x * 0.05, window.getView().getSize().y * 0.86);
+ window.draw(resources.throttle_display);
+
+ // Draw mech status at the bottom of the screen
+ sf::String status =
+ "MECH STATUS\n\nRIGHT LEG: " + std::to_string(player_mech.right_leg_integrity) + "\n" +
+ "LEFT LEG: " + std::to_string(player_mech.left_leg_integrity) + "\n" +
+ "RIGHT ARM: " + std::to_string(player_mech.right_arm_integrity) + "\n" +
+ "LEFT ARM: " + std::to_string(player_mech.left_arm_integrity) + "\n" +
+ "REACTOR: " + std::to_string(player_mech.reactor_integrity) + "\n" +
+ "COOLER: " + std::to_string(player_mech.cooler_integrity) + "\n" +
+ "COCKPIT: " + std::to_string(player_mech.cockpit_integrity) + "\n" +
+ "HEAT: " + std::to_string((int)player_mech.heat);
+ resources.mech_status.setString(status);
+ resources.mech_status.setPosition(window.getView().getSize().x * 0.15, window.getView().getSize().y * 0.80);
+ window.draw(resources.mech_status);
+ draw_mech(0.265, player_mech, window);
+
+ // Draw player heat meter
+ sf::VertexArray heat_quad_bg(sf::Quads, 4);
+ heat_quad_bg[0].position = sf::Vector2f(window.getView().getSize().x * 0.265 + 178, window.getView().getSize().y * 0.825 + 106);
+ heat_quad_bg[1].position = sf::Vector2f(window.getView().getSize().x * 0.265 + 213, window.getView().getSize().y * 0.825 + 106);
+ heat_quad_bg[2].position = sf::Vector2f(window.getView().getSize().x * 0.265 + 213, window.getView().getSize().y * 0.825);
+ heat_quad_bg[3].position = sf::Vector2f(window.getView().getSize().x * 0.265 + 178, window.getView().getSize().y * 0.825);
+ for (int i = 0; i < 4; i++)
+ {
+ heat_quad_bg[i].color = sf::Color::Black;
+ }
+ window.draw(heat_quad_bg);
+
+ sf::VertexArray heat_quad(sf::Quads, 4);
+ heat_quad[0].position = sf::Vector2f(window.getView().getSize().x * 0.265 + 180, window.getView().getSize().y * 0.83 + 100);
+ heat_quad[1].position = sf::Vector2f(window.getView().getSize().x * 0.265 + 212, window.getView().getSize().y * 0.83 + 100);
+ heat_quad[2].position = sf::Vector2f(window.getView().getSize().x * 0.265 + 212, window.getView().getSize().y * 0.83 + 100 - player_mech.heat);
+ heat_quad[3].position = sf::Vector2f(window.getView().getSize().x * 0.265 + 180, window.getView().getSize().y * 0.83 + 100 - player_mech.heat);
+ for (int i = 0; i < 4; i++)
+ {
+ heat_quad[i].color = sf::Color(200, 0, 0, 255);
+ }
+ window.draw(heat_quad);
+
+ // Draw target status at the bottom of the screen
+ if (target_id != 0)
+ {
+ sf::Sprite status_bg = sf::Sprite(resources.target_gui_background_texture);
+ status_bg.setPosition(window.getView().getSize().x * 0.685, window.getView().getSize().y * 0.786);
+ status_bg.setScale(window.getView().getSize().x / 2285, window.getView().getSize().y / 1600);
+ window.draw(status_bg);
+
+ sf::String status =
+ "TARGET STATUS\n\nRIGHT LEG: " + std::to_string(target_mech.right_leg_integrity) + "\n" +
+ "LEFT LEG: " + std::to_string(target_mech.left_leg_integrity) + "\n" +
+ "RIGHT ARM: " + std::to_string(target_mech.right_arm_integrity) + "\n" +
+ "LEFT ARM: " + std::to_string(target_mech.left_arm_integrity) + "\n" +
+ "REACTOR: " + std::to_string(target_mech.reactor_integrity) + "\n" +
+ "COOLER: " + std::to_string(target_mech.cooler_integrity) + "\n" +
+ "COCKPIT: " + std::to_string(target_mech.cockpit_integrity) + "\n" +
+ "HEAT: " + std::to_string((int)target_mech.heat);
+ resources.target_status.setString(status);
+ resources.target_status.setPosition(window.getView().getSize().x * 0.7, window.getView().getSize().y * 0.80);
+ window.draw(resources.target_status);
+ draw_mech(0.82, target_mech, window);
+
+ // Draw target heat meter
+ sf::VertexArray heat_quad_bg(sf::Quads, 4);
+ heat_quad_bg[0].position = sf::Vector2f(window.getView().getSize().x * 0.82 + 178, window.getView().getSize().y * 0.825 + 106);
+ heat_quad_bg[1].position = sf::Vector2f(window.getView().getSize().x * 0.82 + 214, window.getView().getSize().y * 0.825 + 106);
+ heat_quad_bg[2].position = sf::Vector2f(window.getView().getSize().x * 0.82 + 214, window.getView().getSize().y * 0.825);
+ heat_quad_bg[3].position = sf::Vector2f(window.getView().getSize().x * 0.82 + 178, window.getView().getSize().y * 0.825);
+ for (int i = 0; i < 4; i++)
+ {
+ heat_quad_bg[i].color = sf::Color::Black;
+ }
+ window.draw(heat_quad_bg);
+
+ sf::VertexArray heat_quad(sf::Quads, 4);
+ heat_quad[0].position = sf::Vector2f(window.getView().getSize().x * 0.82 + 180, window.getView().getSize().y * 0.83 + 100);
+ heat_quad[1].position = sf::Vector2f(window.getView().getSize().x * 0.82 + 212, window.getView().getSize().y * 0.83 + 100);
+ heat_quad[2].position = sf::Vector2f(window.getView().getSize().x * 0.82 + 212, window.getView().getSize().y * 0.83 + 100 - target_mech.heat);
+ heat_quad[3].position = sf::Vector2f(window.getView().getSize().x * 0.82 + 180, window.getView().getSize().y * 0.83 + 100 - target_mech.heat);
+ for (int i = 0; i < 4; i++)
+ {
+ heat_quad[i].color = sf::Color(200, 0, 0, 255);
+ }
+ window.draw(heat_quad);
+ }
+
+ // Draw the crosshair
+ if (player_mech.destroyed() == false)
+ {
+ float chx = (window.getView().getSize().x / 2) - (resources.crosshair_texture.getSize().x / 2);
+ float chy = (window.getView().getSize().y / 2) - (resources.crosshair_texture.getSize().y / 2) * 3;
+ sf::Vector2f chv(chx, chy);
+ resources.crosshair_sprite.setPosition(chv);
+ window.draw(resources.crosshair_sprite);
+ }
+
+ // Draw notices
+ if (show_notice == true)
+ {
+ display_notice(window, notice, frame_time);
+ }
+}
diff --git a/src/intermission_menu.cpp b/src/intermission_menu.cpp
new file mode 100644
index 0000000..f5b89dc
--- /dev/null
+++ b/src/intermission_menu.cpp
@@ -0,0 +1,1050 @@
+#include
+#include
+#include
+
+// Constructor
+intermission_menu::intermission_menu()
+{
+ kp = 0;
+ spark_timer = 0;
+ start_game = false;
+ return_to_main = false;
+}
+
+// Gets the current directory, initializes resources, market menu and settings menu
+void intermission_menu::init(std::string cwd, assets &resources)
+{
+ this->cwd = cwd;
+ this->resources = resources;
+ market.init(cwd);
+ s_menu.init(cwd, resources, false);
+}
+
+// Returns true if a prompt is displayed
+bool intermission_menu::prompt_displayed()
+{
+ return save_prompt_open == true || load_prompt_open == true || repair_prompt_open == true;
+}
+
+// Displays a notice with the given string
+void intermission_menu::display_notice(sf::RenderWindow &window, std::string notice, float frame_time)
+{
+ sf::Vector2f notice_pos;
+ notice_pos.x = (window.getView().getSize().x / 2) - (resources.notice.getGlobalBounds().width / 2);
+ notice_pos.y = (window.getView().getSize().y / 2) - 100;
+ resources.notice.setString(notice);
+ resources.notice.setPosition(notice_pos);
+ window.draw(resources.notice);
+
+ notice_timer += 10 * frame_time;
+ if (notice_timer >= 30)
+ {
+ notice_timer = 0;
+ show_notice = false;
+ market.show_notice = false;
+ }
+}
+
+// Draws butons associated with saved games
+void intermission_menu::draw_saved_game_buttons(sf::RenderWindow &window)
+{
+ float x = window.getView().getSize().x / 2 - 150;
+
+ for (unsigned int i = 0; i < saved_game_labels.size(); i++)
+ {
+ saved_game_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ saved_game_buttons[i][0].position = sf::Vector2f(x, (200 + i * 35) - 4);
+ saved_game_buttons[i][1].position = sf::Vector2f(x, (200 + i * 35) + 24);
+ saved_game_buttons[i][2].position = sf::Vector2f(x + 225, (200 + i * 35) + 24);
+ saved_game_buttons[i][3].position = sf::Vector2f(x + 225, (200 + i * 35) - 4);
+
+ sf::VertexArray saved_game_shadow = sf::VertexArray(sf::Quads, 4);
+ saved_game_shadow[0].position = sf::Vector2f(x, (200 + i * 35) - 4);
+ saved_game_shadow[1].position = sf::Vector2f(x, (200 + i * 35) + 27);
+ saved_game_shadow[2].position = sf::Vector2f(x + 228, (200 + i * 35) + 27);
+ saved_game_shadow[3].position = sf::Vector2f(x + 228, (200 + i * 35) - 4);
+
+ saved_game_shadow[0].color = sf::Color::Black;
+ saved_game_shadow[1].color = sf::Color::Black;
+ saved_game_shadow[2].color = sf::Color::Black;
+ saved_game_shadow[3].color = sf::Color::Black;
+
+ if (saved_game_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ saved_game_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ saved_game_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ saved_game_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ saved_game_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ saved_game_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ saved_game_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ saved_game_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ saved_game_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ saved_game_labels[i].setFont(resources.exoplanetaria);
+ saved_game_labels[i].setCharacterSize(16);
+ saved_game_labels[i].setFillColor(sf::Color::Black);
+ saved_game_labels[i].setPosition(x + 20, 200 + (i * 35));
+
+ if (saved_game_labels[i].getString() != "")
+ {
+ window.draw(saved_game_shadow);
+ window.draw(saved_game_buttons[i]);
+ window.draw(saved_game_labels[i]);
+ }
+ }
+}
+
+// Draws buttons used to delete saved games
+void intermission_menu::draw_delete_buttons(sf::RenderWindow &window)
+{
+ float x = window.getView().getSize().x / 2 + 100;
+
+ for (unsigned int i = 0; i < saved_game_labels.size(); i++)
+ {
+ delete_save_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ delete_save_buttons[i][0].position = sf::Vector2f(x, (200 + i * 35) - 4);
+ delete_save_buttons[i][1].position = sf::Vector2f(x, (200 + i * 35) + 24);
+ delete_save_buttons[i][2].position = sf::Vector2f(x + 70, (200 + i * 35) + 24);
+ delete_save_buttons[i][3].position = sf::Vector2f(x + 70, (200 + i * 35) - 4);
+
+ sf::VertexArray delete_save_shadow = sf::VertexArray(sf::Quads, 4);
+ delete_save_shadow[0].position = sf::Vector2f(x, (200 + i * 35) - 4);
+ delete_save_shadow[1].position = sf::Vector2f(x, (200 + i * 35) + 27);
+ delete_save_shadow[2].position = sf::Vector2f(x + 73, (200 + i * 35) + 27);
+ delete_save_shadow[3].position = sf::Vector2f(x + 73, (200 + i * 35) - 4);
+
+ delete_save_shadow[0].color = sf::Color::Black;
+ delete_save_shadow[1].color = sf::Color::Black;
+ delete_save_shadow[2].color = sf::Color::Black;
+ delete_save_shadow[3].color = sf::Color::Black;
+
+ if (delete_save_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ delete_save_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ delete_save_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ delete_save_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ delete_save_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ delete_save_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ delete_save_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ delete_save_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ delete_save_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ delete_save_labels[i].setFont(resources.exoplanetaria);
+ delete_save_labels[i].setCharacterSize(16);
+ delete_save_labels[i].setFillColor(sf::Color::Black);
+ delete_save_labels[i].setPosition(x + 10, 200 + (i * 35));
+ delete_save_labels[i].setString("DELETE");
+
+ if (saved_game_labels[i].getString() != "")
+ {
+ window.draw(delete_save_shadow);
+ window.draw(delete_save_buttons[i]);
+ window.draw(delete_save_labels[i]);
+ }
+ }
+}
+
+// Returns saved game data as a single string
+std::string intermission_menu::get_save_data(player_controller &pc)
+{
+ return std::to_string(pc.credits) + "\n" +
+ std::to_string(pc.mission) + "\n" +
+ std::to_string(pc.player_mech.cockpit_integrity) + "\n" +
+ std::to_string(pc.player_mech.reactor_integrity) + "\n" +
+ std::to_string(pc.player_mech.cooler_integrity)+ "\n" +
+ std::to_string(pc.player_mech.left_arm_integrity) + "\n" +
+ std::to_string(pc.player_mech.right_arm_integrity) + "\n" +
+ std::to_string(pc.player_mech.left_leg_integrity) + "\n" +
+ std::to_string(pc.player_mech.right_leg_integrity) + "\n" +
+ std::to_string(pc.player_mech.max_cockpit_integrity) + "\n" +
+ std::to_string(pc.player_mech.max_reactor_integrity) + "\n" +
+ std::to_string(pc.player_mech.max_cooler_integrity) + "\n" +
+ std::to_string(pc.player_mech.max_left_arm_integrity) + "\n" +
+ std::to_string(pc.player_mech.max_right_arm_integrity) + "\n" +
+ std::to_string(pc.player_mech.max_left_leg_integrity) + "\n" +
+ std::to_string(pc.player_mech.max_right_leg_integrity) + "\n" +
+ std::to_string(pc.player_mech.cooler_modifier) + "\n" +
+ std::to_string(pc.player_mech.guns_modifier) + "\n" +
+ std::to_string(pc.player_mech.cannons_modifier) + "\n" +
+ std::to_string(pc.player_mech.weight) + "\n" +
+ pc.player_mech.primary_weapon + "\n" +
+ pc.player_mech.secondary_weapon + "\n" +
+ pc.player_mech.reactor + "\n" +
+ pc.player_mech.cooler + "\n" +
+ pc.player_mech.left_leg + "\n" +
+ pc.player_mech.right_leg + "\n" +
+ pc.player_mech.left_arm + "\n" +
+ pc.player_mech.right_arm + "\n" +
+ pc.player_mech.cockpit;
+}
+
+// Creates a new save game
+void intermission_menu::create_save(player_controller &pc)
+{
+ std::string saves = get_file_contents(cwd + "/save/saves.list");
+ std::string delimiter = "\n";
+ std::string token;
+
+ int index = 0;
+ size_t pos = 0;
+ while ((pos = saves.find(delimiter)) != std::string::npos)
+ {
+ token = saves.substr(0, pos);
+ saves.erase(0, pos + delimiter.length());
+ index++;
+ }
+
+ if (index < 10)
+ {
+ std::string save = append_file(cwd + "/save/saves.list", input);
+ std::string result = write_to_file(cwd + "/save/" + input + ".sav", get_save_data(pc));
+ save_prompt_open = false;
+ create_save_prompt_open = false;
+ notice = "GAME SAVED";
+ show_notice = true;
+ }
+ else
+ {
+ notice = "SAVE LIMIT REACHED";
+ show_notice = true;
+ }
+
+ input = "";
+ resources.input_text.setString(input);
+}
+
+// Overwrites an existing save game
+void intermission_menu::save_game(player_controller &pc, int i)
+{
+ std::string result = write_to_file(cwd + "/save/" + saved_game_labels[i].getString() + ".sav", get_save_data(pc));
+ save_prompt_open = false;
+ notice = "GAME SAVED";
+ show_notice = true;
+}
+
+// Loads a saved game
+void intermission_menu::load_game(std::string cwd, std::string file, player_controller &pc)
+{
+ int index = 0;
+ size_t pos = 0;
+ std::string token;
+ std::string delimiter = "\n";
+ std::vector values(30);
+ std::string data = get_file_contents(cwd + "/save/" + file + ".sav");
+
+ while ((pos = data.find(delimiter)) != std::string::npos)
+ {
+ values[index] = data.substr(0, pos);
+ data.erase(0, pos + delimiter.length());
+ index++;
+ }
+
+ pc.credits = std::stoi(values[0]);
+ pc.mission = std::stoi(values[1]);
+ pc.player_mech.cockpit_integrity = std::stoi(values[2]);
+ pc.player_mech.reactor_integrity = std::stoi(values[3]);
+ pc.player_mech.cooler_integrity = std::stoi(values[4]);
+ pc.player_mech.left_arm_integrity = std::stoi(values[5]);
+ pc.player_mech.right_arm_integrity = std::stoi(values[6]);
+ pc.player_mech.left_leg_integrity = std::stoi(values[7]);
+ pc.player_mech.right_leg_integrity = std::stoi(values[8]);
+ pc.player_mech.max_cockpit_integrity = std::stoi(values[9]);
+ pc.player_mech.max_reactor_integrity = std::stoi(values[10]);
+ pc.player_mech.max_cooler_integrity = std::stoi(values[11]);
+ pc.player_mech.max_left_arm_integrity = std::stoi(values[12]);
+ pc.player_mech.max_right_arm_integrity = std::stoi(values[13]);
+ pc.player_mech.max_left_leg_integrity = std::stoi(values[14]);
+ pc.player_mech.max_right_leg_integrity = std::stoi(values[15]);
+ pc.player_mech.cooler_modifier = std::stoi(values[16]);
+ pc.player_mech.guns_modifier = std::stoi(values[17]);
+ pc.player_mech.cannons_modifier = std::stoi(values[18]);
+ pc.player_mech.weight = std::stoi(values[19]);
+ pc.player_mech.primary_weapon = values[20];
+ pc.player_mech.secondary_weapon = values[21];
+ pc.player_mech.reactor = values[22];
+ pc.player_mech.cooler = values[23];
+ pc.player_mech.left_leg = values[24];
+ pc.player_mech.right_leg = values[25];
+ pc.player_mech.left_arm = values[26];
+ pc.player_mech.right_arm = values[27];
+ pc.player_mech.cockpit = values[28];
+}
+
+// Deletes a saved game
+void intermission_menu::delete_save_game(int i)
+{
+ std::string save_to_delete = cwd + "/save/" + saved_game_labels[i].getString() + ".sav";
+ char file [100];
+ sprintf(file, "%s", save_to_delete.c_str());
+ std::remove(file);
+ std::string saves = get_file_contents(cwd + "/save/saves.list");
+ std::string delimiter = "\n";
+ std::string new_saves;
+ std::string token;
+ size_t pos = 0;
+ while ((pos = saves.find(delimiter)) != std::string::npos)
+ {
+ token = saves.substr(0, pos);
+ if (token != saved_game_labels[i].getString())
+ {
+ new_saves += token + "\n";
+ }
+ saves.erase(0, pos + delimiter.length());
+ }
+ new_saves.erase(new_saves.find_last_not_of(" \n\r\t")+1);
+ write_to_file(cwd + "/save/saves.list", new_saves);
+ notice = "SAVE DELETED";
+ show_notice = true;
+}
+
+// Resets all game related progress
+void intermission_menu::reset_game(player_controller &pc)
+{
+ pc.credits = 0;
+ pc.mission = 1;
+ pc.player_mech.cockpit_integrity = 1000;
+ pc.player_mech.reactor_integrity = 1000;
+ pc.player_mech.cooler_integrity = 1000;
+ pc.player_mech.left_arm_integrity = 1000;
+ pc.player_mech.right_arm_integrity = 1000;
+ pc.player_mech.left_leg_integrity = 1000;
+ pc.player_mech.right_leg_integrity = 1000;
+ pc.player_mech.max_cockpit_integrity = 1000;
+ pc.player_mech.max_reactor_integrity = 1000;
+ pc.player_mech.max_cooler_integrity = 1000;
+ pc.player_mech.max_left_arm_integrity = 1000;
+ pc.player_mech.max_right_arm_integrity = 1000;
+ pc.player_mech.max_left_leg_integrity = 1000;
+ pc.player_mech.max_right_leg_integrity = 1000;
+ pc.player_mech.cooler_modifier = 0;
+ pc.player_mech.guns_modifier = 0;
+ pc.player_mech.cannons_modifier = 0;
+ pc.player_mech.weight = 70;
+ pc.player_mech.primary_weapon = "Standard Pulse Laser";
+ pc.player_mech.secondary_weapon = "Standard Autocannon";
+ pc.player_mech.reactor = "Standard Reactor";
+ pc.player_mech.cooler = "Standard Cooler";
+ pc.player_mech.left_leg = "Standard Left Leg";
+ pc.player_mech.right_leg = "Standard Right Leg";
+ pc.player_mech.left_arm = "Standard Left Arm";
+ pc.player_mech.right_arm = "Standard Right Arm";
+ pc.player_mech.cockpit = "Standard Cockpit";
+}
+
+// Draws the repair menu
+void intermission_menu::draw_repair_menu(sf::RenderWindow &window, player_controller &pc)
+{
+ // Title
+ int cost_to_repair = 10 * (pc.player_mech.max_total_integrity() - pc.player_mech.total_integrity());
+ sf::Vector2f notice_pos;
+ notice_pos.x = (window.getView().getSize().x / 2) - (resources.notice.getGlobalBounds().width / 2);
+ notice_pos.y = (window.getView().getSize().y / 2) - 120;
+ if (cost_to_repair > 0)
+ {
+ resources.notice.setString("Repairing your mech will cost " + std::to_string(cost_to_repair) + " credits.");
+ }
+ else
+ {
+ resources.notice.setString("Your mech is not in need of repair.");
+ }
+ resources.notice.setPosition(notice_pos);
+ window.draw(resources.notice);
+
+ // Repair Button
+ if (resources.repair_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.repair_button_sprite.setTexture(resources.repair_button_hover_texture);
+ }
+ else
+ {
+ resources.repair_button_sprite.setTexture(resources.repair_button_texture);
+ }
+ float b3x = (window.getView().getSize().x / 2) - (resources.repair_button_texture.getSize().x / 2);
+ float b3y = (window.getView().getSize().y / 2) - 20;
+ sf::Vector2f b3v(b3x, b3y);
+ resources.repair_button_sprite.setPosition(b3v);
+ window.draw(resources.repair_button_sprite);
+
+ // Cancel Button
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_hover_texture);
+ }
+ else
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_texture);
+ }
+ float cx = (window.getView().getSize().x / 2) - (resources.cancel_button_texture.getSize().x / 2);
+ float cy = (window.getView().getSize().y / 2) + 20;
+ sf::Vector2f cv(cx, cy);
+ resources.cancel_button_sprite.setPosition(cv);
+ window.draw(resources.cancel_button_sprite);
+}
+
+// Draws the save game menu
+void intermission_menu::draw_save_menu(sf::RenderWindow &window)
+{
+ if (create_save_prompt_open == true)
+ {
+ sf::Vector2f term_pos;
+ sf::Vector2f text_pos;
+ term_pos.x = (window.getView().getSize().x / 2) - (resources.term_sprite.getTexture()->getSize().x / 2);
+ term_pos.y = (window.getView().getSize().y / 2) - 70;
+ text_pos.x = term_pos.x + 8;
+ text_pos.y = term_pos.y + 8;
+ resources.term_sprite.setPosition(term_pos);
+ resources.input_text.setPosition(text_pos);
+ window.draw(resources.term_sprite);
+ window.draw(resources.input_text);
+
+ sf::Vector2f notice_pos;
+ notice_pos.x = (window.getView().getSize().x / 2) - (resources.notice.getGlobalBounds().width / 2);
+ notice_pos.y = (window.getView().getSize().y / 2) - 120;
+ resources.notice.setString("Enter a name for your saved game.");
+ resources.notice.setPosition(notice_pos);
+ window.draw(resources.notice);
+
+ // Save Button
+ if (resources.save_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.save_game_button_sprite.setTexture(resources.save_game_button_hover_texture);
+ }
+ else
+ {
+ resources.save_game_button_sprite.setTexture(resources.save_game_button_texture);
+ }
+ float b3x = (window.getView().getSize().x / 2) - (resources.save_game_button_texture.getSize().x / 2);
+ float b3y = (window.getView().getSize().y / 2) - 20;
+ sf::Vector2f b3v(b3x, b3y);
+ resources.save_game_button_sprite.setPosition(b3v);
+ window.draw(resources.save_game_button_sprite);
+
+ // Cancel Button
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_hover_texture);
+ }
+ else
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_texture);
+ }
+ float b4x = (window.getView().getSize().x / 2) - (resources.load_game_button_texture.getSize().x / 2);
+ float b4y = (window.getView().getSize().y / 2) + 20;
+ sf::Vector2f b4v(b4x, b4y);
+ resources.cancel_button_sprite.setPosition(b4v);
+ window.draw(resources.cancel_button_sprite);
+ }
+ else
+ {
+ // Create new save button
+ if (resources.create_new_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.create_new_button_sprite.setTexture(resources.create_new_button_hover_texture);
+ }
+ else
+ {
+ resources.create_new_button_sprite.setTexture(resources.create_new_button_texture);
+ }
+ float bx = (window.getView().getSize().x / 2) - (resources.create_new_button_texture.getSize().x / 2);
+ float by = 150;
+ sf::Vector2f bv(bx, by);
+ resources.create_new_button_sprite.setPosition(bv);
+ window.draw(resources.create_new_button_sprite);
+
+ // Cancel button
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_hover_texture);
+ }
+ else
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_texture);
+ }
+ float cx = (window.getView().getSize().x / 2) - (resources.cancel_button_texture.getSize().x / 2);
+ float cy = 100;
+ sf::Vector2f cv(cx, cy);
+ resources.cancel_button_sprite.setPosition(cv);
+ window.draw(resources.cancel_button_sprite);
+
+ int index = 0;
+ size_t pos = 0;
+ std::string saves = get_file_contents(cwd + "/save/saves.list");
+ std::string delimiter = "\n";
+ std::string token;
+
+ // Get the number of saved games
+ while ((pos = saves.find(delimiter)) != std::string::npos)
+ {
+ token = saves.substr(0, pos);
+ saves.erase(0, pos + delimiter.length());
+ index++;
+ }
+
+ // Resize arrays
+ saved_game_buttons.resize(index);
+ saved_game_labels.resize(index);
+ delete_save_buttons.resize(index);
+ delete_save_labels.resize(index);
+
+ // Reset variables
+ pos = 0;
+ index = 0;
+ saves = get_file_contents(cwd + "/save/saves.list");
+
+ // Create text objects for all existing save files
+ while ((pos = saves.find(delimiter)) != std::string::npos)
+ {
+ token = saves.substr(0, pos);
+ saved_game_labels[index].setString(token);
+ saves.erase(0, pos + delimiter.length());
+ index++;
+ }
+
+ // Save game buttons
+ draw_saved_game_buttons(window);
+
+ // Delete save buttons
+ draw_delete_buttons(window);
+ }
+}
+
+// Draws the load game menu
+void intermission_menu::draw_load_menu(sf::RenderWindow &window)
+{
+ int index = 0;
+ size_t pos = 0;
+ std::string saves = get_file_contents(cwd + "/save/saves.list");
+ std::string delimiter = "\n";
+ std::string token;
+
+ // Get the number of saved games
+ while ((pos = saves.find(delimiter)) != std::string::npos)
+ {
+ token = saves.substr(0, pos);
+ saves.erase(0, pos + delimiter.length());
+ index++;
+ }
+
+ // Resize arrays
+ saved_game_buttons.resize(index);
+ saved_game_labels.resize(index);
+ delete_save_buttons.resize(index);
+ delete_save_labels.resize(index);
+
+ // Reset variables
+ pos = 0;
+ index = 0;
+ saves = get_file_contents(cwd + "/save/saves.list");
+
+ // Create text objects for all existing save files
+ while ((pos = saves.find(delimiter)) != std::string::npos)
+ {
+ token = saves.substr(0, pos);
+ saved_game_labels[index].setString(token);
+ saves.erase(0, pos + delimiter.length());
+ index++;
+ }
+
+ // Load game buttons
+ draw_saved_game_buttons(window);
+
+ // Delete save buttons
+ draw_delete_buttons(window);
+
+ // Cancel Button
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_hover_texture);
+ }
+ else
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_texture);
+ }
+ float bx = (window.getView().getSize().x / 2) - (resources.cancel_button_texture.getSize().x / 2);
+ float by = 150;
+ sf::Vector2f bv(bx, by);
+ resources.cancel_button_sprite.setPosition(bv);
+ window.draw(resources.cancel_button_sprite);
+}
+
+// Handles all drawing and interaction with the menu
+bool intermission_menu::draw_menu(sf::RenderWindow &window, player_controller &pc, float frame_time)
+{
+ if (start_game == false && return_to_main == false)
+ {
+ // Play intermission music
+ resources.intermission_music.setVolume(50 * audio_volume);
+
+ if (resources.intermission_music.getStatus() != sf::Sound::Playing)
+ {
+ resources.intermission_music.play();
+ }
+
+ // Process events
+ sf::Event event;
+ while (window.pollEvent(event))
+ {
+ // Close window : exit
+ if (event.type == sf::Event::Closed)
+ {
+ window.close();
+ }
+
+ if(event.type == sf::Event::MouseMoved)
+ {
+ mouse_position = sf::Mouse().getPosition(window);
+ }
+
+ if (event.type == sf::Event::MouseButtonPressed)
+ {
+ if(event.mouseButton.button == sf::Mouse::Left)
+ {
+ if (prompt_displayed() == false && show_notice == false && market.visible == false && s_menu.visible == false)
+ {
+ if (resources.next_mission_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ if (pc.player_mech.destroyed() == false)
+ {
+ resources.intermission_music.stop();
+ start_game = true;
+ }
+ else
+ {
+ notice = "YOUR MECH IS INOPERABLE";
+ show_notice = true;
+ }
+ }
+
+ if (resources.repair_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ repair_prompt_open = true;
+ }
+
+ if (resources.market_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ market.visible = true;
+ }
+
+ if (resources.save_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ save_prompt_open = true;
+ }
+
+ if (resources.load_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ load_prompt_open = true;
+ }
+
+ if (resources.options_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ s_menu.visible = true;
+ }
+
+ if (resources.main_menu_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.intermission_music.stop();
+ reset_game(pc);
+ return_to_main = true;
+ }
+ }
+ else if (save_prompt_open == true)
+ {
+ if (create_save_prompt_open == true)
+ {
+ if (resources.save_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ create_save(pc);
+ }
+
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ create_save_prompt_open = false;
+ }
+ }
+ else
+ {
+ if (resources.create_new_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ create_save_prompt_open = true;
+ }
+
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ save_prompt_open = false;
+ }
+
+ for (unsigned int i = 0; i < saved_game_labels.size(); i++)
+ {
+ if (saved_game_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ save_game(pc, i);
+ }
+ }
+
+ for (unsigned int i = 0; i < delete_save_labels.size(); i++)
+ {
+ if (delete_save_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ delete_save_game(i);
+ save_prompt_open = false;
+ }
+ }
+ }
+ }
+ else if (load_prompt_open == true)
+ {
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ load_prompt_open = false;
+ }
+
+ for (unsigned int i = 0; i < saved_game_labels.size(); i++)
+ {
+ if (saved_game_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ load_game(cwd, saved_game_labels[i].getString(), pc);
+ load_prompt_open = false;
+ notice = "GAME LOADED";
+ show_notice = true;
+ }
+ }
+
+ for (unsigned int i = 0; i < delete_save_labels.size(); i++)
+ {
+ if (delete_save_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ delete_save_game(i);
+ load_prompt_open = false;
+ }
+ }
+ }
+ else if (repair_prompt_open == true)
+ {
+ if (resources.repair_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ int cost_to_repair = 10 * (pc.player_mech.max_total_integrity() - pc.player_mech.total_integrity());
+ if (cost_to_repair > 0)
+ {
+ if (pc.credits >= cost_to_repair)
+ {
+ pc.credits -= cost_to_repair;
+ pc.player_mech.repair();
+ resources.purchase_sound.setVolume(100 * audio_volume);
+ resources.purchase_sound.play();
+ repair_prompt_open = false;
+ notice = "MECH REPAIRED";
+ show_notice = true;
+ }
+ else
+ {
+ notice = "INSUFFICIENT FUNDS";
+ show_notice = true;
+ }
+ }
+ }
+
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ repair_prompt_open = false;
+ }
+ }
+ else if (market.visible == true)
+ {
+ market.handle_events(event, pc, mouse_position);
+ }
+ else if (s_menu.visible == true)
+ {
+ s_menu.handle_events(event, mouse_position);
+ }
+ }
+ }
+
+ if (event.type == sf::Event::TextEntered && save_prompt_open == true)
+ {
+ if (event.text.unicode != '\b' && event.text.unicode != '`' && input.getSize() < 24)
+ {
+ input += event.text.unicode;
+ resources.input_text.setString(input);
+ kp++;
+ }
+ }
+
+ if (event.type == sf::Event::KeyPressed)
+ {
+ if (save_prompt_open == true)
+ {
+ if (event.key.code == sf::Keyboard::Return)
+ {
+ input += "\n";
+ resources.input_text.setString(input);
+ kp = 0;
+ }
+
+ if (event.key.code == sf::Keyboard::BackSpace)
+ {
+ if (input.getSize() > 0)
+ {
+ input.erase(input.getSize() - 1, 1);
+ resources.input_text.setString(input);
+ }
+ }
+
+ if (event.key.code == sf::Keyboard::Escape)
+ {
+ save_prompt_open = false;
+ }
+ }
+ else if (load_prompt_open == true)
+ {
+ if (event.key.code == sf::Keyboard::Escape)
+ {
+ load_prompt_open = false;
+ }
+ }
+ else if (repair_prompt_open == true)
+ {
+ if (event.key.code == sf::Keyboard::Escape)
+ {
+ repair_prompt_open = false;
+ }
+ }
+ else if (market.visible == true)
+ {
+ if (event.key.code == sf::Keyboard::Escape)
+ {
+ market.visible = false;
+ }
+ }
+ else if (s_menu.visible == true)
+ {
+ if (event.key.code == sf::Keyboard::Escape)
+ {
+ s_menu.visible = false;
+ }
+ }
+ }
+ }
+ window.clear();
+
+ // Draw the background
+ resources.menu_background_sprite.setPosition(0,0);
+ resources.menu_background_sprite.setScale(
+ window.getView().getSize().x / resources.menu_background_sprite.getTexture()->getSize().x,
+ window.getView().getSize().y / resources.menu_background_sprite.getTexture()->getSize().y);
+ window.draw(resources.menu_background_sprite);
+
+ // Randomly display welding sparks for the mech being repaired in the background
+ spark_timer += 10 * frame_time;
+ if (spark_timer >= 10)
+ {
+ spark_timer = 0;
+ int random_spark = rand() % 90;
+
+ if (random_spark >= 0 && random_spark < 30)
+ {
+ resources.menu_mech_sprite.setTexture(resources.menu_mech_texture);
+ }
+ else if (random_spark >= 30 && random_spark < 60)
+ {
+ resources.menu_mech_sprite.setTexture(resources.menu_mech_spark_1_texture);
+ }
+ else if (random_spark >= 60)
+ {
+ resources.menu_mech_sprite.setTexture(resources.menu_mech_spark_2_texture);
+ }
+ }
+ resources.menu_mech_sprite.setScale(1.1, 1.1);
+ float mech_x = window.getView().getSize().x / 2 - ((resources.menu_mech_sprite.getTexture()->getSize().x * 1.1) / 2);
+ float mech_y = window.getView().getSize().y - 550;
+ sf::Vector2f mech_position = sf::Vector2f(mech_x, mech_y);
+ resources.menu_mech_sprite.setPosition(mech_position);
+ window.draw(resources.menu_mech_sprite);
+
+ // Draw saved game information
+ sf::Sprite bg_sprite = sf::Sprite(resources.gui_background_2_texture);
+ bg_sprite.setPosition(10, window.getView().getSize().y * 0.23);
+ bg_sprite.setScale(0.24, 1);
+ window.draw(bg_sprite);
+
+ sf::String status =
+ "CREDITS: " + std::to_string(pc.credits) + "\n" +
+ "MISSION: " + std::to_string(pc.mission) + "\n\n" +
+ "MECH LOADOUT\n\nWEIGHT: " + std::to_string(pc.player_mech.weight) + "/110" + "\n" +
+ "PRIMARY WEAPON: " + pc.player_mech.primary_weapon+ " +" + std::to_string(pc.player_mech.guns_modifier) + "\n" +
+ "SECONDARY WEAPON: " + pc.player_mech.secondary_weapon + " +" + std::to_string(pc.player_mech.cannons_modifier) + "\n" +
+ "COCKPIT: " + pc.player_mech.cockpit + "\n" +
+ "REACTOR: " + pc.player_mech.reactor + "\n" +
+ "COOLER: " + pc.player_mech.cooler + " +" + std::to_string(pc.player_mech.cooler_modifier) + "\n" +
+ "LEFT ARM: " + pc.player_mech.left_arm + "\n" +
+ "RIGHT ARM: " + pc.player_mech.right_arm + "\n" +
+ "LEFT LEG: " + pc.player_mech.left_leg + "\n" +
+ "RIGHT LEG: " + pc.player_mech.right_leg + "\n\n" +
+ "MECH STATUS\n\nRIGHT LEG: " + std::to_string(pc.player_mech.right_leg_integrity) + " / " + std::to_string(pc.player_mech.max_right_leg_integrity) + "\n" +
+ "LEFT LEG: " + std::to_string(pc.player_mech.left_leg_integrity) + " / " + std::to_string(pc.player_mech.max_left_leg_integrity) + "\n" +
+ "RIGHT ARM: " + std::to_string(pc.player_mech.right_arm_integrity) + " / " + std::to_string(pc.player_mech.max_right_arm_integrity) + "\n" +
+ "LEFT ARM: " + std::to_string(pc.player_mech.left_arm_integrity) + " / " + std::to_string(pc.player_mech.max_left_arm_integrity) + "\n" +
+ "REACTOR: " + std::to_string(pc.player_mech.reactor_integrity) + " / " + std::to_string(pc.player_mech.max_reactor_integrity) + "\n" +
+ "COOLER: " + std::to_string(pc.player_mech.cooler_integrity) + " / " + std::to_string(pc.player_mech.max_cooler_integrity) + "\n" +
+ "COCKPIT: " + std::to_string(pc.player_mech.cockpit_integrity) + " / " + std::to_string(pc.player_mech.max_cockpit_integrity);
+ resources.mech_status.setString(status);
+ resources.mech_status.setPosition(20, window.getView().getSize().y * 0.25);
+ window.draw(resources.mech_status);
+
+ if (prompt_displayed() == false && show_notice == false && market.visible == false && s_menu.visible == false)
+ {
+ // Next Mission
+ if (resources.next_mission_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.next_mission_button_sprite.setTexture(resources.next_mission_button_hover_texture);
+ }
+ else
+ {
+ resources.next_mission_button_sprite.setTexture(resources.next_mission_button_texture);
+ }
+ float bx = (window.getView().getSize().x / 2) - (resources.next_mission_button_texture.getSize().x / 2);
+ float by = resources.menu_mech_sprite.getPosition().y - 120;
+ sf::Vector2f bv(bx, by);
+ resources.next_mission_button_sprite.setPosition(bv);
+ window.draw(resources.next_mission_button_sprite);
+
+ // Repair
+ if (resources.repair_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.repair_button_sprite.setTexture(resources.repair_button_hover_texture);
+ }
+ else
+ {
+ resources.repair_button_sprite.setTexture(resources.repair_button_texture);
+ }
+ float b2x = (window.getView().getSize().x / 2) - (resources.repair_button_texture.getSize().x / 2);
+ float b2y = resources.menu_mech_sprite.getPosition().y - 70;
+ sf::Vector2f b2v(b2x, b2y);
+ resources.repair_button_sprite.setPosition(b2v);
+ window.draw(resources.repair_button_sprite);
+
+ // Market
+ if (resources.market_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.market_button_sprite.setTexture(resources.market_button_hover_texture);
+ }
+ else
+ {
+ resources.market_button_sprite.setTexture(resources.market_button_texture);
+ }
+ float b3x = (window.getView().getSize().x / 2) - (resources.market_button_texture.getSize().x / 2);
+ float b3y = resources.menu_mech_sprite.getPosition().y - 20;
+ sf::Vector2f b3v(b3x, b3y);
+ resources.market_button_sprite.setPosition(b3v);
+ window.draw(resources.market_button_sprite);
+
+ // Save
+ if (resources.save_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.save_game_button_sprite.setTexture(resources.save_game_button_hover_texture);
+ }
+ else
+ {
+ resources.save_game_button_sprite.setTexture(resources.save_game_button_texture);
+ }
+ float b4x = (window.getView().getSize().x / 2) - (resources.save_game_button_texture.getSize().x / 2);
+ float b4y = resources.menu_mech_sprite.getPosition().y + 30;
+ sf::Vector2f b4v(b4x, b4y);
+ resources.save_game_button_sprite.setPosition(b4v);
+ window.draw(resources.save_game_button_sprite);
+
+ // Load
+ if (resources.load_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.load_game_button_sprite.setTexture(resources.load_game_button_hover_texture);
+ }
+ else
+ {
+ resources.load_game_button_sprite.setTexture(resources.load_game_button_texture);
+ }
+ float b5x = (window.getView().getSize().x / 2) - (resources.load_game_button_texture.getSize().x / 2);
+ float b5y = resources.menu_mech_sprite.getPosition().y + 80;
+ sf::Vector2f b5v(b5x, b5y);
+ resources.load_game_button_sprite.setPosition(b5v);
+ window.draw(resources.load_game_button_sprite);
+
+ // Options
+ if (resources.options_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.options_button_sprite.setTexture(resources.options_button_hover_texture);
+ }
+ else
+ {
+ resources.options_button_sprite.setTexture(resources.options_button_texture);
+ }
+ float b6x = (window.getView().getSize().x / 2) - (resources.options_button_texture.getSize().x / 2);
+ float b6y = resources.menu_mech_sprite.getPosition().y + 130;
+ sf::Vector2f b6v(b6x, b6y);
+ resources.options_button_sprite.setPosition(b6v);
+ window.draw(resources.options_button_sprite);
+
+ // Main Menu
+ if (resources.main_menu_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.main_menu_button_sprite.setTexture(resources.main_menu_button_hover_texture);
+ }
+ else
+ {
+ resources.main_menu_button_sprite.setTexture(resources.main_menu_button_texture);
+ }
+ float b7x = (window.getView().getSize().x / 2) - (resources.main_menu_button_texture.getSize().x / 2);
+ float b7y = resources.menu_mech_sprite.getPosition().y + 180;
+ sf::Vector2f b7v(b7x, b7y);
+ resources.main_menu_button_sprite.setPosition(b7v);
+ window.draw(resources.main_menu_button_sprite);
+ }
+ else if (save_prompt_open == true)
+ {
+ draw_save_menu(window);
+ }
+ else if (load_prompt_open == true)
+ {
+ draw_load_menu(window);
+ }
+ else if (repair_prompt_open == true)
+ {
+ draw_repair_menu(window, pc);
+ }
+ else if (prompt_displayed() == false)
+ {
+ if (show_notice == true)
+ {
+ display_notice(window, notice, frame_time);
+ }
+ else if (market.visible == true)
+ {
+ if (market.show_notice == true)
+ {
+ display_notice(window, market.notice, frame_time);
+ }
+ else
+ {
+ market.draw_menu(window, pc, mouse_position);
+ }
+ }
+ else if (s_menu.visible == true)
+ {
+ s_menu.draw_menu(window, mouse_position, frame_time);
+ }
+ }
+
+ window.display();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/src/key_bindings.cpp b/src/key_bindings.cpp
new file mode 100644
index 0000000..e7b8aac
--- /dev/null
+++ b/src/key_bindings.cpp
@@ -0,0 +1,117 @@
+#include
+
+// Creates aliases for key binds and loads current bindings from file
+void key_bindings::load(std::string cwd)
+{
+ keys["A"] = sf::Keyboard::A;
+ keys["B"] = sf::Keyboard::B;
+ keys["C"] = sf::Keyboard::C;
+ keys["D"] = sf::Keyboard::D;
+ keys["E"] = sf::Keyboard::E;
+ keys["F"] = sf::Keyboard::F;
+ keys["G"] = sf::Keyboard::G;
+ keys["H"] = sf::Keyboard::H;
+ keys["I"] = sf::Keyboard::I;
+ keys["J"] = sf::Keyboard::J;
+ keys["K"] = sf::Keyboard::K;
+ keys["L"] = sf::Keyboard::L;
+ keys["M"] = sf::Keyboard::M;
+ keys["N"] = sf::Keyboard::N;
+ keys["O"] = sf::Keyboard::O;
+ keys["P"] = sf::Keyboard::P;
+ keys["Q"] = sf::Keyboard::Q;
+ keys["R"] = sf::Keyboard::R;
+ keys["S"] = sf::Keyboard::S;
+ keys["T"] = sf::Keyboard::T;
+ keys["U"] = sf::Keyboard::U;
+ keys["V"] = sf::Keyboard::V;
+ keys["W"] = sf::Keyboard::W;
+ keys["X"] = sf::Keyboard::X;
+ keys["Y"] = sf::Keyboard::Y;
+ keys["Z"] = sf::Keyboard::Z;
+
+ keys["Up"] = sf::Keyboard::Up;
+ keys["Down"] = sf::Keyboard::Down;
+ keys["Left"] = sf::Keyboard::Left;
+ keys["Right"] = sf::Keyboard::Right;
+
+ keys["LControl"] = sf::Keyboard::LControl;
+ keys["RControl"] = sf::Keyboard::RControl;
+ keys["LShift"] = sf::Keyboard::LShift;
+ keys["RShift"] = sf::Keyboard::RShift;
+ keys["LAlt"] = sf::Keyboard::LAlt;
+ keys["RAlt"] = sf::Keyboard::RAlt;
+ keys["Space"] = sf::Keyboard::Space;
+ keys["Return"] = sf::Keyboard::Return;
+
+ keys["Num0"] = sf::Keyboard::Num0;
+ keys["Num1"] = sf::Keyboard::Num1;
+ keys["Num2"] = sf::Keyboard::Num2;
+ keys["Num3"] = sf::Keyboard::Num3;
+ keys["Num4"] = sf::Keyboard::Num4;
+ keys["Num5"] = sf::Keyboard::Num5;
+ keys["Num6"] = sf::Keyboard::Num6;
+ keys["Num7"] = sf::Keyboard::Num7;
+ keys["Num8"] = sf::Keyboard::Num8;
+ keys["Num9"] = sf::Keyboard::Num9;
+
+ keys["Numpad0"] = sf::Keyboard::Numpad0;
+ keys["Numpad1"] = sf::Keyboard::Numpad1;
+ keys["Numpad2"] = sf::Keyboard::Numpad2;
+ keys["Numpad3"] = sf::Keyboard::Numpad3;
+ keys["Numpad4"] = sf::Keyboard::Numpad4;
+ keys["Numpad5"] = sf::Keyboard::Numpad5;
+ keys["Numpad6"] = sf::Keyboard::Numpad6;
+ keys["Numpad7"] = sf::Keyboard::Numpad7;
+ keys["Numpad8"] = sf::Keyboard::Numpad8;
+ keys["Numpad9"] = sf::Keyboard::Numpad9;
+
+ keys["F1"] = sf::Keyboard::F1;
+ keys["F2"] = sf::Keyboard::F2;
+ keys["F3"] = sf::Keyboard::F3;
+ keys["F4"] = sf::Keyboard::F4;
+ keys["F5"] = sf::Keyboard::F5;
+ keys["F6"] = sf::Keyboard::F6;
+ keys["F7"] = sf::Keyboard::F7;
+ keys["F8"] = sf::Keyboard::F8;
+ keys["F9"] = sf::Keyboard::F9;
+ keys["F10"] = sf::Keyboard::F10;
+ keys["F11"] = sf::Keyboard::F11;
+ keys["F12"] = sf::Keyboard::F12;
+
+ keys["Tilde"] = sf::Keyboard::Tilde;
+ keys["Tab"] = sf::Keyboard::Tab;
+
+ keys["Home"] = sf::Keyboard::Home;
+ keys["PageUp"] = sf::Keyboard::PageUp;
+ keys["PageDown"] = sf::Keyboard::PageDown;
+ keys["Insert"] = sf::Keyboard::Insert;
+ keys["BackSpace"] = sf::Keyboard::BackSpace;
+ keys["Delete"] = sf::Keyboard::Delete;
+ keys["Pause"] = sf::Keyboard::Pause;
+
+ keys["Dash"] = sf::Keyboard::Dash;
+ keys["Equal"] = sf::Keyboard::Equal;
+ keys["BackSlash"] = sf::Keyboard::BackSlash;
+ keys["LBracket"] = sf::Keyboard::LBracket;
+ keys["RBracket"] = sf::Keyboard::RBracket;
+ keys["SemiColon"] = sf::Keyboard::SemiColon;
+ keys["Quote"] = sf::Keyboard::Quote;
+ keys["Comma"] = sf::Keyboard::Comma;
+ keys["Period"] = sf::Keyboard::Period;
+ keys["Slash"] = sf::Keyboard::Slash;
+
+ size_t pos = 0;
+ std::string entry;
+ std::string delimeter = "\n";
+ std::string saved_bindings = get_file_contents(cwd + "/bindings.list");
+
+ while ((pos = saved_bindings.find(delimeter)) != std::string::npos)
+ {
+ entry = saved_bindings.substr(0, pos);
+ std::string action = entry.substr(0, entry.find(":"));
+ std::string bound = entry.substr(entry.find(":") + 1, pos);
+ bindings[action] = keys[bound];
+ saved_bindings.erase(0, pos + delimeter.length());
+ }
+}
diff --git a/src/main_menu.cpp b/src/main_menu.cpp
new file mode 100644
index 0000000..3d457b4
--- /dev/null
+++ b/src/main_menu.cpp
@@ -0,0 +1,497 @@
+#include
+#include
+#include
+
+// Gets current directory, initializes resources and settings menu
+void main_menu::init(std::string cwd, assets &resources)
+{
+ this->cwd = cwd;
+ this->resources = resources;
+ s_menu.init(cwd, resources, false);
+}
+
+// Loads saved game data from file
+void main_menu::load_game(std::string cwd, std::string file, player_controller &pc)
+{
+ int index = 0;
+ size_t pos = 0;
+ std::string token;
+ std::string delimiter = "\n";
+ std::vector values(30);
+ std::string data = get_file_contents(cwd + "/save/" + file + ".sav");
+
+ while ((pos = data.find(delimiter)) != std::string::npos)
+ {
+ values[index] = data.substr(0, pos);
+ data.erase(0, pos + delimiter.length());
+ index++;
+ }
+
+ pc.credits = std::stoi(values[0]);
+ pc.mission = std::stoi(values[1]);
+ pc.player_mech.cockpit_integrity = std::stoi(values[2]);
+ pc.player_mech.reactor_integrity = std::stoi(values[3]);
+ pc.player_mech.cooler_integrity = std::stoi(values[4]);
+ pc.player_mech.left_arm_integrity = std::stoi(values[5]);
+ pc.player_mech.right_arm_integrity = std::stoi(values[6]);
+ pc.player_mech.left_leg_integrity = std::stoi(values[7]);
+ pc.player_mech.right_leg_integrity = std::stoi(values[8]);
+ pc.player_mech.max_cockpit_integrity = std::stoi(values[9]);
+ pc.player_mech.max_reactor_integrity = std::stoi(values[10]);
+ pc.player_mech.max_cooler_integrity = std::stoi(values[11]);
+ pc.player_mech.max_left_arm_integrity = std::stoi(values[12]);
+ pc.player_mech.max_right_arm_integrity = std::stoi(values[13]);
+ pc.player_mech.max_left_leg_integrity = std::stoi(values[14]);
+ pc.player_mech.max_right_leg_integrity = std::stoi(values[15]);
+ pc.player_mech.cooler_modifier = std::stoi(values[16]);
+ pc.player_mech.guns_modifier = std::stoi(values[17]);
+ pc.player_mech.cannons_modifier = std::stoi(values[18]);
+ pc.player_mech.weight = std::stoi(values[19]);
+ pc.player_mech.primary_weapon = values[20];
+ pc.player_mech.secondary_weapon = values[21];
+ pc.player_mech.reactor = values[22];
+ pc.player_mech.cooler = values[23];
+ pc.player_mech.left_leg = values[24];
+ pc.player_mech.right_leg = values[25];
+ pc.player_mech.left_arm = values[26];
+ pc.player_mech.right_arm = values[27];
+ pc.player_mech.cockpit = values[28];
+}
+
+// Deletes a saved game
+void main_menu::delete_save_game(int i)
+{
+ std::string save_to_delete = cwd + "/save/" + load_game_labels[i].getString() + ".sav";
+ char file [100];
+ sprintf(file, "%s", save_to_delete.c_str());
+ std::remove(file);
+ std::string saves = get_file_contents(cwd + "/save/saves.list");
+ std::string delimiter = "\n";
+ std::string new_saves;
+ std::string token;
+ size_t pos = 0;
+ while ((pos = saves.find(delimiter)) != std::string::npos)
+ {
+ token = saves.substr(0, pos);
+ if (token != load_game_labels[i].getString())
+ {
+ new_saves += token + "\n";
+ }
+ saves.erase(0, pos + delimiter.length());
+ }
+ new_saves.erase(new_saves.find_last_not_of(" \n\r\t")+1);
+ write_to_file(cwd + "/save/saves.list", new_saves);
+ load_prompt_open = false;
+ show_delete_notice = true;
+}
+
+// Draws the load game menu
+void main_menu::draw_load_menu(sf::RenderWindow &window)
+{
+ int index = 0;
+ size_t pos = 0;
+ std::string saves = get_file_contents(cwd + "/save/saves.list");
+ std::string delimiter = "\n";
+ std::string token;
+
+ // Get the number of saved games
+ while ((pos = saves.find(delimiter)) != std::string::npos)
+ {
+ token = saves.substr(0, pos);
+ saves.erase(0, pos + delimiter.length());
+ index++;
+ }
+
+ load_game_buttons.resize(index);
+ load_game_labels.resize(index);
+ delete_save_buttons.resize(index);
+ delete_save_labels.resize(index);
+
+ // Reset variables
+ pos = 0;
+ index = 0;
+ saves = get_file_contents(cwd + "/save/saves.list");
+
+ // Create text objects for all existing save files
+ while ((pos = saves.find(delimiter)) != std::string::npos)
+ {
+ token = saves.substr(0, pos);
+ load_game_labels[index].setString(token);
+ saves.erase(0, pos + delimiter.length());
+ index++;
+ }
+
+ // Load game buttons
+ for (unsigned int i = 0; i < load_game_labels.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 - 150;
+
+ load_game_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ load_game_buttons[i][0].position = sf::Vector2f(x, (200 + i * 35) - 4);
+ load_game_buttons[i][1].position = sf::Vector2f(x, (200 + i * 35) + 24);
+ load_game_buttons[i][2].position = sf::Vector2f(x + 225, (200 + i * 35) + 24);
+ load_game_buttons[i][3].position = sf::Vector2f(x + 225, (200 + i * 35) - 4);
+
+ sf::VertexArray load_game_shadow = sf::VertexArray(sf::Quads, 4);
+ load_game_shadow[0].position = sf::Vector2f(x, (200 + i * 35) - 4);
+ load_game_shadow[1].position = sf::Vector2f(x, (200 + i * 35) + 27);
+ load_game_shadow[2].position = sf::Vector2f(x + 228, (200 + i * 35) + 27);
+ load_game_shadow[3].position = sf::Vector2f(x + 228, (200 + i * 35) - 4);
+
+ load_game_shadow[0].color = sf::Color::Black;
+ load_game_shadow[1].color = sf::Color::Black;
+ load_game_shadow[2].color = sf::Color::Black;
+ load_game_shadow[3].color = sf::Color::Black;
+
+ if (load_game_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ load_game_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ load_game_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ load_game_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ load_game_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ load_game_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ load_game_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ load_game_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ load_game_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ load_game_labels[i].setFont(resources.exoplanetaria);
+ load_game_labels[i].setCharacterSize(16);
+ load_game_labels[i].setFillColor(sf::Color::Black);
+ load_game_labels[i].setPosition(x + 20, 202 + (i * 35 - 2));
+
+ if (load_game_labels[i].getString() != "")
+ {
+ window.draw(load_game_shadow);
+ window.draw(load_game_buttons[i]);
+ window.draw(load_game_labels[i]);
+ }
+ }
+
+ // Delete save buttons
+ for (unsigned int i = 0; i < load_game_labels.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 + 100;
+
+ delete_save_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ delete_save_buttons[i][0].position = sf::Vector2f(x, (200 + i * 35) - 4);
+ delete_save_buttons[i][1].position = sf::Vector2f(x, (200 + i * 35) + 24);
+ delete_save_buttons[i][2].position = sf::Vector2f(x + 70, (200 + i * 35) + 24);
+ delete_save_buttons[i][3].position = sf::Vector2f(x + 70, (200 + i * 35) - 4);
+
+ sf::VertexArray delete_save_shadow = sf::VertexArray(sf::Quads, 4);
+ delete_save_shadow[0].position = sf::Vector2f(x, (200 + i * 35) - 4);
+ delete_save_shadow[1].position = sf::Vector2f(x, (200 + i * 35) + 27);
+ delete_save_shadow[2].position = sf::Vector2f(x + 73, (200 + i * 35) + 27);
+ delete_save_shadow[3].position = sf::Vector2f(x + 73, (200 + i * 35) - 4);
+
+ delete_save_shadow[0].color = sf::Color::Black;
+ delete_save_shadow[1].color = sf::Color::Black;
+ delete_save_shadow[2].color = sf::Color::Black;
+ delete_save_shadow[3].color = sf::Color::Black;
+
+ if (delete_save_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ delete_save_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ delete_save_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ delete_save_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ delete_save_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ delete_save_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ delete_save_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ delete_save_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ delete_save_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ delete_save_labels[i].setFont(resources.exoplanetaria);
+ delete_save_labels[i].setCharacterSize(16);
+ delete_save_labels[i].setFillColor(sf::Color::Black);
+ delete_save_labels[i].setPosition(x + 10, 200 + (i * 35));
+ delete_save_labels[i].setString("DELETE");
+
+ if (load_game_labels[i].getString() != "")
+ {
+ window.draw(delete_save_shadow);
+ window.draw(delete_save_buttons[i]);
+ window.draw(delete_save_labels[i]);
+ }
+ }
+
+ // Cancel Button
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_hover_texture);
+ }
+ else
+ {
+ resources.cancel_button_sprite.setTexture(resources.cancel_button_texture);
+ }
+ float bx = (window.getView().getSize().x / 2) - (resources.cancel_button_texture.getSize().x / 2);
+ float by = 150;
+ sf::Vector2f bv(bx, by);
+ resources.cancel_button_sprite.setPosition(bv);
+ window.draw(resources.cancel_button_sprite);
+}
+
+// Handles all drawing and interaction with the menu
+bool main_menu::draw_menu(sf::RenderWindow &window, player_controller &pc, float frame_time)
+{
+ if (start_game == false)
+ {
+ // Play music
+ resources.main_menu_music.setVolume(100 * audio_volume);
+
+ if (resources.main_menu_music.getStatus() != sf::Sound::Playing)
+ {
+ resources.main_menu_music.play();
+ }
+
+ // Process events
+ sf::Event event;
+ while (window.pollEvent(event))
+ {
+ if(event.type == sf::Event::MouseMoved)
+ {
+ mouse_position = sf::Mouse().getPosition(window);
+ }
+
+ if (event.type == sf::Event::Closed)
+ {
+ window.close();
+ }
+
+ if (s_menu.visible == false)
+ {
+ if (event.type == sf::Event::MouseButtonPressed)
+ {
+ if(event.mouseButton.button == sf::Mouse::Left)
+ {
+ if (load_prompt_open == false)
+ {
+ if (resources.start_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.main_menu_music.stop();
+ start_game = true;
+ }
+
+ if (resources.options_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ s_menu.visible = true;
+ }
+
+ if (resources.load_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ load_prompt_open = true;
+ }
+
+ if (resources.exit_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ window.close();
+ }
+ }
+ else
+ {
+ if (resources.cancel_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ load_prompt_open = false;
+ }
+
+ for (unsigned int i = 0; i < load_game_labels.size(); i++)
+ {
+ if (load_game_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ load_game(cwd, load_game_labels[i].getString(), pc);
+ load_prompt_open = false;
+ show_load_notice = true;
+ }
+ }
+
+ for (unsigned int i = 0; i < delete_save_labels.size(); i++)
+ {
+ if (delete_save_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ delete_save_game(i);
+ }
+ }
+ }
+ }
+ }
+
+ if (event.type == sf::Event::KeyPressed)
+ {
+ if (load_prompt_open == true)
+ {
+ if (event.key.code == sf::Keyboard::Escape)
+ {
+ load_prompt_open = false;
+ }
+ }
+ else if (s_menu.visible == true)
+ {
+ if (event.key.code == sf::Keyboard::Escape)
+ {
+ s_menu.visible = false;
+ }
+ }
+ }
+ }
+ else
+ {
+ s_menu.handle_events(event, mouse_position);
+ }
+ }
+ window.clear();
+
+ // Draw the background
+ resources.menu_background_sprite.setPosition(0,0);
+ resources.menu_background_sprite.setScale(
+ window.getView().getSize().x / resources.menu_background_sprite.getTexture()->getSize().x,
+ window.getView().getSize().y / resources.menu_background_sprite.getTexture()->getSize().y);
+ window.draw(resources.menu_background_sprite);
+
+ // Randomly display welding sparks for the mech being repaired in the background
+ spark_timer += 10 * frame_time;
+ if (spark_timer >= 10)
+ {
+ spark_timer = 0;
+ int random_spark = rand() % 90;
+
+ if (random_spark >= 0 && random_spark < 30)
+ {
+ resources.menu_mech_sprite.setTexture(resources.menu_mech_texture);
+ }
+ else if (random_spark >= 30 && random_spark < 60)
+ {
+ resources.menu_mech_sprite.setTexture(resources.menu_mech_spark_1_texture);
+ }
+ else if (random_spark >= 60)
+ {
+ resources.menu_mech_sprite.setTexture(resources.menu_mech_spark_2_texture);
+ }
+ }
+ resources.menu_mech_sprite.setScale(1.1, 1.1);
+ float mech_x = window.getView().getSize().x / 2 - ((resources.menu_mech_sprite.getTexture()->getSize().x * 1.1) / 2);
+ float mech_y = window.getView().getSize().y - 550;
+ sf::Vector2f mech_position = sf::Vector2f(mech_x, mech_y);
+ resources.menu_mech_sprite.setPosition(mech_position);
+ window.draw(resources.menu_mech_sprite);
+
+ if (load_prompt_open == false && s_menu.visible == false && show_load_notice == false && show_delete_notice == false)
+ {
+ // Start Game Button
+ if (resources.start_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.start_game_button_sprite.setTexture(resources.start_game_button_hover_texture);
+ }
+ else
+ {
+ resources.start_game_button_sprite.setTexture(resources.start_game_button_texture);
+ }
+ float bx = (window.getView().getSize().x / 2) - (resources.start_game_button_texture.getSize().x / 2);
+ float by = resources.menu_mech_sprite.getPosition().y + 40;
+ sf::Vector2f bv(bx, by);
+ resources.start_game_button_sprite.setPosition(bv);
+ window.draw(resources.start_game_button_sprite);
+
+ // Load Game Button
+ if (resources.load_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.load_game_button_sprite.setTexture(resources.load_game_button_hover_texture);
+ }
+ else
+ {
+ resources.load_game_button_sprite.setTexture(resources.load_game_button_texture);
+ }
+ float b2x = (window.getView().getSize().x / 2) - (resources.load_game_button_texture.getSize().x / 2);
+ float b2y = resources.menu_mech_sprite.getPosition().y + 90;
+ sf::Vector2f b2v(b2x, b2y);
+ resources.load_game_button_sprite.setPosition(b2v);
+ window.draw(resources.load_game_button_sprite);
+
+ // Options
+ if (resources.options_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.options_button_sprite.setTexture(resources.options_button_hover_texture);
+ }
+ else
+ {
+ resources.options_button_sprite.setTexture(resources.options_button_texture);
+ }
+ float b3x = (window.getView().getSize().x / 2) - (resources.options_button_texture.getSize().x / 2);
+ float b3y = resources.menu_mech_sprite.getPosition().y + 140;
+ sf::Vector2f b3v(b3x, b3y);
+ resources.options_button_sprite.setPosition(b3v);
+ window.draw(resources.options_button_sprite);
+
+ // Exit Button
+ if (resources.exit_game_button_sprite.getGlobalBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ resources.exit_game_button_sprite.setTexture(resources.exit_game_button_hover_texture);
+ }
+ else
+ {
+ resources.exit_game_button_sprite.setTexture(resources.exit_game_button_texture);
+ }
+ float b4x = (window.getView().getSize().x / 2) - (resources.exit_game_button_texture.getSize().x / 2);
+ float b4y = resources.menu_mech_sprite.getPosition().y + 190;
+ sf::Vector2f b4v(b4x, b4y);
+ resources.exit_game_button_sprite.setPosition(b4v);
+ window.draw(resources.exit_game_button_sprite);
+ }
+ else if (load_prompt_open == true)
+ {
+ draw_load_menu(window);
+ }
+ else if (show_load_notice == true && show_delete_notice == false)
+ {
+ sf::Vector2f text_pos;
+ text_pos.x = (window.getView().getSize().x / 2) - (resources.notice.getGlobalBounds().width / 2);
+ text_pos.y = (window.getView().getSize().y / 2) - 100;
+ resources.notice.setString("GAME LOADED");
+ resources.notice.setPosition(text_pos);
+ window.draw(resources.notice);
+
+ load_notice_timer += 10 * frame_time;
+ if (load_notice_timer >= 30)
+ {
+ resources.main_menu_music.stop();
+ load_notice_timer = 0;
+ show_load_notice = false;
+ game_loaded = true;
+ start_game = true;
+ }
+ }
+ else if (show_load_notice == false && show_delete_notice == true)
+ {
+ sf::Vector2f text_pos;
+ text_pos.x = (window.getView().getSize().x / 2) - (resources.notice.getGlobalBounds().width / 2);
+ text_pos.y = (window.getView().getSize().y / 2) - 100;
+ resources.notice.setString("SAVE DELETED");
+ resources.notice.setPosition(text_pos);
+ window.draw(resources.notice);
+
+ delete_notice_timer += 10 * frame_time;
+ if (delete_notice_timer >= 30)
+ {
+ delete_notice_timer = 0;
+ show_delete_notice = false;
+ }
+ }
+ else if (s_menu.visible == true)
+ {
+ s_menu.draw_menu(window, mouse_position, frame_time);
+ }
+
+ window.display();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/src/market_menu.cpp b/src/market_menu.cpp
new file mode 100644
index 0000000..65a9704
--- /dev/null
+++ b/src/market_menu.cpp
@@ -0,0 +1,1144 @@
+#include
+#include
+
+// Constructor
+market_menu::market_menu()
+{
+ visible = false;
+ item_worth.resize(7);
+ sell_buttons.resize(7);
+ sell_button_labels.resize(7);
+ sell_categories = {"GUNS", "CANNONS", "COOLER", "REACTOR", "COCKPIT", "ARMS", "LEGS"};
+}
+
+// Loads resources from disk
+void market_menu::init(std::string cwd)
+{
+ if (!market_font.loadFromFile(cwd + "/assets/Exoplanetaria-gxxJ5.ttf"))
+ {
+ std::cout << "Failed to load font.";
+ std::cout << "\n";
+ }
+
+ if (!gui_background_texture.loadFromFile(cwd + "/assets/textures/gui_background_2.png"))
+ {
+ std::cout << "Failed to load textures.";
+ }
+
+ if (!purchase_sound_buffer.loadFromFile(cwd + "/assets/sounds/purchase.ogg"))
+ {
+ std::cout << "Error loading sound file purchase.ogg";
+ std::cout << "\n";
+ }
+
+ purchase_sound.setBuffer(purchase_sound_buffer);
+}
+
+// Purchases an item from the market
+void market_menu::purchase_item(player_controller &pc, item item_bought)
+{
+ if (pc.credits >= item_bought.price && pc.player_mech.weight <= 100)
+ {
+ purchase_sound.setVolume(100 * audio_volume);
+ purchase_sound.play();
+ pc.credits -= item_bought.price;
+ pc.player_mech.weight += 10;
+
+ if (item_bought.type == "guns")
+ {
+ pc.player_mech.primary_weapon = item_bought.name;
+ pc.player_mech.guns_modifier = item_bought.modifier;
+ }
+ else if (item_bought.type == "cannons")
+ {
+ pc.player_mech.secondary_weapon = item_bought.name;
+ pc.player_mech.cannons_modifier = item_bought.modifier;
+ }
+ else if (item_bought.type == "cooler")
+ {
+ pc.player_mech.cooler = item_bought.name;
+ pc.player_mech.cooler_integrity = item_bought.modifier;
+ pc.player_mech.max_cooler_integrity = item_bought.modifier;
+ pc.player_mech.cooler_modifier = item_bought.secondary_modifier;
+ }
+ else if (item_bought.type == "reactor")
+ {
+ pc.player_mech.reactor = item_bought.name;
+ pc.player_mech.reactor_integrity = item_bought.modifier;
+ pc.player_mech.max_reactor_integrity = item_bought.modifier;
+ }
+ else if (item_bought.type == "cockpit")
+ {
+ pc.player_mech.cockpit = item_bought.name;
+ pc.player_mech.cockpit_integrity = item_bought.modifier;
+ pc.player_mech.max_cockpit_integrity = item_bought.modifier;
+ }
+ else if (item_bought.type == "arms")
+ {
+ pc.player_mech.left_arm = item_bought.name;
+ pc.player_mech.left_arm_integrity = item_bought.modifier;
+ pc.player_mech.max_left_arm_integrity = item_bought.modifier;
+
+ pc.player_mech.right_arm = item_bought.name;
+ pc.player_mech.right_arm_integrity = item_bought.modifier;
+ pc.player_mech.max_right_arm_integrity = item_bought.modifier;
+ }
+ else if (item_bought.type == "legs")
+ {
+ pc.player_mech.left_leg = item_bought.name;
+ pc.player_mech.left_leg_integrity = item_bought.modifier;
+ pc.player_mech.max_left_leg_integrity = item_bought.modifier;
+
+ pc.player_mech.right_leg = item_bought.name;
+ pc.player_mech.right_leg_integrity = item_bought.modifier;
+ pc.player_mech.max_right_leg_integrity = item_bought.modifier;
+ }
+ }
+}
+
+// Sells an item installed on the player's mech
+void market_menu::sell_item(player_controller &pc, std::string category)
+{
+ if (category == "GUNS")
+ {
+ if (pc.player_mech.primary_weapon != "Standard Pulse Laser")
+ {
+ pc.credits += (item_worth[0]);
+ pc.player_mech.weight -= 10;
+ pc.player_mech.primary_weapon = "Standard Pulse Laser";
+ pc.player_mech.guns_modifier = 0;
+ purchase_sound.setVolume(100 * audio_volume);
+ purchase_sound.play();
+ }
+ else
+ {
+ notice = "CANNOT SELL THIS ITEM";
+ show_notice = true;
+ }
+ }
+ else if (category == "CANNONS")
+ {
+ if (pc.player_mech.secondary_weapon != "Standard Autocannon")
+ {
+ pc.credits += (item_worth[1]);
+ pc.player_mech.weight -= 10;
+ pc.player_mech.secondary_weapon = "Standard Autocannon";
+ pc.player_mech.cannons_modifier = 0;
+ purchase_sound.setVolume(100 * audio_volume);
+ purchase_sound.play();
+ }
+ else
+ {
+ notice = "CANNOT SELL THIS ITEM";
+ show_notice = true;
+ }
+ }
+ else if (category == "COOLER")
+ {
+ if (pc.player_mech.cooler != "Standard Cooler")
+ {
+ pc.credits += (item_worth[2]);
+ pc.player_mech.weight -= 10;
+ pc.player_mech.cooler = "Standard Cooler";
+ pc.player_mech.cooler_modifier = 0;
+ pc.player_mech.cooler_integrity = 1000;
+ pc.player_mech.max_cooler_integrity = 1000;
+ purchase_sound.setVolume(100 * audio_volume);
+ purchase_sound.play();
+ }
+ else
+ {
+ notice = "CANNOT SELL THIS ITEM";
+ show_notice = true;
+ }
+ }
+ else if (category == "REACTOR")
+ {
+ if (pc.player_mech.reactor != "Standard Reactor")
+ {
+ pc.credits += (item_worth[3]);
+ pc.player_mech.weight -= 10;
+ pc.player_mech.reactor = "Standard Reactor";
+ pc.player_mech.reactor_integrity = 1000;
+ pc.player_mech.max_reactor_integrity = 1000;
+ purchase_sound.setVolume(100 * audio_volume);
+ purchase_sound.play();
+ }
+ else
+ {
+ notice = "CANNOT SELL THIS ITEM";
+ show_notice = true;
+ }
+ }
+ else if (category == "COCKPIT")
+ {
+ if (pc.player_mech.cockpit != "Standard Cockpit")
+ {
+ pc.credits += (item_worth[4]);
+ pc.player_mech.weight -= 10;
+ pc.player_mech.cockpit = "Standard Cockpit";
+ pc.player_mech.cockpit_integrity = 1000;
+ pc.player_mech.max_cockpit_integrity = 1000;
+ purchase_sound.setVolume(100 * audio_volume);
+ purchase_sound.play();
+ }
+ else
+ {
+ notice = "CANNOT SELL THIS ITEM";
+ show_notice = true;
+ }
+ }
+ else if (category == "ARMS")
+ {
+ if (pc.player_mech.left_arm != "Standard Left Arm")
+ {
+ pc.credits += (item_worth[5]);
+ pc.player_mech.weight -= 10;
+
+ pc.player_mech.left_arm = "Standard Left Arm";
+ pc.player_mech.left_arm_integrity = 1000;
+ pc.player_mech.max_left_arm_integrity = 1000;
+
+ pc.player_mech.right_arm = "Standard Right Arm";
+ pc.player_mech.right_arm_integrity = 1000;
+ pc.player_mech.max_right_arm_integrity = 1000;
+
+ purchase_sound.setVolume(100 * audio_volume);
+ purchase_sound.play();
+ }
+ else
+ {
+ notice = "CANNOT SELL THIS ITEM";
+ show_notice = true;
+ }
+ }
+ else if (category == "LEGS")
+ {
+ if (pc.player_mech.left_leg != "Standard Left Leg")
+ {
+ pc.credits += (item_worth[6]);
+ pc.player_mech.weight -= 10;
+
+ pc.player_mech.left_leg = "Standard Left Leg";
+ pc.player_mech.left_leg_integrity = 1000;
+ pc.player_mech.max_left_leg_integrity = 1000;
+
+ pc.player_mech.right_leg = "Standard Right Leg";
+ pc.player_mech.right_leg_integrity = 1000;
+ pc.player_mech.max_right_leg_integrity = 1000;
+
+ purchase_sound.setVolume(100 * audio_volume);
+ purchase_sound.play();
+ }
+ else
+ {
+ notice = "CANNOT SELL THIS ITEM";
+ show_notice = true;
+ }
+ }
+}
+
+// Generates items for sale
+void market_menu::generate_items()
+{
+ int gun_amount = 4;
+ guns.resize(gun_amount);
+ gun_buttons.resize(gun_amount);
+ gun_button_labels.resize(gun_amount);
+ gun_descriptions.resize(gun_amount);
+ for (int i = 0; i < gun_amount; i++)
+ {
+ guns[i].type = "guns";
+
+ int level = rand() % 100;
+
+ if (level > 90)
+ {
+ guns[i].name = "L3 Pulse Laser";
+ guns[i].level = 3;
+ guns[i].modifier = 6 + ( rand() % ( 9 - 6 + 1 ) );
+ guns[i].price = guns[i].modifier * 10000;
+ }
+ else if (level <= 90 && level > 60)
+ {
+ guns[i].name = "L2 Pulse Laser";
+ guns[i].level = 2;
+ guns[i].modifier = 4 + ( rand() % ( 6 - 4 + 1 ) );
+ guns[i].price = guns[i].modifier * 10000;
+ }
+ else
+ {
+ guns[i].name = "L1 Pulse Laser";
+ guns[i].level = 1;
+ guns[i].modifier = 1 + ( rand() % ( 3 - 1 + 1 ) );
+ guns[i].price = guns[i].modifier * 10000;
+ }
+ }
+
+ int cannon_amount = 4;
+ cannons.resize(cannon_amount);
+ cannon_buttons.resize(cannon_amount);
+ cannon_button_labels.resize(cannon_amount);
+ cannon_descriptions.resize(cannon_amount);
+ for (int i = 0; i < cannon_amount; i++)
+ {
+ cannons[i].type = "cannons";
+
+ int level = rand() % 100;
+ if (level > 90)
+ {
+ cannons[i].name = "L3 Autocannon";
+ cannons[i].level = 3;
+ cannons[i].modifier = 7 + ( rand() % ( 9 - 7 + 1 ) );
+ cannons[i].price = cannons[i].modifier * 10000;
+ }
+ else if (level <= 90 && level > 60)
+ {
+ cannons[i].name = "L2 Autocannon";
+ cannons[i].level = 2;
+ cannons[i].modifier = 4 + ( rand() % ( 6 - 4 + 1 ) );
+ cannons[i].price = cannons[i].modifier * 10000;
+ }
+ else
+ {
+ cannons[i].name = "L1 Autocannon";
+ cannons[i].level = 1;
+ cannons[i].modifier = 1 + ( rand() % ( 3 - 1 + 1 ) );
+ cannons[i].price = cannons[i].modifier * 10000;
+ }
+ }
+
+ int cooler_amount = 4;
+ coolers.resize(cooler_amount);
+ cooler_buttons.resize(cooler_amount);
+ cooler_button_labels.resize(cooler_amount);
+ cooler_descriptions.resize(cooler_amount);
+ for (int i = 0; i < cooler_amount; i++)
+ {
+ coolers[i].type = "cooler";
+
+ int level = rand() % 100;
+ if (level > 90)
+ {
+ coolers[i].name = "L3 Cooler";
+ coolers[i].level = 3;
+ coolers[i].modifier = 3000 + ( rand() % ( 3500 - 3000 + 1 ) );
+ coolers[i].secondary_modifier = 7 + ( rand() % ( 9 - 7 + 1 ) );
+ coolers[i].price = coolers[i].modifier * 15 + coolers[i].secondary_modifier * 5000;
+ }
+ else if (level <= 90 && level > 60)
+ {
+ coolers[i].name = "L2 Cooler";
+ coolers[i].level = 2;
+ coolers[i].modifier = 2000 + ( rand() % ( 2500 - 2000 + 1 ) );
+ coolers[i].secondary_modifier = 4 + ( rand() % ( 6 - 4 + 1 ) );
+ coolers[i].price = coolers[i].modifier * 10 + coolers[i].secondary_modifier * 5000;
+ }
+ else
+ {
+ coolers[i].name = "L1 Cooler";
+ coolers[i].level = 1;
+ coolers[i].modifier = 1000 + ( rand() % ( 1500 - 1000 + 1 ) );
+ coolers[i].secondary_modifier = 1 + ( rand() % ( 3 - 1 + 1 ) );
+ coolers[i].price = coolers[i].modifier * 5 + coolers[i].secondary_modifier * 5000;
+ }
+ }
+
+ int reactor_amount = 4;
+ reactors.resize(reactor_amount);
+ reactor_buttons.resize(reactor_amount);
+ reactor_button_labels.resize(reactor_amount);
+ reactor_descriptions.resize(reactor_amount);
+ for (int i = 0; i < reactor_amount; i++)
+ {
+ reactors[i].type = "reactor";
+
+ int level = rand() % 100;
+ if (level > 90)
+ {
+ reactors[i].name = "L3 Reactor";
+ reactors[i].level = 3;
+ reactors[i].modifier = 3000 + ( rand() % ( 3500 - 3000 + 1 ) );
+ reactors[i].price = reactors[i].modifier * 15;
+ }
+ else if (level <= 90 && level > 60)
+ {
+ reactors[i].name = "L2 Reactor";
+ reactors[i].level = 2;
+ reactors[i].modifier = 2000 + ( rand() % ( 2500 - 2000 + 1 ) );
+ reactors[i].price = reactors[i].modifier * 10;
+ }
+ else
+ {
+ reactors[i].name = "L1 Reactor";
+ reactors[i].level = 1;
+ reactors[i].modifier = 1000 + ( rand() % ( 1500 - 1000 + 1 ) );
+ reactors[i].price = reactors[i].modifier *5;
+ }
+ }
+
+ int cockpit_amount = 4;
+ cockpits.resize(cockpit_amount);
+ cockpit_buttons.resize(cockpit_amount);
+ cockpit_button_labels.resize(cockpit_amount);
+ cockpit_descriptions.resize(cockpit_amount);
+ for (int i = 0; i < cockpit_amount; i++)
+ {
+ cockpits[i].type = "cockpit";
+
+ int level = rand() % 100;
+ if (level > 90)
+ {
+ cockpits[i].name = "L3 Cockpit";
+ cockpits[i].level = 3;
+ cockpits[i].modifier = 4000 + ( rand() % ( 3500 - 3000 + 1 ) );
+ cockpits[i].price = cockpits[i].modifier * 15;
+ }
+ else if (level <= 90 && level > 60)
+ {
+ cockpits[i].name = "L2 Cockpit";
+ cockpits[i].level = 2;
+ cockpits[i].modifier = 2000 + ( rand() % ( 2500 - 2000 + 1 ) );
+ cockpits[i].price = cockpits[i].modifier *10;
+ }
+ else
+ {
+ cockpits[i].name = "L1 Cockpit";
+ cockpits[i].level = 1;
+ cockpits[i].modifier = 1000 + ( rand() % ( 1500 - 1000 + 1 ) );
+ cockpits[i].price = cockpits[i].modifier * 5;
+ }
+ }
+
+ int arm_amount = 4;
+ arms.resize(arm_amount);
+ arm_buttons.resize(arm_amount);
+ arm_button_labels.resize(arm_amount);
+ arm_descriptions.resize(arm_amount);
+ for (int i = 0; i < arm_amount; i++)
+ {
+ arms[i].type = "arms";
+
+ int level = rand() % 100;
+ if (level > 90)
+ {
+ arms[i].name = "L3 Arms";
+ arms[i].level = 3;
+ arms[i].modifier = 3000 + ( rand() % ( 3500 - 3000 + 1 ) );
+ arms[i].price = arms[i].modifier * 15;
+ }
+ else if (level <= 90 && level > 60)
+ {
+ arms[i].name = "L2 Arms";
+ arms[i].level = 2;
+ arms[i].modifier = 2000 + ( rand() % ( 2500 - 2000 + 1 ) );
+ arms[i].price = arms[i].modifier * 10;
+ }
+ else
+ {
+ arms[i].name = "L1 Arms";
+ arms[i].level = 1;
+ arms[i].modifier = 1000 + ( rand() % ( 1500 - 1000 + 1 ) );
+ arms[i].price = arms[i].modifier * 5;
+ }
+ }
+
+ int leg_amount = 4;
+ legs.resize(leg_amount);
+ leg_buttons.resize(leg_amount);
+ leg_button_labels.resize(leg_amount);
+ leg_descriptions.resize(leg_amount);
+ for (int i = 0; i < leg_amount; i++)
+ {
+ legs[i].type = "legs";
+
+ int level = rand() % 100;
+ if (level > 90)
+ {
+ legs[i].name = "L3 Legs";
+ legs[i].level = 3;
+ legs[i].modifier = 3000 + ( rand() % ( 3500 - 3000 + 1 ) );
+ legs[i].price = legs[i].modifier * 15;
+ }
+ else if (level <= 90 && level > 60)
+ {
+ legs[i].name = "L2 Legs";
+ legs[i].level = 2;
+ legs[i].modifier = 2000 + ( rand() % ( 2500 - 2000 + 1 ) );
+ legs[i].price = legs[i].modifier * 10;
+ }
+ else
+ {
+ legs[i].name = "L1 Legs";
+ legs[i].level = 1;
+ legs[i].modifier = 1000 + ( rand() % ( 1500 - 1000 + 1 ) );
+ legs[i].price = legs[i].modifier * 5;
+ }
+ }
+}
+
+// Mouse click events
+void market_menu::handle_events(sf::Event event, player_controller &pc, sf::Vector2i mouse_position)
+{
+ if (event.type == sf::Event::MouseButtonPressed)
+ {
+ if(event.mouseButton.button == sf::Mouse::Left)
+ {
+ for (unsigned int i = 0; i < gun_buttons.size(); i++)
+ {
+ if (gun_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ purchase_item(pc, guns[i]);
+ }
+ }
+
+ for (unsigned int i = 0; i < cannon_buttons.size(); i++)
+ {
+ if (cannon_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ purchase_item(pc, cannons[i]);
+ }
+ }
+
+ for (unsigned int i = 0; i < cooler_buttons.size(); i++)
+ {
+ if (cooler_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ purchase_item(pc, coolers[i]);
+ }
+ }
+
+ for (unsigned int i = 0; i < reactor_buttons.size(); i++)
+ {
+ if (reactor_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ purchase_item(pc, reactors[i]);
+ }
+ }
+
+ for (unsigned int i = 0; i < cockpit_buttons.size(); i++)
+ {
+ if (cockpit_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ purchase_item(pc, cockpits[i]);
+ }
+ }
+
+ for (unsigned int i = 0; i < arm_buttons.size(); i++)
+ {
+ if (arm_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ purchase_item(pc, arms[i]);
+ }
+ }
+
+ for (unsigned int i = 0; i < leg_buttons.size(); i++)
+ {
+ if (leg_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ purchase_item(pc, legs[i]);
+ }
+ }
+
+ for (unsigned int i = 0; i < sell_buttons.size(); i++)
+ {
+ if (sell_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ sell_item(pc, sell_categories[i]);
+ }
+ }
+
+ if (exit_button.getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ visible = false;
+ }
+ }
+ }
+}
+
+// Draws the market menu
+void market_menu::draw_menu(sf::RenderWindow &window, player_controller &pc, sf::Vector2i mouse_position)
+{
+ sf::Sprite bg_sprite = sf::Sprite(gui_background_texture);
+ bg_sprite.setPosition(window.getView().getSize().x / 2 - 210, 20);
+ bg_sprite.setScale(0.54, 2);
+ window.draw(bg_sprite);
+
+ for (unsigned int i = 0; i < gun_buttons.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 + 100;
+
+ gun_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ gun_buttons[i][0].position = sf::Vector2f(x + 10, (80 + i * 35) - 4);
+ gun_buttons[i][1].position = sf::Vector2f(x + 10, (80 + i * 35) + 24);
+ gun_buttons[i][2].position = sf::Vector2f(x + 80, (80 + i * 35) + 24);
+ gun_buttons[i][3].position = sf::Vector2f(x + 80, (80 + i * 35) - 4);
+
+ sf::VertexArray gun_button_shadow = sf::VertexArray(sf::Quads, 4);
+ gun_button_shadow[0].position = sf::Vector2f(x + 10, (80 + i * 35) - 4);
+ gun_button_shadow[1].position = sf::Vector2f(x + 10, (80 + i * 35) + 27);
+ gun_button_shadow[2].position = sf::Vector2f(x + 83, (80 + i * 35) + 27);
+ gun_button_shadow[3].position = sf::Vector2f(x + 83, (80 + i * 35) - 4);
+
+ gun_button_shadow[0].color = sf::Color::Black;
+ gun_button_shadow[1].color = sf::Color::Black;
+ gun_button_shadow[2].color = sf::Color::Black;
+ gun_button_shadow[3].color = sf::Color::Black;
+
+ if (gun_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ gun_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ gun_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ gun_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ gun_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ gun_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ gun_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ gun_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ gun_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ std::string desc = guns[i].name + ": +" + std::to_string(guns[i].modifier) + " damage, $" + std::to_string(guns[i].price);
+ gun_descriptions[i].setFont(market_font);
+ gun_descriptions[i].setCharacterSize(14);
+ if (guns[i].level == 3)
+ {
+ gun_descriptions[i].setFillColor(sf::Color::Green);
+ }
+ else if (guns[i].level == 2)
+ {
+ gun_descriptions[i].setFillColor(sf::Color::Yellow);
+ }
+ else if (guns[i].level == 1)
+ {
+ gun_descriptions[i].setFillColor(sf::Color::Red);
+ }
+ gun_descriptions[i].setPosition(x - 280, 80 + (i * 35));
+ gun_descriptions[i].setString(desc);
+
+ gun_button_labels[i].setFont(market_font);
+ gun_button_labels[i].setCharacterSize(16);
+ gun_button_labels[i].setFillColor(sf::Color::Black);
+ gun_button_labels[i].setPosition(x + 28, 80 + (i * 35));
+ gun_button_labels[i].setString("BUY");
+
+ window.draw(gun_descriptions[i]);
+ window.draw(gun_button_shadow);
+ window.draw(gun_buttons[i]);
+ window.draw(gun_button_labels[i]);
+ }
+
+ for (unsigned int i = 0; i < cannon_buttons.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 + 100;
+
+ cannon_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ cannon_buttons[i][0].position = sf::Vector2f(x + 10, (220 + i * 35) - 4);
+ cannon_buttons[i][1].position = sf::Vector2f(x + 10, (220 + i * 35) + 24);
+ cannon_buttons[i][2].position = sf::Vector2f(x + 80, (220 + i * 35) + 24);
+ cannon_buttons[i][3].position = sf::Vector2f(x + 80, (220 + i * 35) - 4);
+
+ sf::VertexArray cannon_button_shadow = sf::VertexArray(sf::Quads, 4);
+ cannon_button_shadow[0].position = sf::Vector2f(x + 10, (220 + i * 35) - 4);
+ cannon_button_shadow[1].position = sf::Vector2f(x + 10, (220 + i * 35) + 27);
+ cannon_button_shadow[2].position = sf::Vector2f(x + 83, (220 + i * 35) + 27);
+ cannon_button_shadow[3].position = sf::Vector2f(x + 83, (220 + i * 35) - 4);
+
+ cannon_button_shadow[0].color = sf::Color::Black;
+ cannon_button_shadow[1].color = sf::Color::Black;
+ cannon_button_shadow[2].color = sf::Color::Black;
+ cannon_button_shadow[3].color = sf::Color::Black;
+
+ if (cannon_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ cannon_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ cannon_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ cannon_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ cannon_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ cannon_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ cannon_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ cannon_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ cannon_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ std::string desc = cannons[i].name + ": +" + std::to_string(cannons[i].modifier) + " damage, $" + std::to_string(cannons[i].price);
+ cannon_descriptions[i].setFont(market_font);
+ cannon_descriptions[i].setCharacterSize(14);
+ if (cannons[i].level == 3)
+ {
+ cannon_descriptions[i].setFillColor(sf::Color::Green);
+ }
+ else if (cannons[i].level == 2)
+ {
+ cannon_descriptions[i].setFillColor(sf::Color::Yellow);
+ }
+ else if (cannons[i].level == 1)
+ {
+ cannon_descriptions[i].setFillColor(sf::Color::Red);
+ }
+ cannon_descriptions[i].setPosition(x - 280, 220 + (i * 35));
+ cannon_descriptions[i].setString(desc);
+
+ cannon_button_labels[i].setFont(market_font);
+ cannon_button_labels[i].setCharacterSize(16);
+ cannon_button_labels[i].setFillColor(sf::Color::Black);
+ cannon_button_labels[i].setPosition(x + 28, 220 + (i * 35));
+ cannon_button_labels[i].setString("BUY");
+
+ window.draw(cannon_descriptions[i]);
+ window.draw(cannon_button_shadow);
+ window.draw(cannon_buttons[i]);
+ window.draw(cannon_button_labels[i]);
+ }
+
+ for (unsigned int i = 0; i < cooler_buttons.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 + 100;
+
+ cooler_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ cooler_buttons[i][0].position = sf::Vector2f(x + 10, (360 + i * 35) - 4);
+ cooler_buttons[i][1].position = sf::Vector2f(x + 10, (360 + i * 35) + 24);
+ cooler_buttons[i][2].position = sf::Vector2f(x + 80, (360 + i * 35) + 24);
+ cooler_buttons[i][3].position = sf::Vector2f(x + 80, (360 + i * 35) - 4);
+
+ sf::VertexArray cooler_button_shadow = sf::VertexArray(sf::Quads, 4);
+ cooler_button_shadow[0].position = sf::Vector2f(x + 10, (360 + i * 35) - 4);
+ cooler_button_shadow[1].position = sf::Vector2f(x + 10, (360 + i * 35) + 27);
+ cooler_button_shadow[2].position = sf::Vector2f(x + 83, (360 + i * 35) + 27);
+ cooler_button_shadow[3].position = sf::Vector2f(x + 83, (360 + i * 35) - 4);
+
+ cooler_button_shadow[0].color = sf::Color::Black;
+ cooler_button_shadow[1].color = sf::Color::Black;
+ cooler_button_shadow[2].color = sf::Color::Black;
+ cooler_button_shadow[3].color = sf::Color::Black;
+
+ if (cooler_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ cooler_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ cooler_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ cooler_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ cooler_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ cooler_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ cooler_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ cooler_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ cooler_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ std::string desc = coolers[i].name + ": " + std::to_string(coolers[i].modifier) + " armor, +" + std::to_string(coolers[i].secondary_modifier) + " kbtu, $"+ std::to_string(coolers[i].price);
+ cooler_descriptions[i].setFont(market_font);
+ cooler_descriptions[i].setCharacterSize(14);
+ if (coolers[i].level == 3)
+ {
+ cooler_descriptions[i].setFillColor(sf::Color::Green);
+ }
+ else if (coolers[i].level == 2)
+ {
+ cooler_descriptions[i].setFillColor(sf::Color::Yellow);
+ }
+ else if (coolers[i].level == 1)
+ {
+ cooler_descriptions[i].setFillColor(sf::Color::Red);
+ }
+ cooler_descriptions[i].setPosition(x - 280, 360 + (i * 35));
+ cooler_descriptions[i].setString(desc);
+
+ cooler_button_labels[i].setFont(market_font);
+ cooler_button_labels[i].setCharacterSize(16);
+ cooler_button_labels[i].setFillColor(sf::Color::Black);
+ cooler_button_labels[i].setPosition(x + 28, 360 + (i * 35));
+ cooler_button_labels[i].setString("BUY");
+
+ window.draw(cooler_descriptions[i]);
+ window.draw(cooler_button_shadow);
+ window.draw(cooler_buttons[i]);
+ window.draw(cooler_button_labels[i]);
+ }
+
+ for (unsigned int i = 0; i < reactor_buttons.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 + 100;
+
+ reactor_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ reactor_buttons[i][0].position = sf::Vector2f(x + 10, (500 + i * 35) - 4);
+ reactor_buttons[i][1].position = sf::Vector2f(x + 10, (500 + i * 35) + 24);
+ reactor_buttons[i][2].position = sf::Vector2f(x + 80, (500 + i * 35) + 24);
+ reactor_buttons[i][3].position = sf::Vector2f(x + 80, (500 + i * 35) - 4);
+
+ sf::VertexArray reactor_button_shadow = sf::VertexArray(sf::Quads, 4);
+ reactor_button_shadow[0].position = sf::Vector2f(x + 10, (500 + i * 35) - 4);
+ reactor_button_shadow[1].position = sf::Vector2f(x + 10, (500 + i * 35) + 27);
+ reactor_button_shadow[2].position = sf::Vector2f(x + 83, (500 + i * 35) + 27);
+ reactor_button_shadow[3].position = sf::Vector2f(x + 83, (500 + i * 35) - 4);
+
+ reactor_button_shadow[0].color = sf::Color::Black;
+ reactor_button_shadow[1].color = sf::Color::Black;
+ reactor_button_shadow[2].color = sf::Color::Black;
+ reactor_button_shadow[3].color = sf::Color::Black;
+
+ if (reactor_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ reactor_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ reactor_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ reactor_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ reactor_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ reactor_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ reactor_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ reactor_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ reactor_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ std::string desc = reactors[i].name + ": " + std::to_string(reactors[i].modifier) + " armor, $" + std::to_string(reactors[i].price);
+ reactor_descriptions[i].setFont(market_font);
+ reactor_descriptions[i].setCharacterSize(14);
+ if (reactors[i].level == 3)
+ {
+ reactor_descriptions[i].setFillColor(sf::Color::Green);
+ }
+ else if (reactors[i].level == 2)
+ {
+ reactor_descriptions[i].setFillColor(sf::Color::Yellow);
+ }
+ else if (reactors[i].level == 1)
+ {
+ reactor_descriptions[i].setFillColor(sf::Color::Red);
+ }
+ reactor_descriptions[i].setPosition(x - 280, 502 + (i * 35 - 2));
+ reactor_descriptions[i].setString(desc);
+
+ reactor_button_labels[i].setFont(market_font);
+ reactor_button_labels[i].setCharacterSize(16);
+ reactor_button_labels[i].setFillColor(sf::Color::Black);
+ reactor_button_labels[i].setPosition(x + 28, 502 + (i * 35 - 2));
+ reactor_button_labels[i].setString("BUY");
+
+ window.draw(reactor_descriptions[i]);
+ window.draw(reactor_button_shadow);
+ window.draw(reactor_buttons[i]);
+ window.draw(reactor_button_labels[i]);
+ }
+
+ for (unsigned int i = 0; i < cockpit_buttons.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 + 500;
+
+ cockpit_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ cockpit_buttons[i][0].position = sf::Vector2f(x, (80 + i * 35) - 4);
+ cockpit_buttons[i][1].position = sf::Vector2f(x, (80 + i * 35) + 24);
+ cockpit_buttons[i][2].position = sf::Vector2f(x + 70, (80 + i * 35) + 24);
+ cockpit_buttons[i][3].position = sf::Vector2f(x + 70, (80 + i * 35) - 4);
+
+ sf::VertexArray cockpit_button_shadow = sf::VertexArray(sf::Quads, 4);
+ cockpit_button_shadow[0].position = sf::Vector2f(x, (80 + i * 35) - 4);
+ cockpit_button_shadow[1].position = sf::Vector2f(x, (80 + i * 35) + 27);
+ cockpit_button_shadow[2].position = sf::Vector2f(x + 73, (80 + i * 35) + 27);
+ cockpit_button_shadow[3].position = sf::Vector2f(x + 73, (80 + i * 35) - 4);
+
+ cockpit_button_shadow[0].color = sf::Color::Black;
+ cockpit_button_shadow[1].color = sf::Color::Black;
+ cockpit_button_shadow[2].color = sf::Color::Black;
+ cockpit_button_shadow[3].color = sf::Color::Black;
+
+ if (cockpit_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ cockpit_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ cockpit_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ cockpit_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ cockpit_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ cockpit_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ cockpit_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ cockpit_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ cockpit_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ std::string desc = cockpits[i].name + ": " + std::to_string(cockpits[i].modifier) + " armor, $" + std::to_string(cockpits[i].price);
+ cockpit_descriptions[i].setFont(market_font);
+ cockpit_descriptions[i].setCharacterSize(14);
+ if (cockpits[i].level == 3)
+ {
+ cockpit_descriptions[i].setFillColor(sf::Color::Green);
+ }
+ else if (cockpits[i].level == 2)
+ {
+ cockpit_descriptions[i].setFillColor(sf::Color::Yellow);
+ }
+ else if (cockpits[i].level == 1)
+ {
+ cockpit_descriptions[i].setFillColor(sf::Color::Red);
+ }
+ cockpit_descriptions[i].setPosition(x - 230, 82 + (i * 35 - 2));
+ cockpit_descriptions[i].setString(desc);
+
+ cockpit_button_labels[i].setFont(market_font);
+ cockpit_button_labels[i].setCharacterSize(16);
+ cockpit_button_labels[i].setFillColor(sf::Color::Black);
+ cockpit_button_labels[i].setPosition(x + 18, 82 + (i * 35 - 2));
+ cockpit_button_labels[i].setString("BUY");
+
+ window.draw(cockpit_descriptions[i]);
+ window.draw(cockpit_button_shadow);
+ window.draw(cockpit_buttons[i]);
+ window.draw(cockpit_button_labels[i]);
+ }
+
+ for (unsigned int i = 0; i < arm_buttons.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 + 500;
+
+ arm_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ arm_buttons[i][0].position = sf::Vector2f(x, (220 + i * 35) - 4);
+ arm_buttons[i][1].position = sf::Vector2f(x, (220 + i * 35) + 24);
+ arm_buttons[i][2].position = sf::Vector2f(x + 70, (220 + i * 35) + 24);
+ arm_buttons[i][3].position = sf::Vector2f(x + 70, (220 + i * 35) - 4);
+
+ sf::VertexArray arm_button_shadow = sf::VertexArray(sf::Quads, 4);
+ arm_button_shadow[0].position = sf::Vector2f(x, (220 + i * 35) - 4);
+ arm_button_shadow[1].position = sf::Vector2f(x, (220 + i * 35) + 27);
+ arm_button_shadow[2].position = sf::Vector2f(x + 73, (220 + i * 35) + 27);
+ arm_button_shadow[3].position = sf::Vector2f(x + 73, (220 + i * 35) - 4);
+
+ arm_button_shadow[0].color = sf::Color::Black;
+ arm_button_shadow[1].color = sf::Color::Black;
+ arm_button_shadow[2].color = sf::Color::Black;
+ arm_button_shadow[3].color = sf::Color::Black;
+
+ if (arm_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ arm_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ arm_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ arm_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ arm_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ arm_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ arm_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ arm_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ arm_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ std::string desc = arms[i].name + ": " + std::to_string(arms[i].modifier) + " armor, $" + std::to_string(arms[i].price);
+ arm_descriptions[i].setFont(market_font);
+ arm_descriptions[i].setCharacterSize(14);
+ if (arms[i].level == 3)
+ {
+ arm_descriptions[i].setFillColor(sf::Color::Green);
+ }
+ else if (arms[i].level == 2)
+ {
+ arm_descriptions[i].setFillColor(sf::Color::Yellow);
+ }
+ else if (arms[i].level == 1)
+ {
+ arm_descriptions[i].setFillColor(sf::Color::Red);
+ }
+ arm_descriptions[i].setPosition(x - 230, 222 + (i * 35 - 2));
+ arm_descriptions[i].setString(desc);
+
+ arm_button_labels[i].setFont(market_font);
+ arm_button_labels[i].setCharacterSize(16);
+ arm_button_labels[i].setFillColor(sf::Color::Black);
+ arm_button_labels[i].setPosition(x + 18, 222 + (i * 35 - 2));
+ arm_button_labels[i].setString("BUY");
+
+ window.draw(arm_descriptions[i]);
+ window.draw(arm_button_shadow);
+ window.draw(arm_buttons[i]);
+ window.draw(arm_button_labels[i]);
+ }
+
+ for (unsigned int i = 0; i < leg_buttons.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 + 500;
+
+ leg_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ leg_buttons[i][0].position = sf::Vector2f(x, (360 + i * 35) - 4);
+ leg_buttons[i][1].position = sf::Vector2f(x, (360 + i * 35) + 24);
+ leg_buttons[i][2].position = sf::Vector2f(x + 70, (360 + i * 35) + 24);
+ leg_buttons[i][3].position = sf::Vector2f(x + 70, (360 + i * 35) - 4);
+
+ sf::VertexArray leg_button_shadow = sf::VertexArray(sf::Quads, 4);
+ leg_button_shadow[0].position = sf::Vector2f(x, (360 + i * 35) - 4);
+ leg_button_shadow[1].position = sf::Vector2f(x, (360 + i * 35) + 27);
+ leg_button_shadow[2].position = sf::Vector2f(x + 73, (360 + i * 35) + 27);
+ leg_button_shadow[3].position = sf::Vector2f(x + 73, (360 + i * 35) - 4);
+
+ leg_button_shadow[0].color = sf::Color::Black;
+ leg_button_shadow[1].color = sf::Color::Black;
+ leg_button_shadow[2].color = sf::Color::Black;
+ leg_button_shadow[3].color = sf::Color::Black;
+
+ if (leg_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ leg_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ leg_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ leg_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ leg_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ leg_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ leg_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ leg_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ leg_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ std::string desc = legs[i].name + ": " + std::to_string(legs[i].modifier) + " armor, $"+ std::to_string(legs[i].price);
+ leg_descriptions[i].setFont(market_font);
+ leg_descriptions[i].setCharacterSize(14);
+ if (legs[i].level == 3)
+ {
+ leg_descriptions[i].setFillColor(sf::Color::Green);
+ }
+ else if (legs[i].level == 2)
+ {
+ leg_descriptions[i].setFillColor(sf::Color::Yellow);
+ }
+ else if (legs[i].level == 1)
+ {
+ leg_descriptions[i].setFillColor(sf::Color::Red);
+ }
+ leg_descriptions[i].setPosition(x - 230, 362 + (i * 35 - 2));
+ leg_descriptions[i].setString(desc);
+
+ leg_button_labels[i].setFont(market_font);
+ leg_button_labels[i].setCharacterSize(16);
+ leg_button_labels[i].setFillColor(sf::Color::Black);
+ leg_button_labels[i].setPosition(x + 18, 362 + (i * 35 - 2));
+ leg_button_labels[i].setString("BUY");
+
+ window.draw(leg_descriptions[i]);
+ window.draw(leg_button_shadow);
+ window.draw(leg_buttons[i]);
+ window.draw(leg_button_labels[i]);
+ }
+
+ item_worth[0] = pc.player_mech.guns_modifier * 5000;
+ item_worth[1] = pc.player_mech.cannons_modifier * 5000;
+ item_worth[2] = pc.player_mech.cooler_modifier * 7 + pc.player_mech.cooler_modifier * 2500;
+ item_worth[3] = pc.player_mech.max_reactor_integrity * 3;
+ item_worth[4] = pc.player_mech.max_cockpit_integrity * 3;
+ item_worth[5] = pc.player_mech.max_left_arm_integrity * 3;
+ item_worth[6] = pc.player_mech.max_left_leg_integrity * 3;
+
+ sf::Text worth;
+ worth.setString("");
+
+ for (unsigned int i = 0; i < sell_categories.size(); i++)
+ {
+ float y_origin = window.getView().getSize().y * 0.725;
+ float x = i <= 3 ? 10 : 180;
+ float y = i <= 3 ? i : i - 4;
+
+ sell_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ sell_buttons[i][0].position = sf::Vector2f(x, (y_origin + y * 35) - 4);
+ sell_buttons[i][1].position = sf::Vector2f(x, (y_origin + y * 35) + 24);
+ sell_buttons[i][2].position = sf::Vector2f(x + 140, (y_origin + y * 35) + 24);
+ sell_buttons[i][3].position = sf::Vector2f(x + 140, (y_origin + y * 35) - 4);
+
+ sf::VertexArray sell_button_shadow = sf::VertexArray(sf::Quads, 4);
+ sell_button_shadow[0].position = sf::Vector2f(x, (y_origin + y * 35) - 4);
+ sell_button_shadow[1].position = sf::Vector2f(x, (y_origin + y * 35) + 27);
+ sell_button_shadow[2].position = sf::Vector2f(x + 143, (y_origin + y * 35) + 27);
+ sell_button_shadow[3].position = sf::Vector2f(x + 143, (y_origin + y * 35) - 4);
+
+ sell_button_shadow[0].color = sf::Color::Black;
+ sell_button_shadow[1].color = sf::Color::Black;
+ sell_button_shadow[2].color = sf::Color::Black;
+ sell_button_shadow[3].color = sf::Color::Black;
+
+ if (sell_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ sell_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ sell_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ sell_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ sell_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ sell_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ sell_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ sell_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ sell_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ sell_button_labels[i].setFont(market_font);
+ sell_button_labels[i].setCharacterSize(16);
+ sell_button_labels[i].setFillColor(sf::Color::Black);
+ sell_button_labels[i].setPosition(x + 18, (y_origin + 2) + (y * 35 - 2));
+ sell_button_labels[i].setString("SELL " + sell_categories[i]);
+
+ window.draw(sell_button_shadow);
+ window.draw(sell_buttons[i]);
+ window.draw(sell_button_labels[i]);
+
+ if (sell_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ worth.setString("$" + std::to_string(item_worth[i]));
+ worth.setFont(market_font);
+ worth.setCharacterSize(16);
+ worth.setFillColor(sf::Color::White);
+ worth.setPosition(mouse_position.x + 20, mouse_position.y);
+ }
+ }
+
+ window.draw(worth);
+
+ float x = window.getView().getSize().x / 2 + 500;
+
+ exit_button = sf::VertexArray(sf::Quads, 4);
+ exit_button[0].position = sf::Vector2f(x, 596);
+ exit_button[1].position = sf::Vector2f(x, 624);
+ exit_button[2].position = sf::Vector2f(x + 70, 624);
+ exit_button[3].position = sf::Vector2f(x + 70, 596);
+
+ sf::VertexArray exit_button_shadow = sf::VertexArray(sf::Quads, 4);
+ exit_button_shadow[0].position = sf::Vector2f(x, 596);
+ exit_button_shadow[1].position = sf::Vector2f(x, 627);
+ exit_button_shadow[2].position = sf::Vector2f(x + 73, 627);
+ exit_button_shadow[3].position = sf::Vector2f(x + 73, 596);
+
+ exit_button_shadow[0].color = sf::Color::Black;
+ exit_button_shadow[1].color = sf::Color::Black;
+ exit_button_shadow[2].color = sf::Color::Black;
+ exit_button_shadow[3].color = sf::Color::Black;
+
+ if (exit_button.getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ exit_button[0].color = sf::Color(53, 53, 53, 255);
+ exit_button[1].color = sf::Color(53, 53, 53, 255);
+ exit_button[2].color = sf::Color(53, 53, 53, 255);
+ exit_button[3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ exit_button[0].color = sf::Color(35, 35, 35, 255);
+ exit_button[1].color = sf::Color(35, 35, 35, 255);
+ exit_button[2].color = sf::Color(35, 35, 35, 255);
+ exit_button[3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ sf::Text exit_button_label;
+ exit_button_label.setFont(market_font);
+ exit_button_label.setCharacterSize(18);
+ exit_button_label.setFillColor(sf::Color::Black);
+ exit_button_label.setPosition(x + 18, 598);
+ exit_button_label.setString("EXIT");
+
+ window.draw(exit_button_shadow);
+ window.draw(exit_button);
+ window.draw(exit_button_label);
+}
diff --git a/src/mech.cpp b/src/mech.cpp
new file mode 100644
index 0000000..03dcb33
--- /dev/null
+++ b/src/mech.cpp
@@ -0,0 +1,190 @@
+#include
+#include
+#include
+
+// Constructor
+mech::mech()
+{
+ heat = 0;
+ speed = 0;
+ weapon = 0;
+ weight = 70;
+
+ cockpit_integrity = 1000;
+ right_leg_integrity = 1000;
+ left_leg_integrity = 1000;
+ right_arm_integrity = 1000;
+ left_arm_integrity = 1000;
+ cooler_integrity = 1000;
+ reactor_integrity = 1000;
+
+ guns_modifier = 0;
+ cannons_modifier = 0;
+ cooler_modifier = 0;
+ max_reactor_integrity = 1000;
+ max_cooler_integrity = 1000;
+ max_left_leg_integrity = 1000;
+ max_right_leg_integrity = 1000;
+ max_left_arm_integrity = 1000;
+ max_right_arm_integrity = 1000;
+ max_cockpit_integrity = 1000;
+
+ primary_weapon = "Standard Pulse Laser";
+ secondary_weapon = "Standard Autocannon";
+ reactor = "Standard Reactor";
+ cooler = "Standard Cooler";
+ left_leg = "Standard Left Leg";
+ right_leg = "Standard Right Leg";
+ left_arm = "Standard Left Arm";
+ right_arm = "Standard Right Arm";
+ cockpit = "Standard Cockpit";
+
+ is_player = false;
+ power_down = false;
+ taking_damage = false;
+}
+
+// Removes all damage from the mech
+void mech::repair()
+{
+ power_down = false;
+ heat = 0;
+ cockpit_integrity = max_cockpit_integrity;
+ right_leg_integrity = max_right_leg_integrity;
+ left_leg_integrity = max_left_leg_integrity;
+ right_arm_integrity = max_right_arm_integrity;
+ left_arm_integrity = max_left_arm_integrity;
+ cooler_integrity = max_cooler_integrity;
+ reactor_integrity = max_reactor_integrity;
+}
+
+// Heat and damage calculations
+void mech::update()
+{
+ if (heat >= 90)
+ {
+ reactor_integrity = reactor_integrity >= 1 ? reactor_integrity - 1 : 0;
+ }
+
+ float cooling = ((1 + cooler_modifier) * ((float)cooler_integrity / (float)max_cooler_integrity)) + 0.01;
+ heat = heat > 0 ? heat - cooling : 0;
+
+ if (taking_damage == true)
+ {
+ damage_timer++;
+ if (damage_timer >= 100)
+ {
+ taking_damage = false;
+ damage_timer = 0;
+ }
+ }
+}
+
+// Returns the total integrity of the mech
+int mech::total_integrity()
+{
+ return reactor_integrity +
+ cooler_integrity + right_arm_integrity +
+ left_arm_integrity + right_leg_integrity +
+ left_leg_integrity + cockpit_integrity;
+}
+
+// Returns the maximum total integrity of the mech
+int mech::max_total_integrity()
+{
+ return max_reactor_integrity +
+ max_cooler_integrity + max_right_arm_integrity +
+ max_left_arm_integrity + max_right_leg_integrity +
+ max_left_leg_integrity + max_cockpit_integrity;
+}
+
+// Returns true if the mech's legs are not destroyed
+bool mech::can_move()
+{
+ return left_leg_integrity > 0 && right_leg_integrity > 0;
+}
+
+// Returns true if the mech's arms are not destroyed
+bool mech::can_fire()
+{
+ return left_arm_integrity > 0 || right_arm_integrity > 0;
+}
+
+// Returns true if only the left arm has been destroyed
+bool mech::left_arm_destroyed()
+{
+ return left_arm_integrity < 1 && right_arm_integrity > 0;
+}
+
+// Returns true if only the right arm has been destroyed
+bool mech::right_arm_destroyed()
+{
+ return left_arm_integrity > 0 && right_arm_integrity < 1;
+}
+
+// Returns true if the mech's total integrity is less than 50% or the mech's reactor is destroyed
+bool mech::destroyed()
+{
+ if (reactor_integrity < 1)
+ {
+ return true;
+ }
+
+ if (total_integrity() < max_total_integrity() / 2)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+// Calculates damage dealt to the targeted component
+void mech::take_damage(std::string target, float distance, int weapon)
+{
+ float dist_mod = weapon == 1 ? 0.05 : 0.01;
+ taking_damage = true;
+ damage_timer = 0;
+
+ if (target == "reactor")
+ {
+ int damage_dealt = weapon * ((rand() % 10) - (distance * dist_mod) - (speed * 10));
+ damage_dealt = damage_dealt > 0 ? damage_dealt : 0;
+ reactor_integrity = reactor_integrity - damage_dealt > 0 ? reactor_integrity - damage_dealt : 0;
+ }
+ else if (target == "cooler")
+ {
+ int damage_dealt = weapon * ((rand() % 20) - (distance * dist_mod) - (speed * 20));
+ damage_dealt = damage_dealt > 0 ? damage_dealt : 0;
+ cooler_integrity = cooler_integrity - damage_dealt > 0 ? cooler_integrity - damage_dealt : 0;
+ }
+ else if (target == "left arm")
+ {
+ int damage_dealt = weapon * ((rand() % 30) - (distance * dist_mod) - (speed * 30));
+ damage_dealt = damage_dealt > 0 ? damage_dealt : 0;
+ left_arm_integrity = left_arm_integrity - damage_dealt > 0 ? left_arm_integrity - damage_dealt : 0;
+ }
+ else if (target == "right arm")
+ {
+ int damage_dealt = weapon * ((rand() % 30) - (distance * dist_mod) - (speed * 30));
+ damage_dealt = damage_dealt > 0 ? damage_dealt : 0;
+ right_arm_integrity = right_arm_integrity - damage_dealt > 0 ? right_arm_integrity - damage_dealt : 0;
+ }
+ else if (target == "left leg")
+ {
+ int damage_dealt = weapon * ((rand() % 40) - (distance * dist_mod) - (speed * 40));
+ damage_dealt = damage_dealt > 0 ? damage_dealt : 0;
+ left_leg_integrity = left_leg_integrity - damage_dealt > 0 ? left_leg_integrity - damage_dealt : 0;
+ }
+ else if (target == "right leg")
+ {
+ int damage_dealt = weapon * ((rand() % 40) - (distance * dist_mod) - (speed * 40));
+ damage_dealt = damage_dealt > 0 ? damage_dealt : 0;
+ right_leg_integrity = right_leg_integrity - damage_dealt > 0 ? right_leg_integrity - damage_dealt : 0;
+ }
+ else if (target == "cockpit")
+ {
+ int damage_dealt = weapon * ((rand() % 30) - (distance * dist_mod) - (speed * 30));
+ damage_dealt = damage_dealt > 0 ? damage_dealt : 0;
+ cockpit_integrity = cockpit_integrity - damage_dealt > 0 ? cockpit_integrity - damage_dealt : 0;
+ }
+}
diff --git a/src/player_controller.cpp b/src/player_controller.cpp
new file mode 100644
index 0000000..a91b718
--- /dev/null
+++ b/src/player_controller.cpp
@@ -0,0 +1,628 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Constructor
+player_controller::player_controller()
+{
+ credits = 0;
+ credits_earned = 0;
+ cannon_flash_timer = 0;
+ muzzle_flash_timer = 0;
+ target_id = 0;
+ enemy_id = 0;
+ mission = 1;
+ guns_timer = 0;
+ cannon_timer = 0;
+ stomp_timer = 0;
+ step_timer = 0;
+ torso_angle = 0;
+ look_offset = -6;
+ player_pos.x = 140;
+ player_pos.y = 140;
+ targeted_component = 0;
+ mouse_move_timer = 0;
+ components = {"reactor", "cooler", "left arm", "right arm", "left leg", "right leg", "cockpit"};
+}
+
+// Gets current directory, initializes resources and key bindings
+void player_controller::init(std::string cwd, assets &resources)
+{
+ this->resources = resources;
+ kb.load(cwd);
+}
+
+// Collision checking
+void player_controller::collision_check(entity other, float view_range)
+{
+ if (other.type == "wall")
+ {
+ if (get_distance(other.position, player_pos) < view_range * 0.4)
+ {
+ resources.crash_sound.setVolume(100 * audio_volume);
+ resources.crash_sound.play();
+ player_mech.speed = 0;
+
+ if (other.position.x > player_pos.x)
+ {
+ player_pos.x -= 20;
+ }
+
+ if (other.position.x < player_pos.x)
+ {
+ player_pos.x += 20;
+ }
+
+ if (other.position.y < player_pos.y)
+ {
+ player_pos.y += 20;
+ }
+
+ if (other.position.y > player_pos.y)
+ {
+ player_pos.y -= 20;
+ }
+ }
+ }
+}
+
+// Target locking
+void player_controller::lock_target(std::vector &entities, int entity_count, float window_width)
+{
+ for (int i = 0; i < entity_count; i++)
+ {
+ if (entities[i].visible == true)
+ {
+ float scale = 3 - (entities[i].distance * 0.05) - look_offset * 0.005;
+ float sprite_width = entities[i].sprite.getTexture()->getSize().x * scale;
+ float center = entities[i].draw_x + (sprite_width / 2);
+
+ if (entities[i].visible == true &&
+ entities[i].dead == false &&
+ center > window_width * 0.45 &&
+ center < window_width * 0.55)
+ {
+ target_id = entities[i].id;
+ break;
+ }
+ }
+ }
+}
+
+// Firing guns
+void player_controller::fire_guns(std::vector &entities, int entity_count, float window_width)
+{
+ if(player_mech.can_fire() == true && guns_firing == false && cannon_firing == false)
+ {
+ guns_firing = true;
+ muzzle_flash = true;
+ player_mech.heat = player_mech.heat >= 90 ? 100 : player_mech.heat + 10 + player_mech.guns_modifier;
+
+ for (int i = 0; i < entity_count; i++)
+ {
+ if (entities[i].visible == true && hit_target == false)
+ {
+ float scale = 3 - (entities[i].distance * 0.05) - look_offset * 0.005;
+ float sprite_width = entities[i].sprite.getTexture()->getSize().x * scale;
+ float center = entities[i].draw_x + (sprite_width / 2);
+
+ if (entities[i].visible == true &&
+ entities[i].dead == false &&
+ center > window_width * 0.45 &&
+ center < window_width * 0.55)
+ {
+ if (target_id != entities[i].id)
+ {
+ target_id = entities[i].id;
+ }
+
+ hit_target = true;
+ break;
+ }
+ }
+ }
+
+ resources.gun_sound.setVolume(50 * audio_volume);
+ resources.gun_sound.play();
+ }
+}
+
+// Firing cannon
+void player_controller::fire_cannon(std::vector &entities, int entity_count, float window_width)
+{
+ if(player_mech.can_fire() == true && cannon_firing == false && guns_firing == false)
+ {
+ cannon_firing = true;
+ cannon_flash = true;
+ player_mech.heat = player_mech.heat >= 50 ? 100 : player_mech.heat + 50 + player_mech.cannons_modifier;
+
+ for (int i = 0; i < entity_count; i++)
+ {
+ if (entities[i].visible == true && hit_target == false)
+ {
+ float scale = 3 - (entities[i].distance * 0.05) - look_offset * 0.005;
+ float sprite_width = entities[i].sprite.getTexture()->getSize().x * scale;
+ float center = entities[i].draw_x + (sprite_width / 2);
+
+ if (entities[i].visible == true &&
+ entities[i].dead == false &&
+ center > window_width * 0.45 &&
+ center < window_width * 0.55)
+ {
+ if (target_id != entities[i].id)
+ {
+ target_id = entities[i].id;
+ }
+
+ hit_target = true;
+ break;
+ }
+ }
+ }
+
+ resources.cannon_sound.setVolume(50 * audio_volume);
+ resources.cannon_sound.play();
+ }
+}
+
+// Resets all volatile variables
+void player_controller::reset()
+{
+ throttle_up = false;
+ throttle_down = false;
+ move_forward = false;
+ move_back = false;
+ turn_left = false;
+ turn_right = false;
+ look_left = false;
+ look_right = false;
+ look_up = false;
+ look_down = false;
+ player_firing = false;
+ target_id = 0;
+ enemy_id = 0;
+ guns_timer = 0;
+ stomp_timer = 0;
+ step_timer = 0;
+ torso_angle = 0;
+ look_offset = -6;
+ player_mech.speed = 0;
+ player_pos.x = 140;
+ player_pos.y = 140;
+ targeted_component = 0;
+ credits_earned = 0;
+}
+
+// Called by main window event handler to handle events related to the player controller
+void player_controller::handle_events(sf::RenderWindow &window, sf::Event event)
+{
+ if(event.type == sf::Event::KeyPressed)
+ {
+ if (player_mech.destroyed() == false)
+ {
+ if(event.key.code == kb.bindings["throttle_up"])
+ {
+ throttle_up = true;
+ }
+
+ if(event.key.code == kb.bindings["throttle_down"])
+ {
+ throttle_down = true;
+ }
+
+ if(event.key.code == kb.bindings["turn_left"])
+ {
+ turn_left = true;
+ }
+
+ if(event.key.code == kb.bindings["turn_right"])
+ {
+ turn_right = true;
+ }
+
+ if(event.key.code == kb.bindings["look_left"])
+ {
+ look_left = true;
+ }
+
+ if(event.key.code == kb.bindings["look_right"])
+ {
+ look_right = true;
+ }
+
+ if (event.key.code == kb.bindings["look_down"])
+ {
+ look_down = true;
+ }
+
+ if (event.key.code == kb.bindings["look_up"])
+ {
+ look_up = true;
+ }
+
+ if(event.key.code == kb.bindings["select_component"])
+ {
+ if (targeted_component < 6)
+ {
+ targeted_component++;
+ }
+ else
+ {
+ targeted_component = 0;
+ }
+ }
+
+ if (event.key.code == kb.bindings["fire_guns"])
+ {
+ player_mech.weapon = 1;
+ player_firing = true;
+ }
+
+ if (event.key.code == kb.bindings["fire_cannon"])
+ {
+ player_mech.weapon = 5;
+ player_firing = true;
+ }
+ }
+ }
+
+ if(event.type == sf::Event::KeyReleased)
+ {
+ if(event.key.code == kb.bindings["throttle_up"])
+ {
+ throttle_up = false;
+ }
+
+ if(event.key.code == kb.bindings["throttle_down"])
+ {
+ throttle_down = false;
+ }
+
+ if(event.key.code == kb.bindings["turn_left"])
+ {
+ turn_left = false;
+ }
+
+ if(event.key.code == kb.bindings["turn_right"])
+ {
+ turn_right = false;
+ }
+
+ if(event.key.code == kb.bindings["look_left"])
+ {
+ look_left = false;
+ }
+
+ if(event.key.code == kb.bindings["look_right"])
+ {
+ look_right = false;
+ }
+
+ if(event.key.code == kb.bindings["look_down"])
+ {
+ look_down = false;
+ }
+
+ if(event.key.code == kb.bindings["look_up"])
+ {
+ look_up = false;
+ }
+
+ if (event.key.code == kb.bindings["fire_guns"])
+ {
+ player_firing = false;
+ }
+
+ if (event.key.code == kb.bindings["fire_cannon"])
+ {
+ player_firing = false;
+ }
+ }
+
+ if(event.type == sf::Event::MouseMoved)
+ {
+ mouse_moved = true;
+
+ sf::Vector2i mouse_pos = sf::Mouse().getPosition(window);
+
+ if (mouse_pos.x >= window.getView().getSize().x * 0.51)
+ {
+ look_right = true;
+ look_left = false;
+ sf::Vector2i center;
+ center.x = sf::Mouse().getPosition(window).x - 1;
+ center.y = sf::Mouse().getPosition(window).y;
+ sf::Mouse().setPosition(center, window);
+ }
+
+ if (mouse_pos.x <= window.getView().getSize().x * 0.49)
+ {
+ look_left = true;
+ look_right = false;
+ sf::Vector2i center;
+ center.x = sf::Mouse().getPosition(window).x + 1;
+ center.y = sf::Mouse().getPosition(window).y;
+ sf::Mouse().setPosition(center, window);
+ }
+
+ if (mouse_pos.y > window.getView().getSize().y * 0.55)
+ {
+ if (invert_mouse == true)
+ {
+ look_up = true;
+ look_down = false;
+ }
+ else
+ {
+ look_down = true;
+ look_up = false;
+ }
+
+ sf::Vector2i center;
+ center.x = sf::Mouse().getPosition(window).x;
+ center.y = window.getView().getSize().y * 0.55;
+ sf::Mouse().setPosition(center, window);
+ }
+
+ if (mouse_pos.y < window.getView().getSize().y * 0.45)
+ {
+ if (invert_mouse == true)
+ {
+ look_down = true;
+ look_up = false;
+ }
+ else
+ {
+ look_up = true;
+ look_down = false;
+ }
+
+ sf::Vector2i center;
+ center.x = sf::Mouse().getPosition(window).x;
+ center.y = window.getView().getSize().y * 0.45;
+ sf::Mouse().setPosition(center, window);
+ }
+ }
+
+ if (event.type == sf::Event::MouseButtonPressed)
+ {
+ if(event.mouseButton.button == sf::Mouse::Left)
+ {
+ player_mech.weapon = 1;
+ player_firing = true;
+ }
+
+ if(event.mouseButton.button == sf::Mouse::Right)
+ {
+ player_mech.weapon = 5;
+ player_firing = true;
+ }
+ }
+
+ if (event.type == sf::Event::MouseButtonReleased)
+ {
+ if(event.mouseButton.button == sf::Mouse::Left)
+ {
+ player_firing = false;
+ }
+
+ if(event.mouseButton.button == sf::Mouse::Right)
+ {
+ player_firing = false;
+ }
+ }
+}
+
+// Update function called every frame
+void player_controller::update(sf::RenderWindow &window, float frame_time)
+{
+ if (mouse_moved == true)
+ {
+ mouse_move_timer += frame_time;
+ if (mouse_move_timer >= frame_time * 3)
+ {
+ mouse_moved = false;
+ mouse_move_timer = 0;
+ look_right = false;
+ look_left = false;
+ look_up = false;
+ look_down = false;
+ }
+ }
+}
+
+// Update function called ten times per second
+void player_controller::fixed_update(sf::Transformable player)
+{
+ player_mech.update();
+
+ // Player movement vectors
+ look_pos.x = player.getPosition().x + 30 * cos (player.getRotation() * (3.14 / 180));
+ look_pos.y = player.getPosition().y + 30 * sin (player.getRotation() * (3.14 / 180));
+
+ back_pos.x = player.getPosition().x + 30 * cos ((player.getRotation() - 180) * (3.14 / 180));
+ back_pos.y = player.getPosition().y + 30 * sin ((player.getRotation() - 180) * (3.14 / 180));
+
+ left_pos.x = player.getPosition().x + 30 * cos ((player.getRotation() - 90) * (3.14 / 180));
+ left_pos.y = player.getPosition().y + 30 * sin ((player.getRotation() - 90) * (3.14 / 180));
+
+ right_pos.x = player.getPosition().x + 30 * cos ((player.getRotation() + 90) * (3.14 / 180));
+ right_pos.y = player.getPosition().y + 30 * sin ((player.getRotation() + 90) * (3.14 / 180));
+
+ // Movement
+ if (player_mech.speed > 0)
+ {
+ move_forward = true;
+ }
+ else
+ {
+ move_forward = false;
+ }
+
+ if (player_mech.speed < 0)
+ {
+ move_back = true;
+ }
+ else
+ {
+ move_back = false;
+ }
+
+ if (move_forward)
+ {
+ if (player_pos.x < look_pos.x)
+ {
+ player_pos.x += player_mech.speed;
+ }
+ if (player_pos.y < look_pos.y)
+ {
+ player_pos.y += player_mech.speed;
+ }
+ if (player_pos.x > look_pos.x)
+ {
+ player_pos.x -= player_mech.speed;
+ }
+ if (player_pos.y > look_pos.y)
+ {
+ player_pos.y -= player_mech.speed;
+ }
+ }
+
+ if (move_back)
+ {
+ if (player_pos.x < back_pos.x)
+ {
+ player_pos.x -= player_mech.speed;
+ }
+ if (player_pos.y < back_pos.y)
+ {
+ player_pos.y -= player_mech.speed;
+ }
+ if (player_pos.x > back_pos.x)
+ {
+ player_pos.x += player_mech.speed;
+ }
+ if (player_pos.y > back_pos.y)
+ {
+ player_pos.y += player_mech.speed;
+ }
+ }
+
+ look_offset = look_offset > 15 ? 15 : look_offset < -27 ? -27 : look_offset;
+
+ // Throttle
+ if (throttle_up == true && player_mech.can_move() == true)
+ {
+ if (player_mech.speed < 0.125)
+ {
+ player_mech.speed += 0.001;
+ }
+ }
+
+ if (throttle_down == true && player_mech.can_move() == true)
+ {
+ if (player_mech.speed > -0.0625)
+ {
+ player_mech.speed -= 0.001;
+ }
+ }
+
+ if (player_mech.can_move() == false)
+ {
+ player_mech.speed = 0;
+ }
+
+ // Mech stomp sounds
+ if (player_mech.speed != 0)
+ {
+ if (player_mech.speed > 0)
+ {
+ step_timer += player_mech.speed;
+ }
+ else
+ {
+ step_timer += -player_mech.speed;
+ }
+
+ if (step_timer >= 0.25)
+ {
+ stomp_timer += 0.1;
+
+ if (stomp_timer >= 0 && stomp_timer < 0.2)
+ {
+ resources.hydraulic_sound.setVolume(15 * audio_volume);
+ resources.hydraulic_sound.play();
+ if (look_offset < 10)
+ {
+ look_offset -= 0.5;
+ }
+ }
+ else if (stomp_timer >= 0.2 && stomp_timer < 0.5)
+ {
+ if (look_offset > -10)
+ {
+ look_offset += 0.5;
+ }
+ }
+ else if (stomp_timer >= 0.5 && stomp_timer < 0.7)
+ {
+ if (look_offset < 10)
+ {
+ look_offset -= 0.5;
+ }
+ }
+
+ if (stomp_timer >= 0.7)
+ {
+ resources.stomp_sound.setVolume(50 * audio_volume);
+ resources.stomp_sound.play();
+ step_timer = 0;
+ stomp_timer = 0;
+ }
+ }
+ }
+
+ // Weapons
+ if (muzzle_flash == true)
+ {
+ muzzle_flash_timer++;
+ if (muzzle_flash_timer >= 4)
+ {
+ muzzle_flash_timer = 0;
+ muzzle_flash = false;
+ }
+ }
+
+ if (cannon_flash == true)
+ {
+ cannon_flash_timer++;
+ if (cannon_flash_timer >= 4)
+ {
+ cannon_flash_timer = 0;
+ cannon_flash = false;
+ }
+ }
+
+ if (guns_firing == true)
+ {
+ guns_timer++;
+ if (guns_timer >= 6)
+ {
+ guns_timer = 0;
+ guns_firing = false;
+ }
+ }
+
+ if (cannon_firing == true)
+ {
+ cannon_timer++;
+ if (cannon_timer >= 24)
+ {
+ cannon_timer = 0;
+ cannon_firing = false;
+ }
+ }
+}
diff --git a/src/settings.cpp b/src/settings.cpp
new file mode 100644
index 0000000..7085b34
--- /dev/null
+++ b/src/settings.cpp
@@ -0,0 +1,46 @@
+#include
+#include
+#include
+
+bool music = true;
+bool invert_mouse = false;
+double audio_volume = 1;
+
+// Loads settings from file
+void load_settings(std::string cwd)
+{
+ size_t pos = 0;
+ std::string entry;
+ std::string delimeter = "\n";
+ std::string saved_settings = get_file_contents(cwd + "/settings.list");
+
+ while ((pos = saved_settings.find(delimeter)) != std::string::npos)
+ {
+ entry = saved_settings.substr(0, pos);
+ std::string key = entry.substr(0, entry.find(":"));
+ std::string value = entry.substr(entry.find(":") + 1, pos);
+ if (key == "volume")
+ {
+ audio_volume = std::stod(value);
+ }
+ if (key == "music")
+ {
+ music = std::stoi(value);
+ }
+ if (key == "invert_mouse")
+ {
+ invert_mouse = std::stoi(value);
+ }
+ saved_settings.erase(0, pos + delimeter.length());
+ }
+}
+
+// Saves settings to file
+void save_settings(std::string cwd)
+{
+ std::string current_settings = "volume:" + std::to_string(audio_volume) + "\n" +
+ "music:" + std::to_string(music) + "\n";
+ "invert_mouse:" + std::to_string(invert_mouse) + "\n";
+
+ write_to_file(cwd + "/settings.list", current_settings);
+}
diff --git a/src/settings_menu.cpp b/src/settings_menu.cpp
new file mode 100644
index 0000000..51909f4
--- /dev/null
+++ b/src/settings_menu.cpp
@@ -0,0 +1,248 @@
+#include
+#include
+#include
+#include
+
+// Gets the current working directory from main, initializes variables and objects
+void settings_menu::init(std::string cwd, assets &resources, bool in_game)
+{
+ this->cwd = cwd;
+ this->resources = resources;
+ this->in_game = in_game;
+ visible = false;
+ abort_prompt_open = false;
+ buttons.resize(5);
+ button_text.resize(5);
+ button_labels.resize(5);
+ button_values.resize(5);
+ abort_buttons.resize(2);
+ abort_button_text.resize(2);
+ abort_button_labels.resize(2);
+ button_text[0] = " INVERT MOUSE";
+ button_text[1] = " ENABLE MUSIC";
+ button_text[2] = " AUDIO VOLUME";
+ button_text[3] = " RESUME GAME";
+ button_text[4] = "ABORT MISSION";
+ abort_button_text[0] = "ABORT";
+ abort_button_text[1] = "RESUME";
+}
+
+// Mouse click events
+void settings_menu::handle_events(sf::Event event, sf::Vector2i mouse_position)
+{
+ if (event.type == sf::Event::MouseButtonPressed)
+ {
+ if(event.mouseButton.button == sf::Mouse::Left)
+ {
+ if (abort_prompt_open == false)
+ {
+ for (unsigned int i = 0; i < buttons.size(); i++)
+ {
+ if (buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ if (i == 0)
+ {
+ invert_mouse = !invert_mouse;
+ }
+ else if (i == 1)
+ {
+ music = !music;
+ }
+ else if (i == 2)
+ {
+ if (audio_volume <= 0.9)
+ {
+ audio_volume += 0.1;
+ }
+ else
+ {
+ audio_volume = 0.1;
+ }
+ }
+ else if (i == 3)
+ {
+ save_settings(cwd);
+ visible = false;
+ }
+ else if (i == 4 && in_game == true)
+ {
+ abort_prompt_open = true;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (unsigned int i = 0; i < abort_buttons.size(); i++)
+ {
+ if (abort_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ if (i == 0)
+ {
+ abort_mission = true;
+ abort_prompt_open = false;
+ }
+ else if (i == 1)
+ {
+ abort_prompt_open = false;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// Draws the menu
+void settings_menu::draw_menu(sf::RenderWindow &window, sf::Vector2i mouse_position, float frame_time)
+{
+ if (abort_prompt_open == false)
+ {
+ sf::Sprite bg_sprite = sf::Sprite(resources.gui_background_2_texture);
+ bg_sprite.setPosition(window.getView().getSize().x / 2 - 100, window.getView().getSize().y / 2 - 200);
+ float y_scale = in_game == true ? 0.6 : 0.5;
+ bg_sprite.setScale(0.2, y_scale);
+ window.draw(bg_sprite);
+
+ float y = window.getView().getSize().y / 2 - 180;
+
+ button_text[3] = in_game == true ? " RESUME GAME" : " EXIT MENU";
+ button_values[0].setString(invert_mouse == true ? "YES" :"NO");
+ button_values[1].setString(music == true ? "YES" :"NO");
+ button_values[2].setString(std::to_string((int)((100 * audio_volume) + 0.5)) + "%");
+
+ for (unsigned int i = 0; i < buttons.size(); i++)
+ {
+ float x = window.getView().getSize().x / 2 - 70;
+
+ buttons[i] = sf::VertexArray(sf::Quads, 4);
+ buttons[i][0].position = sf::Vector2f(x, (y + i * 35) - 4);
+ buttons[i][1].position = sf::Vector2f(x, (y + i * 35) + 24);
+ buttons[i][2].position = sf::Vector2f(x + 140, (y + i * 35) + 24);
+ buttons[i][3].position = sf::Vector2f(x + 140, (y + i * 35) - 4);
+
+ sf::VertexArray button_shadow = sf::VertexArray(sf::Quads, 4);
+ button_shadow[0].position = sf::Vector2f(x, (y + i * 35) - 4);
+ button_shadow[1].position = sf::Vector2f(x, (y + i * 35) + 27);
+ button_shadow[2].position = sf::Vector2f(x + 143, (y + i * 35) + 27);
+ button_shadow[3].position = sf::Vector2f(x + 143, (y + i * 35) - 4);
+
+ button_shadow[0].color = sf::Color::Black;
+ button_shadow[1].color = sf::Color::Black;
+ button_shadow[2].color = sf::Color::Black;
+ button_shadow[3].color = sf::Color::Black;
+
+ if (buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ button_labels[i].setFont(resources.exoplanetaria);
+ button_labels[i].setCharacterSize(16);
+ button_labels[i].setFillColor(sf::Color::Black);
+ button_labels[i].setString(button_text[i]);
+
+ button_values[i].setFont(resources.exoplanetaria);
+ button_values[i].setCharacterSize(14);
+ button_values[i].setFillColor(sf::Color::White);
+
+ if (i == 0)
+ button_labels[i].setPosition(x + 12, y);
+ else
+ button_labels[i].setPosition(x + 12, y + (i * 35));
+
+ if (i == 0)
+ button_values[i].setPosition(x + 180, y);
+ else
+ button_values[i].setPosition(x + 180, y + (i * 35));
+
+ bool draw = true;
+
+ if (i == 4)
+ {
+ draw = in_game == false? false : true;
+ }
+
+ if (draw == true)
+ {
+ window.draw(button_shadow);
+ window.draw(buttons[i]);
+ window.draw(button_labels[i]);
+ window.draw(button_values[i]);
+ }
+ }
+ }
+ else
+ {
+ resources.notice.setFont(resources.orbitron);
+ resources.notice.setString("ABORT MISSION?");
+ sf::Vector2f text_pos;
+ text_pos.x = (window.getView().getSize().x / 2) - (resources.notice.getGlobalBounds().width / 2);
+ text_pos.y = (window.getView().getSize().y / 2) - 150;
+ resources.notice.setPosition(text_pos);
+ window.draw(resources.notice);
+ resources.notice.setFont(resources.exoplanetaria);
+
+ float x = window.getView().getSize().x / 2 - 70;
+ float y = window.getView().getSize().y / 2 - 75;
+
+ for (unsigned int i = 0; i < abort_buttons.size(); i++)
+ {
+ abort_buttons[i] = sf::VertexArray(sf::Quads, 4);
+ abort_buttons[i][0].position = sf::Vector2f(x, (y + i * 35) - 4);
+ abort_buttons[i][1].position = sf::Vector2f(x, (y + i * 35) + 24);
+ abort_buttons[i][2].position = sf::Vector2f(x + 130, (y + i * 35) + 24);
+ abort_buttons[i][3].position = sf::Vector2f(x + 130, (y + i * 35) - 4);
+
+ sf::VertexArray button_shadow = sf::VertexArray(sf::Quads, 4);
+ button_shadow[0].position = sf::Vector2f(x, (y + i * 35) - 4);
+ button_shadow[1].position = sf::Vector2f(x, (y + i * 35) + 27);
+ button_shadow[2].position = sf::Vector2f(x + 133, (y + i * 35) + 27);
+ button_shadow[3].position = sf::Vector2f(x + 133, (y + i * 35) - 4);
+
+ button_shadow[0].color = sf::Color::Black;
+ button_shadow[1].color = sf::Color::Black;
+ button_shadow[2].color = sf::Color::Black;
+ button_shadow[3].color = sf::Color::Black;
+
+ if (abort_buttons[i].getBounds().contains(mouse_position.x, mouse_position.y))
+ {
+ abort_buttons[i][0].color = sf::Color(53, 53, 53, 255);
+ abort_buttons[i][1].color = sf::Color(53, 53, 53, 255);
+ abort_buttons[i][2].color = sf::Color(53, 53, 53, 255);
+ abort_buttons[i][3].color = sf::Color(53, 53, 53, 255);
+ }
+ else
+ {
+ abort_buttons[i][0].color = sf::Color(35, 35, 35, 255);
+ abort_buttons[i][1].color = sf::Color(35, 35, 35, 255);
+ abort_buttons[i][2].color = sf::Color(35, 35, 35, 255);
+ abort_buttons[i][3].color = sf::Color(35, 35, 35, 255);
+ }
+
+ abort_button_labels[i].setFont(resources.exoplanetaria);
+ abort_button_labels[i].setCharacterSize(16);
+ abort_button_labels[i].setFillColor(sf::Color::Black);
+ abort_button_labels[i].setString(abort_button_text[i]);
+
+ if (i == 0)
+ abort_button_labels[i].setPosition(x + 38, y);
+ else
+ abort_button_labels[i].setPosition(x + 38, y + (i * 35));
+
+ window.draw(button_shadow);
+ window.draw(abort_buttons[i]);
+ window.draw(abort_button_labels[i]);
+ }
+ }
+}
diff --git a/src/tutorial.cpp b/src/tutorial.cpp
new file mode 100644
index 0000000..5f67175
--- /dev/null
+++ b/src/tutorial.cpp
@@ -0,0 +1,165 @@
+#include
+
+// Constructor
+tutorial::tutorial(std::string cwd)
+{
+ step = 0;
+ visible = false;
+
+ if (!gui_background_texture.loadFromFile(cwd + "/assets/textures/gui_background.png"))
+ {
+ std::cout << "Failed to load textures.";
+ }
+ gui_background_sprite.setTexture(gui_background_texture);
+
+ if (!tutorial_font.loadFromFile(cwd + "/assets/Exoplanetaria-gxxJ5.ttf"))
+ {
+ std::cout << "Failed to load font.";
+ }
+}
+
+// Draws tutorial messages
+void tutorial::draw_tutorial(sf::RenderWindow &window, bool show_keys, float speed, float torso_angle, float heat)
+{
+ if (step == 0)
+ {
+ sf::String text = std::string("Key bindings can be changed by modifying the bindings.list file.\n") +
+ std::string("Press 'show_keys' (F2) now to view all of your current key bindings.\n") +
+ std::string("Press 'show_keys' (F2) again to stop displaying key bindings.");
+ tutorial_text.setString(text);
+
+ if (show_keys == true)
+ {
+ step = 1;
+ }
+ }
+ else if (step == 1)
+ {
+ sf::String text = std::string("Your mech's torso and legs are controlled separately.\n") +
+ std::string("Press the 'look left' or 'look right' key now to rotate\n") +
+ std::string("your mech's torso 90 degrees to the left or right.");
+ tutorial_text.setString(text);
+
+ if (torso_angle >= 80 || torso_angle <= -80)
+ {
+ step = 2;
+ }
+ }
+ else if (step == 2)
+ {
+ sf::String text = std::string("Press the 'map' key to increase the size of the mini-map / radar display.\n") +
+ std::string("The map key cycles between map sizes and toggles display of the map.\n") +
+ std::string("The white circle represents your mech's position in the world.\n") +
+ std::string("The green line represents the direction your mech's legs are facing.\n") +
+ std::string("The red line represents the direction your mech's torso is facing.\n\n") +
+ std::string("Press enter to continue.");
+ tutorial_text.setString(text);
+ }
+ else if (step == 3)
+ {
+ sf::String text = std::string("Rotate your mech's torso back to zero degrees.\n") +
+ std::string("This means the mech's legs and torso are facing the same direction.");
+ tutorial_text.setString(text);
+
+ if (torso_angle >= -3 && torso_angle <= 3)
+ {
+ step = 4;
+ }
+ }
+ else if (step == 4)
+ {
+ sf::String text = std::string("Increase your mech's throttle by pressing and holding the 'throttle_up' key.\n") +
+ std::string("Try increasing the throttle to 25% now.");
+ tutorial_text.setString(text);
+
+ int throttle = floor((speed) / 0.125 * 100);
+ if (throttle >= 25)
+ {
+ step = 5;
+ }
+ }
+ else if (step == 5)
+ {
+ sf::String text = std::string("Decrease your mech's throttle by pressing and holding the 'throttle_down' key.\n") +
+ std::string("Try decreasing the throttle to 3% now.");
+ tutorial_text.setString(text);
+
+ int throttle = floor((speed) / 0.125 * 100);
+ if (throttle <= 3)
+ {
+ step = 6;
+ }
+ }
+ else if (step == 6)
+ {
+ sf::String text = std::string("Firing your weapons increases the amount of heat generated by your mech.\n") +
+ std::string("Generating too much heat will cause damage to the mech's reactor.\n") +
+ std::string("Autocannons are a long range weapon with a low rate of fire.\n") +
+ std::string("Pulse lasers are a short range weapon with a higher rate of fire.\n") +
+ std::string("Autocannons do more damage in a single shot compared to pulse lasers.\n") +
+ std::string("Fire your weapons now by pressing the 'fire_guns' or 'fire_cannons' key.\n") +
+ std::string("Pay close attention to the heat readout and meter on your HUD.");
+ tutorial_text.setString(text);
+
+ if (heat > 0)
+ {
+ step = 7;
+ }
+ }
+ else if (step == 7)
+ {
+ sf::String text = std::string("If your mech's cooler is damaged, your mech will be more likely to overheat.\n") +
+ std::string("If your mech's arms are damaged, your weapons could be disabled.\n") +
+ std::string("If your mech's legs are damaged, you may become unable to move.\n") +
+ std::string("If your mech's cockpit is damaged, torso movement may be disabled.\n") +
+ std::string("If your mech's reactor is destroyed, the mech becomes inoperable.\n") +
+ std::string("If total combined damage exceeds 50%, the mech also becomes inoperable.\n\n") +
+ std::string("Press enter to continue.");
+ tutorial_text.setString(text);
+ }
+ else if (step == 8)
+ {
+ sf::String text = std::string("When encountering an enemy mech, press the 'lock_target' key\n") +
+ std::string("or fire weapons at the mech to activate a target lock.\n") +
+ std::string("Press the 'select component' key to change which component you are targeting.\n") +
+ std::string("Damage dealt by either mech is affected by speed and distance.\n") +
+ std::string("Some components are more resistant to damage such as the cooler and reactor.\n\n") +
+ std::string("Press enter to continue.");
+ tutorial_text.setString(text);
+ }
+ else if (step == 9)
+ {
+ sf::String text = std::string("The objective in each mission is to eliminate all enemy mechs.\n") +
+ std::string("Enemy mechs increase in number and difficulty as you progress.\n") +
+ std::string("You will notice enemies have increased armor or firepower in later missions.\n\n") +
+ std::string("Press enter to continue.");
+ tutorial_text.setString(text);
+ }
+ else if (step == 10)
+ {
+ sf::String text = std::string("After each mission, you will have the opportunity to upgrade your mech.\n") +
+ std::string("More powerful weapons increase heat. An upgraded cooler can help with this.\n") +
+ std::string("Your mech's chassis can only handle 110 tons of equipment.\n") +
+ std::string("You will need to keep this in mind when deciding which upgrades to install.\n") +
+ std::string("Upgrades can be sold for a portion of the original purchase price.\n\n") +
+ std::string("Press enter to restart the tutorial.\n") +
+ std::string("Press the 'show tutorial' key to hide these messages.");
+ tutorial_text.setString(text);
+ }
+
+ sf::Vector2f bg_pos;
+ bg_pos.x = (window.getView().getSize().x / 2) - (tutorial_text.getGlobalBounds().width / 2) - 25;
+ bg_pos.y = (window.getView().getSize().y / 2) - 170;
+ gui_background_sprite.setPosition(bg_pos);
+ gui_background_sprite.setScale(tutorial_text.getGlobalBounds().width * 0.00075, tutorial_text.getGlobalBounds().height * 0.006);
+ window.draw(gui_background_sprite);
+
+ tutorial_text.setFont(tutorial_font);
+ tutorial_text.setCharacterSize(18);
+ tutorial_text.setFillColor(sf::Color::White);
+ sf::Vector2f text_pos;
+ text_pos.x = (window.getView().getSize().x / 2) - (tutorial_text.getGlobalBounds().width / 2);
+ text_pos.y = (window.getView().getSize().y / 2) - 150;
+ tutorial_text.setPosition(text_pos);
+ window.draw(tutorial_text);
+}
diff --git a/src/world_generator.cpp b/src/world_generator.cpp
new file mode 100644
index 0000000..8664e39
--- /dev/null
+++ b/src/world_generator.cpp
@@ -0,0 +1,769 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Constructor
+world_generator::world_generator()
+{
+ wall_count = 0;
+ mob_count = 0;
+ mission = 1;
+ theme = 1;
+ maze = true;
+ min_npc_spawned = false;
+}
+
+// Generates the playing area and npc mechs
+void world_generator::generate_world(assets &resources, std::vector &entities, int entity_count)
+{
+ int e = 0;
+ entities = std::vector(entity_count);
+
+ // Border
+ for (int i = 0; i < 153; i++)
+ {
+ entities[e].position.x = 60;
+ entities[e].position.y = 40 + i * 4;
+ entities[e].type = "wall";
+ entities[e].icon.setTexture(resources.wall_icon_texture);
+ e++;
+ }
+
+ for (int i = 0; i < 153; i++)
+ {
+ entities[e].position.x = 550;
+ entities[e].position.y = 40 + i * 4;
+ entities[e].type = "wall";
+ entities[e].icon.setTexture(resources.wall_icon_texture);
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ entities[e].position.x = 60 + i * 4;
+ entities[e].position.y = 40;
+ entities[e].type = "wall";
+ entities[e].icon.setTexture(resources.wall_icon_texture);
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ entities[e].position.x = 60 + i * 4;
+ entities[e].position.y = 650;
+ entities[e].type = "wall";
+ entities[e].icon.setTexture(resources.wall_icon_texture);
+ e++;
+ }
+
+ if (maze == true)
+ {
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ entities[e].position.x = 180;
+ entities[e].position.y = 40 + i * 4;
+ entities[e].type = "wall";
+ entities[e].icon.setTexture(resources.wall_icon_texture);
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 125; i++)
+ {
+ entities[e].position.x = 300;
+ entities[e].position.y = 154 + i * 4;
+ entities[e].type = "wall";
+ entities[e].icon.setTexture(resources.wall_icon_texture);
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 120; i++)
+ {
+ entities[e].position.x = 420;
+ entities[e].position.y = 40 + i * 4;
+ entities[e].type = "wall";
+ entities[e].icon.setTexture(resources.wall_icon_texture);
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ entities[e].position.x = 60 + i * 4;
+ entities[e].position.y = 400;
+ entities[e].type = "wall";
+ entities[e].icon.setTexture(resources.wall_icon_texture);
+ e++;
+ }
+ }
+
+ wall_count = e;
+
+ for (int i = wall_count; i < entity_count; i++)
+ {
+ int r = rand() % 1000;
+
+ if (r < 1000 && r >= 950)
+ {
+ entities[e].type = "tree";
+ if (maze == true)
+ {
+ entities[e].position.x = 75 + ( rand() % ( 165 - 75 + 1 ) );
+ entities[e].position.y = 75 + ( rand() % ( 645 - 75 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ if (theme == 1)
+ {
+ entities[e].sprite.setTexture(resources.tree_texture);
+ }
+ else
+ {
+ entities[e].sprite.setTexture(resources.tree_3_texture);
+ }
+ }
+ else if (r < 950 && r >= 900)
+ {
+ entities[e].type = "tree";
+ if (maze == true)
+ {
+ entities[e].position.x = 195 + ( rand() % ( 285 - 195 + 1 ) );
+ entities[e].position.y = 75 + ( rand() % ( 645 - 75 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ if (theme == 1)
+ {
+ entities[e].sprite.setTexture(resources.tree_texture);
+ }
+ else
+ {
+ entities[e].sprite.setTexture(resources.tree_3_texture);
+ }
+ }
+ else if (r < 900 && r >= 850)
+ {
+ entities[e].type = "tree";
+ if (maze == true)
+ {
+ entities[e].position.x = 315 + ( rand() % ( 405 - 315 + 1 ) );
+ entities[e].position.y = 75 + ( rand() % ( 645 - 75 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ if (theme == 1)
+ {
+ entities[e].sprite.setTexture(resources.tree_texture);
+ }
+ else
+ {
+ entities[e].sprite.setTexture(resources.tree_3_texture);
+ }
+ }
+ else if (r < 850 && r >= 800)
+ {
+ entities[e].type = "tree";
+ if (maze == true)
+ {
+ entities[e].position.x = 435 + ( rand() % ( 530 - 435 + 1 ) );
+ entities[e].position.y = 75 + ( rand() % ( 645 - 75 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ if (theme == 1)
+ {
+ entities[e].sprite.setTexture(resources.tree_texture);
+ }
+ else
+ {
+ entities[e].sprite.setTexture(resources.tree_3_texture);
+ }
+ }
+ else if (r < 800 && r >= 750)
+ {
+ entities[e].type = "tree_2";
+ if (maze == true)
+ {
+ entities[e].position.x = 75 + ( rand() % ( 175 - 75 + 1 ) );
+ entities[e].position.y = 200 + ( rand() % ( 350 - 200 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ if (theme == 1)
+ {
+ entities[e].sprite.setTexture(resources.tree_2_texture);
+ }
+ else
+ {
+ entities[e].sprite.setTexture(resources.tree_4_texture);
+ }
+ }
+ else if (r < 750 && r >= 700)
+ {
+ entities[e].type = "tree_2";
+ if (maze == true)
+ {
+ entities[e].position.x = 195 + ( rand() % ( 285 - 195 + 1 ) );
+ entities[e].position.y = 200 + ( rand() % ( 350 - 200 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ if (theme == 1)
+ {
+ entities[e].sprite.setTexture(resources.tree_2_texture);
+ }
+ else
+ {
+ entities[e].sprite.setTexture(resources.tree_4_texture);
+ }
+ }
+ else if (r < 700 && r >= 650)
+ {
+ entities[e].type = "tree_2";
+ if (maze == true)
+ {
+ entities[e].position.x = 435 + ( rand() % ( 530 - 435 + 1 ) );
+ entities[e].position.y = 75 + ( rand() % ( 645 - 75 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ if (theme == 1)
+ {
+ entities[e].sprite.setTexture(resources.tree_2_texture);
+ }
+ else
+ {
+ entities[e].sprite.setTexture(resources.tree_4_texture);
+ }
+ }
+ else if (r < 650 && r >= 600)
+ {
+ entities[e].type = "tree_2";
+ if (maze == true)
+ {
+ entities[e].position.x = 435 + ( rand() % ( 530 - 435 + 1 ) );
+ entities[e].position.y = 75 + ( rand() % ( 645 - 75 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ if (theme == 1)
+ {
+ entities[e].sprite.setTexture(resources.tree_2_texture);
+ }
+ else
+ {
+ entities[e].sprite.setTexture(resources.tree_4_texture);
+ }
+ }
+
+ int weapons_modifier = mission < 3 ? 0 : mission > 5 ? 3 : mission - 2 ;
+ int armor_modifier = mission < 3 ? 1000 : mission > 5 ? 3000 : (mission - 2) * 1000;
+
+ r = std::rand() % 10000;
+
+ if ((r < 10000 && r >= 10000 - mission * 2) || min_npc_spawned == false)
+ {
+ if (mob_count < mission)
+ {
+ entities[e].id = e;
+ entities[e].type = "mob";
+ entities[e].sub_type = "mech";
+ entities[e].sprite.setTexture(resources.mech_texture, true);
+ entities[e].icon.setTexture(resources.mob_icon_texture);
+
+ int upgrade_chance = rand() % 100;
+ if (upgrade_chance >= 75)
+ {
+ int rand_upgrade = rand() % 100;
+ if (rand_upgrade >= 50)
+ {
+ entities[e].entity_mech.guns_modifier = weapons_modifier;
+ entities[e].entity_mech.cannons_modifier = weapons_modifier;
+ entities[e].entity_mech.cooler_modifier = weapons_modifier;
+ entities[e].entity_mech.cooler_integrity = armor_modifier;
+ entities[e].entity_mech.max_cooler_integrity = armor_modifier;
+ entities[e].entity_mech.reactor_integrity = armor_modifier;
+ entities[e].entity_mech.max_reactor_integrity = armor_modifier;
+ }
+ else
+ {
+ entities[e].entity_mech.reactor_integrity = armor_modifier;
+ entities[e].entity_mech.max_reactor_integrity = armor_modifier;
+ entities[e].entity_mech.cockpit_integrity = armor_modifier;
+ entities[e].entity_mech.max_cockpit_integrity = armor_modifier;
+ entities[e].entity_mech.left_arm_integrity = armor_modifier;
+ entities[e].entity_mech.max_left_arm_integrity = armor_modifier;
+ entities[e].entity_mech.right_arm_integrity = armor_modifier;
+ entities[e].entity_mech.max_right_arm_integrity = armor_modifier;
+ entities[e].entity_mech.left_leg_integrity = armor_modifier;
+ entities[e].entity_mech.max_left_leg_integrity = armor_modifier;
+ entities[e].entity_mech.right_leg_integrity = armor_modifier;
+ entities[e].entity_mech.max_right_leg_integrity = armor_modifier;
+ }
+ }
+
+ if (maze == true)
+ {
+ entities[e].position.x = 75 + ( rand() % ( 175 - 75 + 1 ) );
+ entities[e].position.y = 200 + ( rand() % ( 350 - 200 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ mob_count++;
+ min_npc_spawned = true;
+ }
+ }
+ else if (r < 10000 - mission * 2 && r >= 10000 - mission * 4 && mob_count < mission)
+ {
+ entities[e].id = e;
+ entities[e].type = "mob";
+ entities[e].sub_type = "mech";
+ entities[e].sprite.setTexture(resources.mech_texture, true);
+ entities[e].icon.setTexture(resources.mob_icon_texture);
+
+ int upgrade_chance = rand() % 100;
+ if (upgrade_chance >= 75)
+ {
+ int rand_upgrade = rand() % 100;
+ if (rand_upgrade >= 50)
+ {
+ entities[e].entity_mech.guns_modifier = weapons_modifier;
+ entities[e].entity_mech.cannons_modifier = weapons_modifier;
+ entities[e].entity_mech.cooler_modifier = weapons_modifier;
+ entities[e].entity_mech.cooler_integrity = armor_modifier;
+ entities[e].entity_mech.max_cooler_integrity = armor_modifier;
+ entities[e].entity_mech.reactor_integrity = armor_modifier;
+ entities[e].entity_mech.max_reactor_integrity = armor_modifier;
+ }
+ else
+ {
+ entities[e].entity_mech.reactor_integrity = armor_modifier;
+ entities[e].entity_mech.max_reactor_integrity = armor_modifier;
+ entities[e].entity_mech.cockpit_integrity = armor_modifier;
+ entities[e].entity_mech.max_cockpit_integrity = armor_modifier;
+ entities[e].entity_mech.left_arm_integrity = armor_modifier;
+ entities[e].entity_mech.max_left_arm_integrity = armor_modifier;
+ entities[e].entity_mech.right_arm_integrity = armor_modifier;
+ entities[e].entity_mech.max_right_arm_integrity = armor_modifier;
+ entities[e].entity_mech.left_leg_integrity = armor_modifier;
+ entities[e].entity_mech.max_left_leg_integrity = armor_modifier;
+ entities[e].entity_mech.right_leg_integrity = armor_modifier;
+ entities[e].entity_mech.max_right_leg_integrity = armor_modifier;
+ }
+ }
+
+ if (maze == true)
+ {
+ entities[e].position.x = 195 + ( rand() % ( 285 - 195 + 1 ) );
+ entities[e].position.y = 200 + ( rand() % ( 350 - 200 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ mob_count++;
+ }
+ else if (r < 10000 - mission * 4 && r >= 10000 - mission * 6 && mob_count < mission)
+ {
+ entities[e].id = e;
+ entities[e].type = "mob";
+ entities[e].sub_type = "mech";
+ entities[e].sprite.setTexture(resources.mech_texture, true);
+ entities[e].icon.setTexture(resources.mob_icon_texture);
+
+ int upgrade_chance = rand() % 100;
+ if (upgrade_chance >= 75)
+ {
+ int rand_upgrade = rand() % 100;
+ if (rand_upgrade >= 50)
+ {
+ entities[e].entity_mech.guns_modifier = weapons_modifier;
+ entities[e].entity_mech.cannons_modifier = weapons_modifier;
+ entities[e].entity_mech.cooler_modifier = weapons_modifier;
+ entities[e].entity_mech.cooler_integrity = armor_modifier;
+ entities[e].entity_mech.max_cooler_integrity = armor_modifier;
+ entities[e].entity_mech.reactor_integrity = armor_modifier;
+ entities[e].entity_mech.max_reactor_integrity = armor_modifier;
+ }
+ else
+ {
+ entities[e].entity_mech.reactor_integrity = armor_modifier;
+ entities[e].entity_mech.max_reactor_integrity = armor_modifier;
+ entities[e].entity_mech.cockpit_integrity = armor_modifier;
+ entities[e].entity_mech.max_cockpit_integrity = armor_modifier;
+ entities[e].entity_mech.left_arm_integrity = armor_modifier;
+ entities[e].entity_mech.max_left_arm_integrity = armor_modifier;
+ entities[e].entity_mech.right_arm_integrity = armor_modifier;
+ entities[e].entity_mech.max_right_arm_integrity = armor_modifier;
+ entities[e].entity_mech.left_leg_integrity = armor_modifier;
+ entities[e].entity_mech.max_left_leg_integrity = armor_modifier;
+ entities[e].entity_mech.right_leg_integrity = armor_modifier;
+ entities[e].entity_mech.max_right_leg_integrity = armor_modifier;
+ }
+ }
+
+ if (maze == true)
+ {
+ entities[e].position.x = 315 + ( rand() % ( 405 - 315 + 1 ) );
+ entities[e].position.y = 75 + ( rand() % ( 645 - 75 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ mob_count++;
+ }
+ else if (r < 10000 - mission * 6 && r >= 10000 - mission * 8 && mob_count < mission)
+ {
+ entities[e].id = e;
+ entities[e].type = "mob";
+ entities[e].sub_type = "mech";
+ entities[e].sprite.setTexture(resources.mech_texture, true);
+ entities[e].icon.setTexture(resources.mob_icon_texture);
+
+ int upgrade_chance = rand() % 100;
+ if (upgrade_chance >= 75)
+ {
+ int rand_upgrade = rand() % 100;
+ if (rand_upgrade >= 50)
+ {
+ entities[e].entity_mech.guns_modifier = weapons_modifier;
+ entities[e].entity_mech.cannons_modifier = weapons_modifier;
+ entities[e].entity_mech.cooler_modifier = weapons_modifier;
+ entities[e].entity_mech.cooler_integrity = armor_modifier;
+ entities[e].entity_mech.max_cooler_integrity = armor_modifier;
+ entities[e].entity_mech.reactor_integrity = armor_modifier;
+ entities[e].entity_mech.max_reactor_integrity = armor_modifier;
+ }
+ else
+ {
+ entities[e].entity_mech.reactor_integrity = armor_modifier;
+ entities[e].entity_mech.max_reactor_integrity = armor_modifier;
+ entities[e].entity_mech.cockpit_integrity = armor_modifier;
+ entities[e].entity_mech.max_cockpit_integrity = armor_modifier;
+ entities[e].entity_mech.left_arm_integrity = armor_modifier;
+ entities[e].entity_mech.max_left_arm_integrity = armor_modifier;
+ entities[e].entity_mech.right_arm_integrity = armor_modifier;
+ entities[e].entity_mech.max_right_arm_integrity = armor_modifier;
+ entities[e].entity_mech.left_leg_integrity = armor_modifier;
+ entities[e].entity_mech.max_left_leg_integrity = armor_modifier;
+ entities[e].entity_mech.right_leg_integrity = armor_modifier;
+ entities[e].entity_mech.max_right_leg_integrity = armor_modifier;
+ }
+ }
+
+ if (maze == true)
+ {
+ entities[e].position.x = 435 + ( rand() % ( 530 - 435 + 1 ) );
+ entities[e].position.y = 75 + ( rand() % ( 645 - 75 + 1 ) );
+ }
+ else
+ {
+ entities[e].position.x = 70 + ( rand() % ( 540 - 70 + 1 ) );
+ entities[e].position.y = 50 + ( rand() % ( 640 - 50 + 1 ) );
+ }
+
+ mob_count++;
+ }
+
+ e++;
+ }
+
+ mob_count = 0;
+ min_npc_spawned = false;
+}
+
+// Reverses placement direction of walls which don't render correctly when placed with ascending depth with respect to the camera
+void world_generator::flip_walls_vertical(std::vector &entities, int entity_count, bool inverse)
+{
+ if (inverse == true)
+ {
+ int e = 0;
+
+ // Border
+ for (int i = 0; i < 153; i++)
+ {
+ entities[e].position.x = 60;
+ entities[e].position.y = 648 - i * 4;
+ e++;
+ }
+
+ for (int i = 0; i < 153; i++)
+ {
+ entities[e].position.x = 550;
+ entities[e].position.y = 648 - i * 4;
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ e++;
+ }
+
+ if (maze == true)
+ {
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ entities[e].position.x = 180 ;
+ entities[e].position.y = 275 - i * 4;
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 125; i++)
+ {
+ entities[e].position.x = 300;
+ entities[e].position.y = 650 - i * 4;
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 120; i++)
+ {
+ entities[e].position.x = 420;
+ entities[e].position.y = 515 - i * 4;
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ e++;
+ }
+ }
+ }
+ else
+ {
+ int e = 0;
+
+ // Border
+ for (int i = 0; i < 153; i++)
+ {
+ entities[e].position.x = 60;
+ entities[e].position.y = 40 + i * 4;
+ e++;
+ }
+
+ for (int i = 0; i < 153; i++)
+ {
+ entities[e].position.x = 550;
+ entities[e].position.y = 40 + i * 4;
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ e++;
+ }
+
+ if (maze == true)
+ {
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ entities[e].position.x = 180;
+ entities[e].position.y = 40 + i * 4;
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 125; i++)
+ {
+ entities[e].position.x = 300;
+ entities[e].position.y = 154 + i * 4;
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 120; i++)
+ {
+ entities[e].position.x = 420;
+ entities[e].position.y = 40 + i * 4;
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ e++;
+ }
+ }
+ }
+}
+
+// Reverses placement direction of walls which don't render correctly when placed with ascending depth with respect to the camera
+void world_generator::flip_walls_horizontal(std::vector &entities, int entity_count, bool inverse)
+{
+ if (inverse == true)
+ {
+ int e = 0;
+
+ // Border
+ for (int i = 0; i < 153; i++)
+ {
+ e++;
+ }
+
+ for (int i = 0; i < 153; i++)
+ {
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ entities[e].position.x = 550 - i * 4;
+ entities[e].position.y = 40;
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ entities[e].position.x = 550 - i * 4;
+ entities[e].position.y = 650;
+ e++;
+ }
+
+ if (maze == true)
+ {
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 125; i++)
+ {
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 120; i++)
+ {
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ entities[e].position.x = 300 - i * 4;
+ entities[e].position.y = 400;
+ e++;
+ }
+ }
+ }
+ else
+ {
+ int e = 0;
+
+ // Border
+ for (int i = 0; i < 153; i++)
+ {
+ e++;
+ }
+
+ for (int i = 0; i < 153; i++)
+ {
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ entities[e].position.x = 60 + i * 4;
+ entities[e].position.y = 40;
+ e++;
+ }
+
+ for (int i = 0; i < 122; i++)
+ {
+ entities[e].position.x = 60 + i * 4;
+ entities[e].position.y = 650;
+ e++;
+ }
+
+ if (maze == true)
+ {
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 125; i++)
+ {
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 120; i++)
+ {
+ e++;
+ }
+
+ // Wall
+ for (int i = 0; i < 60; i++)
+ {
+ entities[e].position.x = 60 + i * 4;
+ entities[e].position.y = 400;
+ e++;
+ }
+ }
+ }
+}