📄 playerfunctions.cpp.svn-base
字号:
/*
Rose Online Server Emulator
Copyright (C) 2006,2007 OSRose Team http://www.osrose.net
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
depeloped with Main erose/hrose source server + some change from the original eich source
*/
#include "player.h"
#include "worldserver.h"
// Returns the amount of exp that is needed for the next level
UINT CPlayer::GetLevelEXP( )
{
if (Stats->Level <= 15) return (unsigned int)( ( Stats->Level + 10 ) * ( Stats->Level + 5 ) * ( Stats->Level + 3 ) * 0.7 );
else if (Stats->Level <= 50) return (unsigned int)( ( Stats->Level - 5 ) * ( Stats->Level + 2 ) * ( Stats->Level + 2 ) * 2.2 );
else if (Stats->Level <= 100) return (unsigned int)( ( Stats->Level - 38 ) * ( Stats->Level - 5 ) * ( Stats->Level + 2 ) * 9 );
else if (Stats->Level <= 139) return (unsigned int)( ( Stats->Level + 220 ) * ( Stats->Level + 34 ) * ( Stats->Level + 27 ) );
else return (unsigned int)( ( Stats->Level - 126 ) * ( Stats->Level - 15 ) * ( Stats->Level + 7 ) * 41 );
}
// check if player can level up
bool CPlayer::CheckPlayerLevelUP( )
{
if (CharInfo->Exp >= GetLevelEXP())
{
CharInfo->Exp -= GetLevelEXP();
Stats->Level++;
Stats->HP = GetMaxHP( );
Stats->MP = GetMaxHP( );
CharInfo->StatPoints += 10 + (Stats->Level/2);
if(Stats->Level>=10)
CharInfo->SkillPoints += 1;
BEGINPACKET( pak, 0x79e );
ADDWORD( pak, clientid );
ADDWORD( pak, Stats->Level );
ADDDWORD( pak, CharInfo->Exp );
ADDWORD( pak, CharInfo->StatPoints );
ADDWORD( pak, CharInfo->SkillPoints );
client->SendPacket( &pak );
RESETPACKET( pak, 0x79e );
ADDWORD( pak, clientid );
GServer->SendToVisible( &pak, this );
SetStats( );
//SendLevelUPtoChar(this);
}
return true;
}
// Send a PM to client with user information
bool CPlayer::GetPlayerInfo( )
{
char text[50];
sprintf(text,"Attack: %i | Critical: %i",Stats->Attack_Power, Stats->Critical );
BEGINPACKET( pak, 0x0784 );
ADDSTRING( pak, "[GM]PlayerInfo" );
ADDBYTE( pak, 0 );
ADDSTRING( pak, text );
ADDBYTE( pak, 0 );
client->SendPacket(&pak);
sprintf(text,"Defense: %i | Magic Defense: %i",Stats->Defense, Stats->Magic_Defense);
RESETPACKET( pak, 0x0784 );
ADDSTRING( pak, "[GM]PlayerInfo" );
ADDBYTE( pak, 0 );
ADDSTRING( pak, text );
ADDBYTE( pak, 0 );
client->SendPacket(&pak);
sprintf(text,"Accury: %i | Dodge: %i",Stats->Accury,Stats->Dodge );
RESETPACKET( pak, 0x0784 );
ADDSTRING( pak, "[GM]PlayerInfo" );
ADDBYTE( pak, 0 );
ADDSTRING( pak, text );
ADDBYTE( pak, 0 );
client->SendPacket(&pak);
sprintf(text,"aspeed: %i | mspeed: %i",Stats->Attack_Speed,Stats->Move_Speed );
RESETPACKET( pak, 0x0784 );
ADDSTRING( pak, "[GM]PlayerInfo" );
ADDBYTE( pak, 0 );
ADDSTRING( pak, text );
ADDBYTE( pak, 0 );
client->SendPacket(&pak);
sprintf(text,"HP: %i/%i , MP: %i/%i",Stats->HP,Stats->MaxHP,Stats->MP,Stats->MaxMP);
RESETPACKET( pak, 0x0784 );
ADDSTRING( pak, "[GM]PlayerInfo" );
ADDBYTE( pak, 0 );
ADDSTRING( pak, text );
ADDBYTE( pak, 0 );
client->SendPacket(&pak);
sprintf(text,"Position[%i]: (%.0f,%.0f)",Position->Map,Position->current.x,Position->current.y);
RESETPACKET( pak, 0x0784 );
ADDSTRING( pak, "[GM]PlayerInfo" );
ADDBYTE( pak, 0 );
ADDSTRING( pak, text );
ADDBYTE( pak, 0 );
client->SendPacket(&pak);
sprintf(text,"ClientID: %u | CharID: %u", clientid, CharInfo->charid );
RESETPACKET( pak, 0x0784 );
ADDSTRING( pak, "[GM]PlayerInfo" );
ADDBYTE( pak, 0 );
ADDSTRING( pak, text );
ADDBYTE( pak, 0 );
client->SendPacket(&pak);
sprintf(text,"inGame: %i | Logged: %i", Session->inGame, Session->isLoggedIn );
RESETPACKET( pak, 0x0784 );
ADDSTRING( pak, "[GM]PlayerInfo" );
ADDBYTE( pak, 0 );
ADDSTRING( pak, text );
ADDBYTE( pak, 0 );
client->SendPacket(&pak);
sprintf(text,"ClanName[%u]: %s | ClanGrade: %i | ClanRank: %i", Clan->clanid, Clan->clanname, Clan->grade, Clan->clanrank );
RESETPACKET( pak, 0x0784 );
ADDSTRING( pak, "[GM]PlayerInfo" );
ADDBYTE( pak, 0 );
ADDSTRING( pak, text );
ADDBYTE( pak, 0 );
client->SendPacket(&pak);
return true;
}
// clearn player lists
bool CPlayer::CleanPlayerVector( )
{
CMap* map = GServer->MapList.Index[Position->Map];
VisiblePlayers.clear();
VisibleMonsters.clear();
VisibleDrops.clear();
VisibleNPCs.clear();
return true;
}
//LMA BEGIN
//20070621-211100/outdated?
//we clear and "regenerate" a monster...
bool CPlayer::ForceRefreshMonster(bool refresh_all, UINT monster_id)
{
CMap* map = GServer->MapList.Index[Position->Map];
// Monsters
for(UINT i=0;i<map->MonsterList.size();i++)
{
CMonster* thismon = map->MonsterList.at( i );
if (thismon==NULL)
{
return false;
}
if (!refresh_all && (thismon->clientid!=monster_id))
{
continue;
}
//here we are only interested to respawn guys who kick our ass being invisible :)
float distance = GServer->distance ( this->Position->current, thismon->Position->current );
if ( GServer->IsVisible( this, thismon ) )
{
if (distance < MAXVISUALRANGE )
{
//we clear it
ClearObject( thismon->clientid );
//and respawn it
thismon->SpawnMonster(this, thismon );
//the visibility list will be updated in time automatically.
//if the monster kicks you, it's because it's already too near ;)
if (!refresh_all)
{
return true;
}
}
}
}
return true;
}
//LMA END
// update visibility list
bool CPlayer::VisiblityList( )
{
std::vector<CPlayer*> newVisiblePlayers;
std::vector<CDrop*> newVisibleDrops;
//LMATEST
//std::vector<CMonster*> newVisibleMonsters;
std::vector<unsigned int> newVisibleMonsters;
std::vector<CNPC*> newVisibleNPCs;
// Clients
CMap* map = GServer->MapList.Index[Position->Map];
for(UINT i=0;i<map->PlayerList.size();i++)
{
CPlayer* otherclient = map->PlayerList.at(i);
if ( this==otherclient || !otherclient->Session->inGame)
{
continue;
}
float distance = GServer->distance( this->Position->current, otherclient->Position->current );
if ( GServer->IsVisible( this, otherclient ) )
{
if ( distance < MAXVISUALRANGE && !otherclient->isInvisibleMode )
{
newVisiblePlayers.push_back( otherclient );
}
else
{
ClearObject( otherclient->clientid );
}
}
else
{
if ( distance < MINVISUALRANGE && !otherclient->isInvisibleMode )
{
newVisiblePlayers.push_back( otherclient );
otherclient->SpawnToPlayer(this, otherclient);
}
}
}
// Monsters
for(UINT i=0;i<map->MonsterList.size();i++)
{
CMonster* thismon = map->MonsterList.at( i );
float distance = GServer->distance ( this->Position->current, thismon->Position->current );
if ( GServer->IsVisible( this, thismon ) )
{
if (distance < MAXVISUALRANGE )
{
//LMATEST
//newVisibleMonsters.push_back( thismon );
newVisibleMonsters.push_back( thismon->clientid );
}
else
{
ClearObject( thismon->clientid );
}
}
else
{
if ( distance< MINVISUALRANGE )
{
//LMATEST
//newVisibleMonsters.push_back( thismon );
newVisibleMonsters.push_back( thismon->clientid );
thismon->SpawnMonster(this, thismon );
}
}
}
// Drops
for(unsigned i=0; i<map->DropsList.size(); i++)
{
CDrop* thisdrop = map->DropsList.at(i);
float distance = GServer->distance( this->Position->current, thisdrop->pos );
if ( GServer->IsVisible( this, thisdrop ) )
{
if ( distance< MAXVISUALRANGE )
{
newVisibleDrops.push_back( thisdrop );
}
else
{
this->ClearObject( thisdrop->clientid );
}
}
else
{
if ( distance < MINVISUALRANGE )
{
newVisibleDrops.push_back( thisdrop );
GServer->pakSpawnDrop( this, thisdrop );
}
}
}
// Npcs
for(unsigned i=0; i<map->NPCList.size(); i++)
{
CNPC* thisnpc = map->NPCList.at(i);
float distance = GServer->distance( this->Position->current, thisnpc->pos );
if ( GServer->IsVisible( this, thisnpc ) )
{
if ( distance < MAXVISUALRANGE )
{
newVisibleNPCs.push_back( thisnpc );
}
else
{
this->ClearObject( thisnpc->clientid );
}
}
else
{
if ( distance < MINVISUALRANGE )
{
newVisibleNPCs.push_back( thisnpc );
GServer->pakSpawnNPC( this, thisnpc );
}
}
}
VisiblePlayers.clear();
VisibleDrops.clear();
VisibleMonsters.clear();
VisibleNPCs.clear();
VisiblePlayers = newVisiblePlayers;
VisibleDrops = newVisibleDrops;
VisibleMonsters = newVisibleMonsters;
VisibleNPCs = newVisibleNPCs;
return true;
}
// Returns a free slot in the inventory (0xffff if is full)
UINT CPlayer::GetNewItemSlot( CItem thisitem )
{
UINT tabsize = 30;
UINT itemtab = 0;
switch(thisitem.itemtype)
{
case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9://equip
itemtab=0;
break;
case 10://consumibles
itemtab=1;
break;
case 11:case 12://etc
itemtab=2;
break;
case 14://pat
itemtab=3;
break;
default:
Log(MSG_WARNING,"unknown itemtype %i", thisitem.itemtype);
return 0xffff;
break;
}
for(int i=0;i<30;i++)
{
UINT slot=12;
slot += (tabsize*itemtab)+i;
switch(itemtab)
{
case 0:case 3://equip and pat
{
if(items[slot].itemnum==0 && items[slot].count<1)
return slot;
}
break;
case 1:case 2://consumible and etc
{
if((items[slot].itemnum == thisitem.itemnum && items[slot].count<999)
||(items[slot].itemnum==0 && items[slot].count<1))
return slot;
}
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -