Source Development Banish Soul

zLuke

Very Active Pirate
Developer
Registered
LV
4
 
Joined
Jan 29, 2026
Messages
63
Reaction score
46
Points
63
Age
40

Banish Soul

Allows you to send a dead character to a save point.


Add in file source\Server\GameServer\src\Character.h ~str 245
C++:
bool ForceReliveCityNow(CCharacter* pCaster, const char* szReason = 0);
Add in file source\Server\GameServer\src\Character.cpp ~str 1533

C++:
bool CCharacter::ForceReliveCityNow(CCharacter* pCaster, const char* szReason /*=0*/)
{
    // Must be a valid dead player character.
    if (!IsPlayerCha())
        return false;
    if (IsLiveing() || GetExistState() < enumEXISTS_WITHERING)
        return false;

    // Deterministic priority rule:
    // city-force revive always wins over pending SetRelive() requests.
    m_chSelRelive = enumEPLAYER_RELIVE_NONE;
    m_chReliveLv = 0;
    m_bReliveByItem = false;
    GetPlyMainCha()->ResetChaRelive();

    // Optional map restrictions for this mechanic.
    // Keep this in C++ as a hard safety layer even if Lua also checks maps.
    SubMap* pMap = GetSubMap();
    if (!pMap)
        return false;

    // Instant city relocation path (ignore wither-time).
    if (IsBoat())
    {
        BackToCity(true);
    }
    else
    {
        cChar* rtCityName = 0;
        if (g_CParser.DoString("MapRespawnOnDeath", enumSCRIPT_RETURN_STRING, 1,
            enumSCRIPT_PARAM_LIGHTUSERDATA, 1, this,
            enumSCRIPT_PARAM_STRING, 1, pMap->GetName(),
            DOSTRING_PARAM_END))
        {
            rtCityName = g_CParser.GetReturnString(0);
        }

        if (rtCityName)
        {
            SBirthPoint* pSBirthP = GetRandBirthPoint(GetLogName(), rtCityName);
            if (pSBirthP)
            {
                if (!strcmp(pSBirthP->szMapName, rtCityName))
                    BackToCity(true, rtCityName, pMap->GetCopyNO());
                else
                    BackToCity(true, rtCityName);
            }
            else
            {
                BackToCity(true);
            }
        }
        else
        {
            BackToCity(true);
        }
    }

    // Apply normal city-relive script.
    g_CParser.DoString("Relive", enumSCRIPT_RETURN_NONE, 0,
        enumSCRIPT_PARAM_LIGHTUSERDATA, 1, this, DOSTRING_PARAM_END);

    if (getAttr(ATTR_HP) <= 0)
    {
        LG("renascence compute error",
            "character %s(%d) force-relive city failed, HP <= 0\n",
            GetLogName(), getAttr(ATTR_JOB));
        return false;
    }

    if (pCaster && szReason)
    {
        LG("force_relive",
            "[%s] forced [%s] to city relive. reason: %s\n",
            pCaster->GetLogName(), GetLogName(), szReason);
    }
    return true;
}

Add in file source\Server\GameServer\src\Expand.h ~str 7641
C++:
inline int lua_ForceReliveCityNow(lua_State* pLS)
{
    // Signature:
    // ForceReliveCityNow(caster, target[, reason])
    // or ForceReliveCityNow(target)
    int n = lua_gettop(pLS);
    if (n < 1 || n > 3)
        return 0;

    CCharacter* pCaster = 0;
    CCharacter* pTarget = 0;
    const char* szReason = 0;

    if (n == 1)
    {
        pTarget = (CCharacter*)lua_touserdata(pLS, 1);
    }
    else
    {
        pCaster = (CCharacter*)lua_touserdata(pLS, 1);
        pTarget = (CCharacter*)lua_touserdata(pLS, 2);
        if (n == 3 && lua_isstring(pLS, 3))
            szReason = lua_tostring(pLS, 3);
    }

    if (!pTarget)
    {
        lua_pushnumber(pLS, 0);
        return 1;
    }

    bool bOk = pTarget->ForceReliveCityNow(pCaster, szReason);
    lua_pushnumber(pLS, bOk ? 1 : 0);
    return 1;
}
Add in file source\Server\GameServer\src\Expand.h ~str 7709
C++:
REGFN(ForceReliveCityNow);

