Today I bring you a bonus to spice up PK with multi-kill announcements and auxiliary functions to play sounds from Lua, by party, ChaID or global map
OK let's Start
Src/Libraries/common/include/NetCommnad.h add this:
Now we work on GS
Src/GameServer/src/SubMap.h add this:
Src/GameServer/src/SubMap.cpp add this:
Src/GameServer/src/Character.h add this:
Now search chatColour(0xFFFFFFFF), in Src/GameServer/Character.cpp and right below it adds
Src/Gameserver/src/Character.cpp add this:
Now we will explain the functions in Lua
Src/GameServer/src/Expand.h :
And records the functions:
Now let's start with the client
Src/Client/src/NetIF.cpp search CMD_MC_VOLUNTER_ASK and add this just below:
Src/Client/src/PacketCmd.h add this just before #endif
Src/Client/src/PacketCmd_SC.cpp add this
We're going to configure it on the server
scripts/calculate/function.lua search after_player_kill_player(ATKER, DEFER) and just below local DEFER_Get1_Ry = 0 add this
Now we're going to add sound to the client
music/sound/combat/ Add the sounds here, which I will attach for download
To finish let's just add the sounds to musicinfo.txt
The new features work as follows
PlaySoundCha(role, soundID)
- Plays a sound for a specific player only.
PlaySoundToParty(role, soundID)
- Plays a sound for all members of the player's party.
PlayMapSound(role, soundID)
- Plays a sound for all players within the current map. It can be the ID of the attacker or the victim, it is only used to obtain the map.
AddMultiKill(role)
- Returns the player's current PvP kill streak level.
Example Usage:
Besides alerts, a range of options now opens up with sound playback from Lua. Ejoy!
OK let's Start
Src/Libraries/common/include/NetCommnad.h add this:
C++:
#define CMD_MC_PLAYSOUND CMD_MC_BASE + 118
Now we work on GS
Src/GameServer/src/SubMap.h add this:
C++:
void PlaySoundMap(short sSoundID);
Src/GameServer/src/SubMap.cpp add this:
C++:
void SubMap::PlaySoundMap(short soundID)
{
WPACKET WtPk = GETWPACKET();
WRITE_CMD(WtPk, CMD_MC_PLAYSOUND);
WRITE_SHORT(WtPk, soundID);
CPlayer* pHeadPlayer = 0;
CPlayer* pLastPlayer = 0;
CEyeshotCell* pCEyeCell;
CCharacter* pCCha;
Long lChaCount, lChaNum;
m_CEyeshotCellL.BeginGet();
while (pCEyeCell = m_CEyeshotCellL.GetNext())
{
lChaCount = 0;
lChaNum = pCEyeCell->GetChaNum();
pCCha = pCEyeCell->m_pCChaL;
while (pCCha)
{
if (++lChaCount > lChaNum)
break;
if (pCCha->IsPlayerFocusCha())
{
if (!pHeadPlayer)
{
pHeadPlayer = pCCha->GetPlayer();
pLastPlayer = pHeadPlayer;
}
else
{
pLastPlayer->GetNextPlayer() =
pCCha->GetPlayer();
pLastPlayer =
(CPlayer*)pLastPlayer->GetNextPlayer();
}
}
if (pCCha->m_pCEyeshotCellNext)
pCCha =
pCCha->m_pCEyeshotCellNext->IsCharacter();
else
pCCha = 0;
}
}
if (pLastPlayer)
pLastPlayer->GetNextPlayer() = NULL;
SENDTOCLIENT(WtPk, pHeadPlayer);
}
Src/GameServer/src/Character.h add this:
C++:
int AddMultiKill();
int GetMultiKill();
DWORD m_dwLastPvPKill;
BYTE m_btMultiKill;
Now search chatColour(0xFFFFFFFF), in Src/GameServer/Character.cpp and right below it adds
C++:
m_dwLastPvPKill(0),
m_btMultiKill(0),
Src/Gameserver/src/Character.cpp add this:
C++:
int CCharacter::AddMultiKill()
{
DWORD now = GetTickCount();
DWORD window = 10000;
switch (m_btMultiKill)
{
case 1: window = 10000; break; // secs to Double
case 2: window = 10000; break; // secs to Triple
case 3: window = 10000; break; // secs to Quadra
case 4: window = 10000; break; // secs to Penta
}
if (now - m_dwLastPvPKill > window)
{
m_btMultiKill = 0;
m_dwLastPvPKill = 0;
}
m_btMultiKill++;
if (m_btMultiKill > 5)
m_btMultiKill = 5;
m_dwLastPvPKill = now;
return m_btMultiKill;
}
Now we will explain the functions in Lua
Src/GameServer/src/Expand.h :
C++:
inline int lua_PlaySoundCha(lua_State* L)
{
CCharacter* pCha =
(CCharacter*)lua_touserdata(L, 1);
short soundID =
(short)lua_tonumber(L, 2);
if (!pCha)
return 0;
WPACKET pk = GETWPACKET();
WRITE_CMD(pk, CMD_MC_PLAYSOUND);
WRITE_SHORT(pk, soundID);
pCha->ReflectINFof(pCha, pk);
return 0;
}
inline int lua_PlaySoundToParty(lua_State* L)
{
CCharacter* pCha =
(CCharacter*)lua_touserdata(L, 1);
short soundID =
(short)lua_tonumber(L, 2);
if (!pCha)
return 0;
CPlayer* cPly = pCha->GetPlayer();
if (!cPly || !cPly->HasTeam())
return 0;
WPACKET pk = GETWPACKET();
WRITE_CMD(pk, CMD_MC_PLAYSOUND);
WRITE_SHORT(pk, soundID);
pCha->ReflectINFof(pCha, pk);
int partyCnt = cPly->GetTeamMemberCnt();
for (int i = 0; i < partyCnt; i++)
{
CPlayer* pMember =
g_pGameApp->GetPlayerByDBID(
cPly->GetTeamMemberDBID(i)
);
if (!pMember)
continue;
CCharacter* pMemberCha =
pMember->GetCtrlCha();
if (!pMemberCha)
continue;
pMemberCha->ReflectINFof(
pMemberCha,
pk
);
}
return 0;
}
inline int lua_PlayMapSound(lua_State* L)
{
CCharacter* pCha =
(CCharacter*)lua_touserdata(L, 1);
short soundID =
(short)lua_tonumber(L, 2);
if (pCha && pCha->GetSubMap())
{
pCha->GetSubMap()->PlaySoundMap(soundID);
}
return 0;
}
inline int lua_AddMultiKill(lua_State* L)
{
CCharacter* pCha =
(CCharacter*)lua_touserdata(L, 1);
lua_pushnumber(
L,
pCha->AddMultiKill()
);
return 1;
}
And records the functions:
C++:
REGFN(PlaySoundCha);
REGFN(PlaySoundToParty);
REGFN(PlayMapSound);
REGFN(AddMultiKill);
Now let's start with the client
Src/Client/src/NetIF.cpp search CMD_MC_VOLUNTER_ASK and add this just below:
C++:
case CMD_MC_PLAYSOUND:
{
SC_ServerPlaySound(pk);
return TRUE;
}
Src/Client/src/PacketCmd.h add this just before #endif
C++:
extern void SC_ServerPlaySound(LPRPACKET pk);
Src/Client/src/PacketCmd_SC.cpp add this
C++:
void SC_ServerPlaySound(LPRPACKET pk)
{
short SoundID = pk.ReadShort();
g_pGameApp->PlaySound(SoundID);
}
We're going to configure it on the server
scripts/calculate/function.lua search after_player_kill_player(ATKER, DEFER) and just below local DEFER_Get1_Ry = 0 add this
C++:
local MultiKill = AddMultiKill(ATKER)
if MultiKill == 2 then
Notice("[DOUBLE KILL] "..GetChaDefaultName(ATKER).." has achieved a Double Kill!")
PlayMapSound(ATKER, 457)
elseif MultiKill == 3 then
Notice("[TRIPLE KILL] "..GetChaDefaultName(ATKER).." has achieved a Triple Kill!")
PlayMapSound(ATKER, 458)
elseif MultiKill == 4 then
Notice("[QUADRA KILL] "..GetChaDefaultName(ATKER).." has achieved a Quadra Kill!")
PlayMapSound(ATKER, 459)
elseif MultiKill == 5 then
Notice("[PENTA KILL] "..GetChaDefaultName(ATKER).." has achieved a P-P-P Penta Kill!")
PlayMapSound(ATKER, 460)
end
Now we're going to add sound to the client
music/sound/combat/ Add the sounds here, which I will attach for download
To finish let's just add the sounds to musicinfo.txt
Code:
457 music/sound/combat/doublek.wav 1
458 music/sound/combat/triplek.wav 1
459 music/sound/combat/quadrak.wav 1
460 music/sound/combat/pentak.wav 1
461 music/sound/combat/sysnoti.wav 1
The new features work as follows
PlaySoundCha(role, soundID)
- Plays a sound for a specific player only.
PlaySoundToParty(role, soundID)
- Plays a sound for all members of the player's party.
PlayMapSound(role, soundID)
- Plays a sound for all players within the current map. It can be the ID of the attacker or the victim, it is only used to obtain the map.
AddMultiKill(role)
- Returns the player's current PvP kill streak level.
Example Usage:
C++:
local MultiKill = AddMultiKill(ATKER)
if MultiKill == 2 then
Notice(GetChaDefaultName(ATKER).." achieved DOUBLE KILL!")
PlayMapSound(ATKER, 457)
elseif MultiKill == 3 then
Notice(GetChaDefaultName(ATKER).." achieved TRIPLE KILL!")
PlayMapSound(ATKER, 458)
elseif MultiKill == 4 then
Notice(GetChaDefaultName(ATKER).." achieved QUADRA KILL!")
PlayMapSound(ATKER, 459)
elseif MultiKill == 5 then
Notice(GetChaDefaultName(ATKER).." achieved PENTA KILL!")
PlayMapSound(ATKER, 460)
end
Besides alerts, a range of options now opens up with sound playback from Lua. Ejoy!