Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Coders Chit-Chat

Junior Spellweaver
Joined
Jan 6, 2016
Messages
184
Reaction score
55
A long time ago on the kalmax server there was a (bug) in which you could fly with a panther and a assassin mask on.
My Question, is it possible to create a addon which gives the option for players to fly?

If this is not what you meant for this thread i will move the question :)
If it is, could someone show a example for this? Curious if it is even possible.
 
Banned
Banned
Joined
Jul 14, 2016
Messages
184
Reaction score
77
@Bloodx did you ever do anything else with your KalOnline Engine Lua project?

I was wondering if you would consider (or if it is even possible) making a dll plugin of it for the files r3vo released for free (2016 engine) so that we can use lua scripts within a scripts folder like you had it in your project?

So a lua dll addon to give us the ability to use lua scripting with this setup.

Its not a "needed" addon i just think it would be a cool one and i would use it for sure !!
 
Skilled Illusionist
Joined
Oct 31, 2008
Messages
341
Reaction score
294
A long time ago on the kalmax server there was a (bug) in which you could fly with a panther and a assassin mask on.
My Question, is it possible to create a addon which gives the option for players to fly?

If this is not what you meant for this thread i will move the question :)
If it is, could someone show a example for this? Curious if it is even possible.

hmmm.. maybe this is possible if you Change Player Z Value and Syncro with the Client...

@Bloodx did you ever do anything else with your KalOnline Engine Lua project?

I was wondering if you would consider (or if it is even possible) making a dll plugin of it for the files r3vo released for free (2016 engine) so that we can use lua scripts within a scripts folder like you had it in your project?

So a lua dll addon to give us the ability to use lua scripting with this setup.

Its not a "needed" addon i just think it would be a cool one and i would use it for sure !!

I never continued the work on it, because no one really asked for it.. I think I still have the Source. should be possible to implement a scripting for ppl...

The Question is what kind of scripting is needed ? Changing values with memory editing ? or ? because for all kind of script functions you need to implement them at first..
 
Banned
Banned
Joined
Jul 14, 2016
Messages
184
Reaction score
77
I never continued the work on it, because no one really asked for it.. I think I still have the Source. should be possible to implement a scripting for ppl...

The Question is what kind of scripting is needed ? Changing values with memory editing ? or ? because for all kind of script functions you need to implement them at first..

Changing values with memory editing was why i wanted it.

also i had an old addon i got from someone years ago that used to give starter items in lua

so this may be a cool feature to add too

Code:
-- function Item(Pid,Index,Prefix,Info,Amount,MaxEnd,CurEnd)-- function ItemEx(Pid,Index,Prefix,Info,Amount,MaxEnd,CurEnd,Atk,Mag,Otp,Def,Eva,Eb)
-- function Buff(pid,buffid,bufftimeinminutes)
-- function Screen(...)
-- function State(...)
-- function Timestamp(minutes,addtime) -> addtime true/false



function Main(PID,Class)
    Screen("StarterItem PID: ",PID," Class: ",Class)
    if Class == 0 then -- knight
        ItemEx(PID,2606,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,2607,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,2608,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,790,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,791,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,1128,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,621,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,622,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,623,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,624,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,625,0,0,1,15,15,0,0,0,0,0,0)
    elseif Class == 1 then -- mage
        ItemEx(PID,2606,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,2607,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,2608,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,793,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,631,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,632,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,633,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,634,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,635,0,0,1,15,15,0,0,0,0,0,0)
    elseif Class == 2 then -- archer
        ItemEx(PID,2606,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,2607,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,2608,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,792,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,626,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,627,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,628,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,629,0,0,1,15,15,0,0,0,0,0,0)
        ItemEx(PID,630,0,0,1,15,15,0,0,0,0,0,0)
        


    end



    --for all classes
    Item(PID,337,0,0,1,1,1)
    Item(PID,338,0,0,1,1,1)
    Item(PID,339,0,0,1,1,1)
    Item(PID,559,0,0,1,20,20)


    
end
 
Last edited:
Junior Spellweaver
Joined
Dec 16, 2012
Messages
187
Reaction score
29
I would like to somehow rewrite the CCastle__WarDeclare from a txt editor where I can edit war time, start, ending, rewards given etc..
but for some reason I've got no clue what parameter should be given in:
static int(__cdecl *CCastle__WarBegin)(char a1, int Time) = (int(__cdecl*)(char a1, int Time))0x00419E10;
for example (char 1, int Time) what values should I insert there in order to get my command to work without server crashing
 
