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

C++ Advanced shadow clone adjustment

Zombiegod

Active Member
Joined
Oct 22, 2009
Messages
198
Solutions
1
Reaction score
25
So i really like this script, and i have a few ideas on what to do with it, however it was made for 0.36 (or 0.4) but not 1.3

Could someone that knows hows please adjust it for me to 1.3


EDIT: Corrected my version number, did not realize i had 1.3
 
Last edited:
Alrighty, i did most of it myself

However, i keep getting a error with this bit of code


C++:
bool Monster::isTarget(const Creature* creature) const
{
    if (!isClone(creature) || creature->isRemoved() || !creature->isAttackable() ||
            creature->getZone() == ZONE_PROTECTION || !canSeeCreature(creature)) {
        return false;
    }

    if (creature->getPosition().z != getPosition().z) {
        return false;
    }
    return true;
}

The errors being

Untitldsfsded.png

EDIT: I would still like someone to do it if they can, as sense i do not know how to code, all i can do is try and make the errors disappear and hope that fixed it.
 
Last edited:
okay i did a temp fix for that error hopefully it works. However now i am stuck with some XML stuff


C++:
   if (!attackspells.empty()){
     xmlNodePtr root_attack = xmlDocGetRootElement(xmlParseMemory(attackspells.c_str(), attackspells.length()));
     xmlNodePtr tmpNode_attack = root_attack->children;
     while (tmpNode_attack)
     {
       if (!xmlStrcmp(tmpNode_attack->name, (const xmlChar*)"attack"))
       {
         spellBlock_t sb;
         if (g_monsters.deserializeSpell(tmpNode_attack, sb, "doCreateCustomMonster"))
           pobranyTyp->spellAttackList.push_back(sb);
       }
       tmpNode_attack = tmpNode_attack->next;
     }
   }
none of the XML code is defined, i looked it up and short of no one talking about it i found one post that was trying to convert it too pugiXML, someone replied with this code


C++:
  pugi::xml_document doc;
  pugi::xml_parse_result result = doc.load_buffer_inplace(spells.c_str(), spells.length());

  // if (!result) {
  //  std::cerr << "Something is wrong ;(" << std::endl;
  //  return false;
  // }

  pugi::xml_node root = doc.child("attacks");

  if (root) {
    for (pugi::xml_node tmpNode = root.first_child(); tmpNode; tmpNode = tmpNode.next_sibling())
    {
      spellBlock_t sb;
      if (g_monsters.deserializeSpell(tmpNode, sb, "doCreateCustomMonster")) {
        pobranyTyp->spellAttackList.push_back(sb);
      }
    }
  }

However the part of the code

Code:
spells.c_str()

Is not defined, and every alternative i use too try and define it comes up with errors.
 
TBH i gave up trying to work on this code, and its pisses me off everyone is either to lazy to help, does not know how to help, or wants me to pay them to help. Which is honestly why Open Tibia is dying. How many times i have posted something and not gotten a reply, and spent hours or days working on trying to solve it myself, or gotten a reply then gotten no reply back. If you comment on it but dont plan to help or finish helping say something, people suffer from anxiety and crap, all you are doing is making them think that you are ignoring them and that its their fault.
 
"Open community refers to the opportunity for anyone to join and contribute to the collaborative effort."

Which is not to say that just because you want something done, people should do it for you, just to benefit your needs.

Open communities is just as much about learning as it is helping eachother out.
Nobody is stopping you from using your own time to figure things like this out, heck most people wont even use this type of code.
Usually dedication pays off in life, regardless of what you're trying to accomplish, so I would suggest that instead of moping and waiting for people to solve your issues for you, read up on your source and figure out how everything works. You should be happy that TFS is free, thanks to this open community.

But hey be my guest and say that otland is the reason people suffer from anxiety.
 
Last edited:
It's a cool piece of code but its old code that needs to be compared properly against the existing codebase, it's a lot of work for a general support query.

You said you fixed some of it - post it.
Make it easier for people to help you.
 
"Open community refers to the opportunity for anyone to join and contribute to the collaborative effort."

Which is not to say that just because you want something done, people should do it for you, just to benefit your needs.

Open communities is just as much about learning as it is helping eachother out.
Nobody is stopping you from using your own time to figure things like this out, heck most people wont even use this type of code.
Usually dedication pays off in life, regardless of what you're trying to accomplish, so I would suggest that instead of moping and waiting for people to solve your issues for you, read up on your source and figure out how everything works. You should be happy that TFS is free, thanks to this open community.

But hey be my guest and say that otland is the reason people suffer from anxiety.
Firstly i never blamed otland for the reason people suffer from anxiety, i blamed PEOPLE on otland CAUSING anxiety in people who have anxiety.

Secondly i spent shit loads of time working on this, posting updates, and posting multiple support posts when i got stuck with NONE of them getting any replies, i spend 24 hours a day at home, i spent practically every moment of that working on this damn code.

Yes i am happy TFS is free, i am not happy in the way people treat people.

Don't attack me over getting upset that i feel ignored when i ask for help and NO ONE RESPONDS, but the moment i get angry look what happened i got a response of some who did 0 research on me, assuming i am complaining because "no one will do what i want". No i am complaining because the amount of assistance i got from otland is 0.


It's a cool piece of code but its old code that needs to be compared properly against the existing codebase, it's a lot of work for a general support query.

You said you fixed some of it - post it.
Make it easier for people to help you.

I posted what i changed that was not a obvious basic version 0.4 too 1.3 conversion such as updating code names. However i am willing to post all of it if needed, though ill have to redo the work as i removed the code and did not back it up.


EDIT:

So here is the code as far as i have gotten it, got stuck on "spellBlock_t" referencing a deleted function and no idea on how to fix it.

luascript.cpp

C++:
    //doCreateCustomMonster(....)
    lua_register(luaState, "doCreateCustomMonster", LuaScriptInterface::luaDoCreateCustomMonster);




int32_t LuaScriptInterface::luaDoCreateCustomMonster(lua_State* L)
{
    //doCreateCustomMonster(name, pos, outfit, health, attspell,defensespell,defense,armor,baseSpeed,exp,skull)
    // created By MeNi for otland.net //
    ScriptEnvironment* env = getScriptEnv();
    MonsterType* pobranyTyp = new MonsterType();
    Monster* monster;
    int64_t health, defense, armor, baseSpeed, experience;
    Outfit_t outfit;
    Skulls_t skull;
    Position pos;

    skull = (Skulls_t)getNumber<uint32_t>(L, -1);
    experience = getNumber<uint32_t>(L, -1);
    baseSpeed = getNumber<uint32_t>(L, -1);
    armor = getNumber<uint32_t>(L, -1);
    defense = getNumber<uint32_t>(L, -1);
    std::string defensespells = popString(L);
    std::string attackspells = popString(L);
    health = getNumber<uint32_t>(L, -1);
    outfit = getOutfit(L, -1);
    pushPosition(L, pos);
    std::string name = popString(L);

    pobranyTyp->info.attackSpells.clear();

    pobranyTyp->info.health = health;
    pobranyTyp->info.healthMax = health;
    pobranyTyp->info.outfit = outfit;
    pobranyTyp->name = name;
    pobranyTyp->nameDescription = name;
    pobranyTyp->info.lookcorpse = 0;
    pobranyTyp->info.targetDistance = 1;
    pobranyTyp->info.experience = experience;
    pobranyTyp->info.isSummonable = false;
    pobranyTyp->info.isIllusionable = false;
    pobranyTyp->info.isConvinceable = false;
    pobranyTyp->info.pushable = false;
    pobranyTyp->info.isAttackable = true;
    pobranyTyp->info.isHostile = true;
    pobranyTyp->info.isConvinceable = true;
    pobranyTyp->info.canPushItems = true;
    pobranyTyp->info.canPushCreatures = true;
    pobranyTyp->info.conditionImmunities |= CONDITION_PARALYZE;
    pobranyTyp->info.conditionImmunities |= CONDITION_DRUNK;
    pobranyTyp->info.conditionImmunities |= CONDITION_INVISIBLE;
    pobranyTyp->info.defense = defense;
    pobranyTyp->info.armor = armor;
    pobranyTyp->info.skull = skull;
    pobranyTyp->info.baseSpeed = baseSpeed;
    pobranyTyp->info.changeTargetSpeed = 0;
    pobranyTyp->info.changeTargetChance = 0;
    if (!attackspells.empty()) {
        pugi::xml_document doc;
        pugi::xml_parse_result result = doc.load_file("data\spells\spells.xml");

        // if (!result) {
        //  std::cerr << "Something is wrong ;(" << std::endl;
        //  return false;
        // }

        pugi::xml_node root1 = doc.child("attack");

        if (root1) {
            for (pugi::xml_node tmpNode = root1.first_child(); tmpNode; tmpNode = tmpNode.next_sibling())
            {
                spellBlock_t sb;
                if (g_monsters.deserializeSpell(tmpNode, sb, "doCreateCustomMonster")) {
                    pobranyTyp->info.attackSpells.push_back(sb);
                }
            }
        }

        // if (!result) {
        //  std::cerr << "Something is wrong ;(" << std::endl;
        //  return false;
        // }

        pugi::xml_node root2 = doc.child("healing");

        if (root2) {
            for (pugi::xml_node tmpNode = root2.first_child(); tmpNode; tmpNode = tmpNode.next_sibling())
            {
                spellBlock_t sb;
                if (g_monsters.deserializeSpell(tmpNode, sb, "doCreateCustomMonster")) {
                    pobranyTyp->info.defenseSpells.push_back(sb);
                }
            }
        }
        monster = Monster::createMonster(getString(L, 1));

        if (!g_game.placeCreature(monster, pos, false, false))
        {
            delete monster;
            lua_pushboolean(L, false);
            return 1;
        }

        lua_pushnumber(L, env->addThing((Thing*)monster));
        return 1;
    }
}

luascript.h

C++:
static int luaDoCreateCustomMonster(lua_State* L);

monster.h

