Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using AlphaCore;
- using AlphaCore.Events;
- namespace MarioKart
- {
- [Behavior("Tracker", "true", "1.1", "PsyOps", "Tracks players in the race.")]
- [CommandHelp("!load 1", "Loads default map.", ModLevels.Sysop)]
- [CommandHelp("!add", "Includes you in the player list.", ModLevels.Sysop)]
- [CommandHelp("!add <name>", "Includes <name> in the player list.", ModLevels.Sysop)]
- public class Tracker : BotEventListener
- {
- // +----------+
- // | Commands |
- // +----------+
- public Tracker()
- {
- RegisterCommand("!debug", toggle_debug); // Toggles debug o_0
- RegisterCommand("!load", load_map2);
- RegisterCommand("!prog", show_prog);
- RegisterTimedEvent("MK_Init",5000,intitialize);
- RegisterTimedEvent("Downgrade",250,p_downgrade);
- RegisterTimedEvent("UpgradeL", 250, l_upgrade);
- RegisterTimedEvent("UpgradeM", 500, m_upgrade);
- RegisterTimedEvent("UpgradeH", 750, h_upgrade);
- }
- //-------------------------------------\\
- // +-----------+
- // | Variables |
- // +-----------+
- bool GameOn = false; // Is game in progress?
- List<Player> p_list = new List<Player>(); // Main player list
- bool debug = false; // Debug mode on or off
- Map loaded_map; // This is where the current map will be loaded
- int rankLvz_prefix = 600; // the lvz prefix for ranks, 1st,2nd,3rd *objon rankLvz_prefix+rank
- byte max_penalties = 5; // max amount of speed penalties for offtrack
- //-------------------------------------\\
- // +-------------+
- // | Containers |
- // +-------------+
- // -------- Player Container -----------
- public class Player
- {
- public string name; // Player name
- public ShipTypes ship; // What ship player is in. Determines kart weight and helps with acceleration.
- public int[] progress; // Player progress depending on direction. (index# 2)
- public int[] pos; // Player position recorded in case we need to warp them back
- public int laps; // Each track piece will be a checkpoint for now (index #4)
- public bool on_track; // on_track = is player on the track or off?
- public bool[] direction; // This will be an updated bool array to tell us if player has been going forward (index# 1)
- public byte[] penalty; // Keeps track of how many penalties have been given
- public byte place; // What place player is in.
- public Player(string name)
- {
- this.name = name;
- }
- public Player(int[] progress )
- {
- this.progress = progress;
- }
- public Player(ushort laps, bool on_track, int[] pos, byte[] penalty, ShipTypes ship, byte place)
- {
- this.laps = laps;
- this.on_track = on_track;
- this.pos = pos;
- this.penalty = penalty;
- this.ship = ship;
- this.place = place;
- }
- }
- // -------- Main map container ----------
- public class Map
- {
- public string name; // Name of the track
- public int[] ref_point; // All regions will be based off of this point (x,y)
- public List<track_region> regions; // All regions that make up the map
- public byte laps; // how many laps
- public int total_prog; // total progress to include all regions for 1 lap
- public Map(string name)
- {
- this.name = name;
- }
- public Map(int[] ref_point, List<track_region> regions, byte laps)
- {
- this.ref_point = ref_point;
- this.regions = regions;
- this.laps = laps;
- }
- }
- // ------- Individual region container ------
- public class track_region
- {
- public byte type; // is it linear or radial tracking
- public int[] region_pos; // position = x1,y1,x2,y2 (in tiles!!!! not pixels)
- public int[] in_track; // these will be points to calculate if player is inside of track
- public int[] radial_point; // Point used to compare player position to
- public int[] c_points; // {lap number, total progress points to that point} (index #3)
- public int[] s_point; // Warpto point for that region, must be in the beginning
- public track_region(byte type)
- {
- this.type = type;
- }
- public track_region(int[] region_pos, int[] radial_point, int[] c_points, int[] s_point)
- {
- this.region_pos = region_pos;
- this.radial_point = radial_point;
- this.c_points = c_points;
- this.s_point = s_point;
- }
- }
- //----------------------------------------------------------------\\
- // +-----------------+
- // | Player Tracking |
- // +-----------------+
- // ----------- track_player ----------------
- // I will track player movement here by monitoring PlayerPosition packets
- public void track_player(object sender, PlayerPositionEvent p)
- {
- // Make sure game is active before we track players
- if (GameOn)
- {
- p_list.ForEach(delegate(Player p2)
- {
- bool OnMap = false; // Is player even on the map?
- if (p2.name == p.PlayerName)
- {
- // Checking regions inside of the loaded map
- loaded_map.regions.ForEach(delegate(track_region t)
- {
- if (collision_detect(new int[] { p.MapPositionX, p.MapPositionY }, t.region_pos))
- {
- update_progress(p,t);
- p2.pos = new int[] {p.MapPositionX/16,p.MapPositionY/16 };
- OnMap = true; // Player is in the map
- bool oldT = p2.on_track;
- if (t.type > 8)
- { // Linear on track check
- bool newT = ontrack_line(p, t);
- if (oldT != newT)
- { p2.on_track = newT;}
- }
- else
- { // Radial on track check
- bool newT = ontrack_radial(p, t);
- if (oldT != newT)
- { p2.on_track = newT;}
- }
- }
- });
- }
- if (OnMap == false)
- { // checking to see if they are in the map. this is second check cause i have holes in the map
- if (collision_detect(new int[]{
- p.MapPositionX,p.MapPositionY}, new int[]{loaded_map.ref_point[0],loaded_map.ref_point[1],
- loaded_map.ref_point[0] + loaded_map.ref_point[2],loaded_map.ref_point[1]+loaded_map.ref_point[3]}) == false)
- {
- //last recorded position inside of the map
- warp(p.PlayerName, p2.pos[0], p2.pos[1]);
- }
- }
- });
- }
- }
- // This will update players position
- public void update_progress(PlayerPositionEvent p, track_region t ) // (index #3)
- {
- // itirating through each playe in the list
- p_list.ForEach(delegate(Player p2)
- {
- // if the name matches
- if (p2.name == p.PlayerName)
- {
- // Linear tracking
- if (t.type > 8)
- {
- if (t.type == 9)// X coordinates going forward
- {p2.progress[1] = t.c_points[1] + region_progress(true, p.MapPositionX, t.region_pos[0]); }
- else if (t.type == 10)// X coordinates backwards
- {p2.progress[1] = t.c_points[1] + region_progress(false, p.MapPositionX, t.region_pos[2]);}
- else if (t.type == 11) // Y coordinates going forward
- {p2.progress[1] = t.c_points[1] + region_progress(true, p.MapPositionY, t.region_pos[1]); }
- else if (t.type == 12)// Y coordinates going forward
- {p2.progress[1] = t.c_points[1] + region_progress(false, p.MapPositionY, t.region_pos[3]);}
- }
- // Radial tracking
- else
- {
- // Regular radial progress is just degrees
- if ((t.type == 1) || (t.type == 4) || (t.type == 6) || (t.type == 7))
- { p2.progress[1] = t.c_points[1] + get_rot(p,t); }
- // With the rest we have to subract 90 from angle to get progress
- else if ((t.type == 2) || (t.type == 3) || (t.type == 5) || (t.type == 8))
- { p2.progress[1] = t.c_points[1] + (90 - get_rot(p, t)); }
- }
- int oldL = p2.progress[0]; // Old Lap
- int newL = t.c_points[0]; // New Lap
- // If player lap and region lap are not the same then we need to update
- if (oldL != newL)
- {
- if (newL > oldL )
- {
- if (newL - oldL < 2)
- { p2.laps++; }
- else
- { p2.laps -= 1;}
- }
- else if (oldL > newL )
- {
- if (oldL - newL < 2)
- { p2.laps -= 1;}
- else
- { p2.laps++; }
- }
- }
- // Updating segments
- p2.progress[0] = t.c_points[0];
- // Updating total progress and not just segment progress
- if (p2.laps > loaded_map.laps)
- {
- int temp1 = (p2.laps/loaded_map.laps);
- p2.progress[2] = (temp1 * loaded_map.total_prog) + p2.progress[1];
- }
- else if (p2.laps < 0)
- {
- if ((p2.laps * -1) > loaded_map.laps)
- {
- int temp1 = ((p2.laps * -1)/ loaded_map.laps);
- p2.progress[2] = ((temp1 * loaded_map.total_prog) + p2.progress[1]) * -1;
- }
- else
- { p2.progress[2] = (loaded_map.total_prog - p2.progress[1]) * -1; }
- }
- else if (p2.laps == loaded_map.laps)
- {
- p2.progress[2] = loaded_map.total_prog + p2.progress[1];
- }
- else if (p2.laps >= 0)
- { p2.progress[2] = p2.progress[1]; }
- p_list.Sort(delegate(Player p5, Player p6) { return p6.progress[2].CompareTo(p5.progress[2]); });
- }
- });
- update_place();
- }
- // Radial progress
- public int get_rot(PlayerPositionEvent e, track_region t)
- {
- int send = 0;
- // Formula to extract an angle
- double angle = Math.Atan((double)(e.MapPositionY - t.radial_point[1]) / (double)(e.MapPositionX - t.radial_point[0])) * (180.0 / 3.14159);
- // In case of a negative number we make it positive here
- if (angle < 0)
- { angle = angle * -1; }
- send = (int)Math.Floor(angle);
- return send;
- }
- // Linear progress
- public int region_progress(bool forward, int playerVar, int regionVar)
- {//(checkpoints.max added up) + (player(a) - region(a))
- int send = 0;
- if (forward)//or clockwise
- { send = playerVar - (regionVar * 16); }
- else //or backwards Counterclockwise
- { send = ((regionVar * 16) + 15) - playerVar;}
- return send;
- }
- // Update players placements
- public void update_place()
- {
- byte new_p = 1;
- p_list.ForEach(delegate(Player p)
- {
- if (p.place != new_p)
- {
- message(2,p.name,"*objset -" + (rankLvz_prefix + p.place) + ",+" + (rankLvz_prefix + new_p) + ",");
- p.place = new_p;
- }
- new_p++;
- });
- }
- //----------------------------------------------------------------\\
- // +--------------------+
- // | On-Track Detection |
- // +--------------------+
- // ----------- offtrack_line ----------------
- // Collision code for track - vertical or horizontal. Returns true if collision is detected
- // int[] t = track region. upper left (x1,y1) = (t[0]),(t[1]) and (x2,y2) = (t[2]),(t[3])
- public bool ontrack_line(PlayerPositionEvent p, track_region t)
- {
- return collision_detect(new int[] { p.MapPositionX, p.MapPositionY }, t.in_track);
- }
- // ----------- offtrack_radius ----------------
- // Collision code for track - elbows. Returns true if collision is detected
- public bool ontrack_radial(PlayerPositionEvent p, track_region t)
- {
- bool send = false;
- double inner = GetDistance(t.radial_point[0],t.radial_point[1],t.in_track[0] * 16,t.in_track[1] * 16);
- double outer = GetDistance(t.radial_point[0], t.radial_point[1], t.in_track[2] * 16, t.in_track[3] * 16);
- double player = GetDistance(t.radial_point[0], t.radial_point[1], p.MapPositionX, p.MapPositionY);
- //debug_msg(inner + ":" + outer + ":" + player + ":");
- if (inner < outer)
- {
- if (player > inner && player < outer)
- { send = true;}
- }
- else
- {
- if (player < inner && player > outer)
- { send = true; }
- }
- return send;
- }
- private static double GetDistance(double x1,double y1,double x2,double y2)
- {
- //pythagoras theorem c^2 = a^2 + b^2
- //thus c = square root(a^2 + b^2)
- double a = (double)(x2 - x1);
- double b = (double)(y2 - y1);
- return Math.Sqrt(a * a + b * b);
- }
- //----------------------------------------------------------------\\
- // +--------------------+
- // | Chat Commands |
- // +--------------------+
- // ------------- DEBUG toggle ----------------
- // toggles debug mode
- public void toggle_debug(ChatEvent c)
- {
- if (ModLevels.Sysop == c.ModLevel)
- {
- debug = !debug;
- message(3, "", "Debug mode set to:<" + debug + ">.");
- }
- }
- public void load_map2(ChatEvent c)
- {
- if (ModLevels.Sysop == c.ModLevel)
- {
- string[] data = (c.Message.Trim()).Split(' ');
- load_Map(byte.Parse(data[1]));
- GameOn = true;
- debug_msg("Game mode on!");
- }
- }
- public void show_prog(ChatEvent c)
- {
- if (ModLevels.Sysop == c.ModLevel)
- {
- p_list.ForEach(delegate(Player p)
- {
- message(3, "", "Name:<" + p.name + "> Laps:<"+ p.laps +"/" + loaded_map.laps + "> Progress:<" + p.progress[1] + "/" + p.progress[2] + ">.");
- });
- }
- }
- //----------------------------------------------------------------\\
- // +--------------------+
- // | Misc Utilities |
- // +--------------------+
- // --- General Collision Detection ---
- public bool collision_detect(int[] player,int[] obstacle)
- {
- bool send = false;
- if ((player[0] > obstacle[0] * 16) && (player[1] > obstacle[1] * 16) && (player[0] < obstacle[2] * 16) && (player[1] < obstacle[3] * 16))
- { send = true; }
- return send;
- }
- // Updating player ship type
- public void monitor_SC(object sender, ShipChangeEvent s)
- {
- bool on_list = false;
- p_list.ForEach(delegate(Player p)
- {
- if (p.name == s.PlayerName)
- {
- on_list = true;
- p.ship = s.ShipType;
- }
- });
- if (on_list == false && s.PreviousShipType == ShipTypes.Spectator)
- {
- Player add = new Player(s.PlayerName);
- add.progress = new int[] { 1, 0 ,0};
- add.penalty = new byte[] { 0, max_penalties };
- add.ship = s.ShipType;
- add.on_track = true;
- add.place = 8;
- p_list.Add(add);
- debug_msg("Player:<" + s.PlayerName + "> added to main player list.");
- warp(s.PlayerName, 133, 843);
- message(2, s.PlayerName, "*shipreset");
- }
- else if (s.ShipType == ShipTypes.Spectator)
- {
- p_list.ForEach(delegate(Player p)
- {
- if (p.name == s.PlayerName)
- {
- p_list.Remove(p);
- debug_msg("Player:<" + s.PlayerName + "> has been deleted from the main player list.");
- }
- });
- }
- }
- // messages that are only displayed when debug is set to true
- public void debug_msg(string msg)
- {
- if (debug)
- {
- message(3, "", msg);
- }
- }
- public void p_downgrade()
- {
- p_list.ForEach(delegate(Player p)
- {
- if (p.on_track == false && p.penalty[0] < p.penalty[1] )
- {
- p.penalty[0] += 1;
- message(2, p.name, "*prize #-12");
- }
- });
- }
- public void l_upgrade()
- {
- p_list.ForEach(delegate(Player p)
- {
- if (p.on_track && p.penalty[0] > 0)
- {
- if (p.ship == ShipTypes.Leviathon || p.ship == ShipTypes.Weasel || p.ship == ShipTypes.Lancaster)
- {
- p.penalty[0] -= 1;
- message(2, p.name, "*prize #12");
- }
- }
- });
- }
- public void m_upgrade()
- {
- p_list.ForEach(delegate(Player p)
- {
- if (p.on_track && p.penalty[0] > 0)
- {
- if (p.ship == ShipTypes.Warbird || p.ship == ShipTypes.Spider)
- {
- p.penalty[0] -= 1;
- message(2, p.name, "*prize #12");
- }
- }
- });
- }
- public void h_upgrade()
- {
- p_list.ForEach(delegate(Player p)
- {
- if (p.on_track && p.penalty[0] > 0)
- {
- if (p.ship == ShipTypes.Javelin || p.ship == ShipTypes.Terrier || p.ship == ShipTypes.Shark)
- {
- p.penalty[0] -= 1;
- message(2, p.name, "*prize #12");
- }
- }
- });
- }
- // Initializes bot
- public void intitialize()
- {
- message(4, "", "@MK_Initialize@");
- GameOn = true;
- message(3, "", "Debug mode is set to:<" + debug + ">.");
- message(3, "", "MarioKart module initialized.Game Mode On.");
- message(1, "", "*specall");
- RemoveTimedEvent("MK_Init");
- load_Map(1);
- message(3, "", "Map loaded:<" + loaded_map.name + ">.");
- }
- // just a shortcut to warping someone
- public void warp(string name, int x, int y)
- {
- message(2, name, "*warpto " + x + " " + y);
- }
- // ----- Shortcut for sending messages ------
- public void message(ushort type, string name, string msg)
- {
- //creating chat event
- ChatEvent notify = new ChatEvent();
- //extracting playername from EventArgs e
- notify.PlayerName = name;
- // Setting Chat type here
- if (type == 1) // Public
- {
- notify.ChatType = ChatTypes.Public;
- }
- else if (type == 2) // Private
- {
- notify.ChatType = ChatTypes.Private;
- }
- else if (type == 3) // Arena
- {
- notify.ChatType = ChatTypes.Arena;
- }
- else if (type == 4) // Zone
- {
- notify.ChatType = ChatTypes.Zone;
- }
- // Including the passed msg
- notify.Message = msg;
- if (type != 4)
- {
- //sending message
- SendGameEvent(notify);
- }
- else
- {
- SendCoreEvent(notify);
- }
- }
- // +--------------------+
- // | M A P S |
- // +--------------------+
- //-------------------------------------------
- public void load_Map(int map)
- {
- if (map == 1)
- { //----------------------------- 1,2,3,4,5 ,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
- byte[] region_type = new byte[]{9,2,7,2,11,4,5,4,3,12, 6, 5, 4,10, 3,12, 1, 8, 1, 9}; // what region type 1-12
- int[][] region_pos = new int[][]{
- new int[]{125,0,158,37}, //1
- new int[]{159,0,206,37}, //2
- new int[]{159,38,205,83}, //3
- new int[]{206,37,250,84}, //4
- new int[]{206,85,250,101}, //5
- new int[]{206,102,250,149}, //6
- new int[]{159,102,205,148}, //7
- new int[]{159,149,206,188}, //8
- new int[]{112,149,158,188}, //9
- new int[]{112,102,157,148}, //10
- new int[]{112,63,154,101}, //11
- new int[]{69,60,111,101}, //12
- new int[]{65,102,111,188}, //13
- new int[]{44,106,64,188}, //14
- new int[]{0,102,43,188}, //15
- new int[]{0,85,44,101}, //16
- new int[]{0,37,43,84}, //17
- new int[]{44,38,88,78}, //18
- new int[]{43,0,90,37}, //19
- new int[]{91,0,124,37}, //20
- }; // x1,y1,x2,y2 in tiles!!!!!!!!!
- int[][] on_track = new int[][] {
- new int[]{125,7,159,22}, //1
- new int[]{159,22,159,7}, //2
- new int[]{190,38,175,38}, //3
- new int[]{206,69,206,54}, //4
- new int[]{222,85,237,102}, //5
- new int[]{222,102,237,102}, //6
- new int[]{190,148,175,148}, //7
- new int[]{175,149,190,149}, //8
- new int[]{143,149,128,149}, //9
- new int[]{128,102,143,149}, //10
- new int[]{112,86,112,71}, //11
- new int[]{96,101,81,101}, //12
- new int[]{81,102,96,102}, //13
- new int[]{44,118,65,133}, //14
- new int[]{28,102,13,102}, //15
- new int[]{13,85,28,102}, //16
- new int[]{28,84,13,84}, //17
- new int[]{44,54,44,69}, //18
- new int[]{75,37,60,37}, //19
- new int[]{91,7,125,22} //20
- };
- int[][] spoint = new int[][] {
- new int[]{129,14}, //1
- new int[]{163,15}, //2
- new int[]{182,14}, //3
- new int[]{211,62}, //4
- new int[]{229,88}, //5
- new int[]{228,107}, //6
- new int[]{201,125}, //7
- new int[]{181,152}, //8
- new int[]{154,172}, //9
- new int[]{135,144}, //10
- new int[]{134,197}, //11
- new int[]{108,78}, //12
- new int[]{87,105}, //13
- new int[]{60,126}, //14
- new int[]{40,126}, //15
- new int[]{20,98}, //16
- new int[]{20,80}, //17
- new int[]{47,61}, //18
- new int[]{68,33}, //19
- new int[]{94,14} //20
- };
- Map test_map = new Map("Test Map");
- test_map.ref_point = new int[] {380,440,250,188};
- List<track_region> all_region = new List<track_region>();
- int acc_prog = 0;
- for (int i = 0; i < region_type.Length; i++)
- {
- track_region add = new track_region(region_type[i]);
- // Making sure the points are all based off of ref point
- add.region_pos = new int[]{
- region_pos[i][0] + test_map.ref_point[0], // X1
- region_pos[i][1] + test_map.ref_point[1], // Y1
- region_pos[i][2] + test_map.ref_point[0], // X2
- region_pos[i][3] + test_map.ref_point[1]};// Y2
- // For radial we need to find the point to compare the player with
- add.radial_point = get_rpoint(region_type[i], region_pos[i], test_map.ref_point);
- add.c_points = new int[] { (i + 1),acc_prog}; // adding to the total progress
- acc_prog = acc_prog + get_regionprog(region_type[i], region_pos[i]);
- add.in_track = new int[] {
- on_track[i][0] += test_map.ref_point[0],
- on_track[i][1] += test_map.ref_point[1],
- on_track[i][2] += test_map.ref_point[0],
- on_track[i][3] += test_map.ref_point[1]
- };
- add.s_point = spoint[i];
- add.s_point = new int[] {
- spoint[i][0] += test_map.ref_point[0],
- spoint[i][1] += test_map.ref_point[1],
- };
- all_region.Add(add);
- }
- test_map.laps = (byte)all_region.Count;
- test_map.regions = all_region;
- test_map.total_prog = acc_prog;
- loaded_map = test_map;
- debug_msg("Map Loaded. <" + loaded_map.name + ">.");
- }
- }
- // Finding the very last pixel on the corner corresponding with that track type
- public int[] get_rpoint(byte type,int[] pos, int[] ref_p)
- {
- int[] send = {69,69};
- // using x,y cause its too damn confusing for me to use pos[]
- int x1 = (pos[0] + ref_p[0]) * 16;
- int y1 = (pos[1] + ref_p[1]) * 16;
- int x2 = (pos[2] + ref_p[0]) * 16;
- int y2 = (pos[3] + ref_p[1]) * 16;
- // Grouping similar track types. They are measured off of same point
- if (type == 1 || type == 5)
- { send = new int[] {x2 + 15, y2 + 15}; }
- else if (type == 2 || type == 6)
- { send = new int[] { x1, y2 + 15};}
- else if (type == 3 || type == 7)
- { send = new int[] { x2 + 15, y1};}
- else if (type == 4 || type == 8)
- { send = new int[] { x1, y1 };}
- return send;
- }
- // Using this to add up all progress for entire map
- public int get_regionprog(byte type,int[] pos)
- {
- int send = 0;
- if (type == 9 || type == 10) // horizontal
- { send = ((pos[2] * 16) + 15) - (pos[0] * 16); }
- else if (type == 11 || type == 12) // vertical
- { send = ((pos[3] * 16) + 15) - (pos[1] * 16);}
- else // its radial. all 90 points
- { send = 90; }
- return send;
- }
- public override void Dispose()
- {
- throw new NotImplementedException();
- }
- }
- }
- // +--------------------+
- // | Changelog |
- // +--------------------+
- //-------------------------------------------
- //1.0 Added player position to player container. Also changed code to warp back function.
- //-------------------------------------------
- //-----------------------------------------------------------------\\ index# 1
- /* I will begin a timer at start of game. Every x/100s
- * I will compare progress to last stored progress and determine if
- * the player lost or gained distance and store it as a true/false.
- * from there i can check the last x amount of bools to see if there
- * is a pattern of falses to know if player is going the wrong way
- * this is to ensure i dont display a "going backwards" message
- * every time the player is knocked back.*/
- //------------------------------------------------------------------\\ index# 2
- /* progress[] = {laps,progress}
- * if horizontal or vertical progress will be:
- * progress = xcoord or
- * progress = ycoord
- * if its an elbow it will be recorded in radians:
- * progress = degrees */
- //------------------------------------------------------------------\\ index# 3
- /* Radial progress will have 90 points max for its region
- * Current progress for clockwise:
- * (checkpoints.max added up) + [(player(angle) - region.start(angle)]
- * Current progress for counter-clockwise:
- * (checkpoints.max added up) + (region_angle.end - player.angle)
- *
- * Linear will use the following:
- * total progress for region = ((a2 * 16) + 15) - (a1 * 16)
- * where a = x or y coordinates depending on region type (hor or vert)
- * to figure out current progress for L->R or U->D :
- * (checkpoints.max added up) + (player(a) - region(a)) --where a = x or y
- * progress for R->L or D->U then: --where a = x or y--
- * (checkpoints.max added up) + [(region(a2) - player(a))]*/
- //------------------------------------------------------------------\\ index #4
- /* checkpoint[1] will be all checkpoints added up to that point */
Advertisement
Add Comment
Please, Sign In to add comment