public CraftResult Craft(Craftable c, int amount)
    {
        CraftResult result = new CraftResult();

        result.atomsUsed = new List <AtomAmo>();

        var atoms = c.GetAtomsForProduction();

        for (int i = 0; i < atoms.Length; i++)  // Find Minumum
        {
            var atomAmo = atoms[i];

            AtomData data = Game.Instance.gameData.FindAtomData(atomAmo.atom.GetAtomicNumber());

            int needed = atomAmo.amo * amount;
            if (data.GetCurrAmo() < needed)
            {
                amount = data.GetCurrAmo() / atomAmo.amo;
            }
        }

        for (int i = 0; i < atoms.Length; i++)
        {
            var atomAmo = atoms[i];

            AtomData data = Game.Instance.gameData.FindAtomData(atomAmo.atom.GetAtomicNumber());

            int needed = atomAmo.amo * amount;
            data.Lose(needed);

            AtomAmo atomUsed = new AtomAmo();
            atomUsed.atom = atomAmo.atom;
            atomUsed.amo  = needed;
            result.atomsUsed.Add(atomUsed);
        }
        result.amountCreated = amount;

        int amoOfCraftables;

        if (!craftables.TryGetValue(c, out amoOfCraftables))
        {
            craftables[c] = amount;
        }
        else
        {
            craftables[c] = amoOfCraftables + amount;
        }

        if (OnCraftableProduced != null)
        {
            OnCraftableProduced(c, amount);
        }

        return(result);
    }
