• 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!

[10.98] CipSoft Original Map (converted from 7.7)

Well you guys don't need to argue about it. As far i have understood, the map editor he posted(without source) is an old implementation that complies to convert the map but ignores a lot of special keys in the map files. Its why i asked for source, i always wanted to convert the 7.7 map to otbm format but i lack the skills to write a proper parser.

Here is the flags/properties i have found in the .sec files:

Tile Flags:

Refresh
ProtectionZone

attributes:

String="Tao-Pai Pai\ncarlin"
Editor="Tao-Pai Pai"
KeyNumber=4600
KeyholeNumber=4600
ChestQuestNumber=158
DoorQuestNumber=47
DoorQuestValue=1
Level=60
PoolLiquidType=4
Amount=1
 
Another thing, in opentibia almost all of those attributes were replaced with Action Id.
 
thats what i meant, its all parsed wrong, or well some detailed things as i mentioned in the screenshot atleast : P
 
Feel free to do it yourself, this just saves people time if they want to copy stuff from it to their own map.
 
dude i'm just pointing out what was missing, as you stated before "If you find anything missing post and I will fix it right away."

but yeah im in the same boat as Yamaken, dont know how to parse.
 
A big keyword being missing, maybe I should've highlighted it. Let's take for example Venore is missing from the map, post about it and I will add it. What I won't fix is some flower being on top of another flower.
 
I was working in a tfs 1.3 fork to reproduce 7.7 game and first i have translate objects.srv into objects.xml(which replaces items.otb + items.xml) and i also have translate few objects.srv properties into tfs/opentibia properties. I was also using 7.7 tibia.dat/tibia.spr converted into 10.41 and few hacks in otclient to accept that dat/spr.

Here is few examples:

Code:
  <item id="356" article="a" name="dirt wall">
    <attribute key="flag" value="Bank"/>
    <attribute key="flag" value="Unpass"/>
    <attribute key="flag" value="Unmove"/>
    <attribute key="flag" value="Unthrow"/>
    <attribute key="flag" value="Unlay"/>
    <attribute key="Waypoints" value="0"/>
  </item>
  <item id="357" article="a" name="dirt wall">
    <attribute key="flag" value="Bank"/>
    <attribute key="flag" value="Unpass"/>
    <attribute key="flag" value="Unmove"/>
    <attribute key="flag" value="Unthrow"/>
    <attribute key="flag" value="Unlay"/>
    <attribute key="Waypoints" value="0"/>
  </item>
  <item id="358" article="a" name="dirt wall">
    <attribute key="flag" value="Bank"/>
    <attribute key="flag" value="Unpass"/>
    <attribute key="flag" value="Unmove"/>
    <attribute key="flag" value="Unthrow"/>
    <attribute key="flag" value="Unlay"/>
    <attribute key="Waypoints" value="0"/>
  <item id="3315" article="a" name="guardian halberd">
    <attribute key="flag" value="MultiUse"/>
    <attribute key="flag" value="Take"/>
    <attribute key="flag" value="Clothes"/>
    <attribute key="flag" value="Weapon"/>
    <attribute key="Weight" value="11000"/>
    <attribute key="BodyPosition" value="0"/>
    <attribute key="WeaponType" value="3"/>
    <attribute key="WeaponAttackValue" value="55"/>
    <attribute key="WeaponDefendValue" value="15"/>
  </item>
  <item id="4052" article="a" name="dead minotaur">
    <attribute key="flag" value="Container"/>
    <attribute key="flag" value="LiquidSource"/>
    <attribute key="flag" value="Take"/>
    <attribute key="flag" value="Corpse"/>
    <attribute key="flag" value="Decay"/>
    <attribute key="containerSize" value="10"/>
    <attribute key="fluidSource" value="blood"/>
    <attribute key="Weight" value="140000"/>
    <attribute key="decayTo" value="4053"/>
    <attribute key="duration" value="1800"/>
  </item>