Compile GameServer!

Add to the end of the file
\server\GameServer\resource\script\calculate\skilleffect.lua
C++:
function SkillSp_BanishSoul ( sklv )
   local sp_reduce = 50
    return sp_reduce
end

function SkillCooldown_BanishSoul( sklv )
    local Cooldown = 60000 - sklv * 1500
    return Cooldown
end

function Skill_BanishSoul_Begin( role, sklv )

    local item_count = CheckBagItem(role, 15404)
    if item_count <= 0 then
        SkillUnable(role)
        SystemNotice(role, "Does not possess required item to use skill")
        return
    end
    local a = DelBagItem(role, 15404, 1)
    if a == 0 then
        SkillUnable(role)
        SystemNotice(role, "Failed to consume required item")
        return
    end
end

function Skill_BanishSoul_End( ATKER, DEFER, sklv )
    local ok = ForceReliveCityNow(ATKER, DEFER, "BanishSoul")
    if ok ~= 1 then
        SkillUnable(ATKER)
        SystemNotice(ATKER, "Unable to force target to city respawn.")
        return
    end
end

Add to the end of the file \server\GameServer\resource\script\calculate\ItemEffect.lua

C++:
function Sk_Script_BanishSoul ( role , Item )                                          
    local sk_add = 470
    local form_sklv = GetSkillLv( role , sk_add )

    if form_sklv ~= 0  then
        UseItemFailed ( role )
        return
    end
    a = AddChaSkill ( role , sk_add, 1 , 1 , 0 )
    if a== 0 then
        UseItemFailed ( role )
        return
    end
end

Add in file \server\GameServer\resource\ItemInfo.txt and \Client\scripts\table\iteminfo.txt
Code:
15404    Bloody Doubloon of Exile    i15404    10130005    0    0    0    0    0    00    41    0    0    0    0    0    1    1    1    1    99    0    10000    -1    0    -1    0    0    -1    -1    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0    0    0,0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    He sends the soul of a dead pirate to the city.    1
15405    Banish Soul    book3    10130005    0    0    0    0    0    00    34    0    0    0    0    0    1    1    1    1    1    0    13300    -1    0    -1    0    0    -1    -1    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0,0    0    0    0,0    0    0    0    0    0    0    0    0    0    Sk_Script_BanishSoul    0    0    0    0    0    0    0    1

Add in file \server\GameServer\resource\skillinfo.txt and \Client\scripts\table\skillinfo.txt
Code:
0470    Banish Soul    1    -1,1    1,-1    1,-1    1,-1    -1    2    1    1    -1    -1    0    1    1    800    6    1    0    0    0    0    0    SkillSp_BanishSoul    0    0    0    Skill_BanishSoul_Begin    Skill_BanishSoul_End    0    0    0    0    0    0    0    0    0    0    0    0    0    0    SkillCooldown_BanishSoul    1    1    12    0    116    -1    113    0    -1    0,0    0,0    -1    -1    -1    0    0    -1    -1    148    0    0    0    s0470.png    0    0    He sends the soul of a dead pirate to the city.    Required for use The Bloody Doubloon of Exile.     Fix consumption of 50 SP    0

Copy icon files from archive to \Client\texture\icon\

Compile bin table in client
 

Attachments

Last edited:
Suggested improvement:
When a player dies, give them a short protection time of 5-10 seconds. During this time, the ability "Banish Soul" cannot be used on them.
This change will prevent instant use of "Banish Soul" and give teammates time to revive the player.
You can also add a visual effect to the dead player during the protection time.