Exemple #2
0
    public void Absorb(Atom atom, int amo)
    {
        if (amo == 0)
        {
            return;
        }

        AtomData data = FindAtomData(atom.GetAtomicNumber());

        if (data == null)
        {
            return;
        }

        if (!data.IsDiscovered())
        {
            data.SetIsDiscovered(true);
            if (OnAtomDiscover != null)
            {
                OnAtomDiscover(atom, amo);
            }

            if (maxAtom == null || atom.GetAtomicNumber() > maxAtom.GetAtomicNumber())
            {
                maxAtom = atom;
            }
        }
        if (amo + data.GetCurrAmo() < data.GetCurrAmo())
        {
            amo = int.MaxValue - data.GetCurrAmo();
            if (amo == 0)
            {
                return;
            }
        }

        data.Gain(amo);
        if (OnAtomAdd != null)
        {
            OnAtomAdd(atom, amo);
        }
    }
    public AtomCollisionResult ProduceCombine(Atom a, Atom b, int aAmo, int bAmo)
    {
        AtomCollision info = EstimateCombine(a, b, aAmo, bAmo);

        AtomCollisionResult result = new AtomCollisionResult();

        result.atomsProduced = new List <AtomAmo>();
        result.atomsUsed     = new List <AtomAmo>();

        AtomData aData   = Game.Instance.gameData.FindAtomData(a.GetAtomicNumber());
        AtomData bData   = Game.Instance.gameData.FindAtomData(b.GetAtomicNumber());
        int      usedAmo = Mathf.Min(Mathf.Min(aAmo, aData.GetCurrAmo()), Mathf.Min(bAmo, bData.GetCurrAmo()));

        Atom target = info.targetAtom;
        int  maxAmo = info.amo;

        float successChance   = info.success;
        float stabilityChance = 1.0f;

        stabilityChance = info.stability;

        int produced   = (int)(maxAmo * successChance);
        int stabilized = (int)(produced * stabilityChance);

        AtomAmo atomAmo = new AtomAmo();

        atomAmo.amo  = stabilized;
        atomAmo.atom = target;
        result.atomsProduced.Add(atomAmo);

        Game.Instance.Absorb(target, stabilized);

        AtomAmo atomAUsed = new AtomAmo();

        atomAUsed.atom = a;
        atomAUsed.amo  = usedAmo;
        result.atomsUsed.Add(atomAUsed);

        AtomAmo atomBUsed = new AtomAmo();

        atomBUsed.atom = b;
        atomBUsed.amo  = usedAmo;
        result.atomsUsed.Add(atomBUsed);

        Game.Instance.Use(a, usedAmo);
        Game.Instance.Use(b, usedAmo);

        if (OnAtomCombine != null)
        {
            OnAtomCombine(target, stabilized);
        }

        return(result);
    }
    public bool CanCraft(Craftable c)
    {
        int amount = 1;

        var atoms = c.GetAtomsForProduction();

        for (int i = 0; i < atoms.Length; i++)   // Find Minumum
        {
            var atomAmo = atoms[i];

            AtomData data = Game.Instance.gameData.FindAtomData(atomAmo.atom.GetAtomicNumber());

            int needed = atomAmo.amo * amount;
            if (data.GetCurrAmo() < needed)
            {
                amount = data.GetCurrAmo() / atomAmo.amo;
            }
        }

        return(amount != 0);
    }
    public AtomCollisionResult ProduceSplit(Atom a, int aAmo)
    {
        AtomCollision info = EstimateSplit(a, aAmo);

        AtomData aData = Game.Instance.gameData.FindAtomData(a.GetAtomicNumber());

        aAmo = Mathf.Min(aAmo, aData.GetCurrAmo());

        AtomCollisionResult result = new AtomCollisionResult();

        result.atomsProduced = new List <AtomAmo>();
        result.atomsUsed     = new List <AtomAmo>();

        Atom target = info.targetAtom;

        // Split
        int produced = (int)(info.amo * info.success); // Random Loss

        // Stabilize
        int stabilized = (int)(produced * info.stability);

        // Result
        AtomAmo atomAmo = new AtomAmo();

        atomAmo.amo  = stabilized;
        atomAmo.atom = target;
        result.atomsProduced.Add(atomAmo);
        Game.Instance.Absorb(target, stabilized);

        // Used
        AtomAmo atomAUsed = new AtomAmo();

        atomAUsed.atom = a;
        atomAUsed.amo  = aAmo;
        result.atomsUsed.Add(atomAUsed);
        Game.Instance.Use(a, aAmo);


        if (OnAtomSplit != null)
        {
            OnAtomSplit(target, stabilized);
        }

        return(result);
    }
        public bool CanUpgrade()
        {
            if (IsMaxLevel())
            {
                return(false);
            }

            for (int i = 0; i < data.cost.Count; i++)   // Validation
            {
                AtomAmo atomCost = data.cost[i];
                if (atomCost.atom == null)
                {
                    continue;
                }

                AtomData atomData = Game.Instance.gameData.FindAtomData(atomCost.atom.GetAtomicNumber());
                if (atomData.GetCurrAmo() < atomCost.amo)
                {
                    return(false);
                }
            }
            return(true);
        }
    public AtomCollision EstimateCombine(Atom a, Atom b, int aAmo, int bAmo)
    {
        AtomCollision info = new AtomCollision();

        AtomInfo aInfo = Game.Instance.gameData.FindAtomInfo(a.GetAtomicNumber());
        AtomInfo bInfo = Game.Instance.gameData.FindAtomInfo(b.GetAtomicNumber());
        AtomData aData = Game.Instance.gameData.FindAtomData(a.GetAtomicNumber());
        AtomData bData = Game.Instance.gameData.FindAtomData(b.GetAtomicNumber());

        aAmo = Mathf.Min(aAmo, aData.GetCurrAmo());
        bAmo = Mathf.Min(bAmo, bData.GetCurrAmo());

        //aAmo = Mathf.Min(aAmo, int.MaxValue / aInfo.GetNeutrons());
        //bAmo = Mathf.Min(bAmo, int.MaxValue / bInfo.GetNeutrons());

        int  maxProtons     = aInfo.GetProtons() + bInfo.GetProtons();
        long totalANeutrons = aAmo * aInfo.GetNeutrons();
        long totalBNeutrons = bAmo * bInfo.GetNeutrons();

        if (Game.Instance.gameData.GetAtomAmount() >= maxProtons)
        {
            info.targetAtom = Game.Instance.gameData.FindAtom(maxProtons); // Should Correlate to Atomic number
        }
        else
        {
            info.targetAtom = null;
            return(info);
        }
        AtomInfo targetInfo = Game.Instance.gameData.FindAtomInfo(maxProtons);

        long minProtons  = Mathf.Min(aAmo, bAmo); // Min of Atoms
        long minNeutrons = (totalANeutrons + totalBNeutrons) / targetInfo.GetNeutrons();
        long amo         = minProtons > minNeutrons ? minNeutrons : minProtons;

        info.amo = amo > int.MaxValue ? int.MaxValue : (int)amo;

        // 119 / 10 -> 11.9% Speed
        // 1 - (11.9 / 12)  -> .008333 About 1 / 12
        //
        // At 10% speed of light, Titanium -> Berkelium produces an estimated 1 / 1 billion atoms of Element 119
        float estimatedSpeed = maxProtons / 10f;

        info.success = Mathf.Clamp01(1 - estimatedSpeed / accelerationUpgrade.GetValue());

        // Apparently the half life of atoms can be changed by Time Dialation, Gravity, and External Radiation
        // There is no known way to accurately predict the half-life of atoms. There are two many variables
        // How about this, we place radioactive atoms near a black hole. Depending on the strength and randomness, the atom's half-life may be extended and stored indefinetly.

        // Our goal is to get that between 525600 1 year and 525600000 1000 years
        //  However if we have a value of 0.00085
        // That requires a multiple of 618,352,941 Just for the min

        //100*sqrt(1-((x*x)/(100*100))); Percentage of Speed -> Time Ratio
        //1 / sqrt(1-((x*x)/(100*100))); Percentage of Speed -> Time Multiple
        if (targetInfo.GetHalfLife() == 0f)
        {
            info.stability = 1.0f;
        }
        else
        {
            //float halfLife = targetInfo.GetHalfLife() + timeUpgrade.GetValue();
            //float multiple = 1 / Mathf.Sqrt(1 - (stabilityUpgrade.GetValue() * stabilityUpgrade.GetValue()) / (100 * 100));
            //info.stability = AtomInfo.GetStability(halfLife * multiple * multiple);

            //\frac{\left(\left(t\cdot\left(a-v\right)+v\right)^{\sqrt{\frac{x}{30}}}\right)}{525600}
            float halflife = targetInfo.GetHalfLife() + timeUpgrade.GetValue();
            if (halflife < 0)
            {
                info.stability = 0f;
            }
            else
            {
                float yearPercentage = 5256000; // 10 years ish
                float t = .001f;

                float stableValue = stabilityUpgrade.GetValue();

                float lerp      = Mathf.Lerp(halflife, yearPercentage, t);
                float power     = Mathf.Sqrt(stableValue / 30);
                float stability = Mathf.Pow(lerp, power);
                info.stability = Mathf.Clamp01(stability / yearPercentage);
            }
        }

        return(info);
    }
    public void SetCraftable(Craftable c)
    {
        RemoveCraftable();

        ChoiceOption choiceOption;

        if (craftableChoices.TryGetValue(c, out choiceOption))
        {
            choiceOption.SetButtonEvent(() => {
                RemoveCraftable();
                AudioManager.Instance.PlaySound(choiceClickSound);
            });
            choiceOption.SetColors(ChoiceOption.defaultPressedColor, ChoiceOption.defaultHoverColor, ChoiceOption.defaultNormalColor);
            choiceOption.SetFocus(false);
        }

        currCraftable = c;

        int amo = Game.Instance.playerData.GetCraftableAmount(c);

        craftableImage.sprite = c.GetSprite();

        craftableNameText.text = c.GetName();
        craftableInfoText.text = "Price: $" + c.GetPrice() + "\nCurr Amo: " + amo;

        StringBuilder atomName = new StringBuilder();
        StringBuilder atomAmo  = new StringBuilder();
        StringBuilder atomHave = new StringBuilder();
        var           atoms    = c.GetAtomsForProduction();

        for (int i = 0; i < atoms.Length; i++)
        {
            Atom a = atoms[i].atom;

            AtomData data = Game.Instance.gameData.FindAtomData(a.GetAtomicNumber());
            if (data.GetCurrAmo() >= atoms[i].amo)
            {
                atomName.Append(a.GetName() + "\n");
                atomAmo.Append(atoms[i].amo + "\n");
                atomHave.Append(data.GetCurrAmo() + "\n");
            }
            else
            {
                atomName.Append("<color=#ff8080>" + a.GetName() + "\n</color>");
                atomAmo.Append("<color=#ff8080>" + atoms[i].amo + "\n</color>");
                atomHave.Append("<color=#ff8080>" + data.GetCurrAmo() + "\n</color>");
            }
        }

        atomsRequiredText.text  = atomName.ToString();
        atomAmountText.text     = atomAmo.ToString();
        currAtomAmountText.text = atomHave.ToString();

        var size = atomNeededRect.sizeDelta;

        size.y = atoms.Length * 36;
        atomNeededRect.sizeDelta = size;

        bool canCraft = Game.Instance.playerData.CanCraft(c);

        craftBtn.interactable     = canCraft;
        craftBtnx10.interactable  = canCraft;
        craftBtnx100.interactable = canCraft;

        bool canSell = Game.Instance.playerData.GetCraftableAmount(c) > 0;

        sellBtn.interactable     = canSell;
        sellBtnx10.interactable  = canSell;
        sellBtnx100.interactable = canSell;
    }