C++:
        std::string tmpStrValue = asLowerCaseString(keyAttribute.as_string());

        //flags to signal a item is something
        if (tmpStrValue == "flag") {
            std::string flagName = asLowerCaseString(valueAttribute.as_string());

            if (flagName == "bank") {
                it.group = itemgroup_t::ITEM_GROUP_GROUND;
            } else if (flagName == "container") {
                it.type = ITEM_TYPE_CONTAINER;
                it.group = itemgroup_t::ITEM_GROUP_CONTAINER;
            } else if (flagName == "liquidcontainer") {
                it.group = itemgroup_t::ITEM_GROUP_FLUID;
            } else if (flagName == "liquidpool") {
                it.group = itemgroup_t::ITEM_GROUP_SPLASH;
            } else if (flagName == "clip") {
                it.alwaysOnTopOrder = 1;
                it.alwaysOnTop = true;
            } else if (flagName == "bottom") {
                it.alwaysOnTopOrder = 2;
                it.alwaysOnTop = true;
            } else if (flagName == "top") {
                it.alwaysOnTopOrder = 3;
                it.alwaysOnTop = true;
            } else if (flagName == "avoid") {
                it.blockPathFind = true;
            } else if (flagName == "unpass") {
                it.blockSolid = true;
            } else if (flagName == "unmove") {
                it.moveable = false;
            } else if (flagName == "unthrow") {
                it.blockProjectile = true;
            } else if (flagName == "take") {
                it.pickupable = true;
            } else if (flagName == "cumulative") {
                it.stackable = true;
            } else if (flagName == "text") {
                it.canReadText = true;
            } else if (flagName == "write") {
                it.canWriteText = it.canReadText = true;
            } else if (flagName == "corpse") {
                it.isCorpse = true;
            }
            else if (flagName == "height") {
                it.hasHeight = true;
            }
            else if (flagName == "rotate") {
                it.rotatable = true;
            }
            else if (flagName == "unlay") {
                it.unlay = true;
            }
            else if (flagName == "light") {
                it.isLightSource = true;
            }
            else if (flagName == "disguise") {
                it.isDisguise = true;
            }
            else if (flagName == "liquidsource") {
                it.isLiquidSource = true;
            }
            else if (flagName == "changeuse") {
                it.changeUse = true;
            }
            else if (flagName == "decay") {
                it.canDecay = true;
            }
            else if (flagName == "hang") {
                it.isHangable = true;
            }
            else if (flagName == "food") {
                it.isFood = true;
            }
            else if (flagName == "chest") {
                it.questChest = true;
            }
            else if (flagName == "destroy") {
                it.canDestroy = true;
            }
            else if (flagName == "movementevent") {
                it.movementEvent = true;
            }
            else if (flagName == "collisionevent") {
                it.collisionEvent = true;
            }
            else if (flagName == "separationevent") {
                it.separationEvent = true;
            }
            else if (flagName == "useevent") {
                it.useEvent = true;
            }
            else if (flagName == "multiuse") {
                it.useable = true;
            }
            else if (flagName == "rune") {
                it.type = ITEM_TYPE_RUNE;
            }
            else if (flagName == "special") {
                it.isSpecial = true;
            }
            else if (flagName == "equipment") {
                it.isEquipment = true;
            }
            else if (flagName == "weapon") {
                it.isWeapon = true;
            }
            else if (flagName == "armor") {
                it.isArmor = true;
            }
            else if (flagName == "magicfield") {
                it.type = ITEM_TYPE_MAGICFIELD;
            }
            else if (flagName == "shield") {
                it.isShield = true;
            }
            else if (flagName == "distuse") {
                it.distUse = true;
            }
            else if (flagName == "hooksouth") {
                it.isVertical = true;
            }
            else if (flagName == "hookeast") {
                it.isHorizontal = true;
            }
            else if (flagName == "forceuse") {
                it.forceUse = true;
            }
            else if (flagName == "ropespot") {
                it.ropeSpot = true;
            }
            else if (flagName == "bed") {
                it.type = ITEM_TYPE_BED;
            }
            else if (flagName == "information") {
                it.hasInformation = true;
            }
            else if (flagName == "keydoor") {
                it.isKeydoor = true;
            }
            else if (flagName == "questdoor") {
                it.isQuestDoor = true;
            }
            else if (flagName == "namedoor") {
                it.isNamedoor = true;
            }
            else if (flagName == "writeonce") {
                it.isWriteOnce = true;
            }
            else if (flagName == "leveldoor") {
                it.isLevelDoor = true;
            }
            else if (flagName == "key") {
                it.type = ITEM_TYPE_KEY;
            }
            else if (flagName == "protection") {
                it.isProtection = true;
            } else {
                std::cout << "[Warning - Items::parseItemNode] Unknown flag: " << valueAttribute.as_string() << std::endl;
            }

        //new properties
        } else if (tmpStrValue == "disguisetarget") {
            it.clientId = pugi::cast<uint16_t>(valueAttribute.value());
        } else if (tmpStrValue == "waypoints") {
            it.speed = pugi::cast<uint16_t>(valueAttribute.value());
        }
        else if (tmpStrValue == "elevation") {
            it.elevation = pugi::cast<uint16_t>(valueAttribute.value());
        }
        else if (tmpStrValue == "brightness") {
            it.lightLevel = pugi::cast<uint8_t>(valueAttribute.value());
        }
        else if (tmpStrValue == "lightcolor") {
            it.lightColor = pugi::cast<uint8_t>(valueAttribute.value());
        }
        else if (tmpStrValue == "changetarget") {
            it.changeTarget = pugi::cast<uint16_t>(valueAttribute.value());
        }
        else if (tmpStrValue == "nutrition") {
            it.nutrition = pugi::cast<uint16_t>(valueAttribute.value());
        }
        else if (tmpStrValue == "meaning") {
            it.meaning = pugi::cast<uint16_t>(valueAttribute.value());

        }
        //todo
        else if (tmpStrValue == "corpsecreaturetype") {
            //Player or Monster
        }
        //todo
        else if (tmpStrValue == "avoiddamagetypes") {
            it.blockPathFind = true;

            //it can be fire, poison or energy
            //more like to tell the a start path find system which type of field is this
            tmpStrValue = asLowerCaseString(valueAttribute.as_string());
        }
        //todo
        //no clue why its used in text items
        else if (tmpStrValue == "fontsize") {
        }
        else if (tmpStrValue == "informationtype") {
            it.informationType = pugi::cast<uint16_t>(valueAttribute.value());
            //2 = clock
            //3 = ceremonial mask, no clue yet
            //4 = spellbook
        }
        else if (tmpStrValue == "keydoortarget") {
            it.keydoorTarget = pugi::cast<uint16_t>(valueAttribute.value());
        }
        else if (tmpStrValue == "questdoortarget") {
            it.questdoorTarget = pugi::cast<uint16_t>(valueAttribute.value());
        }
        else if (tmpStrValue == "namedoortarget") {
            it.namedoorTarget = pugi::cast<uint16_t>(valueAttribute.value());
        }
        else if (tmpStrValue == "leveldoortarget") {
            it.leveldoorTarget = pugi::cast<uint16_t>(valueAttribute.value());
        //old properties

    //hack, 7.7 objects.srv lack the corpseType property
    if (it.isCorpse) {
        if (it.fluidSource == FLUID_BLOOD) {
            it.corpseType = RACE_BLOOD;
        } else if (it.fluidSource == FLUID_SLIME) {
            it.corpseType = RACE_VENOM;
        } else {
            it.corpseType = RACE_UNDEAD;
        }
    }

I have removed a lot standard tfs code so i can reduce the post text.
 
I also managed to make rme to load objects.xml and them i could map a proper map to atleast test things online:

e682a7e9f5bd46c9b38e00ba4a8d01db.png
 
How to add load this map? I got unable to load map after running forgotten. I'm new
 
I have stop this project as it was supposed to be a side project to reproduce 7.7 gameplay with a newer client(otclient). If there is enough interest i would like to work on it again, but its need a bigger team than me + 1.
its not that legacy datapack? would you mind to share it ? I want to check it if it's possible
because few things with the nekiro downgraded version are wrong @Yamaken
 
Last edited:
Back
Top