Page 1 of 4

Add linkpearl to new characters

Posted: Fri Oct 03, 2014 1:53 pm
by Vivitaru
Hey guys,

I added a lua function in the core to automatically add a linkpearl to new characters and it will auto-equip. Make sure the linkshell already exists or your linkpearl will become a ronin (pearl with no master :lol:)

Here's the code:

lua_baseentity.h

Code: Select all

  + int32 AddLinkpearl(lua_State* L);
    int32 ChangeMusic(lua_State* L);        // Sets the specified music Track for specified music block.

lua_baseentity.cpp

Code: Select all

   + inline int32 CLuaBaseEntity::AddLinkpearl(lua_State* L) {
   + DSP_DEBUG_BREAK_IF(m_PBaseEntity->objtype == TYPE_NPC);
   +
   + CCharEntity* PChar = (CCharEntity*)m_PBaseEntity;
   + const int8* linkshellName = lua_tostring(L, 1);
   +
   + uint8 invSlotID = charutils::AddItem(PChar, LOC_INVENTORY, 515, 1);
   + CItem* PItem = PChar->getStorage(LOC_INVENTORY)->GetItem(invSlotID);
   +
   +    if (PItem != NULL)
   +    {
   +           std::string qStr = ("UPDATE char_inventory SET signature='");
   +           qStr += linkshellName;
   +           qStr += "' WHERE charid = " + std::to_string(PChar->id);
   +           qStr += " AND itemId = 515 AND signature = ''";
   +           Sql_Query(SqlHandle, qStr.c_str());
   +
   +           const int8* Query = "SELECT linkshellid,color FROM linkshells WHERE name='%s'";
   +           int32 ret = Sql_Query(SqlHandle, Query, linkshellName);
   +           if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
   +           {
   +                   CItemLinkshell* PLinkshell = NULL;
   +
   +                   // Update item with name & color //
   +                   int8 EncodedString[16];
   +                   EncodeStringLinkshell((int8*)linkshellName, EncodedString);
   +                   PItem->setSignature(EncodedString);
   +                   ((CItemLinkshell*)PItem)->SetLSID(Sql_GetUIntData(SqlHandle, 0));
   +                   ((CItemLinkshell*)PItem)->SetLSColor(Sql_GetIntData(SqlHandle, 1));
   +
   +                   // auto-equip it //
   +                   PItem->setSubType(ITEM_LOCKED);
   +                   PChar->equip[SLOT_LINK] = invSlotID;
   +                   PChar->equipLoc[SLOT_LINK] = LOC_INVENTORY;
   +                   PLinkshell = (CItemLinkshell*)PItem;
   +                   if (PLinkshell)
   +                          linkshell::AddOnlineMember(PChar, PLinkshell);
   +		}
   +	}
   +
   +	return 1;
+}