Skilled Illusionist
Joined
Mar 20, 2009
Messages
374
Reaction score
378
I would like to somehow rewrite the CCastle__WarDeclare from a txt editor where I can edit war time, start, ending, rewards given etc..
but for some reason I've got no clue what parameter should be given in:
static int(__cdecl *CCastle__WarBegin)(char a1, int Time) = (int(__cdecl*)(char a1, int Time))0x00419E10;
for example (char 1, int Time) what values should I insert there in order to get my command to work without server crashing

time_t is what you looking for.
Check void __cdecl CGuild::MinuteProcess(unsigned int dwTick); in there it is getting called.
Code:
  if ( g_CWState != CWState )
  {
    if ( CWState == 4 )
    {
      if ( *g_nSystem & 256 )
      {
        if ( g_nSystem[0] & 2 )
          pTime += 60 * (30 - pLocalTime->tm_min);
        else
          pTime += 3600;
      }
      else if ( pLocalTime->tm_hour == 21 )
      {
        pTime += 7200;
      }
      else
      {
        pTime += 3600;
      }
      CCastle::WarBegin(pTime);
    }
    if ( g_CWState != 4 || !CCastle::IsWarDeclared() )
      g_CWState = CWState;
  }
whole CGuild::MinuteProcess:
Code:
void __cdecl CGuild::MinuteProcess(unsigned int dwTick)
{
  int GuildMapEndIterator; // eax
  int v2; // [esp+0h] [ebp-28h]
  int v3; // [esp+4h] [ebp-24h]
  char v4; // [esp+8h] [ebp-20h]
  char a2; // [esp+Ch] [ebp-1Ch]
  CGuild *pGuild; // [esp+14h] [ebp-14h]
  int GuildMapBeginIterator; // [esp+18h] [ebp-10h]
  int CWState; // [esp+1Ch] [ebp-Ch]
  time_t pTime; // [esp+20h] [ebp-8h] MAPDST
  struct tm *pLocalTime; // [esp+24h] [ebp-4h]

  CRWLock::WriteLock(&pCRWLock);
  sub_40F070(g_GuildMap, &GuildMapBeginIterator);
  while ( 1 )
  {
    GuildMapEndIterator = sub_430C20(g_GuildMap, &a2);
    if ( !sub_47D070(&GuildMapBeginIterator, GuildMapEndIterator) )
      break;
    pGuild = sub_420250(&GuildMapBeginIterator, v2)[1];
    if ( pGuild->m_dwDeleteTick && pGuild->m_dwDeleteTick < dwTick )
    {
      if ( pGuild->m_nPlayerRef )
      {
        pGuild->m_dwDeleteTick = 0;
        sub_446090(&GuildMapBeginIterator, &v4, 0);
      }
      else
      {
        CBase::Delete(pGuild);
        GuildMapBeginIterator = *sub_44AF50(g_GuildMap, &v3, GuildMapBeginIterator);
      }
    }
    else
    {
      sub_446090(&GuildMapBeginIterator, &v2, 0);
    }
  }
  pTime = time(0);
  pLocalTime = localtime(&pTime);
  CWState = 0;
  if ( *g_nSystem & 256 )
  {
    if ( g_nSystem[0] & 2 )
    {
      if ( pLocalTime->tm_min >= 5 )
      {
        if ( pLocalTime->tm_min >= 15 )
        {
          if ( pLocalTime->tm_min >= 16 )
          {
            if ( pLocalTime->tm_min < 50 )
              CWState = 4;
          }
          else
          {
            CWState = 2;
          }
        }
        else
        {
          CWState = 1;
        }
      }
      else
      {
        CWState = 0;
      }
    }
    else if ( pLocalTime->tm_hour >= 17 )
    {
      if ( pLocalTime->tm_hour >= 18 )
      {
        if ( pLocalTime->tm_hour < 19 )
          CWState = 4;
      }
      else if ( pLocalTime->tm_min >= 30 )
      {
        CWState = 2;
      }
      else
      {
        CWState = 1;
      }
    }
    else
    {
      CWState = 0;
    }
  }
  else
  {
    switch ( pLocalTime->tm_wday )
    {
      case 4:
        if ( pLocalTime->tm_hour >= 21 )
          CWState = 1;
        break;
      case 5:
        if ( pLocalTime->tm_hour >= 21 )
          CWState = 2;
        else
          CWState = 1;
        break;
      case 6:
        if ( pLocalTime->tm_hour >= 21 )
        {
          if ( pLocalTime->tm_hour < 23 )
            CWState = 4;
        }
        else
        {
          CWState = 2;
        }
        break;
    }
  }
  if ( g_CWState != CWState )
  {
    if ( CWState == 4 )
    {
      if ( *g_nSystem & 256 )
      {
        if ( g_nSystem[0] & 2 )
          pTime += 60 * (30 - pLocalTime->tm_min);
        else
          pTime += 3600;
      }
      else if ( pLocalTime->tm_hour == 21 )
      {
        pTime += 7200;
      }
      else
      {
        pTime += 3600;
      }
      CCastle::WarBegin(pTime);
    }
    if ( g_CWState != 4 || !CCastle::IsWarDeclared() )
      g_CWState = CWState;
  }
  if ( g_CWState )
    CAlliance::PostponeExpire();
  else
    CAlliance::Expire(pTime);
  CRWLock::WriteUnlock(&pCRWLock);
  CCastle::TaxSave();
}
 
