Example #1
0
 // initial setup / referential setup
 void InitiateVertices()
 {
     legacyVertices = new Dictionary <ProceduralObject, Dictionary <Vertex, KeyValuePair <Vector3, Vector3> > >();
     foreach (var obj in selection)
     {
         if (obj.isRootOfGroup && logic.selectedGroup == null)
         {
             foreach (var o in obj.group.objects)
             {
                 var dict = new Dictionary <Vertex, KeyValuePair <Vector3, Vector3> >();
                 foreach (Vertex v in o.vertices)
                 {
                     dict.Add(v, new KeyValuePair <Vector3, Vector3>(ProceduralUtils.VertexWorldPosition(v, o), Vector3.zero));
                 }
                 legacyVertices.Add(o, dict);
             }
         }
         else
         {
             var dict = new Dictionary <Vertex, KeyValuePair <Vector3, Vector3> >();
             foreach (Vertex v in obj.vertices)
             {
                 dict.Add(v, new KeyValuePair <Vector3, Vector3>(ProceduralUtils.VertexWorldPosition(v, obj), Vector3.zero));
             }
             legacyVertices.Add(obj, dict);
         }
     }
 }
Example #2
0
    static private CardDescription GenerateTrapCard(System.Random random, IHistogram model, ImageGlossary images, CreatureModelIndex creatureModels, NameModel nameModel, CardGenerationFlags flags)
    {
        CardDescription card = ScriptableObject.CreateInstance(typeof(CardDescription)) as CardDescription;

        card.cardType = CardType.TRAP;
        card.manaCost = (int)ProceduralUtils.GetRandomValue <ManaCost>(random, model);

        double powerBudget = PowerBudget.ManaPowerBudgets[card.manaCost];
        double powerMargin = PowerBudget.ManaPowerMargin[card.manaCost];
        double powerLimit  = PowerBudget.ManaPowerLimit[card.manaCost];

        card.cardName = "A trap card";
        //card.name += "(" + powerBudget.ToString() + ")";

        GenerateCardEffects(random, model, creatureModels, card, powerBudget, powerMargin, powerLimit);

        // Revise the mana cost based on what effects we actually did generate
        int revisedMana = PowerBudget.PowerLevelToMana(card.PowerLevel());

        if (revisedMana != card.manaCost)
        {
            Debug.Log("Had to revise the mana cost from " + card.manaCost.ToString() + " to " + revisedMana.ToString());
            card.manaCost = revisedMana;
        }
        card.image = ProceduralUtils.GetRandomTexture(random, images.GetTrapImages());

        CardTags tags = CardTagging.GetCardTags(card);

        card.cardName = nameModel.GenerateName(random, tags);

        return(card);
    }
Example #3
0
    public override ITargettingDescription Generate()
    {
        ExceptTargetDescription desc = new ExceptTargetDescription(targetType, alignment);

        TargettingType exceptTargetting = TargettingType.TARGET;

        switch (desc.GetPlayerAlignment())
        {
        case Alignment.POSITIVE:
            exceptTargetting = TargettingType.TARGET_ALLY;
            break;

        case Alignment.NEGATIVE:
            exceptTargetting = TargettingType.TARGET_ENEMY;
            break;
        }

        IProceduralTargettingGenerator targetGen = ProceduralUtils.GetProceduralGenerator(exceptTargetting);

        targetGen.SetupParameters(targetType, random, model, minAllocatedBudget, maxAllocatedBudget);
        desc.targetDescription = targetGen.Generate();
        if (desc.targetDescription is IQualifiableTargettingDescription qualifiableDesc)
        {
            qualifiableDesc.qualifier = desc.qualifier;
        }
        return(desc);
    }
    public override IEffectDescription Generate()
    {
        DrawEffectDescription desc = new DrawEffectDescription();

        desc.drawModifier = ProceduralUtils.GetRandomValue <DrawModifier>(random, model);

        // Find the bounds of card amounts
        int max = ProceduralUtils.GetUpperBound(desc, ref desc.amount, MIN_CARDS, MAX_CARDS, maxAllocatedBudget);
        int min = ProceduralUtils.GetLowerBound(desc, ref desc.amount, MIN_CARDS, max, minAllocatedBudget);

        Assert.IsTrue(max >= min);
        desc.amount = random.Next(min, max);

        // Attempt to narrow down the qualifier pool
        SortedSet <QualifierType> allowableQualifiers = CardEnums.GetValidFlags <QualifierType>(EffectType.DRAW_CARDS);

        QualifierType qualifier = ProceduralUtils.GetRandomValue(random, model, allowableQualifiers);

        if (qualifier != QualifierType.NONE)
        {
            IProceduralQualifierGenerator qualifierGen = ProceduralUtils.GetProceduralGenerator(qualifier);
            qualifierGen.SetupParameters(random, model, minAllocatedBudget / desc.PowerLevel(), maxAllocatedBudget / desc.PowerLevel());
            desc.cardQualifier = qualifierGen.Generate();
        }

        return(desc);
    }
