Author Topic: Easiest way for Random armor/weapons?  (Read 490 times)

Legacy_Zeidae

  • Jr. Member
  • **
  • Posts: 72
  • Karma: +0/-0
Easiest way for Random armor/weapons?
« Reply #15 on: May 29, 2011, 09:12:32 pm »


               Thanks. But there is much more to what i want than that '<img'>
               
               

               
            

Legacy_Xardex

  • Sr. Member
  • ****
  • Posts: 414
  • Karma: +0/-0
Easiest way for Random armor/weapons?
« Reply #16 on: May 29, 2011, 10:25:26 pm »


               If I understood you correctly you want the item properties to scale with the NPCs level? If that is all, you can use this method for pretty much every single item property... I hope I am not missing something.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Easiest way for Random armor/weapons?
« Reply #17 on: May 30, 2011, 01:11:49 am »


               Xardex's answer is far and away the best solution for you, if you aren't really a scripter, as you say. We have a true random loot system on HG, and it took me, with help from acaos, a good three months to write it. It also requires oodles of functionality that native nwn doesn't have (you would want linux nwnx to be able to dynamically assemble item properties without having to use the clunky bioware functions, or it'd take far longer).

We actually do almost ALL of our monster/NPC attributes with variables read from onspawn. It would be relatively simple, by comparison, to make them add randomly instead of reading from variable. Here's a script called fky_ai_locals, that executs from our onspawn, with one line to #include "fky_ai_locals" and a second to     ApplyLocals();

Pardon the length of the script below, but if you think THIS is complicated, you REALLY do not want to try to do anything similar using item props. Again, this is not precisely what you want, it is an example of how to alter monster attributes from onspawn using effects. Instead of reading vars off the monsters, you would probably instead simply want to use dice functions or Random() to pick what wgets applied:

[code=auto:0]
const int DAMAGE_BEHAVIOR_HEAL          = 0x00000010;

int GetDamagePowerFromNumber (int nNum) {
    if (nNum < 6)
        return nNum;
    else
        return nNum + 1;
}

int GetHighestDigit (int nInt) {
    int i, nHighDigit = -1, nHighValue = 0;

    for (i = 0; nInt > 0; i++) {
        if (nInt % 10 > nHighValue) {
            nHighDigit = i;
            nHighValue = nInt % 10;
        }

        nInt /= 10;
    }

    return nHighDigit;
}

int GetOverHealType (int nImm) {
    int nDiv   = (nImm % 10);
    int nNeg   = (nImm /= 10) % 10;
    int nPos   = (nImm /= 10) % 10;
    int nMag   = (nImm /= 10) % 10;
    int nSonic = (nImm /= 10) % 10;
    int nFire  = (nImm /= 10) % 10;
    int nElec  = (nImm /= 10) % 10;
    int nCold  = (nImm /= 10) % 10;
    int nAcid  = (nImm /= 10) % 10;

    if (nAcid == 9 && nElec <= 7)
        return DAMAGE_TYPE_ACID;
    if (nCold == 9 && nFire <= 7)
        return DAMAGE_TYPE_COLD;
    if (nElec == 9 && nAcid <= 7)
        return DAMAGE_TYPE_ELECTRICAL;
    if (nFire == 9 && nCold <= 8)
        return DAMAGE_TYPE_FIRE;
    if (nAcid == 9 && nElec <= 8)
        return DAMAGE_TYPE_ACID;
    if (nCold == 9 && nFire <= 8)
        return DAMAGE_TYPE_COLD;
    if (nElec == 9 && nAcid <= 8)
        return DAMAGE_TYPE_ELECTRICAL;
    if (nNeg == 9 && nPos <= 7)
        return DAMAGE_TYPE_NEGATIVE;
    if (nPos == 9 && nNeg <= 7)
        return DAMAGE_TYPE_POSITIVE;
    if (nSonic == 9)
        return DAMAGE_TYPE_SONIC;
    return 0;
}

