Skip to content
Snippets Groups Projects
Commit 4aa44af2 authored by Robin Halseth Sandvik's avatar Robin Halseth Sandvik
Browse files

Massive rework of inventory system.

- Now has 4 sections.
- Made to support the new inventory design.
- Passive items now only affect player if added to specific sections.
- All sections have their full size, null indicates a slot is empty.
- Functionality to easily move items between sections.
- Much more convoluted back-end code.
- It just works now.
parent 24f5b940
No related branches found
No related tags found
1 merge request!35Massive rework of inventory system.
...@@ -277,7 +277,7 @@ namespace BigSock { ...@@ -277,7 +277,7 @@ namespace BigSock {
/* /*
Adds a listener for a conditional item to this character's event. Adds a listener for a conditional item to this character's event.
*/ */
public void AddItemListener(ConditionalItemBase item) { public void AddItemListener(IConditionalItem item) {
switch(item.Trigger) { switch(item.Trigger) {
case TriggerType.Fire: OnFire += ((OnFireItemBase) item).Handler; break; case TriggerType.Fire: OnFire += ((OnFireItemBase) item).Handler; break;
case TriggerType.Hit: OnHit += ((OnHitItemBase) item).Handler; break; case TriggerType.Hit: OnHit += ((OnHitItemBase) item).Handler; break;
...@@ -294,7 +294,7 @@ namespace BigSock { ...@@ -294,7 +294,7 @@ namespace BigSock {
/* /*
Remove a listener for a conditional item from this character's event. Remove a listener for a conditional item from this character's event.
*/ */
public void RemoveItemListener(ConditionalItemBase item) { public void RemoveItemListener(IConditionalItem item) {
switch(item.Trigger) { switch(item.Trigger) {
case TriggerType.Fire: OnFire -= ((OnFireItemBase) item).Handler; break; case TriggerType.Fire: OnFire -= ((OnFireItemBase) item).Handler; break;
case TriggerType.Hit: OnHit -= ((OnHitItemBase) item).Handler; break; case TriggerType.Hit: OnHit -= ((OnHitItemBase) item).Handler; break;
...@@ -312,26 +312,28 @@ namespace BigSock { ...@@ -312,26 +312,28 @@ namespace BigSock {
Try to pick up an item. Try to pick up an item.
*/ */
public bool TryPickUpItem(IItem item) { public bool TryPickUpItem(IItem item) {
if(Inventory.AddItem(item)) { if(Inventory.AddItem(item) != -1) {
UpdateModifiers(); //UpdateModifiers();
print($"[Character.TryPickUpItem()] {item.Name} picked up. ({Inventory.Items.Count}/{Inventory.Cap})"); print($"[Character.TryPickUpItem()] {item.Name} picked up. ({Inventory.Backpack.Count}/{Inventory.BackpackCap})");
return true; return true;
} }
print($"[Character.TryPickUpItem()] {item.Name} NOT picked up. ({Inventory.Items.Count}/{Inventory.Cap})"); print($"[Character.TryPickUpItem()] {item.Name} NOT picked up. ({Inventory.Backpack.Count}/{Inventory.BackpackCap})");
return false; return false;
} }
/* /*
Try to drop an item. Try to drop an item.
!! Depricated, no use this method.
*/ */
public bool TryDropItem(IItem item) { public bool TryDropItem(IItem item) {
if(Inventory.RemoveItem(item)) { throw new NotImplementedException();
UpdateModifiers(); // if(Inventory.RemoveItem(item)) {
print($"[Character.TryDropItem()] {item.Name} dropped. ({Inventory.Items.Count}/{Inventory.Cap})"); // //UpdateModifiers();
return true; // print($"[Character.TryDropItem()] {item.Name} dropped. ({Inventory.Items.Count}/{Inventory.Cap})");
} // return true;
print($"[Character.TryDropItem()] {item.Name} NOT dropped. ({Inventory.Items.Count}/{Inventory.Cap})"); // }
return false; // print($"[Character.TryDropItem()] {item.Name} NOT dropped. ({Inventory.Items.Count}/{Inventory.Cap})");
// return false;
} }
} }
......
...@@ -5,27 +5,119 @@ using UnityEngine; ...@@ -5,27 +5,119 @@ using UnityEngine;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
/*
Notes for using the inventory system:
- Ignore most the stuff in there.
- You can read the 4 different lists to get what items are there:
- Backpack
- Accessories
- Equipment
- Tools
- !! DO NOT MODIFY LISTS EXTERNALLY, USE THE METHODS !!
- Each list has a corresponding cap.
- You can read the cap to see the limit.
- You can set the cap to expand/shrink the list. (shrink isn't implemented yet)
- How to use:
- AddItem() -- Adds an item to the backpack.
-- This is used for picking up items.
- MoveItem() -- Moves the item from one position to another.
-- This is for managing the inventory in the menu.
- DropItem() -- Drops an item from a particular slot.
-- This is used for when player drops an item in the menu.
//- FindItem()-- Finds the position of the item in the inventory.
-- This is used for when player drops an item in the menu.
- I want to add an item to a particular equipment slot.
-- var pos = inv.AddItem(item);
-- inv.MoveItem(item, InventoryType.Backpack, pos, InventoryType.Equipment, availablePos);
*/
namespace BigSock.Item { namespace BigSock.Item {
/* /*
An inventory of a character. An inventory of a character.
*/ */
public class Inventory { public partial class Inventory {
/* /*
The items in the inventory. The max number of items the backpack can hold.
*/ */
public List<IItem> Items { get; protected set; } = new List<IItem>(); public int BackpackCap {
get => Backpack.Count;
set {
while(value > Backpack.Count) Backpack.Add(null);
// No support for shrinking inventory yet.
if(value < Backpack.Count) throw new NotImplementedException();
}
}
/*
The part that holds items not in use.
*/
public List<IItem> Backpack { get; protected set; } = new List<IItem>();
/* /*
The modifier from all the passives. The max number of accessories the user can have on.
*/ */
public ICharacterStats Modifier { get; protected set; } = new CharacterStats(); public int AccessoriesCap {
get => Accessories.Count;
set {
while(value > Accessories.Count) Accessories.Add(null);
// No support for shrinking inventory yet.
if(value < Accessories.Count) throw new NotImplementedException();
}
}
/*
The accessories the user has on.
An accessory is put on the user's weapon.
*/
public List<IInactiveItem> Accessories { get; protected set; } = new List<IInactiveItem>();
/* /*
The max number of items the inventory can hold. The max number of equipment the user can have on.
*/
public int EquipmentCap {
get => Equipment.Count;
set {
while(value > Equipment.Count) Equipment.Add(null);
// No support for shrinking inventory yet.
if(value < Equipment.Count) throw new NotImplementedException();
}
}
/*
The equipment the user has on.
Equipment is worn by the user (Clothing, hats, etc).
*/
public List<IInactiveItem> Equipment { get; protected set; } = new List<IInactiveItem>();
/*
The max number of tools the user can have out.
*/
public int ToolsCap {
get => Tools.Count;
set {
while(value > Tools.Count) Tools.Add(null);
// No support for shrinking inventory yet.
if(value < Tools.Count) throw new NotImplementedException();
}
}
/*
The tools the user has out.
A tool is something the user can actively use (The abilities the user can use).
*/
public List<IActiveItem> Tools { get; protected set; } = new List<IActiveItem>();
/*
The modifier from all the passives.
*/ */
public int Cap { get; set; } = 10; public ICharacterStats Modifier { get; protected set; } = new CharacterStats();
/* /*
...@@ -34,53 +126,470 @@ namespace BigSock.Item { ...@@ -34,53 +126,470 @@ namespace BigSock.Item {
public Character Owner { get; } public Character Owner { get; }
public Inventory(Character owner) { public Inventory(Character owner, int backpackCap = 1, int accessoriesCap = 1, int equipmentCap = 1, int toolsCap = 4) {
if(owner == null) throw new ArgumentNullException(paramName: nameof(owner)); if(owner == null) throw new ArgumentNullException(paramName: nameof(owner));
Owner = owner; Owner = owner;
BackpackCap = backpackCap;
AccessoriesCap = accessoriesCap;
EquipmentCap = equipmentCap;
ToolsCap = toolsCap;
} }
/* /*
Adds an item to the inventory and manages changes. Adds an item to the inventory and manages changes.
*/ */
public bool AddItem(IItem item) { public int AddItem(IItem item) {
if(Items.Count >= Cap) return false; // Find the first available slot.
var pos = FindEmptySlot();
Items.Add(item); if(pos == -1) return pos;
// Add the passive effects to the modifier. Backpack[pos] = item;
if(item is PassiveItemBase passive) {
Modifier = Modifier.Add(passive.Modifier);
}
// Add the listener for this item to the owner. // if(Items.Count >= Cap) return false;
else if(item is ConditionalItemBase conditional) { //
Owner.AddItemListener(conditional); // Items.Add(item);
}
//! Add ifs to handle the other 2 types of items.
return true; // // Add the passive effects to the modifier.
// if(item is PassiveItemBase passive) {
// Modifier = Modifier.Add(passive.Modifier);
// }
// // Add the listener for this item to the owner.
// else if(item is ConditionalItemBase conditional) {
// Owner.AddItemListener(conditional);
// }
// //! Add ifs to handle the other 2 types of items.
return pos;
} }
/* /*
Removes an item from the inventory and manages changes. Removes an item from the inventory and manages changes.
!! Depricated, no use method.
*/ */
public bool RemoveItem(IItem item) { public bool RemoveItem(IItem item) {
if(!Items.Remove(item)) return false; throw new NotImplementedException();
// if(!Items.Remove(item)) return false;
//
// // Remove the passive effects from the modifier.
// if(item is PassiveItemBase passive) {
// Modifier = Modifier.Remove(passive.Modifier);
// }
// // Remove the listener for this item from the owner.
// else if(item is ConditionalItemBase conditional) {
// Owner.RemoveItemListener(conditional);
// }
// //! Add ifs to handle the other 2 types of items.
// return true;
}
/*
Moves an item from one inventory slot to another.
*/
public bool MoveItem(IItem item, InventoryType fType, int fPos, InventoryType tType, int tPos) {
if(item == null) return false;
if(fType == tType && fPos == tPos) return false;
// Try to remove the item from its original slot.
if(!RemoveItem(item, fType, fPos)) return false;
// Remove the passive effects from the modifier. // Try to add the item to the desired slot.
if(item is PassiveItemBase passive) { if(!AddItem(item, tType, tPos)) {
Modifier = Modifier.Remove(passive.Modifier); // Try to add the item back to its original slot.
if(!AddItem(item, fType, fPos)) {
// If the item was lost to the void.
Debug.Log($"[Inventory.MoveItem({item.Id}, {fType}, {fPos}, {tType}, {tPos})] Couldn't return item to its original place.");
}
return false;
} }
// Remove the listener for this item from the owner. return true;
else if(item is ConditionalItemBase conditional) { }
Owner.RemoveItemListener(conditional);
/*
Drops an item from a given slot.
*/
public bool DropItem(IItem item, InventoryType iType, int pos) {
if(item == null) return false;
return RemoveItem(item, iType, pos);
}
/*
Find the index of an item in teh inventory.
*/
//public int FindItem(IItem item, InventoryType iType) {
// List<IItem> lst;
// switch(iType) {
// case InventoryType.Backpack: lst = (List<IItem>) Backpack; break;
// case InventoryType.Tool: lst = (List<IItem>) Tools; break;
// case InventoryType.Accessory: lst = (List<IItem>) Accessories; break;
// case InventoryType.Equipment: lst = (List<IItem>) Equipment; break;
// default: return -1;
// }
// for(int i = 0; i < lst.Count; ++i)
// if(item == lst[i]) return i;
// return -1;
//}
}
/*
The different areas of the inventory.
*/
public enum InventoryType {
Backpack,
Tool,
Accessory,
Equipment,
}
/*
Black magic, gets background stuff to work.
Don't touch it, don't worry about it, for all you care, there are dwarves in the pc that make this work.
*/
public partial class Inventory {
/*
Finds first empty slot in the backpack.
Returns -1 if all full.
*/
private int FindEmptySlot() {
for(int i = 0; i < Backpack.Count; ++i)
if(Backpack[i] == null) return i;
return -1;
}
/*
Code that handles adding of items with effects to areas other than the backpack.
*/
private bool AddItem(IItem item, InventoryType iType, int pos) {
switch(iType) {
case InventoryType.Backpack: return AddBackpack(item, pos);
case InventoryType.Tool: return AddTool(item, pos);
case InventoryType.Accessory: return AddAccessory(item, pos);
case InventoryType.Equipment: return AddEquipment(item, pos);
default: return false;
} }
//! Add ifs to handle the other 2 types of items. }
private bool RemoveItem(IItem item, InventoryType iType, int pos) {
switch(iType) {
case InventoryType.Backpack: return RemoveBackpack(item, pos);
case InventoryType.Tool: return RemoveTool(item, pos);
case InventoryType.Accessory: return RemoveAccessory(item, pos);
case InventoryType.Equipment: return RemoveEquipment(item, pos);
default: return false;
}
}
private bool AddTool(IItem item, int pos) {
// Check range
if(0 > pos || pos >= Tools.Count) return false;
// Check is empty.
if(Tools[pos] != null) return false;
if(item is IActiveItem itm) {
Tools[pos] = itm;
AddedItem(itm);
return true;
} else return false;
}
private bool RemoveTool(IItem item, int pos) {
// Check range
if(0 > pos || pos >= Tools.Count) return false;
// Check is empty.
if(Tools[pos] != item) return false;
Tools[pos] = null;
RemovedItem(item);
return true;
}
private bool AddBackpack(IItem item, int pos) {
// Check range
if(0 > pos || pos >= Backpack.Count) return false;
// Check is empty.
if(Backpack[pos] != null) return false;
Backpack[pos] = item;
return true; return true;
} }
private bool RemoveBackpack(IItem item, int pos) {
// Check range
if(0 > pos || pos >= Backpack.Count) return false;
// Check is empty.
if(Backpack[pos] != item) return false;
Backpack[pos] = null;
return true;
}
private bool AddEquipment(IItem item, int pos) {
// Check range
if(0 > pos || pos >= Equipment.Count) return false;
// Check is empty.
if(Equipment[pos] != null) return false;
if(item is IInactiveItem itm) {
Equipment[pos] = itm;
AddedItem(itm);
return true;
} else return false;
}
private bool RemoveEquipment(IItem item, int pos) {
// Check range
if(0 > pos || pos >= Equipment.Count) return false;
// Check is empty.
if(Equipment[pos] != item) return false;
Equipment[pos] = null;
RemovedItem(item);
return true;
}
private bool AddAccessory(IItem item, int pos) {
// Check range
if(0 > pos || pos >= Accessories.Count) return false;
// Check is empty.
if(Accessories[pos] != null) return false;
if(item is IInactiveItem itm) {
Accessories[pos] = itm;
AddedItem(itm);
return true;
} else return false;
}
private bool RemoveAccessory(IItem item, int pos) {
// Check range
if(0 > pos || pos >= Accessories.Count) return false;
// Check is empty.
if(Accessories[pos] != item) return false;
Accessories[pos] = null;
RemovedItem(item);
return true;
}
/*
Code that handles adding of items with effects to areas other than the backpack.
*/
private void AddedItem(IItem item) {
if(item is IPassiveItem passive) AddedItem(passive);
if(item is IConditionalItem conditional) AddedItem(conditional);
if(item is IActiveItem active) AddedItem(active);
}
private void RemovedItem(IItem item) {
if(item is IPassiveItem passive) RemovedItem(passive);
if(item is IConditionalItem conditional) RemovedItem(conditional);
if(item is IActiveItem active) RemovedItem(active);
}
private void AddedItem(IPassiveItem item) {
Modifier = Modifier.Add(item.Modifier);
Owner?.UpdateModifiers();
}
private void RemovedItem(IPassiveItem item) {
Modifier = Modifier.Remove(item.Modifier);
Owner?.UpdateModifiers();
}
private void AddedItem(IConditionalItem item) {
Owner?.AddItemListener(item);
}
private void RemovedItem(IConditionalItem item) {
Owner?.RemoveItemListener(item);
}
private void AddedItem(IActiveItem item) {
//Owner?.UpdateAbilities();
}
private void RemovedItem(IActiveItem item) {
//Owner?.UpdateAbilities();
}
} }
}
\ No newline at end of file
/*
ToDo:
- Change the caps so they scale up the list itself instead.
- Get => Lst.Count;
- Set => if(val > Lst.Count) add nulls; else try to remove nulls, throw if can't trim.
- Move method.
- Way to extract abilities from the tools.
- New pick up and drop methods. (Take into account that slots are managed wildly now)
*/
}
/*
##################################@@@@WWW@@#####@W@W@WWW@########################################################
################################WxMWWWMMMMMMMWWMWWW@@WW@@@W@@####################################################
##############################@MxMWWWMMMW@@@@WWWWMW@@@@@@@@@@WW@@################################################
##############################MMMWWWMWW@@@@@W@@WWWW@@@@#@###@@@@@@W@#############################################
############################@xxMMWMWW@@@@@@@@@#@@@W@@@#######@@@@#@@WW@##########################################
###########################WMMxWWMMWW@@@@@@@@@#@@@@@@#########@@@##@@@WWW@#######################################
#########################@MMMMMWMWWWW@@@@@#@@@@##@@@@############@@@@@@@##@@@####################################
#########################WMMWWWWWW@WW@@@@@##@@##@@@@@###########@@@@@######@@WW@#################################
########################WMWWWW@WW@@WW@@@@#######@@@@@@##@@@@@@@@@@@@######@##@@WM@###############################
####################WxMMMWWWW@@W@@@WWW@@@#@#####@@@@@#@@###@@@@@@@@@@#########@@@@@@@############################
##################@MWWWWWWWWW@@@@@@@@@@@#######@@@@@@######@@@WWW@@@################@@@##########################
#################@W@@@@W@WWW@@@@@@@@@##########@@@@#######@@@@@@@@@@@@@@##@@@#########@@#########################
################@@@@@@@WW@@@@@#@@@@##############@########@@@@@@@@@@###@#@@@@@#######@##@########################
###############@W@@WWW@@@@@@@@#@@@@#############@########@@@@@@@@@@##@@##@@@@@@@#####@@@@@@######################
##############@W@WWW@W@@@@@@@@#@@@######################@@#@@####@@@@#####@@@@#########@@#W######################
#############WW@@@W@@@@@@@@#@@@@@##########################@#@@@@@@#####################@#@@#####################
############WMWWWW@WWW@@@@@##@@@############################@@@###########################@W@####################
###########WMWWWW@@@@@@@######@######################@##@@@@@#########@####################@W####################
##########WMWWWWWWW@@@@@@########################@@#####@@@@##@@@@###@@#########@@@######@##@W###################
#########@xMWWWWW@W@@@@@@@############################@@@########@@@@@###@#########@@####@@@@WW##################
#########WMWWW@@@@@@@@@@@@@@##############@###@@@######@@@@@@@@#@@@@@@@@###@########@@@#@@@@@@WW#################
#########WWW@@@@@@@@@W@@@@@@@################@####@@@@@@@@@@@@@@@@####@@@####@@#########@@@@@@@WW################
########@WW@@@@@@@@@W@@@@@###############@####@@##@####@@#@@@@@@@@@#####@@####@@###########@@@@WWW###############
########@WW@@@@@@@@WWW@@@##############################@@@@@@@@#@###############@###########@@@@WM@##############
#######@WW@@@@@@@@@WWW@@@###############################@@@@@####################@##############@@W##############
#######MW@@@@@WW@@WWWW@@@@#########################@@@@@@@@@####@@@###############@###############@@#############
######@WW@@@@@@WW@@W@WW@@@@######################@@@@@@##################@###@#####@#############@@W#############
######@WWWWWW@@@WWWWWWWW@@@#####################@@@@@@########@@@@########@@#@####@##@#############@@############
######WWWWW@WW@@WMWWWWW@@@@####################@@@@#########################@##@@###################@@###########
######MWWWW@@@@@@WWWWW@@@@@##################@@############################@@#######################@@@##########
######W@WWWW@@@@WWWW@@@@@@@###############@@@@@#############################@@###@###################@@##########
######M@@@WWW@@WWWW@@@@W@@@##@####@####@@@@@@#######@#####@#@################@###@####################@@#########
######W@@@WW@@WWW@@@@@@W@@@##@@@@@@#@@@@@@@@########@@####@@@@@@@@############@@#######################W#########
#####WW@@@@@W@WW@@@@@@W@@@##@@@@@@@@@W@@@@@@@#######@#####@@@@@@@@@############@########################@########
#####@W@@@@@WWW@@@@@@@@WW@@@WW@@@@@@@@@@@@@@@@###@@@@@@@@@@@@@@@@@@@@@#@#####@@#@##@####################@########
#####@W@@@@@WWW@@@@@@@@@W@@WMWW@@@@W@@WWW@@@@@@@@@WWWW@@@@@@@@@@#@@@@@@@@#####@#@@@@####################@@#######
#####WW@@@@@WWW@@@##@@WWW@@MMWWW@WWWWW@W@WW@@@@@@WWWW@@@@@@@@@@@@####@###@#####@#@@######################@#######
#####W@W@@W@WWW@@@#@@WMMMWWMMMMMWWWWMMWWWWWWW@WW@WWW@@@@@@@@##########@##########@@@#####################@#######
#####W@W@@@WW@@@@@#@@MxxMWMWMMxMWMxMMMMMMWWWWWWWWWWW@WWW@@@@###########@###########@@#####################@######
#####WWW@@@W@@###@@@WMxnxWMWxxnxMMxMMMxxxMMMMWWW@W@@@@@@@@@@###@########@####@######@#####################@######
####@WWW@@@W@@#####@MnnznMMMxzzznxxxnnnnxxxxMWWWWWW@#@@@@@@@@####@######@###########@@####################@######
####WWW@W@@W@@#####WnznzznMxMnnzznzznnnxnnnnMWWW@W@@@@@@#@@@@@#@#@@@##@#@@############@###################@######
####WWW@@@@W@@@###@Mnznz#zMxxxz+###+#zzzzznnMWMMWWW@@@@@@@@@@@@@@@@@##@@@@@###########@@###################@#####
###@WWMW@@@W@@@@#@@Mzzz#+#nnnxnz########zzznxxxxMWW@@@@@@@@@@@@@@@@@@@#@@@@################################@#####
###W@@WWW@@W@@@@@@@xnzz###+nnnxnz#######zznznnxnxMW@@@@W@@W@@@@@@@@@@@@@@@@#################################@####
##W@@@@WWW@WW@@@@@Wxnz++##+#nzznzz#####znz#znnxxnxxW@@WWWWWW@@@@@@@@@@@@@#@@################################@####
##@@@@@WWWWWWW@@@WWMxz++++++nz##zzz#####zzzzzzznnnxMW@WWWWWWWW@@@@@@@@@@@###@###############################@@###
##W@@@@@WWW@MWWWWWWMMxz+**+##nz#+#z###+++++#####znnxMWWWWWWWWW@@WW@@@@@@@@###@@##############################W###
#@@@@@@@@@@WWWMWWMMMxxz#*i*+#zzz#+###+++++++++++#zznxMMMWWWWWW@@WW@W@@@@@@################################@##W###
#@#@@@@@@@@WWMMMWWWMxnn#+ii**##nz#####+++**++++++#zznxMMMWWWWMW@W@@W@@@@@@@@@################################W###
@@@@@@@#@@@@WWWWWWWMMMMz+**ii*++znnnzz##++++****++#znnxxWWWW@WW@W@WWWW@@@@@@@################################@###
@@@@@@@@@@@@WWWWWWMMMxxxnz+*iii*++#zznnzz#++****+++#zznnxWWW@@W@W@WWWWW@@@@@@@###############################@###
W@@@@@@@@@@@W@WWWWWMxxzz#+**iiiii**+#znnz#+*******++##z#zxWW@@W@@@WWWWWW@@@@@@###############################@@##
W@@@@@@@@@@WW@@@WWWxnnzn##+*ii;;ii*i*++##+***iii****+####zMW@@@@@@@WWWWW@@@@@@@@##############################W##
W@@#@@@@@@WWW@@@WWWxzz+##++*i;;;;;ii********i*iiii***+##+#nMW@@@@@@WWWWWW@W@@@@@@#############################W##
W@@@@@@@@@@W@@@@WWWxz#++****i;;;;;;iiiiiiiiiiiiiiii***+#++#nxW@@@@@WWWWWW@WW@@@@@#############################@##
M@@@@@@@@@WW@@@@WWMx##+*iiiii;;;;;;;iiiiiiiiiiiiiiiii**++###xMW@@@@@WWWWMWWW@@@@@#############################@@#
@@@@@@@@@@WW@@@@MWxn##*iiiii;;;;;;;iiiiiiiiiiiiiiiiiiii*+++#nMM@@@@@WWWWWWWWW@@@###############################@#
@@@@@@@@@WW@@@@WWWxn#*iiii;;;;;;;;;;;;;;iiiiiiiiiii;iiii*+++#nMW@@@@WWWWWWWWW@@@@@#############################@#
@@@@@@@@@@@@@@@WWMn#+iii;;;;;;;;;;;;;;;;;;i;;;;;;ii;;;iii*+++#nM@@@@@WWWWWWMW@@@@@@@#############################
#@@@@@@@@@@@@@WWWMz+*ii;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iii**++##xW@@@@@@WWWWMMW@@@@@@@############################
#W@@@@@@@@@@@@WMMx#+iii;;;;;;;;;;;:;;;;;;;;;;;;;;;;;;;iiii*++++zxW@@@@WWWWWWMMW@@@W@@@###########################
#W@@@@@@@@@@WWMMx#+*iii;;;;;;;;;;;:;;;;;;;;;;;;;;;;;;;;iii***+++#nxW@@WWWWWWWWWWWWWW@@@########################W#
#@@@@@@@@@@@WWMxz++iiii;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iiii***++##zzMMMWWMMWWWMMWWWWW@@@#######################@#
#@@@@@@@@@WWWMxz++*iii;;;;;;;;;;;;:::;::;;;;;;;;;;;;;;iiii***+**+#z#znxMWWWMWWMMWWWWWW@@@######################@#
##@@@@@@@@WWWMz#+*iiiii;;;;;;;;;::;:::::::;;;;;;;;;;;;;iiiii*****++##znnxMWWWWWMWWWWWWW@@@#@###################@#
#@@@@@@@@@@WWx#+*iiiiiii;;;:;:;;::;:::::;:;;;;;;;;;;;;;iiiii*iii***++##zznxMMWWWWMMMMWW@@##@###################W#
#@@@@@@@@@@W@x#+iiiiiii;;;;;;;;;;;:;:;;:;:;;;;;;;;;;;;iiiiiiiiii***++++##zznxxxxMMMMMWW@@@@####################@#
#W@@@@@@@@@W@x+*iiiiii;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;iiiiiiiiiiii****+++##zznxxnxxxMMMW@@@#####################@#
#@W@@@@@@@@W@n*iiiiiii;;;;;;;;;;;;;;;;;:;;;;;;;;:;;;;;iiiiiiiiiiii***++++##zznnnnnnxxMMW@@#######################
#@M@#@@#@@WWWn*iiiiii;;i;;;;;;;;;;;;;;;;;;;;;i;;;;;;;iiiiiiiiiiiii**+++++###znnnnnnnxxMW@@@######################
#@M@@@#@@@WWWz*iiiiiiiiiii;;ii;iiii;;;;;;;;;;i;;;;i;iiiii*iii***i**++#++#####znnnnznxxMM@@#######################
#MWW@@##@@WWWz*i*iii*******i*++++++**iiii;;;iii;;;iiii*****+++##++++#z#######znnnnnznxxMW@@###################@W#
#xW@@###@@@WW#*iiii**i***+*+#zzznnz##++***i;;i;;;;i*i*#####zzznnz##+#z#zzzzzzznnnnnnznxxW@@##################@@W#
#MW@@@###@@@W#i*iii*****++++#znnnnnz#####*i;;i;;;i*++##znnnnnxxnnnzzzz##zzzzzznnnnnnznxxM@@########@#####@@#@@@@#
#WWW@@##@@@@W+i*iii*****++###znnnxnnz#z##+*;;i;;;i+zz#zznxxxMMxxnnnzzz##zzzznnnnnnnnnnxxxW@#######@@@###@@@@@#@M#
@W@@@@####@@M*iiiii**iii*++znxMMMMxxxxz##+*;;;;;;*+znnnnnnxMMMxnzzz#######zzznnnznnnnnnxxMW@#####@@@#@@@@@@@@#@W@
@@@@W@@@#@@@x*iiiiiiiii*+##xMMxMxxxnznz#+**i;;;;i*#nnnnnnnxxxnznzzzzz###+##zzzzzznnnnnnxxxMW@###@@@###@@@@@###@@W
@W@@@@@@@@@@z*iiiiiiii+#+zzzn#*xMnn###+++*ii;;;;i*#nnnnnznnzznnxMxxMxnzzz###zzzzznznnnnnxxxMW@#########@@@@@@@@@W
#@@@@@@@@@@M+iiiiiiii*##n+;+nzz@x#z+#z*i*ii;:;;;i+#nnnnnz##zn#*nz*xMMMMnznz#z####znnnnnnnxxMW@#############@@@@@@
#W@@@@@@@@Wx*iiii;;i*+#+*i;inz#z##z++#+iiii;:;;;i+znnnnz+#zz+;;nzz@Mxnxxxznz#z###zzznnnnnnxxMW##############@@@@@
#W@@@@@@WWWn*i*i;;;ii***ii;;+z#z##+*+*+i;ii;:::;i+znnnn##z#+i::#z#zznnnzxxnz#z####zzznnnnxxxMM##############@@@@@
#WWW@@@WWWWz*iii;;;ii*iii;;;;i*******i;iii;;:::;i+znnnz*z+++*i;izzzzzz###nnz#######zzznnnxxxMW@##############@@@@
#WWWWWMMMWMz*ii;;;;;;;;;;;;;;;iiii***iiiii;;;::;i+znnnz+*iiii;ii*+###+++#nnz#########zznnnxxMW@################@#
#WWWWWnnMMxz*ii;;;;;;;;;;;;;;;;;i***ii**ii;;;;;;i+#nnzz#+***iiiii*****+##z##++++++###zzznnxxMW@###@#@@@@@@@@@@WW#
#@MWWM#nMMxn*ii;;;;;;;;;;;;;;;iii*iii*iiii;;;;;i*+#nnzz#+****ii;iiii**+###+****++++##zzznnxxMW@##@@@@@@WWWW@@WWM#
##WWWM*#nnxn*i;;;;;;;;;;;;;;;;;;;iiiiiiiii;;;;;i*+#zzzzz#*****iiii**+++##+*****++++##zznnnxxM@@#@@@@@WWWMMMWWWW@#
##@MWM+#nnnn*ii;;;:::;;;;;;;;::;;;;;;iiiii;;;;ii*+zzzzz##+*iiiiiii***++++*********++#zznnnxxMW@#@@WWMMMMWMxMWWW@#
###WWW#+znnn+i;;;;;:;;;;;::::::::;;;;;;iii;;;;ii*+zzzzz##+i*iiiiiiii**************++#zznnxxxMW@@@@WWMMMMMMnx@WW##
###WWWzi#znn+ii;;;;;;:;;::::::::::;;:;;;ii;;;;i**#zzzzz##+****iii;iiiii******i****++#zznnnxxMW@@@@WWWMMMMMnn@#@##
##@W@Wni##zn+ii;;;:;;::::::;;:::::::;;;ii;;;;;ii+#zzzzzz#+**iiii;;;;;ii*******i***++#znnnnxxMW@#@WWWWMMMMMnn@@@##
##@@@@M*++zx#iiii;;:::::;::::::;::::;;;;;;;;;;ii+#zzzzz##++*iiiii;;;iiiii********+++#znnnnxxMW@#@@WWMMMMMxxz@W###
###W@@W+*i*x#iii;;:::::;;;::::::::::;;;;;;;;;;;i*#zzzzz#z+**iiii;;;iiiiiiiii*****+++#znnnnxxMW@#@@WMMxxMMxxz@@###
###WWWW*i;inz*i;;;::::::::::::::::::;;;;;;;;;;i*+#zzzzzz#+*iii;i;;iiiiiiiiiiii***++##znnnnxxMW@@@@WxnnxxMxnzW####
####W@@+;:ixz*ii;;;:;:::::::::::::::;;;;;;;;;ii*+#zzzzz##+*iii;;ii;iiiiiiiii**i**++##znxnnxxMW@@@@WMnznnxxnzM####
#####M@+;:ixn*ii;;;:;:::::::::::::::;;;;;;;;;;i*+#zzzzz##+*iii;;;;;iiiiiiiiii****++##znxxxxxMW@@@@WxnnnnxMnzW####
#####@W+;:;#x+ii;;;:;:;::::::::::::;;;;;;;;;;;;*+##zzzzz#+*iii;;;;;iiiii**iii***+++#znnxxxxxMW@WWWWxnzznxMzz@####
#######+;::in+ii;;;:;;;:::::::::::;;;;;;;;;;;;i**+#zzzzz#+*i;;;:;;;;;iiii*ii****++##znnxxxxMW@@MxWWMnzzznxzx#####
#######+;::;*#ii;;;:::::::::::::::;;;;;;;;;;;;i**+#zznzz#+*i;;;:;;;;;iiiiii****+++#zznnxxxxMWW@MMWWMnzzznxzM#####
#######*;::ii*ii;;;;:::::::::::::::;;;;;;;;;;;ii*+#znnnz#+*i;;;:;;;;;;iiiiii****++#zznnxxxMWW@@MMMWMxz##zxzW#####
#######*;:;i*i*ii;;;:::::::::::::::;;;;;;;;;;;ii*+#znnnnz+*i;;;;::;;;;;iiiii***++##zznnxxxMW@@WxMMWMxnzznnzW#####
#######+;::i***ii;;;;:::::::::::::;;;;;;;;:;;;i**+#znzznz#*i;;;:::;;;;;iiii***+++##zznnxxxMW@WxMMMMMxnzznnz@#####
########;;:;ii*ii;;;;::::::::::::::;;;;;;:::;;**++#zz##znz*i;;;:::;;;;;iiii***++##zznnnxxxxMWxxMMMMMxnzznzn######
#######n;;:;;;*ii;;;;::::::::::::::;;;;;::,::;i*++##z#+#zn+ii;;::::;;;;iiii***+###zzznnxxxxMMxxMMMMMxz#znzx######
#######x;;::;:iii;;;;:::::::;;::::::;;;;:::::;i*+++###+##z#*i;;;;:;;;;;iiii**++###zzznxxxxxMxxMMMMMMxz#znz@######
#######Wi;;:::*iii;;;::::::::::;;:::;;;;;:::;i**++##+++##zz+i;;;;;;;;;;iiii**++#z#zznnxxxxMMxnMMMMMxnzznzn@######
#######@*;;;::*iii;;;:::::::::;;::::;i*i;;;:;i*+###++++##nn+ii;;;;;;;;iiiii*++#####znnnxxxxMxxxxxxxnznxzzx#######
########z;;:::iiii;;;;:::::::::::::::;**ii;;i*+##znxnz##znz+*i;;;;;;;;iiii**++####zznnnnxxMMxxnnnnxxnxnzzM#######
########M;:;::iiii;;;;;;:::::;:::::::;iiiiii*+#zzznnnzzznn#+*i;;;;;;;;iiii***+####znnnnxxxxMxxnznnnxxnzzn@#######
########@i;;;:iiii;;;;;;::::::;;::;::;;;;iii*+#zzzzzzznnz#++*i;;;;;;;iii****+#+###znnnxnxxxMxxxnzzznnzzzM########
#########+;;;:iiii;;;;;;;:::::;;:::;;;;i;;ii*++###zzzzzz#+****ii;;;;iiii***++#++##zznnxxxxxMxxxnnzznzzzn#########
#########Mi;::**ii;;;;;;;:;;:;;;;;;;;;;;;;;i***++#######+***i*ii;;;;iiii***++#++##zznnxxxxxMxnnnzzz#zzn@#########
##########n;;;i*iii;;;;;:;;;;;;;;;;;;;;;i;;;iiii*++####++**ii***ii;iiiii**++##++##zznnnnxxxMxnnzzzzzznW##########
############;iiiiiii;;;;;;::;;;;i;;;i;;;;;;;iii;i***+++++******+*iiiiiii**++##++##zznnnxxxxMxnzzzzzzzW###########
###########@+;iiiii;;;;;;;:;;i;;;;;iii;;;;;;iii;;ii**+++++******+*i;ii*i*++###++##zznnnnxxxMxnzz##zzM############
#############@ziiiiii;;;;;:;ii;;i;i;i;;;;;;;ii;;;ii**+##++++***+++*iii***++###+++#zznnnxxxMWMnz##zzx#############
##############xiiiiii;;;;;:;ii;;;;;;;;;;;;:;;;i;;;ii**+##++++*+++***ii****+###++##zznnnxxxx@@xzzzxWW#############
##############Wiiiiii;;;;;;;iii;i;;;;;;::::;;;;;;;iii**++##+++++***iiii***+#zz#+##zznnnxxxM@##@W@@@@#############
##############@*iiii;;;;;;;;;iiii;;;;::::::;;:::;;;ii**++####+++**iiiii***+#zz#+##zzznnnxxM#######W@#############
################i*iiii;;;;;;;ii*+*iiiiiiii*i;;;;;;;ii***+++####+*iii*ii*+++#zz++##zznnnnxxM######@@##############
###############xiiiiiii;;;;;;;;;i+#zz########++++#+++++++##znxn#*iiiii**++##z#++#zznzzznxx@#####W@###############
###############Wiiii;ii;;;;;;;;;;;*++*++###zzzzzzzzznnxxMxxxn#+*ii;iii*++##zz##+#zzzzznnxx@###@W@################
################+iii;iii;;;;;;;;;;;ii*i**i*******+*++##zzz#+++*ii;;iii*+###zz#+##zznzznnxM##@@W@#################
################xiii;;iii;;:;;;;;;;;;iiiii;;;;;;i***++##++++++*iiiiii**+#zzzz++#zzznzznnxMW@@@###################
################@*ii;;;ii;;;;;;;;;;;:;;;i;;;;;;;ii***+**+++#+**iiiiiii*+#znz#++#zzzzzznxxM#######################
#################niiii;ii;;;;;;;;;;;;:::;;;;;;;;;ii*****+##+******i*i*+#zzz##++#zzzzzznxx########################
#################@*iii;;ii;;;;i;;;;;;;;;:::;;;;;;;iii**+++++**********+#zzz#++##zzzzznxx@########################
##################xii;;;ii;;;;i;;;;;;;;;;;;;;;;iiii**+++++***+********##zz##++#zznzzznxM#########################
##################@*i;i;;iiii;;;;;;;;;;iiiiiii******+++*******+******+##zz##+##zzzzznxM##########################
###################xii;;iiiii;;;;;;;;;;;iii****+*************+++***++##zz#++++#zzznnnx@##########################
####################nii;iiiii;;;;;;;;;;;;;ii***ii**i**ii***+*+*+++*++#zz##+++#zzznnnx@###########################
####################@*i;;iiii;;;;ii;;;;;;iiiiiiii*iiiiii***++++++**+##zz#+++#zznnnnxW############################
#####################xii;;;iii;;;;ii;;;;;;iiiiiiiiiiiiiii**++++#+**+#####++##zznnxxM#############################
#######################ii;;;i;;;;;i;;;;;;;;i;;i;iiiiiiii***++++#+**+#z##+####znnxxM##############################
######################@*i;iii;;;;;i;;;;;;;;;;;;;;iiiiiiii****+++++++zz#+###zznnxxM###############################
#######################x*iiii;;;;;;;;;;;;;;;;;;;;iiii;i***i**++++++#zz###z#zznxMM@###############################
########################n*ii;;;;;;;;;;;;;;;;;;;;;iiiiii******+++++##zz###zznnxxM@################################
#########################ziiii;;;;;;;;;;;:;;;;;;;;;;iiii***+*+++++##zz#zznnnxxx@#################################
###########################ii;;;;;;;;;;::::;;:;;;;iiiii******++++##zzzzzznnxxM@##################################
##########################@+iii;::;:::::::::::;;;i;iiii***+*++++##zzzzzznnxxM@###################################
###########################@+ii;::;;;:::::::;:;;;;;;iiii****++++#zzzznnnnxxM#####################################
############################M*i;;::::::::::;;;;;;;;;ii******+++##zznnnnnxxM######################################
#############################M*i;:::::::::;;;;;;;;;;;i******++zzznnnnnnxxW#######################################
##############################Mii;;::::::;;;i;;;;;;;;iiii*+*+##znnnnnnxM@########################################
###############################Mi;;;::;;;;;;;i;;;;;;ii*ii**++#zznnnnnx@##########################################
################################Mi;;;;:;;;;;;;;;;;;;ii****++#zznnnnxW############################################
#################################zi;;;;;i;;;i;;;;;iiiii**+##zznnnM@##############################################
##################################x*i;iiiiiiiiiiiiii***+++#zznMW#################################################
###################################@z***i******i***++++###znW####################################################
#####################################@WMxxxxnz#++++zznxxMM@######################################################
It just works :)
*/
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment