Untitled diff

Created Diff never expires
7 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
687 lines
106 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
687 lines
/* How to use this script:
// Ship Diagnostic Display Ver 1.2.0 by Deeganator
1. create a programming block and load this script into it.

2. Create a timer block, set it to run the programming block with no arguments and to "trigger now" itself
/* How to use this script:
3. Create any number of LCD displays or text displays.
1. create a programming block and load this script into it.
a. Name the displays according to the view you want it to show:
2. Create a timer block, set it to run the programming block with no arguments and to "trigger now" itself
screen_diagnostic_x_y where X is the rotation (0, 1, or 2) and Y is the style (0=scan, 1=flat)
3. Create any number of LCD displays or text displays.
OR
a. Name the displays according to the view you want it to show:
screen_diagnostic_main - this display shows one view that can be changed with buttons (discussed later)
screen_diagnostic_x_y where X is the rotation (0, 1, or 2) and Y is the style (0=scan, 1=flat)
ALSO
OR
Add an _h, an _v, or an _hv to show multiple views on the same screen.
screen_diagnostic_main - this display shows one view that can be changed with buttons (discussed later)
Example : screen_diagnostic_main_hv or screen_diagnostic_5_1_v
ALSO
FURTHERMORE
Add an _h, an _v, or an _hv to show multiple views on the same screen.
Name a display screen_diagnostic_reports to get some basic information about your ships health.
Example : screen_diagnostic_main_hv or screen_diagnostic_5_1_v
4. Start your timer and your displays should buzz to life.
FURTHERMORE
5. You can create buttons or toolbar slots that execute this script with arguments to perform special functions.
Name a display screen_diagnostic_reports to get some basic information about your ships health.
Argument : Function that happens
4. Start your timer and your displays should buzz to life.
reset : Resets the program, tells the script that your ship is brand new as it is right now.
5. You can create buttons or toolbar slots that execute this script with arguments to perform special functions.
rotate : Rotates the view on ship_diagnostic_main.
Argument : Function that happens
mode : Changes the display style on ship_diagnostic_main between flat/scan styles
reset : Resets the program, tells the script that your ship is brand new as it is right now.
save : Save the ship data manually (usually happens automatically)
rotate : Rotates the view on ship_diagnostic_main.
load : Load the ship data manually (usually happens automatically)
mode : Changes the display style on ship_diagnostic_main between flat/scan styles
cursor : No longer does anything. Had to cut it! It may come back. For now use "show on hud" in terminal
save : Save the ship data manually (usually happens automatically)
load : Load the ship data manually (usually happens automatically)
*/
*/
//Customization:======================================================================
//Customization:======================================================================
string panel_prefix = "screen_diagnostic_";
string panel_prefix = "diagnostics_display_";
string alarm_prefix = "diag_alarm_";
string alarm_prefix = "diagnostics_alarm_";
int alarm_refresh_rate = 30;
int alarm_refresh_rate = 30;
int alarm_tracker = 0;
int alarm_tracker = 0;


int xscale = 1;
int xscale = 1;
int yscale = 1;
int yscale = 1;
int zscale = 1;
int zscale = 1;


int render_slowness = 4; // lower is faster animation (0 is minimum)
int render_slowness = 4; // lower is faster animation (0 is minimum)


int border_width = 2; //how much space to give around the edges (REQUIRES RESET)
int border_width = 2; //how much space to give around the edges (REQUIRES RESET)


//Pixels
//Pixels
char gone = ''; //red
char gone = ''; //red
char normal = ''; //green
char normal = ''; //green
char none = ''; //black
char none = ''; //black
char hacked = ''; //blue
char hacked = ''; //blue
char broken = ''; //yellow
char broken = ''; //yellow
char shadow = ''; //gray
char shadow = ''; //gray
char cursor = ''; //blue
char cursor = ''; //blue


///Performance tweaks=================================================================
///Performance tweaks=================================================================
/*change these to change performance of the script
/*change these to change performance of the script
If the combination of these three are too high you may hit an instruction limit and the script will break
If the combination of these three are too high you may hit an instruction limit and the script will break
If any one of these is too high you may experience performance issues (game slows down)
If any one of these is too high you may experience performance issues (game slows down)
If any of these are too low you may get some delay before blocks are updated.
If any of these are too low you may get some delay before blocks are updated.
The script will never update more times per tick than the number of blocks in the ship
The script will never update more times per tick than the number of blocks in the ship
so this is really only important for huge ships.
so this is really only important for huge ships.
I have found 100/100/10 to be a good balance.
I have found 100/100/10 to be a good balance.
As a general rule, it doesn't make sense to render faster than you update.
As a general rule, it doesn't make sense to render faster than you update.
Rendering only happens when changes are made.
Rendering only happens when changes are made.
max_terminal_status_checks_per_tick should be like 1/4 of what the other two are.
max_terminal_status_checks_per_tick should be like 1/4 of what the other two are.
*/
*/


int max_renders_per_tick = 100; //this many blocks' pixels will be refreshed every tick
int max_renders_per_tick = 100; //this many blocks' pixels will be refreshed every tick
int max_updates_per_tick = 50; //this many blocks will be checked for destruction per tick
int max_updates_per_tick = 50; //this many blocks will be checked for destruction per tick
int max_terminal_status_checks_per_tick = 10; //script will check for hacking/damage to this many terminal blocks per tick.
int max_terminal_status_checks_per_tick = 10; //script will check for hacking/damage to this many terminal blocks per tick.
int initial_limit = 250;
int initial_limit = 250;


//=====================================================================================
//=====================================================================================
//Everything below should not be touched unless you REALLY know what you're doing
//Everything below should not be touched unless you REALLY know what you're doing
/////////////////
/////////////////


List < Vector3I > coords_ship_full = new List < Vector3I > {};
List < Vector3I > coords_ship_full = new List < Vector3I > {};
List < Vector3I > coords_ship_now = new List < Vector3I > {};
List < Vector3I > coords_ship_now = new List < Vector3I > {};
List < IMyTerminalBlock > blocks_terminal = new List < IMyTerminalBlock > {};
List < IMyTerminalBlock > blocks_terminal = new List < IMyTerminalBlock > {};
List < Vector3I > coords_terminal_full = new List < Vector3I > {};
List < Vector3I > coords_terminal_full = new List < Vector3I > {};
List < Vector3I > coords_terminal_now = new List < Vector3I > {};
List < Vector3I > coords_terminal_now = new List < Vector3I > {};
List < Vector3I > coords_terminal_working = new List < Vector3I > {};
List < Vector3I > coords_terminal_working = new List < Vector3I > {};
List < Vector3I > coords_terminal_nothacked = new List < Vector3I > {};
List < Vector3I > coords_terminal_nothacked = new List < Vector3I > {};
List < Vector3I > coords_ship_checked = new List < Vector3I > {};
List < Vector3I > coords_ship_checked = new List < Vector3I > {};
List < Vector3I > coords_ship_to_check = new List < Vector3I > {};
List < Vector3I > coords_ship_to_check = new List < Vector3I > {};
List < IMyTerminalBlock > blocks_ship_text_panel = new List < IMyTerminalBlock > {};
List < IMyTerminalBlock > blocks_ship_text_panel = new List < IMyTerminalBlock > {};
List < Vector3I > coords_to_render = new List < Vector3I > {};
List < Vector3I > coords_to_render = new List < Vector3I > {};