Example #5
0
        public void Edit(ProceduralObject obj, Vector2 position)
        {
            editingObject       = obj;
            scrollParams        = Vector2.zero;
            scrollTex           = Vector2.zero;
            movingField         = -1;
            dragTexPos          = Vector2.zero;
            windowRect.position = position;
            Texture tex = ProceduralUtils.GetOriginalTexture(obj);

            originalTex = new Texture2D(tex.width, tex.height, TextureFormat.RGBA32, false);
            originalTex.SetPixels(((Texture2D)tex).GetPixels());
            windowTex = (Texture2D)GameObject.Instantiate(originalTex);
            // load stored data if it exists
            if (editingObject.m_textParameters == null)
            {
                parameters    = new TextParameters();
                parametersOld = new TextParameters();
            }
            else
            {
                parameters    = editingObject.m_textParameters;
                parametersOld = TextParameters.Clone(editingObject.m_textParameters, false);
                windowTex     = parameters.ApplyParameters(originalTex);
                editingObject.m_material.mainTexture = windowTex as Texture;
            }
            updateTimer = 0f;
            dragTimer   = 0f;
            zoomFactor  = 1f;
            if (!showWindow)
            {
                showWindow = true;
            }
        }
Example #6
0
    public override IQualifierDescription Generate()
    {
        CardTypeQualifierDescription desc = new CardTypeQualifierDescription();

        desc.cardType = ProceduralUtils.GetRandomValue <CardType>(random, model);

        return(desc);
    }
Example #7
0
    public override IModifierDescription Generate()
    {
        KeywordModifierDescription desc = new KeywordModifierDescription();

        desc.keyword = ProceduralUtils.GetRandomValueExcluding(random, model, new KeywordAttribute[] { KeywordAttribute.NONE });

        return(desc);
    }
Example #8
0
 protected override void UpdateTerrainData(float[,] data)
 {
     if (mat != null)
     {
         mat.mainTexture            = ProceduralUtils.GenerateTexture2D(data);
         mat.mainTexture.filterMode = FilterMode.Point;
         mat.mainTexture.wrapMode   = TextureWrapMode.Clamp;
     }
 }
Example #9
0
 private void MoveChildrenObj(float dt)
 {
     if (!groupFollows || !parentObject.isRootOfGroup)
     {
         return;
     }
     if (parentObject.group == null)
     {
         return;
     }
     if (dt == -1f) //initialize "points","vys" (children -> position,Y-speed)
     {
         points.Clear();
         vys.Clear();
         foreach (var child in parentObject.group.objects.Where(p => p != parentObject))
         {
             points.Add(child.m_position);
             vys.Add(initialSpeed.y);
         }
     }
     else if (dt == -2f) //reset "points" (children -> position)
     {
         int i = 0;
         foreach (var child in parentObject.group.objects.Where(p => p != parentObject))
         {
             child.m_position = new Vector3(points[i].x, points[i].y, points[i].z);
             i++;
         }
     }
     else if (dt == -3f) //reset "vys" (children -> Y-speed)
     {
         int i = 0;
         foreach (var child in parentObject.group.objects.Where(p => p != parentObject))
         {
             vys[i] = initialSpeed.y;
             i++;
         }
     }
     else //update "child.m_position","vys"
     {
         int i = 0;
         foreach (var child in parentObject.group.objects.Where(p => p != parentObject))
         {
             vys[i]           = vys[i] - gravity * dt;
             child.m_position = new Vector3(
                 child.m_position.x + dt * initialSpeed.x,
                 child.m_position.y + dt * vys[i],
                 child.m_position.z + dt * initialSpeed.z);
             if (child.m_position.y < ProceduralUtils.NearestGroundPointVertical(child.m_position).y)
             {
                 child.m_position.y = child.m_position.y - dt * vys[i];
                 vys[i]             = -vys[i] * bounceFactor;
             }
             i++;
         }
     }
 }
Example #10
0
 void RecenterAllOrigins()
 {
     foreach (var PODictPair in legacyVertices)
     {
         var po = PODictPair.Key;
         ProceduralUtils.RecenterObjOrigin(po, po.vertices);
         po.ApplyModelChange();
     }
 }
    public override IModifierDescription Generate()
    {
        ManaCostModifierDescription desc = new ManaCostModifierDescription(positive);

        int max = ProceduralUtils.GetUpperBound(desc, ref desc.manaCost, MIN_STATS, MAX_STATS, maxAllocatedBudget);
        int min = ProceduralUtils.GetLowerBound(desc, ref desc.manaCost, MIN_STATS, MAX_STATS, minAllocatedBudget);

        desc.manaCost = random.Next(min, max + 1);

        return(desc);
    }
 private string GetShowName()
 {
     if (pickerPrefabNames.Count == 1)
     {
         return(ProceduralUtils.GetDisplayableAssetname(pickerPrefabNames[0]));
     }
     else
     {
         return(string.Format(LocalizationManager.instance.current["filters_pickertypes"], pickerPrefabNames.Count.ToString()));
     }
 }
Example #13
0
    public override IEffectDescription Generate()
    {
        DamageEffectDescription desc = new DamageEffectDescription(heal);

        // Find the bounds of damage amounds
        int max = ProceduralUtils.GetUpperBound(desc, ref desc.amount, MIN_DAMAGE, MAX_DAMAGE, maxAllocatedBudget);
        int min = ProceduralUtils.GetLowerBound(desc, ref desc.amount, MIN_DAMAGE, max, minAllocatedBudget);

        Assert.IsTrue(max >= min);
        desc.amount = random.Next(min, max + 1);

        return(desc);
    }