Junior Spellweaver
Joined
Dec 16, 2012
Messages
187
Reaction score
29
How do I check if a player has an item in inventory + if a player is wearing an item?
Like, if player has G1 sword in inventory, or if a player is wearing a grade 70 armour
 
Skilled Illusionist
Joined
Oct 31, 2008
Messages
341
Reaction score
294
Player::_FindItem(Player *player, int index, int amount) 0x0045D1E0 should it be..

returns Item Object.


Code:
int* item = Player::FindItem(player,index,amount);
						if(item)
						{
							int state = item[12];
							if(state == 1 || state == 9 || state == 129)
							{
								// item is weared..
							}
						}
 
Last edited:
Skilled Illusionist
Joined
Mar 20, 2009
Messages
374
Reaction score
378
I posted my item class long time ago which should help.
http://forum.ragezone.com/f389/source-code-collection-917296-post8081460/#post8081460

you could use it like this:
Code:
static int(__thiscall *FindItem)(int Player, WORD ItemIndex, int Amount) = (int(__thiscall*)(int, WORD, int))0x0045D190;


auto_ptr<KItem> pItem(new KItem(FindItem(pPlayer, nIndex, nNum)));

 if (pItem->IsState(ITEM_MIX_ICE | ITEM_MIX_LEVEL2 | ITEM_OWN | ITEM_PUTON)){
  //do something if the item is g2 ice mix bound and equipped
  pItem->SetAttack(20); //update attack to 20
  pItem->SetEB(20); //update eb to 20
  pItem->SendItemInfo(); //send item info to client
 }


// Item Info
Code:
#define ITEM_PUTON   0x00000001
#define ITEM_SETGEM   0x00000002
#define ITEM_ONTRADE  0x00000004
#define ITEM_CHEAT   0x00000008
#define ITEM_STORAGE  0x00000010
#define ITEM_TRANSFORM  0x00000020
#define ITEM_PROTECTED  0x00000040
#define ITEM_OWN   0x00000080
#define ITEM_MIX_DARK  0x00000100
#define ITEM_MIX_SAINT  0x00000200
#define ITEM_MIX_FLAME  0x00000400
#define ITEM_MIX_ICE  0x00000800
#define ITEM_MIX_LIGHT  0x00001000
#define ITEM_MIX_POISON  0x00002000
#define ITEM_MIX_PARAL  0x00004000
#define ITEM_MIX_POWER  0x00008000
#define ITEM_MIX_TECH  0x00010000
#define ITEM_MIX_FANTA  0x00020000
#define ITEM_MIX_BLOOD  0x00040000
#define ITEM_MIX_LEVEL1  0x00080000
#define ITEM_MIX_LEVEL2  0x00100000
#define ITEM_MIX_FIREBALL 0x00200000