List < Vector3I > coords_gyro_full = new List < Vector3I > {};
List < Vector3I > coords_gyro_full = new List < Vector3I > {};
List < Vector3I > coords_gyro_now = new List < Vector3I > {};
List < Vector3I > coords_gyro_now = new List < Vector3I > {};
List < Vector3I > coords_thrust_full = new List < Vector3I > {};
List < Vector3I > coords_thrust_full = new List < Vector3I > {};
List < Vector3I > coords_thrust_now = new List < Vector3I > {};
List < Vector3I > coords_thrust_now = new List < Vector3I > {};
List < Vector3I > coords_weapon_full = new List < Vector3I > {};
List < Vector3I > coords_weapon_full = new List < Vector3I > {};
List < Vector3I > coords_weapon_now = new List < Vector3I > {};
List < Vector3I > coords_weapon_now = new List < Vector3I > {};
List < Vector3I > coords_power_full = new List < Vector3I > {};
List < Vector3I > coords_power_full = new List < Vector3I > {};
List < Vector3I > coords_power_now = new List < Vector3I > {};
List < Vector3I > coords_power_now = new List < Vector3I > {};


Vector3I shipCoordMin = new Vector3I {};
Vector3I shipCoordMin = new Vector3I {};
Vector3I shipCoordMax = new Vector3I {};
Vector3I shipCoordMax = new Vector3I {};
Vector3I shipSizeVector = new Vector3I {};
Vector3I shipSizeVector = new Vector3I {};
Vector3I UpVec = new Vector3I(1, 0, 0);
Vector3I UpVec = new Vector3I(1, 0, 0);
Vector3I DnVec = new Vector3I(-1, 0, 0);
Vector3I DnVec = new Vector3I(-1, 0, 0);
Vector3I LfVec = new Vector3I(0, 1, 0);
Vector3I LfVec = new Vector3I(0, 1, 0);
Vector3I RtVec = new Vector3I(0, -1, 0);
Vector3I RtVec = new Vector3I(0, -1, 0);
Vector3I FwVec = new Vector3I(0, 0, 1);
Vector3I FwVec = new Vector3I(0, 0, 1);
Vector3I BkVec = new Vector3I(0, 0, -1);
Vector3I BkVec = new Vector3I(0, 0, -1);


IMyCubeGrid myGrid;
IMyCubeGrid myGrid;


int rotation = 0;
int rotation = 0;
int render_mode = 0;
int render_mode = 0;
List < int > cycling_index = new List < int > {
List < int > cycling_index = new List < int > {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
0
};
};
int state = 5;
int state = 5;
int num_blocks_in_ship = 0;
int num_blocks_in_ship = 0;
int num_terminals_in_ship = 0;
int num_terminals_in_ship = 0;
int full_blocks_index = 0; //keeps track of all loops that go over all blocks in ship
int full_blocks_index = 0; //keeps track of all loops that go over all blocks in ship
int terminal_blocks_index = 0; //keeps track of how far we are through checking terminal blocks
int terminal_blocks_index = 0; //keeps track of how far we are through checking terminal blocks
//int render_index =0; //keeps track of how far we are in the render process
//int render_index =0; //keeps track of how far we are in the render process
int render_skipper = 0; //index to track the render_slowness
int render_skipper = 0; //index to track the render_slowness
int divider_position = 0; //used for scanning through data from Storage
int divider_position = 0; //used for scanning through data from Storage
//int damage_iterator=0;
//int damage_iterator=0;
//int total_blocks_to_render=0;
//int total_blocks_to_render=0;
List < int > vert_rot_mapper = new List < int > {
List < int > vert_rot_mapper = new List < int > {
1,
1,
0,
0,
3,
3,
2,
2,
5,
5,
4
4
};
};
List < int > hor_rot_mapper = new List < int > {
List < int > hor_rot_mapper = new List < int > {
5,
5,
2,
2,
1,
1,
4,
4,
3,
3,
0
0
};
};


int gyrohealth = 0;
int gyrohealth = 0;
int thrusterhealth = 0;
int thrusterhealth = 0;
int hullhealth = 0;
int hullhealth = 0;
int weaponhealth = 0;
int weaponhealth = 0;
int systemhealth = 0;
int systemhealth = 0;
int powerhealth = 0;
int powerhealth = 0;


Vector3I cursor_vec = new Vector3I(0, 0, 0); //x,y
Vector3I cursor_vec = new Vector3I(0, 0, 0); //x,y


string[][][] rendered_images; //The jagged array of strings (images) that represent the ship
string[][][] rendered_images; //The jagged array of strings (images) that represent the ship
string[][][] rendered_shadows; //The jagged array of strings (images) that represent the ship's shadow.
string[][][] rendered_shadows; //The jagged array of strings (images) that represent the ship's shadow.


//bool show_damage= true;
//bool show_damage= true;
bool shadows_rendered = false;
bool shadows_rendered = false;
bool shadows_baked = false;
bool shadows_baked = false;
bool drawcursor = false;
bool drawcursor = false;


public Program() {
public Program() {
//firstBlock = Me;
//firstBlock = Me;
myGrid = Me.CubeGrid;
myGrid = Me.CubeGrid;
shipCoordMin = myGrid.Min;
shipCoordMin = myGrid.Min;
shipCoordMax = myGrid.Max;
shipCoordMax = myGrid.Max;
if (border_width < 1) border_width = 1;
if (border_width < 1) border_width = 1;
}
}