inline int32 CLuaBaseEntity::ChangeMusic(lua_State *L)
{
    DSP_DEBUG_BREAK_IF(m_PBaseEntity == NULL);

lua_baseentity.cpp

Code: Select all

Lunar<CLuaBaseEntity>::Register_t CLuaBaseEntity::methods[] =
{
  + LUNAR_DECLARE_METHOD(CLuaBaseEntity, AddLinkpearl),
    LUNAR_DECLARE_METHOD(CLuaBaseEntity,ChangeMusic),

player.lua

Code: Select all

function CharCreate(player)
   +   if not(player:hasItem(515)) then
   +		player:AddLinkpearl("you_linkshell_name");
   +	end

Enjoy! 8-)

Re: Add linkpearl to new characters

Posted: Fri Oct 03, 2014 10:21 pm
by whasf
Thanks! If you could put that in a pull request to the github project that'd be super awesome :)

Re: Add linkpearl to new characters

Posted: Fri Oct 03, 2014 11:04 pm
by kjLotus
whasf wrote:Thanks! If you could put that in a pull request to the github project that'd be super awesome :)
uhh.. i think that falls under custom content

Re: Add linkpearl to new characters

Posted: Sat Oct 04, 2014 12:05 am
by Vivitaru
kjLotus wrote:uhh.. i think that falls under custom content
I just commited the changes on git, how do i pull it out?

Edit: I reverted the changes.

Re: Add linkpearl to new characters

Posted: Sat Oct 04, 2014 1:36 am
by TeoTwawki
Vivitaru, I made a few tweaks to avoid the issue of creating LS that don't exist yet.

My changed version of your luabaseenitty.cpp:

See updated version viewtopic.php?f=20&t=2256&start=30&hili ... ell#p36654

Code: Select all

inline int32 CLuaBaseEntity::AddLinkpearl(lua_State* L)
{
    DSP_DEBUG_BREAK_IF(m_PBaseEntity->objtype == TYPE_NPC);

    const int8* linkshellName = lua_tostring(L, 1);
    const int8* Query = "SELECT name FROM linkshells WHERE name='%s'";
    int32 ret = Sql_Query(SqlHandle, Query, linkshellName);

    if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
    {
        CCharEntity* PChar = (CCharEntity*)m_PBaseEntity;
        uint8 invSlotID = charutils::AddItem(PChar, LOC_INVENTORY, 515, 1);
        CItem* PItem = PChar->getStorage(LOC_INVENTORY)->GetItem(invSlotID);

        if (PItem != NULL)
        {
            std::string qStr = ("UPDATE char_inventory SET signature='");
            qStr += linkshellName;
            qStr += "' WHERE charid = " + std::to_string(PChar->id);
            qStr += " AND itemId = 515 AND signature = ''";
            Sql_Query(SqlHandle, qStr.c_str());

            Query = "SELECT linkshellid,color FROM linkshells WHERE name='%s'";
            ret = Sql_Query(SqlHandle, Query, linkshellName);
            if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
            {
                CItemLinkshell* PLinkshell = NULL;

                // Update item with name & color //
                int8 EncodedString[16];
                EncodeStringLinkshell((int8*)linkshellName, EncodedString);
                PItem->setSignature(EncodedString);
                ((CItemLinkshell*)PItem)->SetLSID(Sql_GetUIntData(SqlHandle, 0));
                ((CItemLinkshell*)PItem)->SetLSColor(Sql_GetIntData(SqlHandle, 1));

                // auto-equip it //
                PItem->setSubType(ITEM_LOCKED);
                PChar->equip[SLOT_LINK] = invSlotID;
                PChar->equipLoc[SLOT_LINK] = LOC_INVENTORY;
                PLinkshell = (CItemLinkshell*)PItem;
                if (PLinkshell)
                    linkshell::AddOnlineMember(PChar, PLinkshell);
            }
        }
    }

    return 1;
}
New code in luautils.cpp:

Code: Select all

	lua_register(LuaHandle,"isValidLS",luautils::isValidLS);

Code: Select all

/************************************************************************
*                                                                       *
*  Check if a given linkshell exists by checking the name in database   *
*                                                                       *
************************************************************************/

int32 isValidLS(lua_State* L)
{
    const int8* linkshellName = lua_tostring(L, 1);
    const int8* Query = "SELECT name FROM linkshells WHERE name='%s'";
    int32 ret = Sql_Query(SqlHandle, Query, linkshellName);

    if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
    {
        lua_pushboolean(L, true);
    }
    else
    {
        lua_pushboolean(L, false);
    }
    return 1;
}
New code in luautils.h:

Code: Select all

	int32 isValidLS(lua_State*);
In player.lua:

Code: Select all

    if (isValidLS(("you_linkshell_name") then
        if not(player:hasItem(515)) then
            player:AddLinkpearl("you_linkshell_name");
        end
    end
If the shell doesn't exist, no pearl get made in their inventory.

I also made a GM command instead of using player.lua do it, to remote pearl people on a more selective basis (against the point of what you were doing I know, but thought I'd share anyway):

Code: Select all

---------------------------------------------------------------------------------------------------
-- func: @givels <linkshell name> <player>
-- auth: forgottenandlost
-- desc: remotely gives the specified linkshell to the target player.
---------------------------------------------------------------------------------------------------

cmdprops =
{
    permission = 1,
    parameters = "ss"
};

function onTrigger(player,ls,target)
    -- Yeah yeah I made an huge if/else block instead of using returns. >.>
    if (ls == nil) then
        player:PrintToPlayer( "You specify the LS by name." );
        player:PrintToPlayer( "@givels <linkshell name> <player>" );
    else
        if (isValidLS(ls) == true) then
            if (target == nil) then
                if (player:getFreeSlotsCount() >= 1) then
                    player:addLSpearl(ls);
                else
                    player:PrintToPlayer( "Can't obtain LS. Sort your inventory doofus!" );
                end
            else
                local targ = GetPlayerByName(target);
                if (targ ~= nil) then
                    if (player:getFreeSlotsCount() >= 1) then
                        targ:addLSpearl(ls);
                    else
                        player:PrintToPlayer( string.format( "Player '%s' doesn't have a free slot for the item.", target ) );
                    end
                else
                    player:PrintToPlayer( string.format( "Player named '%s' not found!", target ) );
                    player:PrintToPlayer( "@givels <linkshell name> <player>" );
                end
            end
        else
            player:PrintToPlayer( string.format( "LS named '%s' not found!", ls ) );
            player:PrintToPlayer( "@givels <linkshell name> <player>" );
        end
    end
end;
edit:
GM command checks for free space before trying to hand out pearls now.

edit2: not sure why I even bothered making it default to self there...Oh well! /lazy[/strike]

Re: Add linkpearl to new characters

Posted: Sat Oct 04, 2014 1:43 am
by Vivitaru
Nice changes forgottenandlost, i definitely should've done it that way!

Re: Add linkpearl to new characters

Posted: Tue Jan 06, 2015 1:29 am
by tagban
This doesn't seem to work properly anymore with the recent database changes. Anyone have a fix?

Re: Add linkpearl to new characters

Posted: Tue Jan 06, 2015 3:00 am
by kjLotus
just have to change the order of things in the lua_baseentity function: it should be doing setSignature and setLSID/LSColor before calling AddItem

Code: Select all

inline int32 CLuaBaseEntity::AddLinkpearl(lua_State* L)
{
    DSP_DEBUG_BREAK_IF(m_PBaseEntity->objtype == TYPE_NPC);

    const int8* linkshellName = lua_tostring(L, 1);
    const int8* Query = "SELECT name FROM linkshells WHERE name='%s'";
    int32 ret = Sql_Query(SqlHandle, Query, linkshellName);

    if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
    {
        CCharEntity* PChar = (CCharEntity*)m_PBaseEntity;

        std::string qStr = ("UPDATE char_inventory SET signature='");
        qStr += linkshellName;
        qStr += "' WHERE charid = " + std::to_string(PChar->id);
        qStr += " AND itemId = 515 AND signature = ''";
        Sql_Query(SqlHandle, qStr.c_str());

        Query = "SELECT linkshellid,color FROM linkshells WHERE name='%s'";
        ret = Sql_Query(SqlHandle, Query, linkshellName);
        if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
        {
            CItem* PItem = itemutils::GetItem(515);

            // Update item with name & color //
            int8 EncodedString[16];
            EncodeStringLinkshell((int8*)linkshellName, EncodedString);
            PItem->setSignature(EncodedString);
            ((CItemLinkshell*)PItem)->SetLSID(Sql_GetUIntData(SqlHandle, 0));
            ((CItemLinkshell*)PItem)->SetLSColor(Sql_GetIntData(SqlHandle, 1));
            uint8 invSlotID = charutils::AddItem(PChar, LOC_INVENTORY, PItem);

            // auto-equip it //
            if (invSlotID != ERROR_SLOTID)
            {
                PItem->setSubType(ITEM_LOCKED);
                PChar->equip[SLOT_LINK] = invSlotID;
                PChar->equipLoc[SLOT_LINK] = LOC_INVENTORY;
                linkshell::AddOnlineMember(PChar, (CItemLinkshell*)PItem);
            }
        }
    }

    return 1;
}
excuse the indentation, there's no shift-tab in the editor in here :\

note: not tested

Re: Add linkpearl to new characters

Posted: Wed Jan 07, 2015 1:10 am
by tagban
Yea that didn't work but mainly because it errored on "linkshellName" not being defined.

Re: Add linkpearl to new characters

Posted: Wed Jan 07, 2015 1:24 am
by kjLotus
tagban wrote:Yea that didn't work but mainly because it errored on "linkshellName" not being defined.
well yeah.. you fill that in yourself or add "const int8* linkshellName = lua_tostring(L, 1);" to the top

i don't know how the previous function worked