• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[TFS1.2] Question Random Attributes on Items

LastCry

New Member
Joined
Aug 1, 2017
Messages
22
Reaction score
2
Hello together,

i found this code and it works fine:
Update for TFS 1.2

Note: Attack speed, extra attack are not as straightforward to implement so they aren't yet. Charges can be easily implemented but isn't yet!


STEP 1: When an item is created we assign it random variations, this is done in the item.cpp class.

In the item.cpp class, inside the constructor with signature Item::Item(const uint16_t _type, uint16_t _count /*= 0*/)

Below
Code:
if (it.isFluidContainer() || it.isSplash()) {
        setFluidType(_count);
    } else if (it.stackable) {
        if (_count != 0) {
            setItemCount(_count);
        } else if (it.charges != 0) {
            setItemCount(it.charges);
        }
    } else if (it.charges != 0) {
        if (_count != 0) {
            setCharges(_count);
        } else {
            setCharges(it.charges);
        }
    }

Add
Code:
//NEW - RANDOM
    if (it.armorRndMin > -1 && it.armorRndMax > it.armorRndMin)
        setIntAttr(ITEM_ATTRIBUTE_ARMOR, it.armorRndMin + rand() % (it.armorRndMax + 1 - it.armorRndMin));
    if (it.defenseRndMin > -1 && it.defenseRndMax > it.defenseRndMin)
        setIntAttr(ITEM_ATTRIBUTE_DEFENSE, it.defenseRndMin + rand() % (it.defenseRndMax + 1 - it.defenseRndMin));
    if (it.extraDefenseRndMin > -1 && it.extraDefenseRndMax > it.extraDefenseRndMin)
        if (it.extraDefenseChance == -1 || (it.extraDefenseChance >= rand() % 101))
           setIntAttr(ITEM_ATTRIBUTE_EXTRADEFENSE, it.extraDefenseRndMin + rand() % (it.extraDefenseRndMax + 1 - it.extraDefenseRndMin));
    if (it.attackRndMin > -1 && it.attackRndMax > it.attackRndMin)
        setIntAttr(ITEM_ATTRIBUTE_ATTACK, it.attackRndMin + rand() % (it.attackRndMax - it.attackRndMin));
    //NEW - RANDOM

STEP 2
Next we need variables to store these random variation values, this is done in the items.h file inside the ItemType class.

Inside items.h
Below
Code:
int32_t runeMagLevel;
int32_t runeLevel;

Add
Code:
//NEW - RANDOM
       int32_t armorRndMin, armorRndMax, defenseRndMin, defenseRndMax, extraDefenseRndMin, extraDefenseRndMax, attackRndMin, attackRndMax, extraAttackRndMin,
            extraAttackRndMax, chargesRndMin, chargesRndMax, attackSpeedRndMin, attackSpeedRndMax;
        int32_t extraAttackChance, extraDefenseChance, attackSpeedChance;
        //NEW - RANDOM


STEP 3: Now we need to assign these variables when we load item definitions from the items.xml file. The loading happens in the items.cpp class.

Inside items.cpp

below
Code:
} else if (tmpStrValue == "armor") {
            it.armor = pugi::cast<int32_t>(valueAttribute.value());
Add
Code:
pugi::xml_attribute tmp = attributeNode.attribute("random_min");
            if (tmp) {
                it.armorRndMin = pugi::cast<int32_t>(tmp.value());
                tmp = attributeNode.attribute("random_max");
                if (tmp)
                    it.armorRndMax = pugi::cast<int32_t>(tmp.value());
            }

Still in items.cpp Below
Code:
        } else if (tmpStrValue == "defense") {
            it.defense = pugi::cast<int32_t>(valueAttribute.value());

Add
Code:
pugi::xml_attribute tmp = attributeNode.attribute("random_min");
            if (tmp) {
                it.defenseRndMin = pugi::cast<int32_t>(tmp.value());
                tmp = attributeNode.attribute("random_max");
                if (tmp)
                    it.defenseRndMax = pugi::cast<int32_t>(tmp.value());
            }

Still in items.cpp Below
Code:
        } else if (tmpStrValue == "extradef") {
            it.extraDefense = pugi::cast<int32_t>(valueAttribute.value());


Add
Code:
pugi::xml_attribute tmp = attributeNode.attribute("chance");
            if (tmp) {
                it.extraDefenseChance = pugi::cast<int32_t>(tmp.value());
                tmp = attributeNode.attribute("random_min");
                if (tmp) {
                    it.extraDefenseRndMin = pugi::cast<int32_t>(tmp.value());
                    tmp = attributeNode.attribute("random_max");
                    if (tmp)
                        it.extraDefenseRndMax = pugi::cast<int32_t>(tmp.value());
                }
            }

Still in items.cpp Below
Code:
        } else if (tmpStrValue == "attack") {
            it.attack = pugi::cast<int32_t>(valueAttribute.value());


Add
Code:
                pugi::xml_attribute tmp = attributeNode.attribute("random_min");
                if (tmp) {
                    it.attackRndMin= pugi::cast<int32_t>(tmp.value());
                    tmp = attributeNode.attribute("random_max");
                    if (tmp)
                        it.attackRndMax= pugi::cast<int32_t>(tmp.value());
                }

We still define the variations in the items.xml file the same as before:
ex:
Code:
<item id="2463" article="a" name="plate armor">
        <attribute key="weight" value="12000" />
        <attribute key="armor" value="10" random_min="9" random_max="11" />
        <attribute key="slotType" value="body" />
</item>

random attributes test.png
Is it Possible to edit the text like in this Post from [tfs1.1]



I wanted it to be static values instead of % values:
Low items had no differences, and high level items were too overpowered with % based changes.

I also wanted the rarity names to show up in lootlists:

nwOc2jw.png

I might see what else I can do here...
Bold rare items maybe? different colour? hmm...


Used the source differences here: GitHub - otbr/forsaken: A free and open-source MMORPG server emulator written in C++
To remove loot being handled in TFS source.

creature.cpp
monsters.cpp/.h
monster.cpp/.h


use notepad++ and the compare plugin, only a few lines in each.

Re-added loot being handled in LUA using lib/core/monstertype.lua as a base.
Spliced in the randomstats.lua code to execute on loot generate but before the lootlist broadcast.

Done.

iSCVyA6.png


BnmyChq.png


ExTHOjU.png


Also tweaked the randomstats code due to grammar:

Code:
            -- Replace article if item rolls as epic
             if tiers[tier].prefix == "epic" then
               it_u:setAttribute(ITEM_ATTRIBUTE_ARTICLE, "an")
             end

3he4jch.png


Because of the effort and steps needed: merge code into one + source edits to remove loot, I haven't posted the code itself.

If anyone wants this code, tell me and I'll try and sit down and write it all out.


Best regards

LastCry
 

Attachments

  • random attributes test.png
    random attributes test.png
    1.8 MB · Views: 48 · VirusTotal
Back
Top