public void Main(string argument) {
public void Main(string argument) {
switch (state) {
switch (state) {
case 0: //terminal block status initalization
case 0: //terminal block status initalization
shadows_rendered = false;
shadows_rendered = false;
shadows_baked = false;
shadows_baked = false;
get_terminal_blocks();
get_terminal_blocks();
coords_terminal_now = new List < Vector3I > (coords_terminal_full);
coords_terminal_now = new List < Vector3I > (coords_terminal_full);
update_terminal_block_status(50); //this actually doesn't iterate more than one tick. Doesn't need to.
update_terminal_block_status(50); //this actually doesn't iterate more than one tick. Doesn't need to.
if (Storage.Length == 0) coords_ship_to_check.AddRange(coords_terminal_full);
if (Storage.Length == 0) coords_ship_to_check.AddRange(coords_terminal_full);
state = 1;
state = 1;
break;
break;
case 1: //all other block intitialization
case 1: //all other block intitialization
Echo("Initializing" + coords_ship_to_check.Count.ToString());
Echo("Initializing" + coords_ship_to_check.Count.ToString());
if (Storage.Length == 0) initialize_ship();
if (Storage.Length == 0) initialize_ship();
if (coords_ship_to_check.Count == 0) {
if (coords_ship_to_check.Count == 0) {
state = 2;
state = 2;
num_blocks_in_ship = coords_ship_full.Count;
num_blocks_in_ship = coords_ship_full.Count;
coords_to_render = new List < Vector3I > (coords_ship_full);
coords_to_render = new List < Vector3I > (coords_ship_full);
full_blocks_index = 0;
full_blocks_index = 0;
}
}
break;
break;
case 2: //generate blank background images
case 2: //generate blank background images
Echo("STATE2");
Echo("STATE2");
shadows_rendered = false;
shadows_rendered = false;
determine_render_limits(initial_limit); //testing this out. 100 should be safe. otherwise max_renders_per_tick.
determine_render_limits(initial_limit); //testing this out. 100 should be safe. otherwise max_renders_per_tick.
if (full_blocks_index >= num_blocks_in_ship) {
if (full_blocks_index >= num_blocks_in_ship) {
generate_backgrounds();
generate_backgrounds();
if (Storage.Length > 0) {
if (Storage.Length > 0) {
state = 3;
state = 3;
//render_index=0;
//render_index=0;
coords_to_render = new List < Vector3I > (coords_ship_full);
coords_to_render = new List < Vector3I > (coords_ship_full);
}
}
if (Storage.Length == 0 && num_blocks_in_ship > 0) {
if (Storage.Length == 0 && num_blocks_in_ship > 0) {
full_blocks_index = 0;
full_blocks_index = 0;
state = 4;
state = 4;
}
}
}
}
break;
break;
case 3: //Main state - drawing, updating, and watching for inputs
case 3: //Main state - drawing, updating, and watching for inputs
string arg = argument.ToLower();
string arg = argument.ToLower();
alarm_tracker--;
alarm_tracker--;
if (alarm_tracker <= 0) {
if (alarm_tracker <= 0) {
trigger_external_timers();
trigger_external_timers();
alarm_tracker = alarm_refresh_rate;
alarm_tracker = alarm_refresh_rate;
}
}
switch (arg) {
switch (arg) {
case "reset":
case "reset":
state = 6;
state = 6;
break;
break;
case "rotate":
case "rotate":
rotation = (rotation + 1) % 6;
rotation = (rotation + 1) % 6;
break;
break;
case "mode":
case "mode":
render_mode = (render_mode + 1) % 2;
render_mode = (render_mode + 1) % 2;
break;
break;
case "save":
case "save":
full_blocks_index = 0; //counter for saving
full_blocks_index = 0; //counter for saving
state = 4;
state = 4;
break;
break;
case "load":
case "load":
divider_position = 0; //counter for loading
divider_position = 0; //counter for loading
if (Storage.Length > 0) state = 5;
if (Storage.Length > 0) state = 5;
break;
break;
case "cursor":
case "cursor":
drawcursor = !drawcursor;
drawcursor = !drawcursor;
break;
break;
case "showdamaged":
case "showdamaged":
show_damage_on_hud();
show_damage_on_hud();
break;
break;
case "":
case "":
break;
break;
default:
default:
set_cursor_position(argument);
set_cursor_position(argument);
break;
break;
}
}
update_ship_block_existence(max_updates_per_tick);
update_ship_block_existence(max_updates_per_tick);
update_terminal_block_status(max_terminal_status_checks_per_tick);
update_terminal_block_status(max_terminal_status_checks_per_tick);
update_rendered_images(max_renders_per_tick);
update_rendered_images(max_renders_per_tick);
render_skipper++;
render_skipper++;
if (render_skipper > render_slowness) {
if (render_skipper > render_slowness) {
Echo("Main loop:");
Echo("Main loop:");
Echo("Terminals: " + coords_terminal_full.Count.ToString() + "/" + coords_terminal_now.Count.ToString());
Echo("Terminals: " + coords_terminal_full.Count.ToString() + "/" + coords_terminal_now.Count.ToString());
Echo("Updating: " + coords_ship_now.Count.ToString() + "/" + coords_ship_full.Count.ToString());
Echo("Updating: " + coords_ship_now.Count.ToString() + "/" + coords_ship_full.Count.ToString());
Echo("Rendering: " + coords_to_render.Count.ToString());
Echo("Rendering: " + coords_to_render.Count.ToString());
cycling_index[0] = (cycling_index[0] + 1) % Math.Abs(Rotate3I(shipSizeVector, 0).Z);
cycling_index[0] = (cycling_index[0] + 1) % Math.Abs(Rotate3I(shipSizeVector, 0).Z);
cycling_index[1] = (cycling_index[1] + 1) % Math.Abs(Rotate3I(shipSizeVector, 1).Z);
cycling_index[1] = (cycling_index[1] + 1) % Math.Abs(Rotate3I(shipSizeVector, 1).Z);
cycling_index[2] = (cycling_index[2] + 1) % Math.Abs(Rotate3I(shipSizeVector, 2).Z);
cycling_index[2] = (cycling_index[2] + 1) % Math.Abs(Rotate3I(shipSizeVector, 2).Z);
cycling_index[3] = (cycling_index[3] + 1) % Math.Abs(Rotate3I(shipSizeVector, 3).Z);
cycling_index[3] = (cycling_index[3] + 1) % Math.Abs(Rotate3I(shipSizeVector, 3).Z);
cycling_index[4] = (cycling_index[4] + 1) % Math.Abs(Rotate3I(shipSizeVector, 4).Z);
cycling_index[4] = (cycling_index[4] + 1) % Math.Abs(Rotate3I(shipSizeVector, 4).Z);
cycling_index[5] = (cycling_index[5] + 1) % Math.Abs(Rotate3I(shipSizeVector, 5).Z);
cycling_index[5] = (cycling_index[5] + 1) % Math.Abs(Rotate3I(shipSizeVector, 5).Z);
draw_images_to_screens();
draw_images_to_screens();
render_skipper = 0;
render_skipper = 0;
}
}
update_healths();
update_healths();
break;
break;
case 4: //save data
case 4: //save data
//full_blocks_index should be set to 0 before switching to this state.
//full_blocks_index should be set to 0 before switching to this state.
Echo("saving");
Echo("saving");
save_data(initial_limit);
save_data(initial_limit);
break;
break;
case 5: //load Data (replaces initialize ship)
case 5: //load Data (replaces initialize ship)
//divider_position should be set to 0 before switching to this state.
//divider_position should be set to 0 before switching to this state.
Echo("Loading");
Echo("Loading");
if (Storage.Length == 0) {
if (Storage.Length == 0) {
state = 0;
state = 0;
break;
break;
}
}
load_data(initial_limit);
load_data(initial_limit);
break;
break;
case 6: //delete
case 6: //delete
Storage = "";
Storage = "";
coords_ship_full = new List < Vector3I > {};
coords_ship_full = new List < Vector3I > {};
coords_ship_now = new List < Vector3I > {};
coords_ship_now = new List < Vector3I > {};
blocks_terminal = new List < IMyTerminalBlock > {};
blocks_terminal = new List < IMyTerminalBlock > {};
coords_terminal_full = new List < Vector3I > {};
coords_terminal_full = new List < Vector3I > {};
coords_terminal_now = new List < Vector3I > {};
coords_terminal_now = new List < Vector3I > {};
coords_terminal_working = new List < Vector3I > {};
coords_terminal_working = new List < Vector3I > {};
coords_terminal_nothacked = new List < Vector3I > {};
coords_terminal_nothacked = new List < Vector3I > {};
coords_ship_checked = new List < Vector3I > {};
coords_ship_checked = new List < Vector3I > {};
coords_ship_to_check = new List < Vector3I > {};
coords_ship_to_check = new List < Vector3I > {};
coords_gyro_full = new List < Vector3I > {};
coords_gyro_full = new List < Vector3I > {};
coords_gyro_now = new List < Vector3I > {};
coords_gyro_now = new List < Vector3I > {};
coords_thrust_full = new List < Vector3I > {};
coords_thrust_full = new List < Vector3I > {};
coords_thrust_now = new List < Vector3I > {};
coords_thrust_now = new List < Vector3I > {};
coords_weapon_full = new List < Vector3I > {};
coords_weapon_full = new List < Vector3I > {};
coords_weapon_now = new List < Vector3I > {};
coords_weapon_now = new List < Vector3I > {};
coords_power_now = new List < Vector3I > {};
coords_power_now = new List < Vector3I > {};
coords_power_full = new List < Vector3I > {};
coords_power_full = new List < Vector3I > {};
blocks_ship_text_panel = new List < IMyTerminalBlock > {};
blocks_ship_text_panel = new List < IMyTerminalBlock > {};
coords_to_render = new List < Vector3I > {};
coords_to_render = new List < Vector3I > {};
shipCoordMin = myGrid.Min;
shipCoordMin = myGrid.Min;
shipCoordMax = myGrid.Max;
shipCoordMax = myGrid.Max;
state = 0;
state = 0;
break;
break;
default:
default:
break;
break;
}
}
}
}