#define ITEM_LOCKSYSTEM  0x00400000
#define ITEM_OWNMASK  ( ITEM_CHEAT | ITEM_OWN)
#define ITEM_NOTMOVEMASK ( ITEM_PUTON | ITEM_OWNMASK)
#define ITEM_STORAGEMASK ( ITEM_OWNMASK | ITEM_TRANSFORM | ITEM_PROTECTED)
#define ITEM_MIX   ( ITEM_MIX_DARK | ITEM_MIX_SAINT | ITEM_MIX_FLAME | ITEM_MIX_ICE | ITEM_MIX_LIGHT | ITEM_MIX_POISON | ITEM_MIX_PARAL | ITEM_MIX_POWER | ITEM_MIX_TECH | ITEM_MIX_FANTA | ITEM_MIX_BLOOD | ITEM_MIX_FIREBALL)
 
Junior Spellweaver
Joined
Dec 16, 2012
Messages
187
Reaction score
29
Well, I've tried hooking up Life absorption in order to make it OTP based..
Unfortunately I couldn't find the address of the LA function itself,
I've tried applying it through ExcuteSkill() unfortunately it started acting weird as i didn't provide the proper variables required for damage calculation, any hint would be appreciated.
Thanks you.
 
Skilled Illusionist
Joined
Oct 31, 2008
Messages
341
Reaction score
294
i'M not sure about the adress atm.
but here how to find it =>

breakpoint on -> 0x0047FBEA

Execute skill => follow breakpoint.


edit:
Adress should be => 0x00488330
 
Skilled Illusionist
Joined
Mar 20, 2009
Messages
374
Reaction score
378
Well, I've tried hooking up Life absorption in order to make it OTP based..
Unfortunately I couldn't find the address of the LA function itself,
I've tried applying it through ExcuteSkill() unfortunately it started acting weird as i didn't provide the proper variables required for damage calculation, any hint would be appreciated.
Thanks you.
Here some code from my script engine project.
change CPlayerSkillEx* and CSkillEx* to void* or any type you like and use pointer offsets as everyone does.
Code:
int __fastcall PreSkill(CPlayerSkillEx *PlayerSkill, void *edx, int nSkill, int nTargetId);
void __fastcall ExcuteSkill(CPlayerSkillEx *PlayerSkill, void *_edx, signed int nSkill, char* packet, char *packetend);
void __fastcall SetSkill(CPlayerSkillEx *PlayerSkill, void *_edx, int nSkill, int nLevel);
void __fastcall SkillUp(CPlayerSkillEx *CPlayerSkill, void *_edx, int nSkill);
void __fastcall LearnSkill(CPlayerSkillEx *PlayerSkill, void* _edx, int nSkill);
void __fastcall ExcutePassiveSkill(CPlayerSkillEx *PlayerSkill, void *edx);
void __fastcall ExcutePassiveSkillV(CPlayerSkillEx *PlayerSkill, void*edx, int nSkill, ...);

Memory->Intercept(IMemory::_I_CALL, (void*)0x457077, _CPlayerSkillEx::SetSkill, 5);
Memory->HookAPI(0x47F7A0, _CPlayerSkillEx::LearnSkill);
Memory->HookAPI(0x47F970, _CPlayerSkillEx::SkillUp);
Memory->HookAPI(0x47FBB0, _CPlayerSkillEx::ExcuteSkill);
Memory->HookAPI(0x480390, _CPlayerSkillEx::PreSkill);

void __fastcall _CPlayerSkillEx::ExcuteSkill(CPlayerSkillEx *PlayerSkill, void *_edx, signed int nSkill, char* data, char *dataEnd){
 PlayerSkill->m_pOwner->Write(S2C_CHATTING, "ss", "CPlayerSkillEx::ExcuteSkill", format("Skill Index: %d", nSkill).c_str());
 if (nSkill < 84){
  CSkillEx *pSkill = PlayerSkill->m_pSkill[nSkill];
  if (pSkill)
   pSkill->Excute(PlayerSkill->m_pOwner, data, dataEnd);
 }
}