Example #14
0
    public override ITargettingDescription Generate()
    {
        TargetXDescription desc = new TargetXDescription(targetType, alignment);

        // Find the bounds of card amounts
        int max = ProceduralUtils.GetUpperBound(desc, ref desc.amount, MinTargets(), MaxTargets(), maxAllocatedBudget);
        int min = ProceduralUtils.GetLowerBound(desc, ref desc.amount, MinTargets(), max, minAllocatedBudget);

        Assert.IsTrue(max >= min);
        desc.amount = random.Next(min, max);

        return(desc);
    }
Example #15
0
    public override IEffectDescription Generate()
    {
        SummonEffectDescription desc = new SummonEffectDescription();

        desc.tokenType = ProceduralUtils.GetRandomValue <CreatureType>(random, model);
        desc.manaCost  = creatureModelIndex.GetToken(desc.tokenType).manaCost;

        // Find the bounds of card amounts
        int max = ProceduralUtils.GetUpperBound(desc, ref desc.amount, MIN_SUMMONS, MAX_SUMMONS, maxAllocatedBudget);
        int min = ProceduralUtils.GetLowerBound(desc, ref desc.amount, MIN_SUMMONS, max, minAllocatedBudget);

        Assert.IsTrue(max >= min);
        desc.amount = random.Next(min, max);

        return(desc);
    }
 void CalculateProjection()
 {
     foreach (var obj in selection)
     {
         if (obj.isRootOfGroup && logic.selectedGroup == null)
         {
             // when root of group
             var bounds = obj.m_mesh.bounds;
             foreach (var po in obj.group.objects)
             {
                 // this should eventually take into account the global bounds of the group, not only itself,
                 // so as to project groups as structured units, not each individual PO
                 var vertexDict = legacyAndProjectedVertices[po];
                 foreach (Vertex v in po.vertices)
                 {
                     var old       = vertexDict[v].Key;
                     var projected = ProjectPoint(ProceduralUtils.VertexWorldPosition(old, po), projectionDirection);
                     projected = Quaternion.Inverse(po.m_rotation) * (projected - po.m_position);
                     if (offset != 0f)
                     {
                         projected -= (projected - old).normalized * offset;
                     }
                     vertexDict[v] = new KeyValuePair <Vector3, Vector3>(old, projected);
                 }
             }
         }
         else
         {
             // when inside group / not root of group
             var bounds     = obj.m_mesh.bounds;
             var vertexDict = legacyAndProjectedVertices[obj];
             foreach (Vertex v in obj.vertices)
             {
                 var old       = vertexDict[v].Key;
                 var projected = ProjectPoint(ProceduralUtils.VertexWorldPosition(old, obj), projectionDirection);
                 projected = Quaternion.Inverse(obj.m_rotation) * (projected - obj.m_position);
                 if (offset != 0f)
                 {
                     projected -= (projected - old).normalized * offset;
                 }
                 vertexDict[v] = new KeyValuePair <Vector3, Vector3>(old, projected);
             }
         }
     }
 }
        Vector3 ProjectPoint(Vector3 worldPoint, Vector3 worldDirection)
        {
            bool    hasTerrainHit = false;
            Vector3 terrainHit;

            worldPoint = worldPoint - (worldDirection * 3f);
            if (ProceduralUtils.TryRaycastTerrain(worldPoint, worldDirection, out terrainHit, collideNetworksBuildings))
            {
                hasTerrainHit = true;
            }

            RaycastHit physicsHit;

            if (Physics.Raycast(new Ray(worldPoint, worldDirection), out physicsHit, 2000))
            {
                if (physicsHit.collider.gameObject.name.StartsWith("PO_ColliderProject"))
                {
                    var point = physicsHit.point;
                    if (hasTerrainHit)
                    {
                        if ((point - worldPoint).sqrMagnitude < (terrainHit - worldPoint).sqrMagnitude)
                        {
                            return(point);
                        }
                        else
                        {
                            return(terrainHit);
                        }
                    }
                    else
                    {
                        return(point);
                    }
                }
            }

            if (hasTerrainHit)
            {
                return(terrainHit);
            }
            else
            {
                return(worldPoint);
            }
        }
    public override IModifierDescription Generate()
    {
        StatModifierDescription desc = new StatModifierDescription(positive);

        int singleMax = ProceduralUtils.GetUpperBound(desc, ref desc.atk, MIN_STATS, MAX_STATS, maxAllocatedBudget);
        int singleMin = ProceduralUtils.GetLowerBound(desc, ref desc.atk, MIN_STATS, MAX_STATS, minAllocatedBudget);

        int doubleMax = ProceduralUtils.GetUpperBound(desc, ref desc.atk, ref desc.def, MIN_STATS, MAX_STATS, maxAllocatedBudget);
        int doubleMin = ProceduralUtils.GetLowerBound(desc, ref desc.atk, ref desc.def, MIN_STATS, MAX_STATS, minAllocatedBudget);

        bool single = random.NextDouble() > 0.5;
        bool atk    = random.NextDouble() > 0.5;

        if (!single && singleMax == 1)
        {
            single = true;
        }
        else if (single && doubleMin * 2 > singleMax)
        {
            single = false;
        }

        if (single)
        {
            int value = random.Next(singleMin, singleMax + 1);

            if (atk)
            {
                desc.atk = value;
            }
            else
            {
                desc.def = value;
            }
        }
        else
        {
            int value = random.Next(doubleMin, doubleMax + 1);
            desc.atk = value;
            desc.def = value;
        }

        return(desc);
    }
