LV
4
- Joined
- Jan 29, 2026
- Messages
- 49
- Reaction score
- 32
- Points
- 38
- Age
- 40
Resurrection at the place of death
Code:
15400 Sailor's Spirit a7350 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 Keep it in your inventory. Allows you to resurrect at the place of death. After resurrection, restores 1% HP 1
15401 Pirate's Spirit a7340 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 Keep it in your inventory. Allows you to resurrect at the place of death. After resurrection, restores 10% HP 1
15402 Captain's Spirit a7353 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 Keep it in your inventory. Allows you to resurrect at the place of death. After resurrection, restores 50% HP 1
15403 Dead Man's Soul a7341 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 Keep it in your inventory. Allows you to resurrect at the place of death. After resurrection, restores 100% HP 1
3. \Client\scripts\lua\forms\player.clu
search "frmRelive = UI_CreateForm"
Replace the resurrection form script with
C++:
frmRelive = UI_CreateForm( "frmRelive", FALSE, 185, 101, 397, 500, TRUE, FALSE )
UI_LoadFormImage( frmRelive, "texture/ui/sure.dds", 185, 101, 0, 0, "", 0, 0 )
UI_ShowForm( frmRelive, FALSE )
UI_AddFormToTemplete( frmRelive, FORM_MAIN )
UI_SetFormStyle( frmRelive, 0 )
UI_SetIsDrag( frmRelive, TRUE )
UI_FormSetIsEscClose( frmRelive, FALSE )
--UI_SetAlpha( frmRelive, 200 )
--UI_FormSetHotKey( frmRelive, ALT_KEY, HOTKEY_X )
labReCity = UI_CreateCompent( frmRelive, LABELEX_TYPE, "labReCity", 1, 1, 34, 34 )
UI_SetCaption( labReCity, "Revive \nin town?" )
UI_SetTextColor( labReCity, COLOR_BLACK)
UI_SetLabelExFont( labReCity, DEFAULT_FONT, TRUE, COLOR_WHITE )
labTitle = UI_CreateCompent( frmRelive, LABELEX_TYPE, "labTitle", 400, 150, 10, 4 )
UI_SetCaption( labTitle, "Revive")
UI_SetTextColor( labTitle, COLOR_BLACK )
UI_SetLabelExFont( labTitle, DEFAULT_FONT, TRUE, COLOR_WHITE )
btnReCity = UI_CreateCompent( frmRelive, BUTTON_TYPE, "btnReCity", 41, 19, 34, 78 )
UI_LoadButtonImage( btnReCity, "texture/ui/SystemBotton3.tga", 41, 19, 169, 39, FALSE )
btnReSpot = UI_CreateCompent( frmRelive, BUTTON_TYPE, "btnReSpot", 76, 19, 94, 78 )
UI_LoadButtonImage( btnReSpot, "texture/ui/Store8.tga", 76, 19, 0, 0, FALSE )
labReSpot = UI_CreateCompent( frmRelive, LABELEX_TYPE, "labReSpot", 41, 19, 104, 81 )
UI_SetCaption( labReSpot, "Resurrect")
UI_SetTextColor( labReSpot, COLOR_BLACK )
UI_SetLabelExFont( labReSpot, DEFAULT_FONT, TRUE, COLOR_WHITE )
imgResurrectItem = UI_CreateCompent( frmRelive, IMAGE_TYPE, "imgResurrectItem", 36, 36, 112 , 30 )
UI_LoadImage( imgResurrectItem, "texture/ui/Store6.tga", NORMAL, 36, 36, 157, 76 )
cmdResurrectItem = UI_CreateCompent( frmRelive, COMMAND_ONE_TYPE, "cmdResurrectItem", 32, 32, 114, 32 )
UI_SetIsShow( cmdResurrectItem, false )
4. \sources\Client\src\UIStartForm.cpp
Add at the beginning of the file after using namespace GUI;
C++:
// Item ID constants for resurrection at the place of death
// These values must match the constants on the server in exp_and_level.lua
#define ITEM_ID_RESURRECT_1 15400 // 1% HP
#define ITEM_ID_RESURRECT_10 15401 // 10% HP
#define ITEM_ID_RESURRECT_50 15402 // 50% HP
#define ITEM_ID_RESURRECT_100 15403 // 100% HP
// Countdown time for the on-site resurrection button (in seconds)
#define RESURRECT_COUNTDOWN_SECONDS 20
static DWORD g_dwResurrectCountdownStartTime = 0;
Replace the entire CStartMgr::_evtReliveFormMouseEvent (~str 771) function with
C++:
void CStartMgr::_evtReliveFormMouseEvent(CCompent *pSender, int nMsgType, int x, int y, DWORD dwKey)
{
std::string name = pSender->GetName();
if (name == "btnReCity")
{
CS_DieReturn(enumEPLAYER_RELIVE_CITY);
pSender->GetForm()->SetIsShow(false);
if (frmSelectOriginRelive)
{
frmSelectOriginRelive->SetIsShow(false);
frmSelectOriginRelive = nullptr;
}
}
else if (name == "btnReSpot")
{
// We send a request for resurrection at the place of death
CS_DieReturn(enumEPLAYER_RELIVE_ITEM_ORIGIN);
pSender->GetForm()->SetIsShow(false);
if (frmSelectOriginRelive)
{
frmSelectOriginRelive->SetIsShow(false);
frmSelectOriginRelive = nullptr;
}
}
}
Replace the entire CStartMgr::MainChaDied() (~str 1052) function with
C++:
void CStartMgr::MainChaDied()
{
if( frmMainChaRelive )
{
int nLeft = ( g_pGameApp->GetWindowHeight() - frmMainChaRelive->GetWidth() ) / 2;
int nTop = ( g_pGameApp->GetWindowHeight() - frmMainChaRelive->GetHeight() ) / 2;
nTop-=80;
frmMainChaRelive->SetPos( nLeft, nTop );
frmMainChaRelive->Refresh();
static CLabel* pInfo = dynamic_cast<CLabel*>( frmMainChaRelive->Find( "labReCity" ) );
CCharacter* pCha = CGameScene::GetMainCha();
bool IsShow = true;
if( pInfo && pCha )
{
if( pCha->IsBoat() )
{
pInfo->SetCaption( g_oLangRec.GetString(761) );
}
else
{
pInfo->SetCaption( "Revive \nin town?" );
if( CGameScene* pScene = CGameApp::GetCurScene() )
{
if( CMapInfo *pInfo = pScene->GetCurMapInfo() )
{
// Modify by lark.li 20080719 begin
//if( stricmp( pInfo->szDataName, "teampk" )==0 )
if( stricmp( pInfo->szDataName, "teampk" )==0 || stricmp( pInfo->szDataName,"starena1") == 0
|| stricmp( pInfo->szDataName,"starena2") == 0 || stricmp( pInfo->szDataName,"starena3") == 0)
IsShow = false;
// End
}
}
}
}
CUIInterface::MainChaMove();
g_stUITrade.CloseAllForm();
CWorldScene* pWorldScene = dynamic_cast<CWorldScene*>(g_pGameApp->GetCurScene());
if(pWorldScene && pWorldScene->GetShipMgr())
{
pWorldScene->GetShipMgr()->CloseForm();
}
// Checking for items to resurrect at the place of death
static CTextButton* pBtnReSpot = dynamic_cast<CTextButton*>(frmMainChaRelive->Find("btnReSpot"));
static COneCommand* cmdResurrectItem = dynamic_cast<COneCommand*>(frmMainChaRelive->Find("cmdResurrectItem"));
if (cmdResurrectItem)
{
cmdResurrectItem->SetIsDrag(false);
}
if (pBtnReSpot && cmdResurrectItem)
{
// Array of item IDs for resurrection (from smallest to largest)
const short sResurrectItemIDs[] = {
ITEM_ID_RESURRECT_1, // 1% HP
ITEM_ID_RESURRECT_10, // 10% HP
ITEM_ID_RESURRECT_50, // 50% HP
ITEM_ID_RESURRECT_100 // 100% HP
};
short sFoundItemID = 0;
short sFoundItemCount = 0;
// Search for the item with the highest ID (the most powerful)
// Traverse the array in reverse order (from highest to lowest)
for (int i = 3; i >= 0; i--)
{
short sItemID = sResurrectItemIDs[i];
short sCount = g_stUIEquip.GetItemCount(sItemID);
if (sCount > 0)
{
sFoundItemID = sItemID;
sFoundItemCount = sCount;
break;
}
}
bool bHasItem = (sFoundItemID > 0);
// Initialize the countdown when the character dies
static CLabel* labReSpot = dynamic_cast<CLabel*>(frmMainChaRelive->Find("labReSpot"));
if (bHasItem && pBtnReSpot)
{
g_dwResurrectCountdownStartTime = CGameApp::GetCurTick();
pBtnReSpot->SetIsEnabled(false); // The button is inactive during the countdown
char szCaption[64];
sprintf(szCaption, "%d", RESURRECT_COUNTDOWN_SECONDS);
labReSpot->SetCaption(szCaption);
}
else if (pBtnReSpot)
{
pBtnReSpot->SetIsEnabled(false);
labReSpot->SetCaption("Resurrect");
g_dwResurrectCountdownStartTime = 0; // Reset the timer if there is no item
}
// Clearing the previous item
if (cmdResurrectItem)
{
cmdResurrectItem->DelCommand();
cmdResurrectItem->SetIsShow(false);
}
if (bHasItem && cmdResurrectItem)
{
CItemRecord* pItemRec = GetItemRecordInfo(sFoundItemID);
if (pItemRec)
{
CItemCommand* pItem = new CItemCommand(pItemRec);
if (pItem->GetData().sID == 0)
{
pItem->GetData().sID = (short)pItemRec->lID;
}
pItem->GetData().sNum = sFoundItemCount;
pItem->SetOwnDefText("");
pItem->SetCanDrag(false);
cmdResurrectItem->AddCommand(pItem);
cmdResurrectItem->SetIsShow(true);
}
}
}
if( IsShow ) frmMainChaRelive->Show();
}
}
Add to the beginning of the function CStartMgr::FrameMove
C++:
// Update the countdown for the resurrection button in place
if (frmMainChaRelive && frmMainChaRelive->GetIsShow() && g_dwResurrectCountdownStartTime > 0)
{
static CTextButton* pBtnReSpot = dynamic_cast<CTextButton*>(frmMainChaRelive->Find("btnReSpot"));
static CLabel* labReSpot = dynamic_cast<CLabel*>(frmMainChaRelive->Find("labReSpot"));
if (labReSpot)
{
DWORD dwElapsed = dwTime - g_dwResurrectCountdownStartTime;
int nSecondsRemaining = RESURRECT_COUNTDOWN_SECONDS - (int)(dwElapsed / 1000);
if (nSecondsRemaining > 0)
{
// Update the countdown button text
char szCaption[64];
sprintf(szCaption, " %d", nSecondsRemaining);
labReSpot->SetCaption(szCaption);
pBtnReSpot->SetIsEnabled(false);
}
else
{
// Time has expired - we make the button active
labReSpot->SetCaption("Resurrect");
pBtnReSpot->SetIsEnabled(true);
g_dwResurrectCountdownStartTime = 0;
}
}
}
5. \sources\Libraries\common\include\CompCommand.h
Search enum EPlayerReliveType (~str 284)
Add to the end of the enumeration
C++:
enumEPLAYER_RELIVE_ITEM_ORIGIN,
6. \sources\Server\GameServer\src\Character.h
Search m_chReliveLv; (~str 789)
Add to next string
C++:
bool m_bReliveByItem;
7. \sources\Server\GameServer\src\Character.cpp
Search m_chReliveLv = 0; (~str 112)
Add to next string
C++:
m_bReliveByItem = false;
Search (~str 1487)
C++:
else if (m_chSelRelive == enumEPLAYER_RELIVE_ORIGIN)
C++:
else if (m_chSelRelive == enumEPLAYER_RELIVE_ORIGIN)
{
if (m_chReliveLv > 0)
{
SubMap *pCMap = GetSubMap();
GetSubMap()->GoOut(this);
SetExistState(enumEXISTS_NATALITY);
//m_timerScripts.Reset();
m_chSelRelive = enumEPLAYER_RELIVE_NONE;
if (m_bReliveByItem) // Check the new flag
{
g_CParser.DoString("Relive_now_item", enumSCRIPT_RETURN_NONE, 0,
enumSCRIPT_PARAM_LIGHTUSERDATA, 1, this,
enumSCRIPT_PARAM_NUMBER, 1, m_chReliveLv, DOSTRING_PARAM_END);
}
else
{
g_CParser.DoString("Relive_now", enumSCRIPT_RETURN_NONE, 0,
enumSCRIPT_PARAM_LIGHTUSERDATA, 1, this,
enumSCRIPT_PARAM_NUMBER, 1, m_chReliveLv, DOSTRING_PARAM_END);
}
m_bReliveByItem = false; // Reset flag after use
if (getAttr(ATTR_HP) <= 0)
LG("renascence compute error", "character %s(%d)after renascence compute HP is unlawful\n", GetLogName(), getAttr(ATTR_JOB));
SwitchMap(pCMap, pCMap->GetName(), GetPos().x, GetPos().y, false, enumSWITCHMAP_DIE, pCMap->GetCopyNO());
}
}
8. \sources\Server\GameServer\src\CharacterPrl.cpp
Search (~str 317)
C++:
case CMD_CM_DIE_RETURN:
C++:
case CMD_CM_DIE_RETURN:
{
Char chReliveType = READ_CHAR(pk);
if (chReliveType == enumEPLAYER_RELIVE_CITY)
{
GetPlyMainCha()->ResetChaRelive();
m_chSelRelive = enumEPLAYER_RELIVE_CITY;
m_bReliveByItem = false;
}
else if (chReliveType == enumEPLAYER_RELIVE_ORIGIN)
{
GetPlyMainCha()->ResetChaRelive();
m_chSelRelive = enumEPLAYER_RELIVE_ORIGIN;
m_bReliveByItem = false;
}
else if (chReliveType == enumEPLAYER_RELIVE_ITEM_ORIGIN)
{
bool bSuccess = false;
short sItemID = 0;
short sHPPercent = 0;
g_CParser.DoString("CheckAndUseResurrectItem", enumSCRIPT_RETURN_NUMBER, 3,
enumSCRIPT_PARAM_LIGHTUSERDATA, 1, this, DOSTRING_PARAM_END);
sItemID = (short)g_CParser.GetReturnNumber(1);
sHPPercent = (short)g_CParser.GetReturnNumber(2);
bSuccess = ((g_CParser.GetReturnNumber(0) == 1) || (sItemID > 0 && sHPPercent > 0));
if (bSuccess && sHPPercent > 0)
{
m_chSelRelive = enumEPLAYER_RELIVE_ORIGIN;
m_chReliveLv = (Char)sHPPercent;
m_bReliveByItem = true;
}
else
{
GetPlyMainCha()->ResetChaRelive();
m_chSelRelive = enumEPLAYER_RELIVE_NONE;
m_bReliveByItem = false;
}
}
else if (chReliveType == enumEPLAYER_RELIVE_NORIGIN)
{
GetPlyMainCha()->ResetChaRelive();
SetRelive(enumEPLAYER_RELIVE_ORIGIN, 0);
m_bReliveByItem = false;
}
break;
}
9. \server\GameServer\resource\script\calculate\exp_and_level.lua
Add to the end of the file
C++:
-- Defining the ID of items for on-site resurrection (must be set in the configuration)
-- These values must match the constants on the client in UIStartForm.cpp
ITEM_ID_RESURRECT_1 = 15400 -- 1% HP
ITEM_ID_RESURRECT_10 = 15401 -- 10% HP
ITEM_ID_RESURRECT_50 = 15402 -- 50% HP
ITEM_ID_RESURRECT_100 = 15403 -- 100% HP
RESURRECT_ITEM_IDS = {
ITEM_ID_RESURRECT_1,
ITEM_ID_RESURRECT_10,
ITEM_ID_RESURRECT_50,
ITEM_ID_RESURRECT_100
}
RESURRECT_HP_PERCENTS = {
[1] = 1,
[2] = 10,
[3] = 50,
[4] = 100
}
-- List of maps where resurrection at the place of death is prohibited
local FORBIDDEN_RESURRECT_MAPS = {
"guildwar",
-- Add other maps as needed.
-- "map_name_2",
-- "map_name_3",
}
-- Checking and using the item for resurrection on the spot
-- Return: success (number 0/1), itemID (number), hpPercent (number)
function CheckAndUseResurrectItem(role)
local cha_role = TurnToCha(role)
local map_name = GetChaMapName(cha_role)
for i = 1, #FORBIDDEN_RESURRECT_MAPS do
if map_name == FORBIDDEN_RESURRECT_MAPS[i] then
SystemNotice(cha_role, "Resurrection at the place of death is not allowed on this map")
return 0, 0, 0
end
end
local foundItemID = 0
local foundItemIndex = 0
for i = #RESURRECT_ITEM_IDS, 1, -1 do
local itemID = RESURRECT_ITEM_IDS[i]
local itemCount = CheckBagItem(cha_role, itemID)
if itemCount and itemCount > 0 then
foundItemID = itemID
foundItemIndex = i
break
end
end
if foundItemID == 0 then
SystemNotice(cha_role, "You need an item to resurrect at the place of death")
return 0, 0, 0
end
local ret = DelBagItem(cha_role, foundItemID, 1)
if ret ~= 1 then
SystemNotice(cha_role, "Error when using the resurrection item")
return 0, 0, 0
end
local hpPercent = RESURRECT_HP_PERCENTS[foundItemIndex]
return 1, foundItemID, hpPercent
end
-- On-site resurrection using an item (percentage HP/SP restoration)
function Relive_now_item(role, hpPercent)
local cha_role = TurnToCha(role)
local mxhp = Mxhp(cha_role)
local mxsp = Mxsp(cha_role)
local hp = math.max(1, math.floor((hpPercent / 100.0) * mxhp))
local sp = math.max(1, math.floor((hpPercent / 100.0) * mxsp))
SetCharaAttr(hp, cha_role, ATTR_HP)
SetCharaAttr(sp, cha_role, ATTR_SP)
end
Compile the client and server. Compile the tables in the client, and the clu scripts.
Enjoy!!!
2026 (c) zLuke