private void get_terminal_blocks() {
private void get_terminal_blocks() {
blocks_terminal = new List < IMyTerminalBlock > ();
blocks_terminal = new List < IMyTerminalBlock > ();
GridTerminalSystem.GetBlocksOfType < IMyTerminalBlock > (blocks_terminal);
GridTerminalSystem.GetBlocksOfType < IMyTerminalBlock > (blocks_terminal);
foreach(IMyTerminalBlock block in blocks_terminal) {
foreach(IMyTerminalBlock block in blocks_terminal) {
if (block.CubeGrid == Me.CubeGrid) {
if (block.CubeGrid == Me.CubeGrid) {
coords_terminal_full.Add(block.Position);
coords_terminal_full.Add(block.Position);
if (block is IMyThrust) {
if (block is IMyThrust) {
coords_thrust_full.Add(block.Position);
coords_thrust_full.Add(block.Position);
}
}
if (block is IMyGyro) {
if (block is IMyGyro) {
coords_gyro_full.Add(block.Position);
coords_gyro_full.Add(block.Position);
}
}
if (is_weapon(block)) {
if (is_weapon(block)) {
coords_weapon_full.Add(block.Position);
coords_weapon_full.Add(block.Position);
}
}
}
}
}
}
num_terminals_in_ship = blocks_terminal.Count;
num_terminals_in_ship = blocks_terminal.Count;
}
}


private void update_terminal_block_status(int limit) {
private void update_terminal_block_status(int limit) {
int count = 0;
int count = 0;
blocks_terminal = new List < IMyTerminalBlock > ();
blocks_terminal = new List < IMyTerminalBlock > ();
GridTerminalSystem.GetBlocksOfType < IMyTerminalBlock > (blocks_terminal);
GridTerminalSystem.GetBlocksOfType < IMyTerminalBlock > (blocks_terminal);
if (terminal_blocks_index >= blocks_terminal.Count) {
if (terminal_blocks_index >= blocks_terminal.Count) {
terminal_blocks_index = 0;
terminal_blocks_index = 0;
}
}
while (count < limit && terminal_blocks_index < blocks_terminal.Count) {
while (count < limit && terminal_blocks_index < blocks_terminal.Count) {
count++;
count++;
IMyTerminalBlock block = blocks_terminal[terminal_blocks_index];
IMyTerminalBlock block = blocks_terminal[terminal_blocks_index];
Vector3I pos = block.Position;
Vector3I pos = block.Position;
if (!coords_ship_full.Contains(pos)) { //ignore blocks we didn't find at initialization. (safer)
if (!coords_ship_full.Contains(pos)) { //ignore blocks we didn't find at initialization. (safer)
terminal_blocks_index++;
terminal_blocks_index++;
continue;
continue;
}
}
if (!myGrid.CubeExists(block.Position)) { //Note :if the block is gone we can still reference it.
if (!myGrid.CubeExists(block.Position)) { //Note :if the block is gone we can still reference it.
safely_remove(coords_terminal_now, pos);
safely_remove(coords_terminal_now, pos);
safely_remove(coords_terminal_working, pos);
safely_remove(coords_terminal_working, pos);
safely_remove(coords_terminal_nothacked, pos);
safely_remove(coords_terminal_nothacked, pos);
safely_remove(coords_gyro_now, pos);
safely_remove(coords_gyro_now, pos);
safely_remove(coords_thrust_now, pos);
safely_remove(coords_thrust_now, pos);
safely_remove(coords_weapon_now, pos);
safely_remove(coords_weapon_now, pos);
safely_remove(coords_power_now, pos);
safely_remove(coords_power_now, pos);
} else if (coords_terminal_full.Contains(pos)) {
} else if (coords_terminal_full.Contains(pos)) {
safely_add(coords_terminal_now, pos);
safely_add(coords_terminal_now, pos);
if (block.IsFunctional) {
if (block.IsFunctional) {
safely_add(coords_terminal_working, pos);
safely_add(coords_terminal_working, pos);
}
}
if (!block.IsBeingHacked) {
if (!block.IsBeingHacked) {
safely_add(coords_terminal_nothacked, pos);
safely_add(coords_terminal_nothacked, pos);
}
}
if (!block.IsFunctional) {
if (!block.IsFunctional) {
safely_remove(coords_terminal_working, pos);
safely_remove(coords_terminal_working, pos);
}
}
if (block.IsBeingHacked) {
if (block.IsBeingHacked) {
safely_remove(coords_terminal_nothacked, pos);
safely_remove(coords_terminal_nothacked, pos);
}
}
if (block is IMyThrust) {
if (block is IMyThrust) {
safely_add(coords_thrust_now, pos);
safely_add(coords_thrust_now, pos);
safely_add(coords_thrust_full, pos);
safely_add(coords_thrust_full, pos);
}
}
if (block is IMyGyro) {
if (block is IMyGyro) {
safely_add(coords_gyro_now, pos);
safely_add(coords_gyro_now, pos);
safely_add(coords_gyro_full, pos);
safely_add(coords_gyro_full, pos);
}
}
if (is_weapon(block)) {
if (is_weapon(block)) {
safely_add(coords_weapon_now, pos);
safely_add(coords_weapon_now, pos);
safely_add(coords_weapon_full, pos);
safely_add(coords_weapon_full, pos);
}
}
if (is_power(block)) {
if (is_power(block)) {
safely_add(coords_power_now, pos);
safely_add(coords_power_now, pos);
safely_add(coords_power_full, pos);
safely_add(coords_power_full, pos);
}
}
}
}
terminal_blocks_index++;
terminal_blocks_index++;
}
}
}
}


private void update_ship_block_existence(int limit) {
private void update_ship_block_existence(int limit) {
int count = 0;
int count = 0;
if (full_blocks_index >= num_blocks_in_ship) full_blocks_index = 0;
if (full_blocks_index >= num_blocks_in_ship) full_blocks_index = 0;
while (count < limit && full_blocks_index < num_blocks_in_ship) {
while (count < limit && full_blocks_index < num_blocks_in_ship) {
Vector3I testvec = coords_ship_full[full_blocks_index];
Vector3I testvec = coords_ship_full[full_blocks_index];
if (!myGrid.CubeExists(testvec)) {
if (!myGrid.CubeExists(testvec)) {
safely_remove(coords_ship_now, testvec);
safely_remove(coords_ship_now, testvec);
safely_remove(coords_terminal_working, testvec);
safely_remove(coords_terminal_working, testvec);
safely_remove(coords_terminal_nothacked, testvec);
safely_remove(coords_terminal_nothacked, testvec);
safely_remove(coords_terminal_now, testvec);
safely_remove(coords_terminal_now, testvec);
safely_remove(coords_gyro_now, testvec);
safely_remove(coords_gyro_now, testvec);
safely_remove(coords_thrust_now, testvec);
safely_remove(coords_thrust_now, testvec);
safely_remove(coords_weapon_now, testvec);
safely_remove(coords_weapon_now, testvec);
safely_remove(coords_power_now, testvec);
safely_remove(coords_power_now, testvec);
} else {
} else {
safely_add(coords_ship_now, testvec);
safely_add(coords_ship_now, testvec);
}
}
full_blocks_index++;
full_blocks_index++;
count++;
count++;
}
}
}
}


private void determine_render_limits(int limit) {
private void determine_render_limits(int limit) {
Echo("determining limits");
Echo("determining limits");
int count = 0;
int count = 0;
Vector3I border_vector = new Vector3I(border_width, border_width, border_width);
Vector3I border_vector = new Vector3I(border_width, border_width, border_width);
Vector3I vec = new Vector3I {};
Vector3I vec = new Vector3I {};
while (count < limit && full_blocks_index < num_blocks_in_ship) {
while (count < limit && full_blocks_index < num_blocks_in_ship) {
vec = coords_ship_full[full_blocks_index];
vec = coords_ship_full[full_blocks_index];
if (vec.X < shipCoordMin.X) shipCoordMin.X = vec.X;
if (vec.X < shipCoordMin.X) shipCoordMin.X = vec.X;
if (vec.X > shipCoordMax.X) shipCoordMax.X = vec.X;
if (vec.X > shipCoordMax.X) shipCoordMax.X = vec.X;
if (vec.Y < shipCoordMin.Y) shipCoordMin.Y = vec.Y;
if (vec.Y < shipCoordMin.Y) shipCoordMin.Y = vec.Y;
if (vec.Y > shipCoordMax.Y) shipCoordMax.Y = vec.Y;
if (vec.Y > shipCoordMax.Y) shipCoordMax.Y = vec.Y;
if (vec.Z < shipCoordMin.Z) shipCoordMin.Z = vec.Z;
if (vec.Z < shipCoordMin.Z) shipCoordMin.Z = vec.Z;
if (vec.Z > shipCoordMax.Z) shipCoordMax.Z = vec.Z;
if (vec.Z > shipCoordMax.Z) shipCoordMax.Z = vec.Z;
count++;
count++;
full_blocks_index++;
full_blocks_index++;
}
}
if (full_blocks_index < num_blocks_in_ship) return;
if (full_blocks_index < num_blocks_in_ship) return;
shipCoordMin -= border_vector;
shipCoordMin -= border_vector;
shipCoordMax += border_vector;
shipCoordMax += border_vector;
shipSizeVector = shipCoordMax - shipCoordMin;
shipSizeVector = shipCoordMax - shipCoordMin;
rendered_images = new String[6][][];
rendered_images = new String[6][][];
rendered_shadows = new String[6][][];
rendered_shadows = new String[6][][];
for (int r = 0; r < 6; r++) {
for (int r = 0; r < 6; r++) {
Vector3I absShipSize = Vector3I.Abs(Rotate3I(shipSizeVector, r));
Vector3I absShipSize = Vector3I.Abs(Rotate3I(shipSizeVector, r));
int[] tempSizeArray = {
int[] tempSizeArray = {
absShipSize.X,
absShipSize.X,
absShipSize.Y,
absShipSize.Y,
absShipSize.Z
absShipSize.Z
};
};
rendered_images[r] = new String[2][];
rendered_images[r] = new String[2][];
rendered_shadows[r] = new String[2][];
rendered_shadows[r] = new String[2][];
for (int j = 0; j < 2; j++) {
for (int j = 0; j < 2; j++) {
rendered_images[r][j] = new String[tempSizeArray[2]];
rendered_images[r][j] = new String[tempSizeArray[2]];
rendered_shadows[r][j] = new String[tempSizeArray[2]];
rendered_shadows[r][j] = new String[tempSizeArray[2]];
}
}
}
}
}
}