int __fastcall _CPlayerSkillEx::PreSkill(CPlayerSkillEx *PlayerSkill, void *edx, int nSkill, int nTargetId){
 PlayerSkill->m_pOwner->Write(S2C_CHATTING, "ss", "CPlayerSkillEx::PreSkill", format("nSkill: %d", nSkill).c_str());
 if (nSkill >= 64)
  return 1;
 CSkillEx *pSkill = PlayerSkill->m_pSkill[nSkill];
 if (pSkill)
  return pSkill->PreExcute(PlayerSkill->m_pOwner, nTargetId);
 return 0;
}

void __fastcall _CPlayerSkillEx::ExcutePassiveSkill(CPlayerSkillEx *PlayerSkill, void *edx){
 for (signed int i = 0; i < 84; ++i){
  CSkillEx *pSkill = PlayerSkill->m_pSkill[i];
  if (pSkill)
   pSkill->ExcutePassive(PlayerSkill->m_pOwner, 0, 0);
 }
}

void __fastcall ExcutePassiveSkillV(CPlayerSkillEx *PlayerSkill, void*edx, int nSkill, ...){
 va_list va;
 va_start(va, nSkill);
 CSkillEx *pSkill = PlayerSkill->m_pSkill[nSkill];
 if (pSkill)
  pSkill->ExcutePassiveV(PlayerSkill->m_pOwner, va);
 va_end(va);
}

  
void __fastcall _CPlayerSkillEx::LearnSkill(CPlayerSkillEx *PlayerSkill, void* _edx, int nSkill){
 if (nSkill < MAX_SKILL_INDEX && !PlayerSkill->IsSkill(nSkill)){
  CSkillEx *pSkill = PlayerSkill->FindSkillEx(nSkill);
  if (pSkill != NULL){
   if (pSkill->CanLearn(PlayerSkill->m_pOwner->m_nLevel, PlayerSkill->m_pOwner->m_dwSpecialty)){
    if (PlayerSkill->IsLearnSkill(pSkill->m_nLmtSkill, pSkill->m_nLmtSkillLevel)){
     pSkill = _CSkillEx::Copy(pSkill);
     _CSkillEx::Init(pSkill, nSkill, 1);
     pSkill->ExcutePassive(PlayerSkill->m_pOwner, 0, 0);
     PlayerSkill->m_pSkill[nSkill] = pSkill;
     if (PlayerSkill->IsSpendSUPointSkill(nSkill))
      PlayerSkill->m_pOwner->vPlayer->UpdateProperty(PlayerSkill->m_pOwner, P_SUPOINT, FALSE, 1);
     PlayerSkill->m_pOwner->Write(S2C_SKILLUP, "bb", nSkill, 1);
     MainServer::_CDBSocket::Write(S2D_INSERTSKILL, "dbw", PlayerSkill->m_pOwner->m_nPID, nSkill, PlayerSkill->m_pOwner->m_nSUPoint);
    }
   }
  }
  else
   CLog::Write(RED, "CPlayerSkillEx::LearnSkill() Can't find Skill(Class:%d, Skill:%d)", PlayerSkill->m_nClass, nSkill);
 }
}

void __fastcall _CPlayerSkillEx::SkillUp(CPlayerSkillEx *PlayerSkill, void *edx, int nSkill){
 if (nSkill < MAX_SKILL_INDEX){
  CSkillEx *pSkill = PlayerSkill->m_pSkill[nSkill];
  if (pSkill != NULL){
   if (pSkill->CanSkillUp(PlayerSkill->m_pOwner)){
    int NewLevel = pSkill->m_nLevel + 1;
    pSkill->ExcutePassive(PlayerSkill->m_pOwner, NewLevel, TRUE);
    pSkill->m_nLevel = NewLevel;
    if (PlayerSkill->IsSpendSUPointSkill(nSkill))
     PlayerSkill->m_pOwner->vPlayer->UpdateProperty(PlayerSkill->m_pOwner, P_SUPOINT, FALSE, 1);
    PlayerSkill->m_pOwner->Write(S2C_SKILLUP, "bb", nSkill, NewLevel);
    MainServer::_CDBSocket::Write(S2D_SKILLUP, "dbbw", PlayerSkill->m_pOwner->m_nPID, nSkill, NewLevel, PlayerSkill->m_pOwner->m_nSUPoint);
   }
  }else
   CLog::Write(RED, "CPlayerSkillEx::SkillUp() Can't find Skill(Class:%d, Skill:%d)", PlayerSkill->m_nClass, nSkill);
 }
}

