부품 설계도

[C#] 디아블로 스타일 인벤토리 전체 코드

밤말팅 2020. 12. 27. 03:42

 

[C#] 디아블로 스타일 인벤토리 만들기

안녕하십니까! 밤말팅입니다! 두 번째 포스팅으로 만나 뵙게 되었네요~ 오랜만에 들고 온 컨텐츠는 바로! [디아블로 스타일 인벤토리 만들기]입니다! 가방 크기는 전혀 신경 쓰지 않으셔도 되겠

game-part-factory.tistory.com

이 글은 위에서 설명하는 클래스의 전체 코드입니다!

 

내용이 궁금하시면 해당 포스팅을 참고해주시면 감사드리겠습니다~

 

using System;
using System.Collections.Generic;
public class ItemInfo
{
    public static int nextId = 0;

    public int itemID;
    public int sizeX;
    public int sizeY;
    public int stackMax;

    public ItemInfo(int wantSizeX, int wantSizeY, int wantStackMax)
    {
        itemID = nextId++;
        sizeX = wantSizeX;
        sizeY = wantSizeY;
        stackMax = wantStackMax;
    }

    public static ItemInfo sword = new ItemInfo(1, 4, 1);
    public static ItemInfo sheild = new ItemInfo(2, 4, 1);
    public static ItemInfo armor = new ItemInfo(4, 6, 1);
    public static ItemInfo shoes = new ItemInfo(3, 3, 1);
    public static ItemInfo pants = new ItemInfo(4, 5, 1);
    public static ItemInfo bread = new ItemInfo(3, 2, 16);
}
public class ItemContain
{
    private int locationX = 0;
    private int locationY = 0;
    private int stack = 0;
    private ItemInfo itemCurrent = null;

    public ItemContain(int wantLocationX, int wantLocationY, int wantStack, ItemInfo wantItem)
    {
        locationX = wantLocationX;
        locationY = wantLocationY;
        stack = wantStack;
        itemCurrent = wantItem;
    }

    public ItemContain(int wantStack, ItemInfo wantItem)
    {
        stack = wantStack;
        itemCurrent = wantItem;
    }

    public bool ItemCheck(ItemInfo wantItem)
    {
        if (itemCurrent.itemID == wantItem.itemID) 
        {
            return true;
        };
        return false;
    }

    public int ItemStack(int wantNumber)
    {
        stack += wantNumber;
        if(stack > itemCurrent.stackMax)
        {
            int retval = stack - itemCurrent.stackMax;
            stack = itemCurrent.stackMax;
            return retval;
        }
        else
        {
            return 0;
        };
    }

    public int ItemDestack(int wantNumber)
    {
        stack -= wantNumber;
        return stack;
    }

    public ItemContain ItemSplit(int wantStack)
    {
        if (stack > wantStack)
        {
            ItemDestack(wantStack);
            return new ItemContain(locationX, locationY, wantStack, itemCurrent);
        }
        else
        {
            return this;
        };
    }

    public bool ItemOverlap(int targetLocationX, int targetLocationY)
    {
        if(targetLocationX >= locationX && targetLocationX < locationX + itemCurrent.sizeX && targetLocationY >= locationY && targetLocationY < locationY + itemCurrent.sizeY)
        {
            return true;
        }
        else
        {
            return false;
        };
    }

    public bool ItemOverlap(int targetLocationX, int targetLocationY, int targetSizeX, int targetSizeY)
    {
        if(targetLocationX >= locationX + itemCurrent.sizeX || targetLocationX + targetSizeX <= locationX || targetLocationY >= locationY + itemCurrent.sizeY || targetLocationY + targetSizeY <= locationY)
        {
            return false;
        }
        else
        {
            return true;
        };
    }

    public int GetItemStack()
    {
        return stack;
    }

    public ItemInfo GetItemInfo()
    {
        return itemCurrent;
    }

    public int GetLocationX()
    {
        return locationX;
    }

    public int GetLocationY()
    {
        return locationY;
    }

    public int GetSizeX()
    {
        return itemCurrent.sizeX;
    }

    public int GetSizeY()
    {
        return itemCurrent.sizeY;
    }

    public void SetItemStack(int wantStack)
    {
        stack = wantStack;
    }

    public void SetLocation(int wantX, int wantY)
    {
        locationX = wantX;
        locationY = wantY;
    }
}
public class XFinder
{
    public int startX;
    public int lastX;

    public XFinder(int wantStartX, int wantLastX)
    {
        startX = wantStartX;
        lastX = wantLastX;
    }
}
public class InventoryBase
{
    public List<ItemContain> itemList = new List<ItemContain>();
    public int inventorySizeX;
    public int inventorySizeY;
    
    public bool ItemPlacementFinder(int wantSizeX, int wantSizeY, out int returnLocationX, out int returnLocationY)
    {
        if(itemList.Count <= 0)
        {
            returnLocationX = 0;
            returnLocationY = 0;
            return true;
        }
        else
        {
            int currentFindX;
            int ignoreIndex = 0;
            List<XFinder> finderList = new List<XFinder>();
            List<int> heightList = new List<int>();
            heightList.Add(0);

            for(int heightIndex = 0; heightIndex < heightList.Count; ++heightIndex)
            {
                if (heightList[heightIndex] + wantSizeY > inventorySizeY)
                {
                    returnLocationX = 0;
                    returnLocationY = 0;
                    return false;
                };

                currentFindX = 0;

                int targetLastY;

                for (int i = ignoreIndex; i < itemList.Count; ++i)
                {
                    if (itemList[i].GetLocationY() == heightList[heightIndex])
                    {
                        targetLastY = itemList[i].GetLocationY() + itemList[i].GetSizeY();

                        HeightSave(heightList, heightIndex, targetLastY);

                        if ((itemList[i].GetLocationX() - currentFindX) >= wantSizeX)
                        {
                            finderList.Add(new XFinder(currentFindX, itemList[i].GetLocationX()));
                        };
                        currentFindX = itemList[i].GetLocationX() + itemList[i].GetSizeX();
                        ignoreIndex = i;
                    }
                    else if (itemList[i].GetLocationY() > heightList[heightIndex])
                    {
                        HeightSave(heightList, heightIndex, itemList[i].GetLocationY());
                        break;
                    };
                };
                if ((inventorySizeX - currentFindX) >= wantSizeX)
                {
                    finderList.Add(new XFinder(currentFindX, inventorySizeX));
                };

                bool leftPass;
                bool rightPass;
                for (int i = 0; i < itemList.Count; ++i)
                {
                    if (itemList[i].GetLocationY() < heightList[heightIndex] + wantSizeY)
                    {
                        if (itemList[i].GetLocationY() + itemList[i].GetSizeY() > heightList[heightIndex])
                        {
                            for (int j = 0; j < finderList.Count; ++j)
                            {
                                if (itemList[i].GetLocationX() + itemList[i].GetSizeX() >= finderList[j].startX && itemList[i].GetLocationX() <= finderList[j].lastX)
                                {
                                    leftPass = (itemList[i].GetLocationX() - finderList[j].startX) >= wantSizeX;
                                    rightPass = (finderList[j].lastX - (itemList[i].GetLocationX() + itemList[i].GetSizeX())) >= wantSizeX;

                                    if (rightPass)
                                    {
                                        if (leftPass)
                                        {
                                            finderList.Insert(j + 1, new XFinder(itemList[i].GetLocationX() + itemList[i].GetSizeX(), finderList[j].lastX));
                                            finderList[j].lastX = itemList[i].GetLocationX();
                                        }
                                        else
                                        {
                                            finderList[j].startX = itemList[i].GetLocationX() + itemList[i].GetSizeX();
                                        };
                                    }
                                    else
                                    {
                                        if (leftPass)
                                        {
                                            finderList[j].lastX = itemList[i].GetLocationX();
                                        }
                                        else
                                        {
                                            finderList.RemoveAt(j);
                                        };
                                    };
                                };
                            };
                        };
                    }
                    else
                    {
                        break;
                    };
                };

                if (finderList.Count > 0)
                {
                    returnLocationX = finderList[0].startX;
                    returnLocationY = heightList[heightIndex];
                    return true;
                };
            };
        };
        returnLocationX = 0;
        returnLocationY = 0;
        return false;
    }
    
    public bool ItemPlacement(ItemContain wantItem, int wantX, int wantY)
    {
        int touchItemIndex;

        if (ItemCollision(wantX,wantY,wantItem.GetSizeX(),wantItem.GetSizeY(),out touchItemIndex) > 0)
        {
            ItemContain itemCheck = itemList[touchItemIndex];

            if (itemCheck != null && itemCheck.ItemCheck(wantItem.GetItemInfo()))
            {
                wantItem.SetItemStack(itemCheck.ItemStack(wantItem.GetItemStack()));
                
                if(wantItem.GetItemStack() <= 0)
                {
                    return true;
                }
                else
                {
                    return false;
                };
            }
            else
            {
                return false;
            };
        }
        else
        {
            if (wantY + wantItem.GetSizeY() > inventorySizeY || wantX + wantItem.GetSizeX() > inventorySizeX)
            {
                return false;
            }
            else
            {
                ItemInsertList(wantItem, wantX, wantY);
                wantItem.SetLocation(wantX, wantY);
                return true;
            };
        };
    }
    
    public int ItemStackCheck(ItemInfo wantItem)
    {
        int itemLeft = 0;

        for (int i = 0; i < itemList.Count; ++i)
        {
            if (itemList[i].ItemCheck(wantItem))
            {
                itemLeft += itemList[i].GetItemStack();
            };
        };

        return itemLeft;
    }
    
    public int ItemStack(ItemInfo wantItem, int wantStack)
    {
        int itemLeft = wantStack;
        for (int i = 0; i < itemList.Count; ++i)
        {
            if (itemList[i].ItemCheck(wantItem))
            {
                itemLeft = itemList[i].ItemStack(itemLeft);
                if (itemLeft <= 0)
                {
                    return 0;
                };
            };
        };

        return itemLeft;
    }
    
    public int ItemDestack(ItemInfo wantItem, int wantStack)
    {
        int itemLeft = wantStack;
        int itemNumberChecker;
        for(int i = itemList.Count -1; i >= 0; --i)
        {
            if (itemList[i].ItemCheck(wantItem))
            {
                itemNumberChecker = itemList[i].ItemDestack(itemLeft);
                if (itemNumberChecker <= 0)
                {
                    itemLeft = Math.Abs(itemNumberChecker);
                    ItemRemoveList(i);
                }
                else
                {
                    return 0;
                };

                if (itemLeft <= 0)
                {
                    return 0;
                };
            };
        };
        return itemLeft;
    }
    
    public bool ItemInsertList(ItemContain wantItem, int wantX, int wantY)
    {
        int targetIndex = 0;

        int targetLocationX;
        int targetLocationY;

        for(int i = 0; i < itemList.Count; ++i)
        {
            targetLocationY = itemList[i].GetLocationY();
            if(wantY == targetLocationY)
            {
                targetLocationX = itemList[i].GetLocationX();
                if(wantX < targetLocationX)
                {
                    targetIndex = i;
                    break;
                }
                else if(wantX > targetLocationX)
                {
                    targetIndex = i + 1;
                }
                else
                {
                    return false;
                };
            }
            else if (wantY < targetLocationY)
            {
                targetIndex = i;
                break;
            }
            else
            {
                targetIndex = i + 1;
            };
        };

        if(targetIndex >= itemList.Count)
        {
            itemList.Add(wantItem);
        }
        else
        {
            itemList.Insert(targetIndex, wantItem);
        };

        return true;
    }
    
    public ItemContain ItemRemoveList(int wantIndex)
    {
        ItemContain resultItem = itemList[wantIndex];

        itemList.RemoveAt(wantIndex);

        return resultItem;
    }

    
    public void ItemRemoveList(ItemInfo wantItem)
    {
        for (int i = 0; i < itemList.Count; ++i)
        {
            if (itemList[i].ItemCheck(wantItem))
            {
                ItemRemoveList(i);
            };
        };
    }
    
    public int ItemCollision(int wantX, int wantY, int wantSizeX, int wantSizeY, out int firstTouch)
    {
        if(wantY + wantSizeY > inventorySizeY)
        {
            firstTouch = -4;
            return -1024;
        };
        int itemTouch = 0;
        firstTouch = -4;

        for(int i = 0; i < itemList.Count; ++i)
        {
            if (itemList[i].ItemOverlap(wantX, wantY, wantSizeX, wantSizeY))
            {
                ++itemTouch;
                if(firstTouch == -4)
                {
                    firstTouch = i;
                };
            };
        };

        return itemTouch;
    }
    
    public ItemContain ItemFind(int wantX, int wantY)
    {
        for (int i = 0; i < itemList.Count; ++i)
        {
            if (itemList[i].ItemOverlap(wantX, wantY))
            {
                return itemList[i];
            };
        };

        return null;
    }
    
    public ItemContain ItemFind(int wantX, int wantY, out int returnIndex)
    {
        for (int i = 0; i < itemList.Count; ++i)
        {
            if (itemList[i].ItemOverlap(wantX, wantY))
            {
                returnIndex = i;
                return itemList[i];
            };
        };

        returnIndex = -4;
        return null;
    }

    public void HeightSave(List<int> heightList, int findStartIndex, int targetY)
    {
        for (int j = findStartIndex; j < heightList.Count; ++j)
        {
            if (targetY == heightList[j])
            {
                return;
            }
            else if (targetY < heightList[j])
            {
                heightList.Insert(j, targetY);
                return;
            };
        };

        heightList.Add(targetY);
    }
}
public class Inventory
{
    public InventoryBase currentBase = new InventoryBase();
    public ItemContain itemGrab;

    public int ItemGet(ItemInfo wantItem, int wantStack)
    {
        int itemLeft = wantStack;

        if (wantItem.stackMax > 1)
        {
            itemLeft = currentBase.ItemStack(wantItem, wantStack);
        };

        int targetLocationX;
        int targetLocationY;

        while(itemLeft > 0)
        {
            if (currentBase.ItemPlacementFinder(wantItem.sizeX, wantItem.sizeY, out targetLocationX, out targetLocationY))
            {
                currentBase.ItemPlacement(new ItemContain(Math.Min(itemLeft, wantItem.stackMax), wantItem), targetLocationX, targetLocationY);
                itemLeft -= wantItem.stackMax;
            }
            else if(itemGrab == null)
            {
                itemGrab = new ItemContain(0, wantItem);
                itemLeft = itemGrab.ItemStack(itemLeft);
            }
            else
            {
                return itemLeft;
            };
        };

        return 0;
    }

    public void ItemRemove(ItemInfo wantItem, int wantStack)
    {
        int stackLeft = wantStack;

        if (itemGrab.ItemCheck(wantItem))
        {
            itemGrab.ItemDestack(stackLeft);

            if(itemGrab.GetItemStack() < 0)
            {
                stackLeft = Math.Abs(itemGrab.GetItemStack());
                itemGrab = null;
            }
            else
            {
                return;
            };
        };

        currentBase.ItemDestack(wantItem, stackLeft);
    }

    public void ItemRemove(ItemInfo wantItem)
    {
        if (itemGrab.ItemCheck(wantItem))
        {
            itemGrab = null;
        };

        currentBase.ItemRemoveList(wantItem);
    }

    public int ItemStackCheck(ItemInfo wantItem)
    {
        int returnValue = currentBase.ItemStackCheck(wantItem);

        if (itemGrab.ItemCheck(wantItem))
        {
            returnValue += itemGrab.GetItemStack();
        };

        return returnValue;
    }

    public ItemContain ItemThrow()
    {
        ItemContain returnItem = itemGrab;
        itemGrab = null;
        return returnItem;
    }

    public void ItemUngrab()
    {
        if (itemGrab != null && currentBase.ItemPlacement(itemGrab, itemGrab.GetLocationX(), itemGrab.GetLocationY()))
        {
            itemGrab = null;
        };
    }

    public ItemContain ItemInfo(int wantX, int wantY)
    {
        return currentBase.ItemFind(wantX, wantY);
    }

    public void ItemClickLeft(int wantX, int wantY)
    {
        if (itemGrab != null)
        {
            if (currentBase.ItemPlacement(itemGrab, wantX, wantY))
            {
                itemGrab = null;
            }
            else
            {
                int touchItemIndex;
                if (currentBase.ItemCollision(wantX, wantY, itemGrab.GetSizeX(), itemGrab.GetSizeY(), out touchItemIndex) <= 1)
                {
                    if (currentBase.itemList[touchItemIndex].ItemCheck(itemGrab.GetItemInfo()))
                    {
                        if(currentBase.itemList[touchItemIndex].GetItemStack() >= itemGrab.GetItemInfo().stackMax)
                        {
                            ItemContain targetItem = currentBase.ItemRemoveList(touchItemIndex);

                            if (currentBase.ItemPlacement(itemGrab, wantX, wantY))
                            {
                                itemGrab = targetItem;
                            }
                            else
                            {
                                currentBase.ItemInsertList(targetItem, targetItem.GetLocationX(), targetItem.GetLocationY());
                            };
                        }
                        else
                        {
                            itemGrab.SetItemStack(currentBase.itemList[touchItemIndex].ItemStack(itemGrab.GetItemStack()));
                        };
                    }
                    else
                    {
                        ItemContain targetItem = currentBase.ItemRemoveList(touchItemIndex);

                        if (currentBase.ItemPlacement(itemGrab, wantX, wantY))
                        {
                            itemGrab = targetItem;
                        }
                        else
                        {
                            currentBase.ItemInsertList(targetItem, targetItem.GetLocationX(), targetItem.GetLocationY());
                        };
                    };
                };
            };
        }
        else
        {
            int targetIndex;
            ItemContain targetContain = currentBase.ItemFind(wantX, wantY, out targetIndex);

            if (targetContain != null)
            {
                itemGrab = targetContain;
                currentBase.ItemRemoveList(targetIndex);
            };
        };
    }

    public void ItemClickRight(int wantX, int wantY)
    {
        if(itemGrab != null)
        {
            if (currentBase.ItemPlacement(itemGrab.ItemSplit(1), wantX, wantY)) 
            {
                if (itemGrab.GetItemStack() <= 0)
                {
                    itemGrab = null;
                };
            }
            else
            {
                itemGrab.ItemStack(1);
            };
        }
        else
        {
            int targetIndex;
            ItemContain targetContain = currentBase.ItemFind(wantX, wantY, out targetIndex);

            if (targetContain != null)
            {
                if(targetContain.GetItemStack() > 1)
                {
                    itemGrab = targetContain.ItemSplit((int)Math.Floor(targetContain.GetItemStack() / 2.0f));
                }
                else
                {
                    itemGrab = targetContain;
                    currentBase.ItemRemoveList(targetIndex);
                };
            };
        };
    }
}