void ApplyImmunities (object oSelf, int nImm, int bVuln=FALSE, int nAdd=10) {
    effect eEff;

    int nDigit0 = (nImm % 10);
    int nDigit1 = (nImm /= 10) % 10;
    int nDigit2 = (nImm /= 10) % 10;
    int nDigit3 = (nImm /= 10) % 10;
    int nDigit4 = (nImm /= 10) % 10;
    int nDigit5 = (nImm /= 10) % 10;
    int nDigit6 = (nImm /= 10) % 10;
    int nDigit7 = (nImm /= 10) % 10;
    int nDigit8 = (nImm /= 10) % 10;

    if (bVuln) {
        if (nDigit8 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityDecrease(DAMAGE_TYPE_ACID, (nDigit8 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit7 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityDecrease(DAMAGE_TYPE_COLD, (nDigit7 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit6 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityDecrease(DAMAGE_TYPE_ELECTRICAL, (nDigit6 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit5 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityDecrease(DAMAGE_TYPE_FIRE, (nDigit5 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit4 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityDecrease(DAMAGE_TYPE_SONIC, (nDigit4 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit3 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityDecrease(DAMAGE_TYPE_MAGICAL, (nDigit3 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit2 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityDecrease(DAMAGE_TYPE_POSITIVE, (nDigit2 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit1 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityDecrease(DAMAGE_TYPE_NEGATIVE, (nDigit1 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit0 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityDecrease(DAMAGE_TYPE_DIVINE, (nDigit0 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }
    } else {
        if (nDigit8 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_ACID, (nDigit8 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit7 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, (nDigit7 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit6 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_ELECTRICAL, (nDigit6 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit5 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_FIRE, (nDigit5 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit4 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_SONIC, (nDigit4 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit3 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_MAGICAL, (nDigit3 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit2 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_POSITIVE, (nDigit2 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit1 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_NEGATIVE, (nDigit1 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit0 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_DIVINE, (nDigit0 * 10) + nAdd));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }
    }
}

void ApplyAutocast (object oSelf, string sAutocast) {
    int i, nSpell, nMeta, nLevel, nElem, nCasts = GetStringSubStrings(sAutocast);

    if (!GetIsObjectValid(oSelf))
        return;

    if (!GetIsObjectValid(GetArea(oSelf))) {
        DelayCommand(1.0, ApplyAutocast(oSelf, sAutocast));
        return;
    }

    for (i = 0; i < nCasts; i++) {
        string sCast = GetStringSubString(sAutocast, i);

        nElem  = GetStringSubStrings(sCast, ",");
        nMeta  = METAMAGIC_NONE;
        nLevel = 0;

        if (nElem > 2)
            nLevel = StringToInt(GetStringSubString(sCast, 2, ","));
        else
            nLevel = 0;

        if (nElem > 1)
            nMeta = StringToInt(GetStringSubString(sCast, 1, ","));
        else
            nMeta = METAMAGIC_NONE;

        if (nElem > 1)
            nSpell = StringToInt(GetStringSubString(sCast, 0, ","));
        else
            nSpell = StringToInt(sCast);

        AssignCommand(oSelf, ActionCastSpellAtObject(nSpell,
            oSelf, nMeta, TRUE, nLevel, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));
    }
}

void ApplyDynamicEquipmentProperties (object oOwner, int nSlot, string sProps, int nTries=3) {
    if (!GetIsObjectValid(oOwner))
        return;

    object oItem = GetItemInSlot(nSlot, oOwner);

    if (!GetIsObjectValid(oItem)) {
        if (nTries < 1)
            return;

        DelayCommand(1.0, ApplyDynamicEquipmentProperties(oOwner, nSlot, sProps, nTries - 1));
        return;
    }

    ApplyDynamicItemProperties(sProps, oItem);

    int i, nVars = GetLocalInt(oOwner, "ItemVariables_" + IntToString(nSlot));

    for (i = 1; i <= nVars; i++) {
        string sVar = GetLocalString(oOwner, "ItemVariable_" + IntToString(nSlot) + "_" + IntToString(i));

        RestoreLocals(oItem, sVar);
    }
}

void ApplyDynamics (object oSelf) {
    int i;

    if (!GetIsObjectValid(oSelf))
        return;


    /* Dynamic Item Properties */
    int nMask = GetLocalInt(oSelf, "ItemProperties_Mask");
    string sProps;
    for (i = 0; i < 18; i++) {
        if (nMask & (1 << i)) {
            sProps = GetLocalString(oSelf, "ItemProperties_" + IntToString(i));

            if (sProps != "")
                DelayCommand(2.0, ApplyDynamicEquipmentProperties(oSelf, i, sProps));
        }
    }


    /* Dynamic Effects */
    string sEffs = GetLocalString(oSelf, "Effects");

    if (sEffs != "")
        DelayCommand(1.0, ApplyDynamicEffects(sEffs, oSelf, -2, -1.0, SUBTYPE_SUPERNATURAL));


    /* Autocasting */
    string sAutocast = GetLocalString(oSelf, "Autocast");

    if (sAutocast != "")
        DelayCommand(1.0, ApplyAutocast(oSelf, sAutocast));


    /* Events */
    string sEvents = GetLocalString(oSelf, "Events");

    if (sEvents != "") {
        if (FindSubString(sEvents, "HEARTBEAT") >= 0)
            SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);

        /* sigh deeply at the stupid misspelling by the NWN creators */
        if (FindSubString(sEvents, "PERCEIVE") >= 0)
            SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT);

        if (FindSubString(sEvents, "ATTACKED") >= 0)
            SetSpawnInCondition(NW_FLAG_ATTACK_EVENT);

        if (FindSubString(sEvents, "SPELL") >= 0)
            SetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT);

        if (FindSubString(sEvents, "DAMAGED") >= 0)
            SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT);

        if (FindSubString(sEvents, "DISTURBED") >= 0)
            SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT);

        if (FindSubString(sEvents, "ROUND") >= 0)
            SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT);

        if (FindSubString(sEvents, "DIALOGUE") >= 0)
            SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT);

        if (FindSubString(sEvents, "DEATH") >= 0)
            SetSpawnInCondition(NW_FLAG_DEATH_EVENT);
    }
}

void ApplyCrafting (object oSelf) {
    int i, nMask = GetLocalInt(oSelf, "ItemCrafting_Mask");
    if (!nMask)
        return;

    string sCraft;
    for (i = 0; i <= 6; i++) {
        if (nMask & (1 << i)) {
            sCraft = GetLocalString(oSelf, "ItemCrafting_" + IntToString(i));

            if (sCraft != "") {
                object oItem = GetItemInSlot(i, oSelf);
                RestoreItemAppearance(oItem, sCraft);
            }
        }
    }
}

void ApplyLocals () {
    object oSelf = OBJECT_SELF;

    int nPlot = GetLocalInt(oSelf, "Plot");
    if (nPlot)
        SetPlotFlag(oSelf, TRUE);

    int nAILevel = GetLocalInt(oSelf, "AILevel");
    if (nAILevel)
        SetAILevel(oSelf, nAILevel);


    int nRandDrop = GetLocalInt(oSelf, "RandDrop");

    if (nRandDrop) {
        object oNPC = oSelf;
        object oItem = GetFirstItemInInventory(oNPC);

        while (GetIsObjectValid(oItem)) {
            if (GetDroppableFlag(oItem) == FALSE) {
                int nDroppable = d100() > 50;

                SetDroppableFlag(oItem, nDroppable);
            }

            oItem = GetNextItemInInventory(oNPC);
        }
    }


    int i, nDigit0, nDigit1, nDigit2, nDigit3, nDigit4, nDigit5, nDigit6, nDigit7, nDigit8, nDigit9;
    effect eEff;

    /* Cutscene Ghost */
    int nGhost = GetLocalInt(oSelf, "Ghost");
    if (nGhost) {
        eEff = SupernaturalEffect(EffectCutsceneGhost());

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    }


    /* Ability AB override */
    int nAbilityAB = GetLocalInt(oSelf, "AbilityAB");

    if (nAbilityAB)
        SetAbilityAB(oSelf, nAbilityAB);


    /* Add AB */
    int nAddAB = GetLocalInt(oSelf, "AddAB");

    if (nAddAB) {
        eEff = SupernaturalEffect(EffectAttackIncrease(nAddAB));

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    }


    /* Extra Attacks */
    int nAddAttacks = GetLocalInt(oSelf, "AddAttacks");

    if (nAddAttacks) {
        eEff = SupernaturalEffect(EffectModifyAttacks(nAddAttacks));

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    }


    /* Saves: 9NMDfrwFRW
     *   9: Unused
     *
     *   N: Negative            (2 points per)
     *   M: Mind Spells/Fear    (2 points per)
     *   D: Death Magic         (2 points per)
     *
     *   f: Fortitude Penalty   (2 points per)
     *   r: Reflex Penalty      (2 points per)
     *   w: Will Penalty        (2 points per)
     *
     *   F: Fortitude Bonus     (2 points per)
     *   R: Reflex Bonus        (2 points per)
     *   W: Will Bonus          (2 points per)
     */
    int nSaves = GetLocalInt(oSelf, "Saves");

    if (nSaves) {
        nDigit0 = (nSaves % 10);
        nDigit1 = (nSaves /= 10) % 10;
        nDigit2 = (nSaves /= 10) % 10;
        nDigit3 = (nSaves /= 10) % 10;
        nDigit4 = (nSaves /= 10) % 10;
        nDigit5 = (nSaves /= 10) % 10;
        nDigit6 = (nSaves /= 10) % 10;
        nDigit7 = (nSaves /= 10) % 10;
        nDigit8 = (nSaves /= 10) % 10;
        nDigit9 = (nSaves /= 10) % 10;

        if (nDigit8 > 0) {
            eEff = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_ALL, nDigit8 * 2, SAVING_THROW_TYPE_NEGATIVE));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit7 > 0) {
            eEff = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_ALL, nDigit7 * 2, SAVING_THROW_TYPE_MIND_SPELLS));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);

            eEff = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_ALL, nDigit7 * 2, SAVING_THROW_TYPE_FEAR));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit6 > 0) {
            eEff = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_ALL, nDigit6 * 2, SAVING_THROW_TYPE_DEATH));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit5 > 0) {
            eEff = SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_FORT, nDigit5 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit4 > 0) {
            eEff = SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_REFLEX, nDigit4 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit3 > 0) {
            eEff = SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_WILL, nDigit3 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit2 > 0) {
            eEff = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_FORT, nDigit2 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit1 > 0) {
            eEff = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_REFLEX, nDigit1 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit0 > 0) {
            eEff = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_WILL, nDigit0 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }
    }


    /* Conceal */
    int nConceal = GetLocalInt(oSelf, "Conceal");

    if (nConceal) {
        eEff = SupernaturalEffect(EffectConcealment(nConceal));

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    }


    /* PhysImmunities: H V 7 6 BI PI SI BR PR SR
     *
     *   H: 1 = Haste
     *
     *   V: 1 = True Seeing          4 = Darkvision             7 = TS/SI/Darkvision
     *      2 = See Invisible        5 = TS/Darkvision
     *      3 = TS/SI                6 = SI/Darkvision
     *
     *   7: UNUSED
     *   6: UNUSED
     *
     *   BI: 10 + (digit * 10)% bludgeoning
     *   PI: 10 + (digit * 10)% piercing
     *   SI: 10 + (digit * 10)% slashing
     *
     *   BR: (digit * 5)/- bludgeoning
     *   PR: (digit * 5)/- piercing
     *   SR: (digit * 5)/- slashing
     */
    int nRes = GetLocalInt(oSelf, "PhysImmunities");

    if (nRes) {
        nDigit0 = (nRes % 10);
        nDigit1 = (nRes /= 10) % 10;
        nDigit2 = (nRes /= 10) % 10;
        nDigit3 = (nRes /= 10) % 10;
        nDigit4 = (nRes /= 10) % 10;
        nDigit5 = (nRes /= 10) % 10;
        nDigit6 = (nRes /= 10) % 10;
        nDigit7 = (nRes /= 10) % 10;
        nDigit8 = (nRes /= 10) % 10;
        nDigit9 = (nRes /= 10) % 10;

        if (nDigit9 > 0) {
            eEff = SupernaturalEffect(EffectHaste());
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit8 > 0) {
            if (nDigit8 & 1) {
                eEff = SupernaturalEffect(EffectTrueSeeing());
                ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
            }

            if (nDigit8 & 2) {
                eEff = SupernaturalEffect(EffectSeeInvisible());
                ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
            }

            if (nDigit8 & 4) {
                eEff = SupernaturalEffect(EffectUltravision());
                ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
            }
        }

        if (nDigit5 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, (nDigit5 * 10) + 10));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit4 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_PIERCING, (nDigit4 * 10) + 10));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit3 > 0) {
            eEff = SupernaturalEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_SLASHING, (nDigit3 * 10) + 10));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit2 > 0) {
            eEff = SupernaturalEffect(EffectDamageResistance(DAMAGE_TYPE_BLUDGEONING, nDigit2 * 5));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit1 > 0) {
            eEff = SupernaturalEffect(EffectDamageResistance(DAMAGE_TYPE_PIERCING, nDigit1 * 5));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit0 > 0) {
            eEff = SupernaturalEffect(EffectDamageResistance(DAMAGE_TYPE_SLASHING, nDigit0 * 5));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }
    }


    /* Ability Boosting- str dex con int wis cha - increase by twice the input number - from 2-12 */
    int nAbility = GetLocalInt(oSelf, "Ability");

    if (nAbility) {
        nDigit0 = (nAbility % 10);
        nDigit1 = (nAbility /= 10) % 10;
        nDigit2 = (nAbility /= 10) % 10;
        nDigit3 = (nAbility /= 10) % 10;
        nDigit4 = (nAbility /= 10) % 10;
        nDigit5 = (nAbility /= 10) % 10;

        if (nDigit0) {
            eEff = SupernaturalEffect(EffectAbilityIncrease(ABILITY_CHARISMA, nDigit0 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit1) {
            eEff = SupernaturalEffect(EffectAbilityIncrease(ABILITY_WISDOM, nDigit1 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit2) {
            eEff = SupernaturalEffect(EffectAbilityIncrease(ABILITY_INTELLIGENCE, nDigit2 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit3) {
            eEff = SupernaturalEffect(EffectAbilityIncrease(ABILITY_CONSTITUTION, nDigit3 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit4) {
            eEff = SupernaturalEffect(EffectAbilityIncrease(ABILITY_DEXTERITY, nDigit4 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit5) {
            eEff = SupernaturalEffect(EffectAbilityIncrease(ABILITY_STRENGTH, nDigit5 * 2));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }
    }

    /* Skill increase - 5 + (5 * input number) */
    /* Taunt/Bluff/Persuade/Intimidate/Perform/Heal/AniEmp MS Hide Listen Spot Tumble Parry Conc Disc */
    int nSkill = GetLocalInt(oSelf, "Skill");

    if (nSkill) {
        nDigit0 = (nSkill % 10);
        nDigit1 = (nSkill /= 10) % 10;
        nDigit2 = (nSkill /= 10) % 10;
        nDigit3 = (nSkill /= 10) % 10;
        nDigit4 = (nSkill /= 10) % 10;
        nDigit5 = (nSkill /= 10) % 10;
        nDigit6 = (nSkill /= 10) % 10;
        nDigit7 = (nSkill /= 10) % 10;
        nDigit8 = (nSkill /= 10) % 10;

        if (nDigit0) {
            eEff = SupernaturalEffect(EffectSkillIncrease(SKILL_DISCIPLINE, 5 + (nDigit0 * 5)));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit1) {
            eEff = SupernaturalEffect(EffectSkillIncrease(SKILL_CONCENTRATION, 5 + (nDigit1 * 5)));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit2) {
            eEff = SupernaturalEffect(EffectSkillIncrease(SKILL_PARRY, 5 + (nDigit2 * 5)));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit3) {
            eEff = SupernaturalEffect(EffectSkillIncrease(SKILL_TUMBLE, 5 + (nDigit3 * 5)));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit4) {
            eEff = SupernaturalEffect(EffectSkillIncrease(SKILL_SPOT, 5 + (nDigit4 * 5)));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit5) {
            eEff = SupernaturalEffect(EffectSkillIncrease(SKILL_LISTEN, 5 + (nDigit5 * 5)));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit6) {
            eEff = SupernaturalEffect(EffectSkillIncrease(SKILL_HIDE, 5 + (nDigit6 * 5)));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit7) {
            eEff = SupernaturalEffect(EffectSkillIncrease(SKILL_MOVE_SILENTLY, 5 + (nDigit7 * 5)));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }

        if (nDigit8) {
            eEff = EffectSkillIncrease(SKILL_PERFORM, 5 + (nDigit8 * 5));
            eEff = EffectLinkEffects(eEff, EffectSkillIncrease(SKILL_TAUNT, 5 + (nDigit8 * 5)));
            eEff = EffectLinkEffects(eEff, EffectSkillIncrease(SKILL_BLUFF, 5 + (nDigit8 * 5)));
            eEff = EffectLinkEffects(eEff, EffectSkillIncrease(SKILL_PERSUADE, 5 + (nDigit8 * 5)));
            eEff = EffectLinkEffects(eEff, EffectSkillIncrease(SKILL_INTIMIDATE, 5 + (nDigit8 * 5)));
            eEff = EffectLinkEffects(eEff, EffectSkillIncrease(SKILL_HEAL, 5 + (nDigit8 * 5)));
            eEff = EffectLinkEffects(eEff, EffectSkillIncrease(SKILL_ANIMAL_EMPATHY, 5 + (nDigit8 * 5)));
            eEff = SupernaturalEffect(eEff);

            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
        }
    }


    /* SR */
    int nSR = GetLocalInt(oSelf, "SR");

    if (nSR) {
        eEff = SupernaturalEffect(EffectSpellResistanceIncrease(nSR));

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    }


    /* Regen */
    int nRegen = GetLocalInt(oSelf, "Regen");

    if (nRegen) {
        eEff = SupernaturalEffect(EffectRegenerate(nRegen, 6.0));

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    }


    /* Soak - specified as Soak+Plus (defaults to 20+1; specify 0+0 for no soak) */
    string sSoak = GetLocalString(oSelf, "Soak");

    if (sSoak != "") {
        struct SubString ss, spss;

        ss.rest = sSoak;

        while (ss.rest != "") {
            ss = GetFirstSubString(ss.rest, " ");

            if (ss.first != "0+0" && ss.first != "0") {
                spss = GetFirstSubString(ss.first, "+");

                int nSoak = StringToInt(spss.first);
                int nPlus = GetDamagePowerFromNumber(StringToInt(spss.rest));

                eEff = SupernaturalEffect(EffectDamageReduction(nSoak, nPlus));

                ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
            }
        }
    } else {
        eEff = SupernaturalEffect(EffectDamageReduction(20, DAMAGE_POWER_PLUS_ONE));

        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    }


    /* Acid Cold Elec Fire Sonic Magic Positive Negative Divine */

    int nImm = GetLocalInt(oSelf, "OverImmunities");
    if (nImm) {
        int nHealDigit = -1, nOverHeal = GetLocalInt(oSelf, "OverHeal");

        /* if set, the highest immunity will actually heal damage of that type */
        if (nOverHeal) {
            int nHealMult = 0, nHealType = GetLocalInt(oSelf, "OverHealType");

            if (nHealType == 0)
                nHealType = GetOverHealType(GetLocalInt(oSelf, "EnergyImmunities"));

            if (nHealType) {
                switch (nHealType) {
                    case DAMAGE_TYPE_ACID:       nHealDigit = 8; break;
                    case DAMAGE_TYPE_COLD:       nHealDigit = 7; break;
               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Easiest way for Random armor/weapons?
« Reply #18 on: May 31, 2011, 10:56:42 am »


               I've Resurrected my own PW, which has a Pseudo-Random Loot Generator of its own.

Everytime a player logs in, it parses their inventory, gathering Item Properties and Item ResRefs.
(Harvest Phase)

It stores these to nwnx database - the Item Properties are stored as int values which relate to their specific properties.
-2013297536   = Vampiric Regeneration +9  etc


Anyhow...
Thats the Harvest Phase.

Next comes the spawn phase of Monsters.

When a Monster Spawns, it gets the Nearest Player Character - potentially the one who spawned him, and then ascertains the average ability scores of the team that player is a member of.

It then Works out its own Ability Scores in relation to the players Teams Scores, and calculates what the difference is, and tries to balance the difference out by adding Ability Score Bonuses to the Creature.

Ala - Dynamic Level Scaling Monsters - the Monsters however only scale a certain amount, and only after a Certain CR Level.


Anyhow...
Inside the Dynamic Spawn system, I have my Dynamic Loot generator function called.

If this is a Scaled Spawn - (level increases etc)
It rolls a dice to determine should we spawn an item....

If yes....
    Roll a Dice to determine its Tier.
     Tier 1 = Low Level (Blue Text)
           2 = Medium (Green)
           3 = High (Magenta)
           4 = Very High (Gold/Yellow)

The tiers determine the amount of Properties the item can have maximum - of each type.

eg - Tier 4 can have 3 Damage Bonus Properties Maximum, and upto 5 other properties....
      Tier 1 can have 1 Damage Bonus, and 2 Other Properties.

The Properties are selected at random from the Repository of Item Properties via a Select SQL Statement which is ordered via

order = Rand() limit 1   (select 1 random row)


This is looped over in nwn script, and each property is added to the item that was spawned.


It then renames the items in a similar way.

I have a large repository of Item Name Prefixes and Suffix's,

Drow   xxxxxx    of the Sunset
Demon's xxxxxx of the Night  

etc

The items are then re-named according to a randomly selected prefix and suffix..


The Uber Secret Tier 5 items ONLY spawn if item Prefixes and Suffixes of certain types come together with an appropriate Item Type.

eg

Bhaal's Ring of Immortality    might spawn as a normal Dynamic Loot item of tier 1 to 4
But
Bhaal's Long Sword of Immortality  would spawn as a Tier 5 item, and would have SPECIFIC item properties stored for that combo item in the database.   These tier 5 items are UBER Rare, and I've only seen one of them appear once - which is kinda good, means theres lots of variation, and possibility.



So.. anyway.
Hope this gives you some ideas.
               
               

               
            

Legacy_Zeidae

  • Jr. Member
  • **
  • Posts: 72
  • Karma: +0/-0
Easiest way for Random armor/weapons?
« Reply #19 on: June 02, 2011, 04:10:14 pm »


               Thanks for all the replies.
I've decided on just creating 5 item property groupings and will add the properties based on creature level. I'll control the difficulty of the monsters by the number of armors they have and how many properties they'll get. And then use effects to adjust for player level.