void __fastcall _CPlayerSkillEx::SetSkill(CPlayerSkillEx *PlayerSkill, void *_edx, int nSkill, int nLevel){
 if (nSkill > MAX_SKILL_INDEX)
  return;
 CSkillEx *pSkill = NULL;
 CSkillEx *pSkillCopy = NULL;
 if (PlayerSkill->m_nClass <= PC_ARCHER){
  pSkill = (CSkillEx *)PlayerSkill->FindSkill(nSkill);
  if (pSkill != NULL){
   pSkillCopy = _CSkillEx::Copy(pSkill);
   _CSkillEx::Init(pSkillCopy, nSkill, nLevel);
   PlayerSkill->m_pSkill[nSkill] = pSkillCopy;
   return;
  }
  else
   CLog::Write(RED, "CPlayerSkillEx::SetSkill() Can't find Skill(Class:%d, Skill:%d)", PlayerSkill->m_nClass, nSkill);
 }else//Thief or Shamman Skill Test
 {
  CSkillEx *pSkillEx = NULL;
  CSkillEx *pSkillCopyEx = NULL;
  pSkillEx = PlayerSkill->FindSkillEx(nSkill);
  if (pSkillEx != NULL){
   pSkillCopyEx = (CSkillEx *)CopyEx(pSkillEx);
   InitEx(pSkillCopyEx, nSkill, nLevel);
   PlayerSkill->m_pSkill[nSkill] = pSkillCopyEx;
   return;
  }
  else
   CLog::Write(RED, "CPlayerSkillEx::SetSkill() Can't find Skill(Class:%d, Skill:%d)", PlayerSkill->m_nClass, nSkill);
 }
}
any questions?
 
Junior Spellweaver
Joined
Dec 16, 2012
Messages
187
Reaction score
29
Brilliant, I've got it sorted out apparently all I was missing was the proper function to hook..
Well, one more issue is that I can't get to rewrite AllotEXP__Party in order to apply exp events or fixes for exp calculation
A code snippet or AllotEXP__Party rewritten would be highly appreciated,
As always, Thank you for practicing into pumping life in Kal section once more.
 
Skilled Illusionist
Joined
Mar 20, 2009
Messages
374
Reaction score
378
well, i have barely touched it but here is what i've got so far.