private void generate_backgrounds() {
private void generate_backgrounds() {
Echo("Generating backgrounds");
Echo("Generating backgrounds");
//Fill the image strings with empty characters
//Fill the image strings with empty characters
//the following should be pretty darn fast.
//the following should be pretty darn fast.
for (int r = 0; r < 6; r++) {
for (int r = 0; r < 6; r++) {
Vector3I rotvec = Vector3I.Abs(Rotate3I(shipSizeVector, r));
Vector3I rotvec = Vector3I.Abs(Rotate3I(shipSizeVector, r));
//construct one horizontal line.
//construct one horizontal line.
string line_string = new String(none, rotvec.X) + "\n";
string line_string = new String(none, rotvec.X) + "\n";
//Construct a block from horizontal lines
//Construct a block from horizontal lines
string block_string = "";
string block_string = "";
for (int i = 0; i < rotvec.Y; i++) {
for (int i = 0; i < rotvec.Y; i++) {
block_string = block_string + line_string;
block_string = block_string + line_string;
}
}
//set background for flat image mode (1)
//set background for flat image mode (1)
rendered_images[r][1][0] = block_string;
rendered_images[r][1][0] = block_string;
rendered_shadows[r][1][0] = block_string;
rendered_shadows[r][1][0] = block_string;
for (int i = 0; i < rotvec.Z; i++) {
for (int i = 0; i < rotvec.Z; i++) {
//set background for cross section mode (2)
//set background for cross section mode (2)
rendered_images[r][0][i] = block_string +
rendered_images[r][0][i] = block_string +
rotvec.X.ToString() + "x" + rotvec.Y.ToString() +
rotvec.X.ToString() + "x" + rotvec.Y.ToString() +
"@Z:" + i.ToString() + " r=" + r.ToString();
"@Z:" + i.ToString() + " r=" + r.ToString();
}
}
}
}
}
}


private void update_rendered_images(int limit) {
private void update_rendered_images(int limit) {
int count = 0;
int count = 0;
char newchar = 'X';
char newchar = 'X';
if (!shadows_baked) {
if (!shadows_baked) {
limit = initial_limit;
limit = initial_limit;
}
}
if (coords_to_render.Count == 0) {
if (coords_to_render.Count == 0) {
//render_index=0;
//render_index=0;
//show_damage=false;
//show_damage=false;
//damage_iterator=(damage_iterator+1)%4;
//damage_iterator=(damage_iterator+1)%4;
//if (damage_iterator==0) show_damage=false;
//if (damage_iterator==0) show_damage=false;
if (shadows_rendered) shadows_baked = true;
if (shadows_rendered) shadows_baked = true;
shadows_rendered = true;
shadows_rendered = true;
}
}
if (shadows_rendered && !shadows_baked) {
if (shadows_rendered && !shadows_baked) {
//The reason we're doing this is to avoid crazy render state dependency for a one-time function.
//The reason we're doing this is to avoid crazy render state dependency for a one-time function.
bake_shadows();
bake_shadows();
coords_to_render = new List < Vector3I > (coords_ship_full);
coords_to_render = new List < Vector3I > (coords_ship_full);
return;
return;
}
}
while (count < limit && coords_to_render.Count > 0) {
while (count < limit && coords_to_render.Count > 0) {
count++;
count++;
Vector3I testvec = coords_to_render[0];
Vector3I testvec = coords_to_render[0];
newchar = normal;
newchar = normal;
if (!coords_ship_now.Contains(testvec)) newchar = gone;
if (!coords_ship_now.Contains(testvec)) newchar = gone;
if (coords_terminal_now.Contains(testvec)) {
if (coords_terminal_now.Contains(testvec)) {
if (!coords_terminal_working.Contains(testvec)) newchar = broken;
if (!coords_terminal_working.Contains(testvec)) newchar = broken;
if (!coords_terminal_nothacked.Contains(testvec)) newchar = hacked;
if (!coords_terminal_nothacked.Contains(testvec)) newchar = hacked;
}
}
for (int r = 0; r < 6; r++) {
for (int r = 0; r < 6; r++) {
Vector3I rotsize = Vector3I.Abs(Rotate3I(shipSizeVector, r));
Vector3I rotsize = Vector3I.Abs(Rotate3I(shipSizeVector, r));
Vector3I rotscanned = Vector3I.Abs(Rotate3I(testvec - shipCoordMin, r));
Vector3I rotscanned = Vector3I.Abs(Rotate3I(testvec - shipCoordMin, r));
Vector3I rotcursor = Vector3I.Abs(Rotate3I(cursor_vec - shipCoordMin, r));
Vector3I rotcursor = Vector3I.Abs(Rotate3I(cursor_vec - shipCoordMin, r));
if (drawcursor && (
if (drawcursor && (
rotscanned.X == rotcursor.X || rotscanned.Y == rotcursor.Y)) newchar = cursor;
rotscanned.X == rotcursor.X || rotscanned.Y == rotcursor.Y)) newchar = cursor;
int xyindex = rotscanned.X + (rotsize.Y - rotscanned.Y) * (rotsize.X + 1);
int xyindex = rotscanned.X + (rotsize.Y - rotscanned.Y) * (rotsize.X + 1);
char oldchar = GetCharAt(rendered_images[r][0][rotscanned.Z], xyindex);
char oldchar = GetCharAt(rendered_images[r][0][rotscanned.Z], xyindex);
char oldchar_flat = GetCharAt(rendered_images[r][1][0], xyindex);
char oldchar_flat = GetCharAt(rendered_images[r][1][0], xyindex);
if (!shadows_rendered) {
if (!shadows_rendered) {
rendered_shadows[r][1][0] = ReplaceAt(rendered_shadows[r][1][0], xyindex, shadow);
rendered_shadows[r][1][0] = ReplaceAt(rendered_shadows[r][1][0], xyindex, shadow);
continue;
continue;
}
}
for (int i = 0; i < 2; i++) {
for (int i = 0; i < 2; i++) {
if (i == 1) {
if (i == 1) {
rendered_images[r][i][0] = ReplaceAt(rendered_images[r][i][0], xyindex, newchar);
rendered_images[r][i][0] = ReplaceAt(rendered_images[r][i][0], xyindex, newchar);
}
}
if (i == 0) {
if (i == 0) {
rendered_images[r][i][rotscanned.Z] = ReplaceAt(rendered_images[r][i][rotscanned.Z], xyindex, newchar);
rendered_images[r][i][rotscanned.Z] = ReplaceAt(rendered_images[r][i][rotscanned.Z], xyindex, newchar);
}
}
}
}
}
}
coords_to_render.Remove(testvec);
coords_to_render.Remove(testvec);
}
}
}
}