C++:
bool isClone(Creature* creature) { return creature || getName() == creature->getName() || getMonster() || getSkull() == SKULL_BLACK; }

monster.cpp

C++:
bool Monster::isTarget(const Creature* creature) const
{
    if (creature->isRemoved() || !creature->isAttackable() || !creature->isClone() ||
            creature->getZone() == ZONE_PROTECTION || !canSeeCreature(creature)) {
        return false;
    }

    if (creature->getPosition().z != getPosition().z) {
        return false;
    }
    return true;
}

creature.cpp

C++:
bool Creature::setAttackedCreature(Creature* creature)
{
    if (creature) {
        const Position& creaturePos = creature->getPosition();
        if (creaturePos.z != getPosition().z || !canSee(creaturePos)) {
            attackedCreature = nullptr;
            return false;
        }

        if (creature || getName() == creature->getName() || getSkull() == SKULL_BLACK || getMonster())
            return false;

        attackedCreature = creature;
        onAttackedCreature(attackedCreature);
        attackedCreature->onAttacked();
    } else {
        attackedCreature = nullptr;
    }

    for (Creature* summon : summons) {
        summon->setAttackedCreature(creature);
    }
    return true;
}

monsters.h

C++:
class Monsters
{
    public:
        Monsters() = default;
        // non-copyable
        Monsters(const Monsters&) = delete;
        Monsters& operator=(const Monsters&) = delete;

        bool loadFromXml(bool reloading = false);
        bool isLoaded() const {
            return loaded;
        }
        bool reload();

        MonsterType* getMonsterType(const std::string& name);

        bool deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, const std::string& description = "");

        static uint32_t getLootRandom();

    private:
        ConditionDamage* getDamageCondition(ConditionType_t conditionType,
                                            int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval);
      

        bool loadMonster(const std::string& file, const std::string& monsterName, std::list<std::pair<MonsterType*, std::string>>& monsterScriptList, bool reloading = false);

        void loadLootContainer(const pugi::xml_node& node, LootBlock&);
        bool loadLootItem(const pugi::xml_node& node, LootBlock&);

        std::map<std::string, MonsterType> monsters;
        std::unique_ptr<LuaScriptInterface> scriptInterface;

        bool loaded = false;
};


all of that and i have 0 idea if it will actually work all i know is intellisense does not complain

EDIT2: So i gave up, i have no idea how to fix it, everything i tried just errors out, and short of trying to right my own code for it which would be shoddy at best as idk what exactly that part of the code does.
Post automatically merged:

seemed to have fixed the final issue

first change

C++:
spellBlock_t sb;

to


C++:
for (spellBlock_t sb : pobranyTyp->info.attackSpells)

and

for (spellBlock_t sb : pobranyTyp->info.defenseSpells)

Next goto monster.h and change


C++:
    spellBlock_t(const spellBlock_t& other) = delete;
    spellBlock_t& operator=(const spellBlock_t& other) = delete;

to


C++:
    spellBlock_t(const spellBlock_t& other) = default;
    spellBlock_t& operator=(const spellBlock_t& other) = default;

idk if that is a proper fix, but it compile and the server loaded.

now i am working on the lua script, but thats a headache do too on the missing and outdated functions
 
Last edited:
now i am working on the lua script, but thats a headache do too on the missing and outdated functions

Yeah I started the lua conversion, then took a break, and haven't got back to it xD
Alot of old functions to type over.
 
Yeah I started the lua conversion, then took a break, and haven't got back to it xD
Alot of old functions to type over.
right now i am having issues with the weapon part as (at least in my player functions) "getPlayerWeapon" does not seem to exist, and i have been trying to make it read each slot but.. just my head.
 
Something like this:

Getting the attack value for example:
Lua:
-- None of this is tested, use debug print line below to make sure it gets attack values properly
local checkWeaponSlots = {
    CONST_SLOT_LEFT,
    CONST_SLOT_RIGHT,
}

for i = 1,#checkWeaponSlots do -- Check what weapon is being used
    if player:getSlotItem(checkWeaponSlots[i]) ~= nil then
        local handItem = player:getSlotItem(checkWeaponSlots[i])
        local itemType = ItemType(handItem:getId())
        local weaponAttack = itemType:getAttack()
        print(weaponAttack) -- for debug
        if weaponAttack > 0 then
            return weaponAttack
        end
    end
end

Wands might need a bit of creativity.
 
Last edited:
get this

Code:
Lua Script Error: [Test Interface]
data/spells/scripts/ZCustom/shadows.lua
data/spells/scripts/ZCustom/shadows.lua:52: attempt to index global 'player' (a nil value)
stack traceback:
        [C]: in function '__index'
        data/spells/scripts/ZCustom/shadows.lua:52: in main chunk
[Warning - Event::checkScript] Can not load script: scripts/ZCustom/shadows.lua
Post automatically merged:

okay can confirm the source edit i shared will compile, however they mess everything up, i could not target anything
Post automatically merged:

Well unless someone takes what i have done and can fix it and make it workable, or completely redoes it i give up, thread closed until someone wants to take up the gauntlet.
 
Last edited:
Back
Top