Prototyping - Finalizing the Default Mission
We broke down mission construction in to two parts. The default mission is the first step where the only goal is to destroy all ships with the 'enemy' alignment. Then return to base.
We add no new objects this time. Instead, we modify the headquarters object to add the capability to return to base. Then add several scripts to handle mission settings and checking. Refer to the mission design in part 23.
GML Code
Our work in GameMaker this time around
obj_ship: Destroy 4
When a ship is destroyed, we need to set the update_mission trigger in obj_hq to check for mission updates in the next frame. Then add to the kill count if the player caused the death.
1 2 3 4 5 6 |
///Check mission update mission.update_mission = true if last_hit == find_player_ship() mission.player_kills+=1 |
obj_hq: Create 1
This is a replacement for the original variable declarations in obj_hq to account for the world and mission interactions. Note that we're adding sprites indices and world locations to act as the base.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
///Init vars /* Overall mission variables */ night = false player_kills = 0 player_ship_type = SHIPTYPE.hornet /* ship handles */ player = 0 /* deferred creation */ for (var i=0;i<21;i++) npc_ship[i] = 0 /* World interaction variables */ x = 107*32 y = 106*32 spr_frame_l = 68 spr_frame_c = 69 spr_frame_r = 70 /* Mission settings */ mission_complete = false mission_dead = false update_mission = false mission_wave = 0 last_wave = 0 for (var i=0; i<10; i++) wave_messages[i]="" |
obj_hq: Create 2
Introduce a data struction that holds important mission targets that we'll use later as a filter for all possible targets
1 2 |
///Data structure target_list = ds_list_create() /* Holds the ids of mission targets */ |
obj_hq: Room Start 3
Call our mission initialization script that we'll define later
1 2 |
///Initialize mission mission_initialize(gamedata.current_mission) |
obj_hq: Step 1
Every step, we'll check to see if the player ship has returned to base and the mission has been completed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
///Mission complete - check return to base if mission_complete && instance_exists(player) { if map_pos(player.x) == map_pos(x) { if map_pos(player.y) == map_pos(y) { hud.fade_out = true with obj_ship_ai mode = AIMODE.inactive with obj_ship { speed = 0 active = false } if player_kills > 0 then { gamedata.current_mission_kills = player_kills gamedata.current_total_kills += player_kills player_kills = 0 } } } } |
obj_hq: Step 2
Returns the game to the main menu after the player has died
1 2 3 |
///Player died - back to main if mission_dead hud.fade_out = true |
obj_hq: Draw 1
Draws the sprites for the headquarters a layer higher than the player to simulate entering the headquarters building.
1 2 3 4 |
///HQ cover sprite draw_sprite_ext(BLK1,spr_frame_l,x-32,y,1,1,0,c_white,1) draw_sprite_ext(BLK1,spr_frame_c,x,y,1,1,0,c_white,1) draw_sprite_ext(BLK1,spr_frame_r,x+32,y,1,1,0,c_white,1) |
obj_hq: Room End 1
Update (actually remove) mission data on death
1 2 3 4 5 6 |
///Update on mission death if mission_dead { gamedata.current_mission-- gamedata.current_mission_kills = 0 } |
obj_hq: Begin Step 1
Perform the mission update if the trigger is set. It's set whenever a ship is destroyed.
1 2 3 4 5 6 7 8 9 10 11 |
///Update mission check /* check for mission event update (triggered at ship destruction) */ if update_mission { if !instance_exists(player) mission_dead = true mission_check(gamedata.current_mission) update_mission = false } |
Script: mission_initialize
Sets up the mission by calling several child scripts.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* Init mission by assigning ships to waves and (in)activating them only obj_hq can call this script Arg0 is the current mission */ mission_wave = 0 /* Set mission content */ set_mission_messages(argument0) set_mission_parameters(argument0) set_mission_waves(argument0) /* set player ship type */ player.ship_type = player_ship_type /* ensure later waves are inactive */ for (var i=0; i<20; i++) { if npc_ship[i] > 0 { if npc_ship[i].wave_number > mission_wave ship_inactivate(npc_ship[i]) } } mission_check(argument0) |
Script: mission_check
Checks to see if a wave is complete and advances us through the mission logic.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* Checks mission for wave updates when activated by ship destruction */ if mission_complete == false { /* Start mission */ if mission_wave == 0 then wave_activate(++mission_wave) else /* Continue ongoing mission */ { if is_wave_clear(mission_wave) wave_activate(++mission_wave) } if mission_wave > last_wave then mission_complete = true } |
Script: set_mission_messages
Sets the messages for the mission used at the beginning of each wave in the HUD message ticker. Default is a random start and finish message.
1 2 3 4 5 6 7 8 9 10 11 |
/* Sets the messages for mission - only callable from obj_hq Arg0 - current mission */ switch argument0 { default: { wave_messages[1] = choose("Give em hell, vel", "Destroy all vulture ships") wave_messages[2] = choose("Mission complete vel", "Come on back, vel") } break; } |
Script: set_mission_parameters
Sets important mission parameters like the type of player ship. Default is the hornet ship on a daytime mission
1 2 3 4 5 6 7 8 9 |
/* Sets overall mission paramters */ switch argument0 { default: { night = false player_ship_type = SHIPTYPE.hornet } break; } |
Script: set_mission_waves
Assigns each of the 20 possible NPC ships to waves. Default is that all ships are in the first and only wave
1 2 3 4 5 6 |
/* Assign ships to waves, all default to wave 1 already */ switch argument0 { default: last_wave = 1; break; } |
Script: ship_inactivate
Suspends NPC ship operation
1 2 3 4 5 6 7 8 |
/* Arg0 is the ship id */ var mission = instance_find(obj_hq,0); argument0.ai.mode = AIMODE.inactive argument0.visible = false if ds_list_find_index(mission.target_list, argument0) > -1 ds_list_delete(mission.target_list,ds_list_find_value(mission.target_list,argument0)) |
Script: ship_activate
Activates a ship in the game world
1 2 3 4 5 6 7 8 |
/* Arg0 is the ship id */ var mission = instance_find(obj_hq,0); argument0.ai.mode = AIMODE.move argument0.visible = true if argument0.alignment == ALIGNMENT.enemy ds_list_add(mission.target_list,argument0) |
Script: wave_activate
Activates all ships in a wave in the game world
1 2 3 4 5 6 7 8 9 10 11 12 |
/* Activate all ships in a wave - only callable from obj_hq */ for (var i=0; i<20; i++) { if instance_exists(npc_ship[i]) && npc_ship[i] > 0 { if npc_ship[i].wave_number == argument0 ship_activate(npc_ship[i]) } } /* Set wave message */ hud_message(wave_messages[argument0]) |
Script: is_wave_clear
Checks if all ships in a particular wave have been destroyed or otherwise completed their mission (inactivated)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* Checks if a wave has been cleared Arg0 is the wave to check */ for (var i=0; i<20; i++) { if instance_exists(npc_ship[i]) && npc_ship[i] > 0 { if npc_ship[i].wave_number == argument0 && ds_list_find_index(target_list, npc_ship[i]) >= 0 return false } } return true |