private void bake_shadows() {
private void bake_shadows() {
shadows_baked = true;
shadows_baked = true;
Echo("Baking");
Echo("Baking");
for (int r = 0; r < 6; r++) {
for (int r = 0; r < 6; r++) {
Vector3I rotsize = Vector3I.Abs(Rotate3I(shipSizeVector, r));
Vector3I rotsize = Vector3I.Abs(Rotate3I(shipSizeVector, r));
for (int i = 0; i < rotsize.Z; i++) {
for (int i = 0; i < rotsize.Z; i++) {
int progress = Convert.ToInt32(i * (rotsize.X / rotsize.Z));
int progress = Convert.ToInt32(i * (rotsize.X / rotsize.Z));
rendered_images[r][0][i] = rendered_shadows[r][1][0] + new string(cursor, progress);
rendered_images[r][0][i] = rendered_shadows[r][1][0] + new string(cursor, progress);
}
}
}
}
}
}


private void draw_images_to_screens() {
private void draw_images_to_screens() {
Echo("Updating screens");
Echo("Updating screens");
blocks_ship_text_panel = new List < IMyTerminalBlock > ();
blocks_ship_text_panel = new List < IMyTerminalBlock > ();
GridTerminalSystem.GetBlocksOfType < IMyTextPanel > (blocks_ship_text_panel);
GridTerminalSystem.GetBlocksOfType < IMyTextPanel > (blocks_ship_text_panel);
foreach(IMyTextPanel txt in blocks_ship_text_panel) {
foreach(IMyTextPanel txt in blocks_ship_text_panel) {
string cname = txt.CustomName.ToLower();
string cname = txt.CustomName.ToLower();
//Echo(cname);
//Echo(cname);
int namestart = cname.IndexOf(panel_prefix);
int namestart = cname.IndexOf(panel_prefix);
if (namestart >= 0) {
if (namestart >= 0) {
Echo("Found screen: " + cname);
Echo("Found screen: " + cname);
txt.ShowPublicTextOnScreen();
txt.ShowPublicTextOnScreen();
if (cname.IndexOf("report") > 0) {
if (cname.IndexOf("report") > 0) {
draw_health_report(txt);
draw_health_report(txt);
continue;
continue;
}
}
int rot, mod, ind, indh, indv, indhv;
int rot, mod, ind, indh, indv, indhv;
if (cname.IndexOf("main") >= 0) {
if (cname.IndexOf("main") >= 0) {
rot = rotation;
rot = rotation;
mod = render_mode;
mod = render_mode;
ind = cycling_index[rot];
ind = cycling_index[rot];
indh = cycling_index[hor_rot_mapper[rot]];
indh = cycling_index[hor_rot_mapper[rot]];
indv = cycling_index[vert_rot_mapper[rot]];
indv = cycling_index[vert_rot_mapper[rot]];
indhv = cycling_index[hor_rot_mapper[vert_rot_mapper[rot]]];
indhv = cycling_index[hor_rot_mapper[vert_rot_mapper[rot]]];
if (mod > 0) {
if (mod > 0) {
ind = 0;
ind = 0;
indh = 0;
indh = 0;
indv = 0;
indv = 0;
indhv = 0;
indhv = 0;
mod = 1;
mod = 1;
}
}
} else {
} else {
if (cname.Length >= (namestart + panel_prefix.Length + 1)) {
if (cname.Length >= (namestart + panel_prefix.Length + 1)) {
Int32.TryParse(cname.Substring(namestart + panel_prefix.Length, 1), out rot);
Int32.TryParse(cname.Substring(namestart + panel_prefix.Length, 1), out rot);
} else {
} else {
rot = 0;
rot = 0;
}
}
if (cname.Length >= (namestart + panel_prefix.Length + 3)) {
if (cname.Length >= (namestart + panel_prefix.Length + 3)) {
Int32.TryParse(cname.Substring(namestart + panel_prefix.Length + 2, 1), out mod);
Int32.TryParse(cname.Substring(namestart + panel_prefix.Length + 2, 1), out mod);
} else {
} else {
mod = 0;
mod = 0;
}
}
if (rot > 5 || rot < 0) rot = 0;
if (rot > 5 || rot < 0) rot = 0;
ind = cycling_index[rot];
ind = cycling_index[rot];
indh = cycling_index[hor_rot_mapper[rot]];
indh = cycling_index[hor_rot_mapper[rot]];
indv = cycling_index[vert_rot_mapper[rot]];
indv = cycling_index[vert_rot_mapper[rot]];
indhv = cycling_index[hor_rot_mapper[vert_rot_mapper[rot]]];
indhv = cycling_index[hor_rot_mapper[vert_rot_mapper[rot]]];
if (mod > 0) {
if (mod > 0) {
ind = 0;
ind = 0;
indh = 0;
indh = 0;
indv = 0;
indv = 0;
indhv = 0;
indhv = 0;
mod = 1;
mod = 1;
}
}
}
}
Echo("[" + rot.ToString() + "," + mod.ToString() + "]");
Echo("[" + rot.ToString() + "," + mod.ToString() + "]");
txt.WritePublicText(rendered_images[rot][mod][ind]);
txt.WritePublicText(rendered_images[rot][mod][ind]);
if (cname.IndexOf("_h") >= 0) {
if (cname.IndexOf("_h") >= 0) {
txt.WritePublicText(
txt.WritePublicText(
concat_horizontal(rendered_images[rot][mod][ind], rendered_images[hor_rot_mapper[rot]][mod][indh]));
concat_horizontal(rendered_images[rot][mod][ind], rendered_images[hor_rot_mapper[rot]][mod][indh]));
}
}
if (cname.IndexOf("_v") >= 0) {
if (cname.IndexOf("_v") >= 0) {
txt.WritePublicText(rendered_images[rot][mod][ind]);
txt.WritePublicText(rendered_images[rot][mod][ind]);
txt.WritePublicText(rendered_images[vert_rot_mapper[rot]][mod][indv], true);
txt.WritePublicText(rendered_images[vert_rot_mapper[rot]][mod][indv], true);
}
}
if (cname.IndexOf("_hv") >= 0) {
if (cname.IndexOf("_hv") >= 0) {
txt.WritePublicText(
txt.WritePublicText(
concat_horizontal(rendered_images[rot][mod][ind], rendered_images[hor_rot_mapper[rot]][mod][indh]));
concat_horizontal(rendered_images[rot][mod][ind], rendered_images[hor_rot_mapper[rot]][mod][indh]));
txt.WritePublicText(
txt.WritePublicText(
concat_horizontal(rendered_images[vert_rot_mapper[rot]][mod][indv],
concat_horizontal(rendered_images[vert_rot_mapper[rot]][mod][indv],
rendered_images[hor_rot_mapper[vert_rot_mapper[rot]]][mod][indhv]), true);
rendered_images[hor_rot_mapper[vert_rot_mapper[rot]]][mod][indhv]), true);
}
}
}
}
}
}
}
}