Code:
void __thiscall CParty::AllotExp(CParty *pParty, int *nAllExp, int nMonsterLevel, tagPOINT *ptPMonster)
{
  void *EndIt; // eax MAPDST
  char *Pair; // eax
  char v11; // [esp+3Ch] [ebp-68h]
  int a2; // [esp+40h] [ebp-64h]
  char v13; // [esp+48h] [ebp-5Ch]
  char v14; // [esp+50h] [ebp-54h]
  char v15; // [esp+54h] [ebp-50h]
  char v16; // [esp+58h] [ebp-4Ch]
  char v17; // [esp+5Ch] [ebp-48h]
  int nBonusExp; // [esp+60h] [ebp-44h]
  int beginit; // [esp+64h] [ebp-40h]
  char BeginIt; // [esp+6Ch] [ebp-38h] MAPDST
  int nCount; // [esp+70h] [ebp-34h]
  int nLevelDiff; // [esp+74h] [ebp-30h] MAPDST
  int nTopLevel; // [esp+78h] [ebp-2Ch]
  CChar *pPartyMember; // [esp+7Ch] [ebp-28h]
  int nLevelAdd; // [esp+80h] [ebp-24h]
  void *v27; // [esp+84h] [ebp-20h]
  int Exp; // [esp+94h] [ebp-10h]
  std::map varC; // [esp+98h] [ebp-Ch]




  CIOCriticalSection::Enter(&pParty->m_lock);
  nLevelDiff = nMonsterLevel - pParty->m_nTopLevel;
  if ( nLevelDiff < 0 )
  {
    if ( abs(nLevelDiff) >= 20 )
      nLevelDiff = 20;
    else
      nLevelDiff = abs(nLevelDiff);
    *nAllExp = (*nAllExp - *nAllExp * (g_nReviseExpB[(pParty->m_nTopLevel - 1) / 10][nLevelDiff] / 100.0));
  }
  else
  {
    if ( nLevelDiff >= 20 )
      nLevelDiff = 20;
    *nAllExp = (*nAllExp * (g_nReviseExpA[(pParty->m_nTopLevel - 1) / 10][nLevelDiff] / 100.0) + *nAllExp);
  }
  if ( *nAllExp > 0 )
  {
    sub_41C7D0(&v27);
    nLevelAdd = 0;
    nCount = 0;
    Container::Find(pParty->m_vecParty);
    while ( 1 )
    {
      EndIt = Container::End(pParty->m_vecParty, &v16);
      if ( !Container::iterator::not_equal(&BeginIt, EndIt) )
        break;
      pPartyMember = Container::GetObject(&BeginIt)->vfptr;
      if ( CChar::IsNormal(pPartyMember) && PowDistance(&pPartyMember->m_ptPixel, ptPMonster) <= 640 )
      {
        if ( pParty->m_nTopLevel - pPartyMember->m_nLevel <= 20 )
          ++nCount;
        nLevelAdd += pPartyMember->m_nLevel;
        sub_41C840(&v27, &pPartyMember);
      }
      sub_420030(&v17, 0);
    }
    if ( nCount > 1 )
      *nAllExp = (*nAllExp * ((nCount - 1) / 10.0) + *nAllExp);
    sub_445C80(&varC);
    nTopLevel = pParty->m_nTopLevel;
    Container::Find(&v27);
    while ( 1 )
    {
      EndIt = Container::End(&v27, &v14);
      if ( !Container::iterator::not_equal(&BeginIt, EndIt) )
        break;
      pPartyMember = Container::GetObject(&BeginIt)->vfptr;
      Exp = (*nAllExp * (pPartyMember->m_nLevel / nLevelAdd));
      nLevelDiff = nTopLevel - pPartyMember->m_nLevel;
      if ( nLevelDiff <= 28 )
      {
        if ( nLevelDiff > 0 )
          Exp = (Exp - Exp * (g_nRevisePartyExp[nLevelDiff] / 100.0));
      }
      else
      {
        Exp = 0;
      }
      if ( Exp )
      {
        CIOObject::AddRef(&pPartyMember->ParantClass.vfptr, &pPartyMember->m_nFindRef);
        Pair = PairStdMap(&v13, &pPartyMember, &Exp);
        STLMap_Insert(&varC, &a2, Pair);
      }
      sub_420030(&v15, 0);
    }
    CIOCriticalSection::Leave(&pParty->m_lock);
    *nAllExp = 0;
    std::map::begin(&varC, &beginit);
    while ( 1 )
    {
      EndIt = Container::Find(&varC);
      if ( !Container::iterator::not_equal(&beginit, EndIt) )
        break;
      pPartyMember = *std::map::iterator::value(&beginit);
      Exp = *(std::map::iterator::value(&beginit) + 4);
      *nAllExp += Exp;
      nBonusExp = (CMainConfig::s_nEvent & 1) != 0 ? 0x64 : 0;
      if ( CChar::IsBState(pPartyMember, 0x8000000000i64)
        || CChar::IsBState(pPartyMember, 0x10000000000i64)
        || CChar::IsBState(pPartyMember, 0x20000000000i64) )
      {
        nBonusExp += 10;
      }
      if ( CChar::IsBState(pPartyMember, 2i64) )
      {
        nBonusExp += 30;
      }
      else if ( CChar::IsBState(pPartyMember, 1i64) )
      {
        nBonusExp += 30;
      }
      pPartyMember->ParantClass.vfptr->UpdateProperty(pPartyMember, P_EXP, P_INCREASE, (Exp + nBonusExp * Exp / 100));
      CIOObject::_Release(&pPartyMember->ParantClass.vfptr, &pPartyMember->m_nFindRef);
      sub_446090(&beginit, &v11, 0);
    }
    sub_4398F0(&varC);
    sub_44F580(&v27);
  }
  else
  {
    CIOCriticalSection::Leave(&pParty->m_lock);
  }
}