Example #19
0
 public void Apply()
 {
     foreach (var obj in selection)
     {
         obj.customTexture = tex;
         var texture = (tex == null) ? ProceduralUtils.GetBasePrefabMainTex(obj) : tex;
         obj.m_material.mainTexture = texture;
         if (obj.m_textParameters != null)
         {
             if (obj.m_textParameters.Count() > 0)
             {
                 Texture original    = ProceduralUtils.GetOriginalTexture(obj);
                 var     originalTex = new Texture2D(original.width, original.height, TextureFormat.RGBA32, false);
                 originalTex.SetPixels(((Texture2D)original).GetPixels());
                 var newtex = (Texture2D)GameObject.Instantiate(originalTex);
                 obj.m_material.mainTexture = obj.m_textParameters.ApplyParameters(originalTex) as Texture;
             }
         }
     }
 }
Example #20
0
 public override void UpdateModule(ProceduralObjectsLogic logic, bool simulationPaused, bool layerVisible)
 {
     if (!state)
     {
         point0 = new Vector3(parentObject.m_position.x, parentObject.m_position.y, parentObject.m_position.z);
     }
     else if (!simulationPaused && layerVisible)
     {
         float dt = Time.deltaTime * timeSpeed;
         MoveChildrenObj(dt);
         vy = vy - gravity * dt;
         parentObject.m_position = new Vector3(
             parentObject.m_position.x + dt * initialSpeed.x,
             parentObject.m_position.y + dt * vy,
             parentObject.m_position.z + dt * initialSpeed.z);
         if (parentObject.m_position.y < ProceduralUtils.NearestGroundPointVertical(parentObject.m_position).y)
         {
             parentObject.m_position.y = parentObject.m_position.y - dt * vy;
             vy = -vy * bounceFactor;
             if (t > 0)
             {
                 t--;
             }
             else if (t == 0 || vy < 0.1f)
             {
                 if (!repeat)
                 {
                     state = !state;
                 }
                 else
                 {
                     t = bounceTimes;
                     parentObject.m_position = new Vector3(point0.x, point0.y, point0.z);
                     vy = initialSpeed.y;
                     MoveChildrenObj(-2f);
                     MoveChildrenObj(-3f);
                 }
             }
         }
     }
 }
    public void TestBoop(SocketIOEvent e)
    {
        string[] arr     = e.data["text"].ToString().Split(char.Parse(@"\"));
        string   message = String.Join(null, arr);

        message = message.Substring(1, message.Length - 2);
        // Debug.Log(message);
        wsData = message;
        List <List <Vector3> > verticesList = new List <List <Vector3> >();
        ProceduralUtils        procedural   = new ProceduralUtils();

        verticesList = procedural.GetCoordinates(wsData);

        for (int i = 0; i < verticesList.Count; i++)
        {
            procedural.CreateMesh(verticesList[i], i);
        }
        verticesList.Clear();
        if (e.data == null)
        {
            return;
        }
    }
 public override void OnOpen(List <ProceduralObject> selection)
 {
     this.selection = POGroup.AllObjectsInSelection(selection, logic.selectedGroup);
     foreach (var po in this.selection)
     {
         if (po.meshStatus == 1)
         {
             continue;
         }
         try
         {
             po.historyEditionBuffer.InitializeNewStep(EditingStep.StepType.vertices, po.vertices);
             ProceduralUtils.RecenterObjOrigin(po, po.vertices);
             po.ApplyModelChange();
             po.historyEditionBuffer.ConfirmNewStep(po.vertices);
         }
         catch (Exception e)
         {
             Debug.LogWarning("[ProceduralObjects] PO could not recenter object origin of object #" + po.id + " of type " + po.basePrefabName + "\n" + e);
             po.historyEditionBuffer.ConfirmNewStep(po.vertices);
         }
     }
     ExitAction();
 }
Example #23
0
    public override CardDescription GenerateCard(int seed, CardGenerationFlags flags = CardGenerationFlags.NONE)
    {
        // First select the card type
        System.Random random = new System.Random(seed);

        // Still generate a type even if a flag is provided, so that the generation with a seed matches
        // ie. we don't want to generate 2 different creatures from the same seed just because we specified a creature flag
        CardType t = ProceduralUtils.GetRandomValue <CardType>(random, model);

        if ((flags & CardGenerationFlags.CREATURE) == CardGenerationFlags.CREATURE)
        {
            t = CardType.CREATURE;
        }
        else if ((flags & CardGenerationFlags.SPELL) == CardGenerationFlags.SPELL)
        {
            t = CardType.SPELL;
        }
        else if ((flags & CardGenerationFlags.TRAP) == CardGenerationFlags.TRAP)
        {
            t = CardType.TRAP;
        }

        switch (t)
        {
        case CardType.CREATURE:
            return(GenerateCreatureCard(random, model, images, creatureModelIndex, nameModel, flags));

        case CardType.SPELL:
            return(GenerateSpellCard(random, model, images, creatureModelIndex, nameModel, flags));

        case CardType.TRAP:
            return(GenerateTrapCard(random, model, images, creatureModelIndex, nameModel, flags));
        }

        return(new CardDescription());
    }
 private float[,] GenerateTerrainData()
 {
     return(ProceduralUtils.GenerateTerrainData(size.x, size.y, scale / 1000f, baseAmplitude, octaves, lacunarity, persistence, offset));
 }
Example #25
0
 protected override void UpdateTerrainData(float[,] data)
 {
     data = ProceduralUtils.IslandFilter(data, innerRadius, outerRadius);
     base.UpdateTerrainData(data);
 }
Example #26
0
 protected void UpdateTerrainTexture(float[,] data)
 {
     t.terrainData.alphamapResolution = size.x;
     t.terrainData.SetAlphamaps(0, 0, ProceduralUtils.GenerateTextureData(data, layers.ToArray()));
 }
Example #27
0
    static private bool GenerateCardEffect(System.Random random, IHistogram model, CreatureModelIndex creatureModels, CardEffectDescription effectDesc, EffectType effect, double minBudget, double maxBudget, bool positive)
    {
        IProceduralEffectGenerator effectGen = ProceduralUtils.GetProceduralGenerator(effect);

        effectGen.SetupParameters(random, model, creatureModels, minBudget, maxBudget);
        effectDesc.effectType = effectGen.Generate();

        // Adjust budgets
        minBudget /= effectDesc.effectType.PowerLevel();
        maxBudget /= effectDesc.effectType.PowerLevel();
        if (minBudget > maxBudget)
        {
            double temp = minBudget;
            minBudget = maxBudget;
            maxBudget = temp;
        }
        // Always allow for default targetting (multiplier 1.0x)
        if (maxBudget < 1.0)
        {
            maxBudget = 1.0;
        }

        TargetType                 targetType          = TargetType.CREATURES;
        SortedSet <TargetType>     validTargets        = CardEnums.GetValidFlags <TargetType>(effect);
        SortedSet <TargettingType> allowableTargetting = new SortedSet <TargettingType>();
        SortedSet <QualifierType>  allowableQualifiers = new SortedSet <QualifierType>();

        while (validTargets.Count > 0 && allowableTargetting.Count == 0)
        {
            targetType = ProceduralUtils.GetRandomValue(random, model, validTargets);
            validTargets.Remove(targetType);

            switch (effectDesc.effectType.GetAlignment())
            {
            case Alignment.POSITIVE:
                if (positive)
                {
                    allowableTargetting = ProceduralUtils.GetTargettingByAlignment(Alignment.POSITIVE);

                    allowableQualifiers = ProceduralUtils.GetQualifiersByAlignment(Alignment.NEUTRAL);
                    allowableQualifiers.UnionWith(ProceduralUtils.GetQualifiersByAlignment(Alignment.POSITIVE));
                    allowableQualifiers.IntersectWith(CardEnums.GetValidFlags <QualifierType>(targetType));
                    if (allowableQualifiers.Count > 0)
                    {
                        allowableTargetting.UnionWith(ProceduralUtils.GetTargettingByAlignment(Alignment.NEUTRAL));
                    }
                }
                else
                {
                    allowableTargetting = ProceduralUtils.GetTargettingByAlignment(Alignment.NEGATIVE);

                    allowableQualifiers = ProceduralUtils.GetQualifiersByAlignment(Alignment.NEGATIVE);
                    allowableQualifiers.IntersectWith(CardEnums.GetValidFlags <QualifierType>(targetType));
                    if (allowableQualifiers.Count > 0)
                    {
                        allowableTargetting.UnionWith(ProceduralUtils.GetTargettingByAlignment(Alignment.NEUTRAL));
                    }
                }
                break;

            case Alignment.NEGATIVE:
                if (positive)
                {
                    allowableTargetting = ProceduralUtils.GetTargettingByAlignment(Alignment.NEGATIVE);

                    allowableQualifiers = ProceduralUtils.GetQualifiersByAlignment(Alignment.NEUTRAL);
                    allowableQualifiers.UnionWith(ProceduralUtils.GetQualifiersByAlignment(Alignment.NEGATIVE));
                    allowableQualifiers.IntersectWith(CardEnums.GetValidFlags <QualifierType>(targetType));
                    if (allowableQualifiers.Count > 0)
                    {
                        allowableTargetting.UnionWith(ProceduralUtils.GetTargettingByAlignment(Alignment.NEUTRAL));
                    }
                }
                else
                {
                    allowableTargetting = ProceduralUtils.GetTargettingByAlignment(Alignment.POSITIVE);
                    allowableQualifiers = ProceduralUtils.GetQualifiersByAlignment(Alignment.POSITIVE);
                    allowableQualifiers.IntersectWith(CardEnums.GetValidFlags <QualifierType>(targetType));
                    if (allowableQualifiers.Count > 0)
                    {
                        allowableTargetting.UnionWith(ProceduralUtils.GetTargettingByAlignment(Alignment.NEUTRAL));
                    }
                }
                break;

            default:
                if (positive)
                {
                    allowableTargetting = new SortedSet <TargettingType>((TargettingType[])Enum.GetValues(typeof(TargettingType)));
                    allowableQualifiers = new SortedSet <QualifierType>((QualifierType[])Enum.GetValues(typeof(QualifierType)));
                    allowableQualifiers.IntersectWith(CardEnums.GetValidFlags <QualifierType>(targetType));
                }
                else
                {
                    allowableTargetting = new SortedSet <TargettingType>();
                }
                break;
            }

            allowableTargetting.IntersectWith(CardEnums.GetValidFlags <TargettingType>(targetType));
            allowableTargetting.IntersectWith(CardEnums.GetValidFlags <TargettingType>(effectDesc.triggerCondition));

            // Special case
            // Up to can never be a downside because you can choose 0 targets
            if (!positive)
            {
                allowableTargetting.Remove(TargettingType.UP_TO_TARGET);
                allowableTargetting.Remove(TargettingType.UP_TO_TARGET_ALLY);
                allowableTargetting.Remove(TargettingType.UP_TO_TARGET_ENEMY);
            }
        }

        // Could not find any valid targetting to achieve the desired alignment
        if (allowableTargetting.Count == 0)
        {
            SortedSet <TargetType> targets = CardEnums.GetValidFlags <TargetType>(effect);

            Debug.Log("Wasn't able to generate targets for effect <" + effect.ToString() + ">");
            return(false);
        }


        // Attempt to narrow down the targetting pool
        SortedSet <TargettingType> targettingWithinBudget = new SortedSet <TargettingType>(allowableTargetting.Intersect(ProceduralUtils.GetTargettingWithinBudget(maxBudget)));

        if (targettingWithinBudget.Count > 0)
        {
            allowableTargetting = targettingWithinBudget;
        }
        else
        {
            Debug.Log("Unable to narrow down targetting types for <" + effect.ToString() + ", " + targetType.ToString() + "> for budget " + maxBudget);
        }

        TargettingType targettingType = ProceduralUtils.GetRandomValue(random, model, allowableTargetting);
        IProceduralTargettingGenerator targettingGen = ProceduralUtils.GetProceduralGenerator(targettingType);

        targettingGen.SetupParameters(targetType, random, model, minBudget, maxBudget);
        effectDesc.targettingType = targettingGen.Generate();

        // Adjust budgets
        minBudget /= effectDesc.targettingType.PowerLevel();
        maxBudget /= effectDesc.targettingType.PowerLevel();
        if (minBudget > maxBudget)
        {
            double temp = minBudget;
            minBudget = maxBudget;
            maxBudget = temp;
        }


        if (effectDesc.targettingType is IQualifiableTargettingDescription qualifiable)
        {
            // Generate a possible qualifier

            // Attempt to narrow down the qualifier pool
            SortedSet <QualifierType> qualifiersWithinBudget = new SortedSet <QualifierType>(allowableQualifiers.Intersect(ProceduralUtils.GetQualifiersWithinBudget(maxBudget)));
            if (targettingWithinBudget.Count > 0)
            {
                allowableQualifiers = qualifiersWithinBudget;
            }
            else
            {
                Debug.Log("Unable to narrow down qualifier types for <" + effect.ToString() + ", " + targetType.ToString() + "> for budget " + maxBudget);
            }

            QualifierType qualifier = ProceduralUtils.GetRandomValue(random, model, allowableQualifiers);
            if (qualifier != QualifierType.NONE)
            {
                IProceduralQualifierGenerator qualifierGen = ProceduralUtils.GetProceduralGenerator(qualifier);
                qualifierGen.SetupParameters(random, model, minBudget, maxBudget);
                qualifiable.qualifier = qualifierGen.Generate();
            }
        }

        return(true);
    }
Example #28
0
    static private CardDescription GenerateCreatureCard(System.Random random, IHistogram model, ImageGlossary images, CreatureModelIndex creatureModels, NameModel nameModel, CardGenerationFlags flags)
    {
        CreatureCardDescription card = ScriptableObject.CreateInstance(typeof(CreatureCardDescription)) as CreatureCardDescription;

        card.creatureType = ProceduralUtils.GetRandomValue <CreatureType>(random, model);

        if ((flags & CardGenerationFlags.HUMAN) == CardGenerationFlags.HUMAN)
        {
            card.creatureType = CreatureType.HUMAN;
        }
        else if ((flags & CardGenerationFlags.GOBLIN) == CardGenerationFlags.GOBLIN)
        {
            card.creatureType = CreatureType.GOBLIN;
        }
        else if ((flags & CardGenerationFlags.FAERIE) == CardGenerationFlags.FAERIE)
        {
            card.creatureType = CreatureType.FAERIE;
        }

        MultiCardHistogram combinedModel = ScriptableObject.CreateInstance(typeof(MultiCardHistogram)) as MultiCardHistogram;

        combinedModel.Init(new IHistogram[] { model, creatureModels.GetModel(card.creatureType) });

        card.manaCost = (int)ProceduralUtils.GetRandomValue <ManaCost>(random, model);

        // Potentially generate a stronger body, but with a drawback
        double bodyManaCost = GetCreatureBodyBudget(creatureModels.GetBodyLambda(card.creatureType), random.Next(), card.manaCost + 1);
        int    maxStats     = PowerBudget.StatBudget(bodyManaCost);

        // Decide on stats
        card.health = GetHealth(random, creatureModels.GetStatProbability(card.creatureType, (int)Math.Round(bodyManaCost, MidpointRounding.AwayFromZero)), maxStats);
        card.attack = maxStats - card.health;

        // Decide on power budget
        double powerBudget = PowerBudget.ManaPowerBudgets[card.manaCost];
        double powerMargin = PowerBudget.ManaPowerMargin[card.manaCost];
        double powerLimit  = PowerBudget.ManaPowerLimit[card.manaCost];

        card.cardName = "A creature card";
        //card.name += "(" + powerBudget.ToString() + ")";

        // Decide on keyword attributes
        int maxKeywords = 3;

        for (int i = 0; i < maxKeywords; i++)
        {
            double keywordPowerLimit = powerLimit - card.PowerLevel();
            if (keywordPowerLimit < 0)
            {
                keywordPowerLimit = 0;
            }
            KeywordAttribute keyword = ProceduralUtils.GetRandomValue(random, combinedModel, ProceduralUtils.GetKeywordsWithinBudget(keywordPowerLimit, card.attack, card.health));
            if (keyword == KeywordAttribute.NONE)
            {
                break;
            }
            card.AddAttribute(keyword);
        }

        // Decide on effects
        GenerateCardEffects(random, combinedModel, creatureModels, card, powerBudget, powerMargin, powerLimit);

        // Revise the mana cost based on what effects we actually did generate
        int revisedMana = PowerBudget.PowerLevelToMana(card.PowerLevel());

        if (revisedMana != card.manaCost)
        {
            Debug.Log("Had to revise the mana cost from " + card.manaCost.ToString() + " to " + revisedMana.ToString());
            card.manaCost = revisedMana;
        }
        card.image = ProceduralUtils.GetRandomTexture(random, images.GetCreatureImages(card.creatureType));

        CardTags tags = CardTagging.GetCardTags(card);

        card.cardName = nameModel.GenerateName(random, tags);

        return(card);
    }
Example #29
0
    static private void GenerateCardEffects(System.Random random, IHistogram model, CreatureModelIndex creatureModels, CardDescription cardDesc, double powerBudget, double powerMargin, double powerLimit)
    {
        // A trap card only has one trigger condition
        if (cardDesc.cardType == CardType.TRAP)
        {
            ProceduralUtils.GetRandomValue(random, model, CardEnums.GetValidFlags <TriggerCondition>(CardType.TRAP));
        }

        int effectCount = 0;

        List <TriggerCondition> triggerBlacklist = new List <TriggerCondition>();

        while ((cardDesc.PowerLevel() + PowerBudget.FLAT_EFFECT_COST) < powerBudget && effectCount < EffectConstants.MAX_CARD_EFFECTS)
        {
            // Generate effects
            CardEffectDescription cardEffect = new CardEffectDescription();

            // Create effects with a power level ranging between using max limit of budget, or uniformly distributing the min budget
            double maxAllowableBudget = powerLimit - cardDesc.PowerLevel() - PowerBudget.FLAT_EFFECT_COST;
            double minAllowableBudget = (powerBudget - cardDesc.PowerLevel() - PowerBudget.FLAT_EFFECT_COST) / (EffectConstants.MAX_CARD_EFFECTS - effectCount);

            if (cardDesc.cardType == CardType.SPELL || (cardDesc.cardType == CardType.TRAP && effectCount > 0))
            {
                // After the first condition of a trap or after casting a spell all further effects of
                // the card should just resolve so trigger cond is NONE
                cardEffect.triggerCondition = TriggerCondition.NONE;

                // If NONE has been blacklisted that means that there are no candidates for the remaining budget
                if (triggerBlacklist.Contains(TriggerCondition.NONE))
                {
                    //Debug.Log("No effects are valid for budget " + maxAllowableBudget);

                    break;
                }
            }
            else
            {
                if (ProceduralUtils.FlagsExist(triggerBlacklist, CardEnums.GetValidFlags <TriggerCondition>(cardDesc.cardType)))
                {
                    cardEffect.triggerCondition = ProceduralUtils.GetRandomValueExcluding(random, model, triggerBlacklist, CardEnums.GetValidFlags <TriggerCondition>(cardDesc.cardType));
                }
                else
                {
                    // No triggers available mean each trigger type has been blacklisted

                    //Debug.Log("No effects are valid for budget " + maxAllowableBudget);

                    break;
                }
            }

            double triggerBudgetModifier = PowerBudget.GetTriggerModifier(cardEffect.triggerCondition, cardDesc);
            maxAllowableBudget /= triggerBudgetModifier;
            minAllowableBudget /= triggerBudgetModifier;

            SortedSet <EffectType> candidatesWithinBudget = ProceduralUtils.GetEffectsWithinBudget(maxAllowableBudget);
            if (candidatesWithinBudget.Count == 0)
            {
                triggerBlacklist.Add(cardEffect.triggerCondition);

                Debug.Log("No effects are valid for budget " + maxAllowableBudget);
                continue;
            }

            bool validEffect = false;

            SortedSet <EffectType> effectCandidates = new SortedSet <EffectType>(CardEnums.GetValidFlags <EffectType>(cardEffect.triggerCondition).Intersect(candidatesWithinBudget));
            effectCandidates.Remove(EffectType.NONE);

            while (!validEffect && effectCandidates.Count > 0)
            {
                EffectType effectType = ProceduralUtils.GetRandomValueExcluding(random, model, new EffectType[] { EffectType.NONE }, effectCandidates);
                // This means that there isn't an effect that meets this condition
                if (effectType == EffectType.NONE)
                {
                    // Add to black list so we don't get multiple effects that trigger on same condition
                    if (cardEffect.triggerCondition != TriggerCondition.NONE)
                    {
                        triggerBlacklist.Add(cardEffect.triggerCondition);
                    }
                    break;
                }

                validEffect = GenerateCardEffect(random, model, creatureModels, cardEffect, effectType, minAllowableBudget, maxAllowableBudget, true);
            }

            // This means that there isn't an effect that meets this condition
            if (validEffect)
            {
                cardDesc.cardEffects.Add(cardEffect);
                effectCount++;
            }
            else
            {
                Debug.Log("No valid effect could be generated for trigger <" + cardEffect.triggerCondition.ToString() + "> with budget " + maxAllowableBudget);
            }

            // Add to black list so we don't get multiple effects that trigger on same condition
            if (cardEffect.triggerCondition != TriggerCondition.NONE)
            {
                triggerBlacklist.Add(cardEffect.triggerCondition);
            }
        }

        // Generate a draw back
        while (cardDesc.PowerLevel() > powerMargin)
        {
            // TODO: Drawback should be one of, additional cost, negative effect, or negative modification to existing effect
            // For now just add additional negative effect

            CardEffectDescription cardEffect = new CardEffectDescription();

            double maxAllowableBudget = (cardDesc.PowerLevel() - powerBudget - PowerBudget.FLAT_EFFECT_COST) / PowerBudget.DOWNSIDE_WEIGHT;
            double minAllowableBudget = (cardDesc.PowerLevel() - powerMargin - PowerBudget.FLAT_EFFECT_COST) / PowerBudget.DOWNSIDE_WEIGHT;

            if (cardDesc.cardType == CardType.SPELL || (cardDesc.cardType == CardType.TRAP && effectCount > 0))
            {
                // After the first condition of a trap or after casting a spell all further effects of
                // the card should just resolve so trigger cond is NONE
                cardEffect.triggerCondition = TriggerCondition.NONE;

                // If NONE has been blacklisted that means that there are no candidates for the remaining budget
                if (triggerBlacklist.Contains(TriggerCondition.NONE))
                {
                    Debug.Log("No effects are valid for budget " + maxAllowableBudget);

                    break;
                }
            }
            else
            {
                if (ProceduralUtils.FlagsExist(triggerBlacklist, CardEnums.GetValidFlags <TriggerCondition>(cardDesc.cardType)))
                {
                    cardEffect.triggerCondition = ProceduralUtils.GetRandomValueExcluding(random, model, triggerBlacklist, CardEnums.GetValidFlags <TriggerCondition>(cardDesc.cardType));
                }
                else
                {
                    // No triggers available mean each trigger type has been blacklisted

                    Debug.Log("No effects are valid for budget " + maxAllowableBudget);

                    break;
                }
            }

            double triggerBudgetModifier = PowerBudget.GetTriggerModifier(cardEffect.triggerCondition, cardDesc);
            maxAllowableBudget /= triggerBudgetModifier;
            minAllowableBudget /= triggerBudgetModifier;

            SortedSet <EffectType> candidatesWithinBudget = ProceduralUtils.GetEffectsWithinBudget(maxAllowableBudget);
            if (candidatesWithinBudget.Count == 0)
            {
                triggerBlacklist.Add(cardEffect.triggerCondition);

                Debug.Log("No effects are valid for budget " + maxAllowableBudget);
                continue;
            }

            bool validEffect = false;

            SortedSet <EffectType> effectCandidates = new SortedSet <EffectType>(CardEnums.GetValidFlags <EffectType>(cardEffect.triggerCondition).Intersect(candidatesWithinBudget));
            effectCandidates.Remove(EffectType.NONE);

            while (!validEffect && effectCandidates.Count > 0)
            {
                EffectType effectType = ProceduralUtils.GetRandomValueExcluding(random, model, new EffectType[] { EffectType.NONE }, effectCandidates);
                // This means that there isn't an effect that meets this condition
                if (effectType == EffectType.NONE)
                {
                    // Add to black list so we don't get multiple effects that trigger on same condition
                    if (cardEffect.triggerCondition != TriggerCondition.NONE)
                    {
                        triggerBlacklist.Add(cardEffect.triggerCondition);
                    }
                    break;
                }

                validEffect = GenerateCardEffect(random, model, creatureModels, cardEffect, effectType, minAllowableBudget, maxAllowableBudget, false);
            }

            // This means that there isn't an effect that meets this condition
            if (validEffect)
            {
                cardDesc.cardEffects.Add(cardEffect);
                break;
            }
            else
            {
                Debug.Log("No valid effect could be generated for trigger <" + cardEffect.triggerCondition.ToString() + "> with budget " + -maxAllowableBudget);
            }

            // Add to black list so we don't get multiple effects that trigger on same condition
            if (cardEffect.triggerCondition != TriggerCondition.NONE)
            {
                triggerBlacklist.Add(cardEffect.triggerCondition);
            }
        }
    }