private Vector3I Rotate3I(Vector3I vec, int axis) {
private Vector3I Rotate3I(Vector3I vec, int axis) {
int xsiz = shipSizeVector.X;
int xsiz = shipSizeVector.X;
int ysiz = shipSizeVector.Y;
int ysiz = shipSizeVector.Y;
int zsiz = shipSizeVector.Z;
int zsiz = shipSizeVector.Z;
//rotates differently depending on ships dimensions. Tries to get wide on horizontal.
//rotates differently depending on ships dimensions. Tries to get wide on horizontal.
switch (axis) {
switch (axis) {
case 0: //x
case 0: //x
return new Vector3I(vec.Z * zscale, -vec.X * xscale, vec.Y * yscale);
return new Vector3I(vec.Z * zscale, -vec.X * xscale, vec.Y * yscale);
case 1: //y
case 1: //y
return new Vector3I(-vec.Z * zscale, vec.Y * yscale, vec.X * xscale);
return new Vector3I(-vec.Z * zscale, vec.Y * yscale, vec.X * xscale);
case 2: //z
case 2: //z
return new Vector3I(vec.X * xscale, vec.Y * yscale, vec.Z * zscale);
return new Vector3I(vec.X * xscale, vec.Y * yscale, vec.Z * zscale);
case 3: //x rot 90
case 3: //x rot 90
return new Vector3I(vec.X * xscale, -vec.Z * zscale, vec.Y * yscale);
return new Vector3I(vec.X * xscale, -vec.Z * zscale, vec.Y * yscale);
case 4: //y rot 90
case 4: //y rot 90
return new Vector3I(-vec.Y * yscale, vec.Z * zscale, vec.X * xscale);
return new Vector3I(-vec.Y * yscale, vec.Z * zscale, vec.X * xscale);
case 5: //z rot 90
case 5: //z rot 90
return new Vector3I(vec.Y * yscale, vec.X * xscale, vec.Z * zscale);
return new Vector3I(vec.Y * yscale, vec.X * xscale, vec.Z * zscale);
default:
default:
return vec;
return vec;
}
}
}
}


public string ReplaceAt(string input, int index, char newChar) {
public string ReplaceAt(string input, int index, char newChar) {
//index will be something like x + y*(width+1) (the +1 is because of the \n)
//index will be something like x + y*(width+1) (the +1 is because of the \n)
char[] chars = input.ToCharArray();
char[] chars = input.ToCharArray();
chars[index] = newChar;
chars[index] = newChar;
return new string(chars);
return new string(chars);
}
}


public char GetCharAt(string input, int index) {
public char GetCharAt(string input, int index) {
char[] chars = input.ToCharArray();
char[] chars = input.ToCharArray();
return chars[index];
return chars[index];
}
}


private void initialize_ship() {
private void initialize_ship() {
int count = 0; //limiter on instruction count.
int count = 0; //limiter on instruction count.
Vector3I c;
Vector3I c;
while (coords_ship_to_check.Count > 0) {
while (coords_ship_to_check.Count > 0) {
c = coords_ship_to_check[0];
c = coords_ship_to_check[0];
coords_ship_to_check.Remove(c);
coords_ship_to_check.Remove(c);
if (!coords_ship_checked.Contains(c)) {
if (!coords_ship_checked.Contains(c)) {
if (myGrid.CubeExists(c)) {
if (myGrid.CubeExists(c)) {
if (!coords_ship_full.Contains(c)) {
if (!coords_ship_full.Contains(c)) {
coords_ship_full.Add(c);
coords_ship_full.Add(c);
}
}
if (!coords_ship_checked.Contains(c + UpVec)) coords_ship_to_check.Add(c + UpVec);
if (!coords_ship_checked.Contains(c + UpVec)) coords_ship_to_check.Add(c + UpVec);
if (!coords_ship_checked.Contains(c + DnVec)) coords_ship_to_check.Add(c + DnVec);
if (!coords_ship_checked.Contains(c + DnVec)) coords_ship_to_check.Add(c + DnVec);
if (!coords_ship_checked.Contains(c + LfVec)) coords_ship_to_check.Add(c + LfVec);
if (!coords_ship_checked.Contains(c + LfVec)) coords_ship_to_check.Add(c + LfVec);
if (!coords_ship_checked.Contains(c + RtVec)) coords_ship_to_check.Add(c + RtVec);
if (!coords_ship_checked.Contains(c + RtVec)) coords_ship_to_check.Add(c + RtVec);
if (!coords_ship_checked.Contains(c + FwVec)) coords_ship_to_check.Add(c + FwVec);
if (!coords_ship_checked.Contains(c + FwVec)) coords_ship_to_check.Add(c + FwVec);
if (!coords_ship_checked.Contains(c + BkVec)) coords_ship_to_check.Add(c + BkVec);
if (!coords_ship_checked.Contains(c + BkVec)) coords_ship_to_check.Add(c + BkVec);
}
}
coords_ship_checked.Add(c);
coords_ship_checked.Add(c);
}
}
count++;
count++;
if (count > initial_limit) break;
if (count > initial_limit) break;
}
}
}
}


private void save_data(int limit) {
private void save_data(int limit) {
Echo("Saving");
Echo("Saving");
int count = 0;
int count = 0;
if (full_blocks_index >= num_blocks_in_ship) state = 3;
if (full_blocks_index >= num_blocks_in_ship) state = 3;
while (count < limit && full_blocks_index < num_blocks_in_ship) {
while (count < limit && full_blocks_index < num_blocks_in_ship) {
//Storage MUST end with a "|" character for loading to work.
//Storage MUST end with a "|" character for loading to work.
Storage = Storage + coords_ship_full[full_blocks_index].ToString();
Storage = Storage + coords_ship_full[full_blocks_index].ToString();
full_blocks_index++;
full_blocks_index++;
count++;
count++;
}
}
}
}


private void load_data(int limit) {
private void load_data(int limit) {
Echo("loading" + divider_position.ToString());
Echo("loading" + divider_position.ToString());
int count = 0;
int count = 0;
//Echo((Storage.IndexOf('[',divider_position+1)).ToString());
//Echo((Storage.IndexOf('[',divider_position+1)).ToString());
//Echo((Storage.IndexOf('[',divider_position+2)).ToString());
//Echo((Storage.IndexOf('[',divider_position+2)).ToString());
int next_position;
int next_position;
//if there are no more instances of the divider OR we are at/beyond the end
//if there are no more instance
if