Code:
int GetColorLevel(int nMonsterLevel, int nPlayerLevel){
 int nDiffLevel = (nMonsterLevel - nPlayerLevel);
 if (nDiffLevel < 0){
  if (abs(nDiffLevel) >= 20)
   nDiffLevel = 20;
  else
   nDiffLevel = abs(nDiffLevel);
  return g_nDLvB[(nPlayerLevel - 1) / 10][nDiffLevel];
 }else{
  if (nDiffLevel >= 20)
   nDiffLevel = 20;
  else
   nDiffLevel = nMonsterLevel - nPlayerLevel;
  return g_nDLvA[(nPlayerLevel - 1) / 10][nDiffLevel];
 }
 return 0;
}




void CMonsterReal::AllotTransformExp(int bParty, int nID){
 CPlayer *pPlayer;
 CParty *pParty;
 if (bParty){
  pParty = CParty::FindParty(nID);
  if (pParty){
   pParty->AllotTransformExp(this->m_nLevel, &this->m_ptPixel);
   pParty->Release();
  }
 }else{
  pPlayer = CPlayer::FindPlayer(nID);
  if (pPlayer){
   if (GetColorLevel(this->m_nLevel, pPlayer->m_nLevel) >= 3)
    pPlayer->UpdateTransformExp(0);
   pPlayer->Release(&pPlayer->m_nFindRef);
  }
 }
}




void CMonsterReal::Die(CChar *pChar, int bFatal, int *bParty, int *nKeyID){
 this->m_nCurHP = 0;
 pChar->InfoDie(this->m_nId, bFatal);
 int nBestID = 0;
 this->AllotExp(bParty, nKeyID, &nBestID);
 this->m_pInit->DropItem(this, *bParty, *nKeyID, nBestID, pChar->GetDropItemMask());
 this->CancelAllBuff();
 this->WriteInSight(S2C_ACTION, "db", this->m_nId, AT_DIE);
}
 
Last edited:
Junior Spellweaver
Joined
Dec 16, 2012
Messages
187
Reaction score
29
Where can I find/track passive skills?
Well, excuteskill can track these attackable skills.. but how about passive/buff skills that can be called on player's login for a boost or something, where does it get handled?
 
Skilled Illusionist
Joined
Mar 20, 2009
Messages
374
Reaction score
378
Code:
.text:0047FC00    ; public: void __thiscall CPlayerSkill::ExcutePassiveSkill(void)
.text:0047FC50;public: void __cdecl CPlayerSkill::ExcutePassiveSkill(int, ...)




void __thiscall CPlayerSkill::ExcutePassiveSkill(CPlayerSkill *this)
{
 CSkill *pSkill; // [esp+4h] [ebp-8h]
 int i; // [esp+8h] [ebp-4h]
 for (i = 0; i < 84; ++i)
 {
  pSkill = this->m_pSkill[i];
  if (pSkill)
   pSkill->vfptr->ExcutePassive(this->m_pOwner, 0, 0);
 }
}




void CPlayerSkill::ExcutePassiveSkill(CPlayerSkill *this, ...)
{
 CSkill *pSkill; // [esp+4h] [ebp-4h]
 int nSkill; // [esp+14h] [ebp+Ch]
 va_list vaList; // [esp+18h] [ebp+10h]
 va_start(vaList, this);
 nSkill = va_arg(vaList, _DWORD);
 pSkill = this->m_pSkill[nSkill];  if (pSkill)
  pSkill->vfptr->ExcutePassiveV(this->m_pOwner, vaList);
}
 
Junior Spellweaver
Joined
Dec 16, 2012
Messages
187
Reaction score
29
Thanks, talking about skills.. here are 2 useful functions i found (i think you already know them but i'll show them anyways)
Check if a player doesnt have a skill:
PHP:
static int(__thiscall *CPlayerSkill__IsSkill)( int thispointer, int a2) = (int(__thiscall*)(int thispointerpointer, int a2))0x0044A940;
if (!Server::CPlayer::CPlayerSkill__IsSkill(((int)PlayerPointer) + 624, SkillID))
----
Skill reading on player login (so incase you want to call off a skill while player is logging in):
PHP:
static void(__thiscall *SetSkill)(int Player, int SkillID, int a3) = (void(__thiscall*)(int Player, int SkillID, int a3))0x0047F6B0;
 
Last edited:
Junior Spellweaver
Joined
Dec 16, 2012
Messages
187
Reaction score
29
I need the following definitions for AllotEXP function
----------------------------
g_nReviseExpB
g_nReviseExpA
----------------------------
Thank you.
 
Back
Top