diff options
| -rw-r--r-- | reference/game.c | 1316 | ||||
| -rw-r--r-- | src/common.hh | 2 | ||||
| -rw-r--r-- | src/connection.hh | 2 | ||||
| -rw-r--r-- | src/cr.hh | 65 | ||||
| -rw-r--r-- | src/crmain.cc | 19 | ||||
| -rw-r--r-- | src/crplayer.cc | 363 | ||||
| -rw-r--r-- | src/operate.cc | 1 | ||||
| -rw-r--r-- | src/stubs.hh | 14 | ||||
| -rw-r--r-- | src/time.cc | 8 |
9 files changed, 435 insertions, 1355 deletions
diff --git a/reference/game.c b/reference/game.c index 2b04018..a3130b1 100644 --- a/reference/game.c +++ b/reference/game.c @@ -18382,1322 +18382,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority return;
}
-// DWARF original prototype: void TPlayer(TPlayer * this, TConnection * Connection, ulong
-// CharacterID)
-
-void __thiscall TPlayer::TPlayer(TPlayer *this,TConnection *Connection,ulong CharacterID)
-
-{
- char *__dest;
- TSkill **ppTVar1;
- TSkill *pTVar2;
- anon_union_4_2_730cd3ca_for_TOutfit_2 aVar3;
- bool bVar4;
- byte bVar5;
- ushort HouseID;
- int i;
- Object *pOVar6;
- uint uVar7;
- TPlayerData *pTVar8;
- char *__src;
- time_t tVar9;
- TPlayer **ppTVar10;
- int iVar11;
- TCreature *pTVar12;
- tm *__tp;
- int iVar13;
- ulong id;
- int i_1;
- uchar *puVar14;
- int *piVar15;
- char local_ac [4];
- char TimeString [100];
- Object local_3c [4];
- ulong local_2c;
-
- TCreature::TCreature(&this->super_TCreature);
- pOVar6 = this->OpenContainer;
- (this->Depot).ObjectID = 0;
- (this->TradeObject).ObjectID = 0;
- iVar13 = 0xf;
- (this->super_TCreature)._vptr_TCreature = (_func_int_varargs **)&PTR__TPlayer_08127c68;
- do {
- pOVar6->ObjectID = 0;
- iVar13 = iVar13 + -1;
- pOVar6 = pOVar6 + 1;
- } while (iVar13 != -1);
- // try { // try from 080a9026 to 080a902a has its CatchHandler @ 080a9a43
- vector<>::vector(&this->AttackedPlayers,0,10,10);
- // try { // try from 080a9052 to 080a9056 has its CatchHandler @ 080a9a3f
- vector<>::vector(&this->FormerAttackedPlayers,0,10,10);
- (this->super_TCreature).Profession = '\0';
- this->ConstructError = NOERROR;
- (this->super_TCreature).Type = PLAYER;
- (this->Depot).ObjectID = ::NONE.ObjectID;
- local_3c[0] = ::NONE;
- local_2c = ::NONE.ObjectID;
- (this->TradeObject).ObjectID = ::NONE.ObjectID;
- this->OldState = 0;
- this->OpenContainer[0].ObjectID = 0;
- this->OpenContainer[2].ObjectID = 0;
- this->OpenContainer[4].ObjectID = 0;
- this->OpenContainer[1].ObjectID = 0;
- this->OpenContainer[5].ObjectID = 0;
- this->OpenContainer[7].ObjectID = 0;
- this->OpenContainer[6].ObjectID = 0;
- this->OpenContainer[8].ObjectID = 0;
- this->OpenContainer[10].ObjectID = 0;
- this->OpenContainer[3].ObjectID = 0;
- this->OpenContainer[9].ObjectID = 0;
- this->OpenContainer[0xb].ObjectID = 0;
- this->OpenContainer[0xe].ObjectID = 0;
- this->OpenContainer[0xc].ObjectID = 0;
- this->OpenContainer[0xd].ObjectID = 0;
- this->OpenContainer[0xf].ObjectID = 0;
- puVar14 = this->SpellList;
- for (iVar13 = 0x40; iVar13 != 0; iVar13 = iVar13 + -1) {
- puVar14[0] = '\0';
- puVar14[1] = '\0';
- puVar14[2] = '\0';
- puVar14[3] = '\0';
- puVar14 = puVar14 + 4;
- }
- uVar7 = 2000;
- piVar15 = this->QuestValues;
- if (((uint)piVar15 & 4) != 0) {
- uVar7 = 0x7cc;
- this->QuestValues[0] = 0;
- piVar15 = this->QuestValues + 1;
- }
- for (uVar7 = uVar7 >> 2; uVar7 != 0; uVar7 = uVar7 - 1) {
- *piVar15 = 0;
- piVar15 = piVar15 + 1;
- }
- this->Request = 0;
- this->RequestTimestamp = 0;
- this->RequestProcessingGamemaster = 0;
- this->TutorActivities = 0;
- this->NumberOfAttackedPlayers = 0;
- this->NumberOfFormerAttackedPlayers = 0;
- this->PartyLeader = 0;
- (this->super_TCreature).LoseInventory = 1;
- iVar13 = 0;
- this->Guild[0] = '\0';
- this->Rank[0] = '\0';
- this->Title[0] = '\0';
- this->Aggressor = false;
- this->FormerAggressor = false;
- this->TalkBufferFullTime = 0;
- this->MutingEndRound = 0;
- this->NumberOfMutings = 0;
- do {
- this->Addressees[iVar13] = 0;
- iVar13 = iVar13 + 1;
- } while (iVar13 < 0x14);
- // try { // try from 080a91fa to 080a9232 has its CatchHandler @ 080a9a3b
- pTVar8 = AttachPlayerPoolSlot(CharacterID,false);
- this->PlayerData = pTVar8;
- if (pTVar8 == (TPlayerData *)0x0) {
- error("TPlayer::TPlayer: PlayerData-Slot nicht gefunden.\n");
- this->ConstructError = ERROR;
- }
- else {
- SendMails(pTVar8);
- pTVar8 = this->PlayerData;
- __dest = (this->super_TCreature).Name;
- (this->super_TCreature).Connection = Connection;
- strcpy(__dest,pTVar8->Name);
- // try { // try from 080a9266 to 080a99d8 has its CatchHandler @ 080a99f0
- TCreature::SetID(&this->super_TCreature,CharacterID);
- InsertPlayerIndex(&PlayerIndexHead,0,__dest,CharacterID);
- LoadData(this);
- this->AccountID = this->PlayerData->AccountID;
- __src = TConnection::GetIPAddress(Connection);
- strcpy(this->IPAddress,__src);
- pTVar8 = this->PlayerData;
- *(undefined4 *)this->Rights = *(undefined4 *)pTVar8->Rights;
- *(undefined4 *)(this->Rights + 4) = *(undefined4 *)(pTVar8->Rights + 4);
- *(undefined4 *)(this->Rights + 8) = *(undefined4 *)(pTVar8->Rights + 8);
- bVar4 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (bVar4) {
- Log("game","Spieler besitzt Premium Account.\n");
- }
- pTVar8 = this->PlayerData;
- (this->super_TCreature).Sex = pTVar8->Sex;
- strcpy(this->Guild,pTVar8->Guild);
- strcpy(this->Rank,this->PlayerData->Rank);
- strcpy(this->Title,this->PlayerData->Title);
- pTVar8 = this->PlayerData;
- this->Request = 0;
- this->RequestTimestamp = 0;
- this->RequestProcessingGamemaster = 0;
- tVar9 = time((time_t *)0x0);
- if (pTVar8->PlayerkillerEnd < tVar9) {
- this->PlayerData->PlayerkillerEnd = 0;
- }
- CheckOutfit(this);
- TCreature::SetInCrList(&this->super_TCreature);
- Semaphore::down(&PlayerMutex);
- ppTVar10 = vector<TPlayer*>::operator()(&PlayerList,FirstFreePlayer);
- FirstFreePlayer = FirstFreePlayer + 1;
- *ppTVar10 = this;
- Semaphore::up(&PlayerMutex);
- iVar13 = 1;
- NotifyBuddies((this->super_TCreature).ID,__dest,true);
- IncrementPlayersOnline();
- if ((this->super_TCreature).Profession == '\0') {
- IncrementNewbiesOnline();
- }
- pTVar2 = (this->super_TCreature).super_TSkillBase.Skills[0x16];
- bVar4 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (bVar4) {
- bVar4 = 9 < (this->super_TCreature).Profession;
- }
- else {
- bVar4 = false;
- }
- iVar11 = 200;
- if (!bVar4) {
- iVar11 = 100;
- }
- pTVar2->Max = iVar11;
- TSkill::Check((this->super_TCreature).super_TSkillBase.Skills[0x16]);
- pTVar2 = (this->super_TCreature).super_TSkillBase.Skills[0x16];
- iVar11 = (*pTVar2->_vptr_TSkill[0xd])(pTVar2);
- if (0xe < iVar11) {
- bVar4 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (bVar4) {
- bVar4 = 9 < (this->super_TCreature).Profession;
- }
- else {
- bVar4 = false;
- }
- iVar13 = 0xf;
- if (!bVar4) {
- iVar13 = 0x78;
- }
- CharacterID = (iVar11 + -1) % iVar13 + 1;
- iVar13 = (iVar11 + -1) / iVar13 + 1;
- TSkillBase::SetTimer(&(this->super_TCreature).super_TSkillBase);
- }
- pTVar2 = (this->super_TCreature).super_TSkillBase.Skills[2];
- iVar11 = TSkill::Get(pTVar2);
- if (iVar11 < 1) {
- (*pTVar2->_vptr_TSkill[2])(pTVar2,pTVar2->Max,iVar13,CharacterID);
- iVar13 = 0;
- (this->super_TCreature).posx = (this->super_TCreature).startx;
- (this->super_TCreature).posy = (this->super_TCreature).starty;
- (this->super_TCreature).posz = (this->super_TCreature).startz;
- do {
- TSkillBase::DelTimer(&(this->super_TCreature).super_TSkillBase,(ushort)iVar13);
- TSkill::SetMDAct((this->super_TCreature).super_TSkillBase.Skills[iVar13],0);
- ppTVar1 = (this->super_TCreature).super_TSkillBase.Skills + iVar13;
- iVar13 = iVar13 + 1;
- (*ppTVar1)->DAct = 0;
- } while (iVar13 < 0x19);
- aVar3 = (this->super_TCreature).OrgOutfit.field_1;
- (this->super_TCreature).Outfit.OutfitID = (this->super_TCreature).OrgOutfit.OutfitID;
- pTVar2 = (this->super_TCreature).super_TSkillBase.Skills[3];
- (this->super_TCreature).Outfit.field_1 = aVar3;
- (*pTVar2->_vptr_TSkill[2])
- ((this->super_TCreature).super_TSkillBase.Skills[3],pTVar2->Max);
- }
- if (this->PlayerData->LastLoginTime == 0) {
- bVar4 = CheckRight((this->super_TCreature).ID,GAMEMASTER_OUTFIT);
- if (bVar4) {
- Log("game","Gamemaster-Charakter %s loggt zum ersten Mal ein -> Level 2 setzen.\n",
- __dest);
- (this->super_TCreature).super_TSkillBase.Skills[0]->Act = 2;
- (this->super_TCreature).super_TSkillBase.Skills[0]->Exp = 100;
- (this->super_TCreature).super_TSkillBase.Skills[0]->LastLevel = 100;
- (this->super_TCreature).super_TSkillBase.Skills[0]->NextLevel = 200;
- }
- }
- bVar4 = CoordinateFlag();
- if (bVar4) {
- Regenerate(this);
- }
- HouseID = GetHouseID((this->super_TCreature).posx,(this->super_TCreature).posy,
- (this->super_TCreature).posz);
- if (HouseID != 0) {
- bVar4 = IsInvited(HouseID,this,this->PlayerData->LastLogoutTime);
- if (!bVar4) {
- bVar4 = CheckRight((this->super_TCreature).ID,ENTER_HOUSES);
- if (!bVar4) {
- GetExitPosition(HouseID,&(this->super_TCreature).posx,
- &(this->super_TCreature).posy,&(this->super_TCreature).posz);
- }
- }
- }
- bVar4 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (!bVar4) {
- bVar4 = IsPremiumArea((this->super_TCreature).startx,(this->super_TCreature).starty,
- (this->super_TCreature).startz);
- if (bVar4) {
- Log("game",&DAT_08103880,__dest);
- bVar5 = (this->super_TCreature).Profession;
- if (9 < bVar5) {
- bVar5 = bVar5 - 10;
- }
- GetStartPosition(&(this->super_TCreature).startx,&(this->super_TCreature).starty,
- &(this->super_TCreature).startz,bVar5 == 0);
- }
- bVar4 = IsPremiumArea((this->super_TCreature).posx,(this->super_TCreature).posy,
- (this->super_TCreature).posz);
- if (bVar4) {
- Log("game",
- "Spieler %s wird aus PayArea geworfen und in seine Heimatstadt gesetzt.\n",
- __dest);
- (this->super_TCreature).posx = (this->super_TCreature).startx;
- (this->super_TCreature).posy = (this->super_TCreature).starty;
- (this->super_TCreature).posz = (this->super_TCreature).startz;
- }
- }
- TCreature::SetOnMap(&this->super_TCreature);
- TConnection::EnterGame(Connection);
- SendInitGame((TConnection *)(this->super_TCreature).ID,id);
- SendRights((this->super_TCreature).Connection);
- SendFullScreen((this->super_TCreature).Connection);
- local_3c[0].ObjectID = (this->super_TCreature).CrObject.ObjectID;
- GraphicalEffect(local_3c,0xb);
- LoadInventory(this,this->PlayerData->LastLoginTime == 0);
- TCreature::NotifyChangeInventory(&this->super_TCreature);
- SendAmbiente((this->super_TCreature).Connection);
- pTVar12 = GetCreature((this->super_TCreature).ID);
- if (pTVar12 == (TCreature *)0x0) {
- error("TPlayer::TPlayer: Kreatur nicht korrekt angelegt.\n");
- }
- else {
- AnnounceChangedCreature((this->super_TCreature).ID,2);
- }
- SendPlayerSkills((this->super_TCreature).Connection);
- this->OldState = 0;
- CheckState(this);
- if (this->PlayerData->LastLoginTime == 0) {
- bVar4 = CheckRight((this->super_TCreature).ID,GAMEMASTER_OUTFIT);
- if (!bVar4) {
- Log("game","Spieler %s loggt zum ersten Mal ein -> Outfitwahl.\n",__dest);
- SendMessage((this->super_TCreature).Connection,0x14,
- "Welcome to Tibia! Please choose your outfit.");
- SendOutfit((this->super_TCreature).Connection);
- }
- }
- SendBuddies(this);
- pTVar8 = this->PlayerData;
- if (pTVar8->LastLoginTime != 0) {
- __tp = localtime(&pTVar8->LastLoginTime);
- strftime(local_ac,100,"%d. %b %Y %X %Z",__tp);
- SendMessage((this->super_TCreature).Connection,0x14,"Your last visit in Tibia: %s.",
- local_ac);
- pTVar8 = this->PlayerData;
- }
- tVar9 = time((time_t *)0x0);
- pTVar8->LastLoginTime = tVar9;
- }
- return;
-}
-
-
-
-// DWARF original prototype: void TPlayer(TPlayer * this, TConnection * Connection, ulong
-// CharacterID)
-
-void __thiscall TPlayer::TPlayer(TPlayer *this,TConnection *Connection,ulong CharacterID)
-
-{
- char *__dest;
- TSkill **ppTVar1;
- TSkill *pTVar2;
- anon_union_4_2_730cd3ca_for_TOutfit_2 aVar3;
- bool bVar4;
- byte bVar5;
- ushort HouseID;
- int i;
- Object *pOVar6;
- uint uVar7;
- TPlayerData *pTVar8;
- char *__src;
- time_t tVar9;
- TPlayer **ppTVar10;
- int iVar11;
- TCreature *pTVar12;
- tm *__tp;
- int iVar13;
- ulong id;
- int i_1;
- uchar *puVar14;
- int *piVar15;
- char local_ac [4];
- char TimeString [100];
- Object local_3c [4];
- ulong local_2c;
-
- TCreature::TCreature(&this->super_TCreature);
- pOVar6 = this->OpenContainer;
- (this->Depot).ObjectID = 0;
- (this->TradeObject).ObjectID = 0;
- iVar13 = 0xf;
- (this->super_TCreature)._vptr_TCreature = (_func_int_varargs **)&PTR__TPlayer_08127c68;
- do {
- pOVar6->ObjectID = 0;
- iVar13 = iVar13 + -1;
- pOVar6 = pOVar6 + 1;
- } while (iVar13 != -1);
- // try { // try from 080a9ad6 to 080a9ada has its CatchHandler @ 080aa4f3
- vector<>::vector(&this->AttackedPlayers,0,10,10);
- // try { // try from 080a9b02 to 080a9b06 has its CatchHandler @ 080aa4ef
- vector<>::vector(&this->FormerAttackedPlayers,0,10,10);
- (this->super_TCreature).Profession = '\0';
- this->ConstructError = NOERROR;
- (this->super_TCreature).Type = PLAYER;
- (this->Depot).ObjectID = ::NONE.ObjectID;
- local_3c[0] = ::NONE;
- local_2c = ::NONE.ObjectID;
- (this->TradeObject).ObjectID = ::NONE.ObjectID;
- this->OpenContainer[0].ObjectID = 0;
- this->OldState = 0;
- this->OpenContainer[3].ObjectID = 0;
- this->OpenContainer[4].ObjectID = 0;
- this->OpenContainer[2].ObjectID = 0;
- this->OpenContainer[6].ObjectID = 0;
- this->OpenContainer[7].ObjectID = 0;
- this->OpenContainer[5].ObjectID = 0;
- this->OpenContainer[9].ObjectID = 0;
- this->OpenContainer[0xb].ObjectID = 0;
- this->OpenContainer[1].ObjectID = 0;
- this->OpenContainer[8].ObjectID = 0;
- this->OpenContainer[0xc].ObjectID = 0;
- this->OpenContainer[0xe].ObjectID = 0;
- this->OpenContainer[10].ObjectID = 0;
- this->OpenContainer[0xd].ObjectID = 0;
- this->OpenContainer[0xf].ObjectID = 0;
- puVar14 = this->SpellList;
- for (iVar13 = 0x40; iVar13 != 0; iVar13 = iVar13 + -1) {
- puVar14[0] = '\0';
- puVar14[1] = '\0';
- puVar14[2] = '\0';
- puVar14[3] = '\0';
- puVar14 = puVar14 + 4;
- }
- uVar7 = 2000;
- piVar15 = this->QuestValues;
- if (((uint)piVar15 & 4) != 0) {
- piVar15 = this->QuestValues + 1;
- uVar7 = 0x7cc;
- this->QuestValues[0] = 0;
- }
- for (uVar7 = uVar7 >> 2; uVar7 != 0; uVar7 = uVar7 - 1) {
- *piVar15 = 0;
- piVar15 = piVar15 + 1;
- }
- this->Request = 0;
- this->RequestTimestamp = 0;
- this->RequestProcessingGamemaster = 0;
- this->TutorActivities = 0;
- (this->super_TCreature).LoseInventory = 1;
- this->NumberOfAttackedPlayers = 0;
- this->NumberOfFormerAttackedPlayers = 0;
- this->NumberOfMutings = 0;
- iVar13 = 0;
- this->Guild[0] = '\0';
- this->Rank[0] = '\0';
- this->Title[0] = '\0';
- this->Aggressor = false;
- this->FormerAggressor = false;
- this->PartyLeader = 0;
- this->TalkBufferFullTime = 0;
- this->MutingEndRound = 0;
- do {
- this->Addressees[iVar13] = 0;
- iVar13 = iVar13 + 1;
- } while (iVar13 < 0x14);
- // try { // try from 080a9caa to 080a9ce2 has its CatchHandler @ 080aa4eb
- pTVar8 = AttachPlayerPoolSlot(CharacterID,false);
- this->PlayerData = pTVar8;
- if (pTVar8 == (TPlayerData *)0x0) {
- error("TPlayer::TPlayer: PlayerData-Slot nicht gefunden.\n");
- this->ConstructError = ERROR;
- }
- else {
- SendMails(pTVar8);
- pTVar8 = this->PlayerData;
- (this->super_TCreature).Connection = Connection;
- __dest = (this->super_TCreature).Name;
- strcpy(__dest,pTVar8->Name);
- // try { // try from 080a9d16 to 080aa488 has its CatchHandler @ 080aa4a0
- TCreature::SetID(&this->super_TCreature,CharacterID);
- InsertPlayerIndex(&PlayerIndexHead,0,__dest,CharacterID);
- LoadData(this);
- this->AccountID = this->PlayerData->AccountID;
- __src = TConnection::GetIPAddress(Connection);
- strcpy(this->IPAddress,__src);
- pTVar8 = this->PlayerData;
- *(undefined4 *)this->Rights = *(undefined4 *)pTVar8->Rights;
- *(undefined4 *)(this->Rights + 4) = *(undefined4 *)(pTVar8->Rights + 4);
- *(undefined4 *)(this->Rights + 8) = *(undefined4 *)(pTVar8->Rights + 8);
- bVar4 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (bVar4) {
- Log("game","Spieler besitzt Premium Account.\n");
- }
- pTVar8 = this->PlayerData;
- (this->super_TCreature).Sex = pTVar8->Sex;
- strcpy(this->Guild,pTVar8->Guild);
- strcpy(this->Rank,this->PlayerData->Rank);
- strcpy(this->Title,this->PlayerData->Title);
- pTVar8 = this->PlayerData;
- this->Request = 0;
- this->RequestTimestamp = 0;
- this->RequestProcessingGamemaster = 0;
- tVar9 = time((time_t *)0x0);
- if (pTVar8->PlayerkillerEnd < tVar9) {
- this->PlayerData->PlayerkillerEnd = 0;
- }
- CheckOutfit(this);
- TCreature::SetInCrList(&this->super_TCreature);
- Semaphore::down(&PlayerMutex);
- ppTVar10 = vector<TPlayer*>::operator()(&PlayerList,FirstFreePlayer);
- FirstFreePlayer = FirstFreePlayer + 1;
- *ppTVar10 = this;
- Semaphore::up(&PlayerMutex);
- iVar13 = 1;
- NotifyBuddies((this->super_TCreature).ID,__dest,true);
- IncrementPlayersOnline();
- if ((this->super_TCreature).Profession == '\0') {
- IncrementNewbiesOnline();
- }
- pTVar2 = (this->super_TCreature).super_TSkillBase.Skills[0x16];
- bVar4 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (bVar4) {
- bVar4 = 9 < (this->super_TCreature).Profession;
- }
- else {
- bVar4 = false;
- }
- iVar11 = 200;
- if (!bVar4) {
- iVar11 = 100;
- }
- pTVar2->Max = iVar11;
- TSkill::Check((this->super_TCreature).super_TSkillBase.Skills[0x16]);
- pTVar2 = (this->super_TCreature).super_TSkillBase.Skills[0x16];
- iVar11 = (*pTVar2->_vptr_TSkill[0xd])(pTVar2);
- if (0xe < iVar11) {
- bVar4 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (bVar4) {
- bVar4 = 9 < (this->super_TCreature).Profession;
- }
- else {
- bVar4 = false;
- }
- iVar13 = 0xf;
- if (!bVar4) {
- iVar13 = 0x78;
- }
- CharacterID = (iVar11 + -1) % iVar13 + 1;
- iVar13 = (iVar11 + -1) / iVar13 + 1;
- TSkillBase::SetTimer(&(this->super_TCreature).super_TSkillBase);
- }
- pTVar2 = (this->super_TCreature).super_TSkillBase.Skills[2];
- iVar11 = TSkill::Get(pTVar2);
- if (iVar11 < 1) {
- (*pTVar2->_vptr_TSkill[2])(pTVar2,pTVar2->Max,iVar13,CharacterID);
- iVar13 = 0;
- (this->super_TCreature).posx = (this->super_TCreature).startx;
- (this->super_TCreature).posy = (this->super_TCreature).starty;
- (this->super_TCreature).posz = (this->super_TCreature).startz;
- do {
- TSkillBase::DelTimer(&(this->super_TCreature).super_TSkillBase,(ushort)iVar13);
- TSkill::SetMDAct((this->super_TCreature).super_TSkillBase.Skills[iVar13],0);
- ppTVar1 = (this->super_TCreature).super_TSkillBase.Skills + iVar13;
- iVar13 = iVar13 + 1;
- (*ppTVar1)->DAct = 0;
- } while (iVar13 < 0x19);
- aVar3 = (this->super_TCreature).OrgOutfit.field_1;
- (this->super_TCreature).Outfit.OutfitID = (this->super_TCreature).OrgOutfit.OutfitID;
- pTVar2 = (this->super_TCreature).super_TSkillBase.Skills[3];
- (this->super_TCreature).Outfit.field_1 = aVar3;
- (*pTVar2->_vptr_TSkill[2])
- ((this->super_TCreature).super_TSkillBase.Skills[3],pTVar2->Max);
- }
- if (this->PlayerData->LastLoginTime == 0) {
- bVar4 = CheckRight((this->super_TCreature).ID,GAMEMASTER_OUTFIT);
- if (bVar4) {
- Log("game","Gamemaster-Charakter %s loggt zum ersten Mal ein -> Level 2 setzen.\n",
- __dest);
- (this->super_TCreature).super_TSkillBase.Skills[0]->Act = 2;
- (this->super_TCreature).super_TSkillBase.Skills[0]->Exp = 100;
- (this->super_TCreature).super_TSkillBase.Skills[0]->LastLevel = 100;
- (this->super_TCreature).super_TSkillBase.Skills[0]->NextLevel = 200;
- }
- }
- bVar4 = CoordinateFlag();
- if (bVar4) {
- Regenerate(this);
- }
- HouseID = GetHouseID((this->super_TCreature).posx,(this->super_TCreature).posy,
- (this->super_TCreature).posz);
- if (HouseID != 0) {
- bVar4 = IsInvited(HouseID,this,this->PlayerData->LastLogoutTime);
- if (!bVar4) {
- bVar4 = CheckRight((this->super_TCreature).ID,ENTER_HOUSES);
- if (!bVar4) {
- GetExitPosition(HouseID,&(this->super_TCreature).posx,
- &(this->super_TCreature).posy,&(this->super_TCreature).posz);
- }
- }
- }
- bVar4 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (!bVar4) {
- bVar4 = IsPremiumArea((this->super_TCreature).startx,(this->super_TCreature).starty,
- (this->super_TCreature).startz);
- if (bVar4) {
- Log("game",&DAT_08103880,__dest);
- bVar5 = (this->super_TCreature).Profession;
- if (9 < bVar5) {
- bVar5 = bVar5 - 10;
- }
- GetStartPosition(&(this->super_TCreature).startx,&(this->super_TCreature).starty,
- &(this->super_TCreature).startz,bVar5 == 0);
- }
- bVar4 = IsPremiumArea((this->super_TCreature).posx,(this->super_TCreature).posy,
- (this->super_TCreature).posz);
- if (bVar4) {
- Log("game",
- "Spieler %s wird aus PayArea geworfen und in seine Heimatstadt gesetzt.\n",
- __dest);
- (this->super_TCreature).posx = (this->super_TCreature).startx;
- (this->super_TCreature).posy = (this->super_TCreature).starty;
- (this->super_TCreature).posz = (this->super_TCreature).startz;
- }
- }
- TCreature::SetOnMap(&this->super_TCreature);
- TConnection::EnterGame(Connection);
- SendInitGame((TConnection *)(this->super_TCreature).ID,id);
- SendRights((this->super_TCreature).Connection);
- SendFullScreen((this->super_TCreature).Connection);
- local_3c[0].ObjectID = (this->super_TCreature).CrObject.ObjectID;
- GraphicalEffect(local_3c,0xb);
- LoadInventory(this,this->PlayerData->LastLoginTime == 0);
- TCreature::NotifyChangeInventory(&this->super_TCreature);
- SendAmbiente((this->super_TCreature).Connection);
- pTVar12 = GetCreature((this->super_TCreature).ID);
- if (pTVar12 == (TCreature *)0x0) {
- error("TPlayer::TPlayer: Kreatur nicht korrekt angelegt.\n");
- }
- else {
- AnnounceChangedCreature((this->super_TCreature).ID,2);
- }
- SendPlayerSkills((this->super_TCreature).Connection);
- this->OldState = 0;
- CheckState(this);
- if (this->PlayerData->LastLoginTime == 0) {
- bVar4 = CheckRight((this->super_TCreature).ID,GAMEMASTER_OUTFIT);
- if (!bVar4) {
- Log("game","Spieler %s loggt zum ersten Mal ein -> Outfitwahl.\n",__dest);
- SendMessage((this->super_TCreature).Connection,0x14,
- "Welcome to Tibia! Please choose your outfit.");
- SendOutfit((this->super_TCreature).Connection);
- }
- }
- SendBuddies(this);
- pTVar8 = this->PlayerData;
- if (pTVar8->LastLoginTime != 0) {
- __tp = localtime(&pTVar8->LastLoginTime);
- strftime(local_ac,100,"%d. %b %Y %X %Z",__tp);
- SendMessage((this->super_TCreature).Connection,0x14,"Your last visit in Tibia: %s.",
- local_ac);
- pTVar8 = this->PlayerData;
- }
- tVar9 = time((time_t *)0x0);
- pTVar8->LastLoginTime = tVar9;
- }
- return;
-}
-
-
-
-// DWARF original prototype: void ~TPlayer(TPlayer * this, int __in_chrg)
-
-void __thiscall TPlayer::~TPlayer(TPlayer *this,int __in_chrg)
-
-{
- ulong *puVar1;
- anon_union_4_2_730cd3ca_for_TOutfit_2 aVar2;
- bool bVar3;
- TCreature *cr;
- time_t tVar4;
- TCreature *pTVar5;
- __pid_t _Var6;
- ulong uVar7;
- TSkill *pTVar8;
- int iVar9;
- TPlayerData *pTVar10;
- int i;
- TCreature *pTVar11;
- uint uVar12;
- uchar *puVar13;
- int *piVar14;
- char *pcVar15;
- char *in_stack_ffffffd8;
- char *pcVar16;
- char *local_14;
-
- (this->super_TCreature)._vptr_TCreature = (_func_int_varargs **)&PTR__TPlayer_08127c68;
- LogoutOrder(this);
- if (this->ConstructError != NOERROR) {
- DelInList(this);
- goto LAB_080aa53c;
- }
- pTVar10 = this->PlayerData;
- tVar4 = time((time_t *)0x0);
- pTVar10->LastLogoutTime = tVar4;
- SaveData(this);
- if ((this->super_TCreature).IsDead == false) {
- Log("game","Spieler %s loggt aus.\n",(this->super_TCreature).Name);
- pcVar16 = (char *)(this->super_TCreature).posz;
- GraphicalEffect();
- SaveInventory(this);
- }
- else {
- pcVar16 = (this->super_TCreature).Name;
- pcVar15 = pcVar16;
- Log("game","Spieler %s ist gestorben.\n",pcVar16);
- pTVar10 = this->PlayerData;
- if (pTVar10 == (TPlayerData *)0x0) {
- error("TPlayer::~TPlayer: PlayerData ist NULL.\n");
- pTVar10 = this->PlayerData;
- if (pTVar10 != (TPlayerData *)0x0) goto LAB_080aa5d9;
- }
- else {
-LAB_080aa5d9:
- if (pTVar10->Inventory != (uchar *)0x0) {
- operator_delete__(pTVar10->Inventory);
- this->PlayerData->Inventory = (uchar *)0x0;
- }
- }
- if (((this->super_TCreature).Profession == '\0') ||
- (iVar9 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[0]), 5 < iVar9)) {
- pTVar8 = (this->super_TCreature).super_TSkillBase.Skills[2];
- if (pTVar8->Max < 1) goto LAB_080aa7f3;
- pTVar10 = this->PlayerData;
- pcVar16 = pcVar15;
- }
- else {
- pTVar8 = (this->super_TCreature).super_TSkillBase.Skills[2];
-LAB_080aa7f3:
- if (pTVar8->Max < 1) {
- Log("game",&DAT_08103aa0,pcVar16);
- }
- Log("game",&DAT_08103a60,pcVar16);
- pTVar10 = this->PlayerData;
- if (pTVar10 != (TPlayerData *)0x0) {
- uVar12 = 2000;
- aVar2 = (pTVar10->OriginalOutfit).field_1;
- (pTVar10->CurrentOutfit).OutfitID = (pTVar10->OriginalOutfit).OutfitID;
- (pTVar10->CurrentOutfit).field_1 = aVar2;
- this->PlayerData->startx = 0;
- this->PlayerData->starty = 0;
- this->PlayerData->startz = 0;
- this->PlayerData->posx = 0;
- this->PlayerData->posy = 0;
- this->PlayerData->posz = 0;
- this->PlayerData->Profession = 0;
- puVar13 = this->PlayerData->SpellList;
- for (iVar9 = 0x40; iVar9 != 0; iVar9 = iVar9 + -1) {
- puVar13[0] = '\0';
- puVar13[1] = '\0';
- puVar13[2] = '\0';
- puVar13[3] = '\0';
- puVar13 = puVar13 + 4;
- }
- pTVar10 = this->PlayerData;
- piVar14 = pTVar10->QuestValues;
- if (((uint)piVar14 & 4) != 0) {
- piVar14 = pTVar10->QuestValues + 1;
- pTVar10->QuestValues[0] = 0;
- uVar12 = 0x7cc;
- }
- iVar9 = 0;
- for (uVar12 = uVar12 >> 2; uVar12 != 0; uVar12 = uVar12 - 1) {
- *piVar14 = 0;
- piVar14 = piVar14 + 1;
- }
- do {
- this->PlayerData->Minimum[iVar9] = -0x80000000;
- iVar9 = iVar9 + 1;
- } while (iVar9 < 0x19);
- pTVar10 = this->PlayerData;
- }
- (this->super_TCreature).LoseInventory = 2;
- }
- if (pTVar10->PlayerkillerEnd != 0) {
- (this->super_TCreature).LoseInventory = 2;
- }
- bVar3 = CheckRight((this->super_TCreature).ID,KEEP_INVENTORY);
- if (bVar3) {
- (this->super_TCreature).LoseInventory = 0;
- }
- }
- local_14 = (this->super_TCreature).Name;
- in_stack_ffffffd8 = (char *)0xe;
- bVar3 = CheckRight((this->super_TCreature).ID,READ_GAMEMASTER_CHANNEL);
- if (bVar3) {
- CloseProcessedRequests((this->super_TCreature).ID);
- }
- if (this->Request != 0) {
- if (this->RequestProcessingGamemaster == 0) {
- DeleteGamemasterRequest(local_14);
- }
- else {
- pTVar5 = GetCreature(this->RequestProcessingGamemaster);
- pTVar11 = (TCreature *)0x0;
- if ((pTVar5 != (TCreature *)0x0) && (pTVar11 = pTVar5, pTVar5->Type != PLAYER)) {
- error("GetPlayer: Kreatur ist kein Spieler.\n");
- pTVar11 = (TCreature *)0x0;
- }
- if (pTVar11 != (TCreature *)0x0) {
- SendFinishRequest(pTVar11->Connection,local_14);
- in_stack_ffffffd8 = local_14;
- }
- }
- this->Request = 0;
- }
- LeaveAllChannels((this->super_TCreature).ID);
- if (this->PartyLeavingRound == 0) {
- uVar7 = this->PartyLeader;
- }
- else {
- uVar7 = 0;
- }
- if (uVar7 != 0) {
- in_stack_ffffffd8 = (char *)0x1;
- ::LeaveParty((this->super_TCreature).ID,true);
- }
- ClearPlayerkillingMarks(this);
- DelInList(this);
- this->PlayerData->Dirty = true;
- pTVar10 = this->PlayerData;
- if (pTVar10 == (TPlayerData *)0x0) {
- error("DecreasePlayerPoolSlotSticky: Slot ist NULL.\n");
- }
- else {
- Semaphore::down(&PlayerDataPoolMutex);
- piVar14 = &pTVar10->Sticky;
- *piVar14 = *piVar14 + -1;
- Semaphore::up(&PlayerDataPoolMutex);
- }
- pTVar10 = this->PlayerData;
- if (pTVar10 == (TPlayerData *)0x0) {
- pcVar15 = "ReleasePlayerPoolSlot: Slot ist NULL.\n";
- }
- else {
- pcVar16 = (char *)pTVar10->CharacterID;
- in_stack_ffffffd8 = "Gebe Slot von Spieler %ld frei.\n";
- print();
- if (pTVar10->Locked == 0) {
- pcVar15 = "ReleasePlayerPoolSlot: Slot ist nicht gesperrt.\n";
- }
- else {
- _Var6 = getpid();
- if (pTVar10->Locked == _Var6) {
- pTVar10->Locked = 0;
- goto LAB_080aa53c;
- }
- pcVar15 = "ReleasePlayerPoolSlot: Slot ist von einem anderen Thread gesperrt.\n";
- }
- }
- error(pcVar15,in_stack_ffffffd8,pcVar16);
-LAB_080aa53c:
- puVar1 = (this->FormerAttackedPlayers).entry;
- if (puVar1 != (ulong *)0x0) {
- operator_delete__(puVar1);
- }
- puVar1 = (this->AttackedPlayers).entry;
- if (puVar1 != (ulong *)0x0) {
- operator_delete__(puVar1);
- }
- TCreature::~TCreature(&this->super_TCreature,(int)in_stack_ffffffd8);
- return;
-}
-
-
-
-// DWARF original prototype: void ~TPlayer(TPlayer * this, int __in_chrg)
-
-void __thiscall TPlayer::~TPlayer(TPlayer *this,int __in_chrg)
-
-{
- ulong *puVar1;
- anon_union_4_2_730cd3ca_for_TOutfit_2 aVar2;
- bool bVar3;
- TCreature *cr;
- time_t tVar4;
- TCreature *pTVar5;
- __pid_t _Var6;
- ulong uVar7;
- TSkill *pTVar8;
- int iVar9;
- TPlayerData *pTVar10;
- int i;
- TCreature *pTVar11;
- uint uVar12;
- uchar *puVar13;
- int *piVar14;
- char *pcVar15;
- char *in_stack_ffffffd8;
- char *pcVar16;
- char *local_14;
-
- (this->super_TCreature)._vptr_TCreature = (_func_int_varargs **)&PTR__TPlayer_08127c68;
- LogoutOrder(this);
- if (this->ConstructError != NOERROR) {
- DelInList(this);
- goto LAB_080aaa0c;
- }
- pTVar10 = this->PlayerData;
- tVar4 = time((time_t *)0x0);
- pTVar10->LastLogoutTime = tVar4;
- SaveData(this);
- if ((this->super_TCreature).IsDead == false) {
- Log("game","Spieler %s loggt aus.\n",(this->super_TCreature).Name);
- pcVar16 = (char *)(this->super_TCreature).posz;
- GraphicalEffect();
- SaveInventory(this);
- }
- else {
- pcVar16 = (this->super_TCreature).Name;
- pcVar15 = pcVar16;
- Log("game","Spieler %s ist gestorben.\n",pcVar16);
- pTVar10 = this->PlayerData;
- if (pTVar10 == (TPlayerData *)0x0) {
- error("TPlayer::~TPlayer: PlayerData ist NULL.\n");
- pTVar10 = this->PlayerData;
- if (pTVar10 != (TPlayerData *)0x0) goto LAB_080aaaa9;
- }
- else {
-LAB_080aaaa9:
- if (pTVar10->Inventory != (uchar *)0x0) {
- operator_delete__(pTVar10->Inventory);
- this->PlayerData->Inventory = (uchar *)0x0;
- }
- }
- if (((this->super_TCreature).Profession == '\0') ||
- (iVar9 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[0]), 5 < iVar9)) {
- pTVar8 = (this->super_TCreature).super_TSkillBase.Skills[2];
- if (pTVar8->Max < 1) goto LAB_080aacc3;
- pTVar10 = this->PlayerData;
- pcVar16 = pcVar15;
- }
- else {
- pTVar8 = (this->super_TCreature).super_TSkillBase.Skills[2];
-LAB_080aacc3:
- if (pTVar8->Max < 1) {
- Log("game",&DAT_08103aa0,pcVar16);
- }
- Log("game",&DAT_08103a60,pcVar16);
- pTVar10 = this->PlayerData;
- if (pTVar10 != (TPlayerData *)0x0) {
- uVar12 = 2000;
- aVar2 = (pTVar10->OriginalOutfit).field_1;
- (pTVar10->CurrentOutfit).OutfitID = (pTVar10->OriginalOutfit).OutfitID;
- (pTVar10->CurrentOutfit).field_1 = aVar2;
- this->PlayerData->startx = 0;
- this->PlayerData->starty = 0;
- this->PlayerData->startz = 0;
- this->PlayerData->posx = 0;
- this->PlayerData->posy = 0;
- this->PlayerData->posz = 0;
- this->PlayerData->Profession = 0;
- puVar13 = this->PlayerData->SpellList;
- for (iVar9 = 0x40; iVar9 != 0; iVar9 = iVar9 + -1) {
- puVar13[0] = '\0';
- puVar13[1] = '\0';
- puVar13[2] = '\0';
- puVar13[3] = '\0';
- puVar13 = puVar13 + 4;
- }
- pTVar10 = this->PlayerData;
- piVar14 = pTVar10->QuestValues;
- if (((uint)piVar14 & 4) != 0) {
- piVar14 = pTVar10->QuestValues + 1;
- pTVar10->QuestValues[0] = 0;
- uVar12 = 0x7cc;
- }
- iVar9 = 0;
- for (uVar12 = uVar12 >> 2; uVar12 != 0; uVar12 = uVar12 - 1) {
- *piVar14 = 0;
- piVar14 = piVar14 + 1;
- }
- do {
- this->PlayerData->Minimum[iVar9] = -0x80000000;
- iVar9 = iVar9 + 1;
- } while (iVar9 < 0x19);
- pTVar10 = this->PlayerData;
- }
- (this->super_TCreature).LoseInventory = 2;
- }
- if (pTVar10->PlayerkillerEnd != 0) {
- (this->super_TCreature).LoseInventory = 2;
- }
- bVar3 = CheckRight((this->super_TCreature).ID,KEEP_INVENTORY);
- if (bVar3) {
- (this->super_TCreature).LoseInventory = 0;
- }
- }
- local_14 = (this->super_TCreature).Name;
- in_stack_ffffffd8 = (char *)0xe;
- bVar3 = CheckRight((this->super_TCreature).ID,READ_GAMEMASTER_CHANNEL);
- if (bVar3) {
- CloseProcessedRequests((this->super_TCreature).ID);
- }
- if (this->Request != 0) {
- if (this->RequestProcessingGamemaster == 0) {
- DeleteGamemasterRequest(local_14);
- }
- else {
- pTVar5 = GetCreature(this->RequestProcessingGamemaster);
- pTVar11 = (TCreature *)0x0;
- if ((pTVar5 != (TCreature *)0x0) && (pTVar11 = pTVar5, pTVar5->Type != PLAYER)) {
- error("GetPlayer: Kreatur ist kein Spieler.\n");
- pTVar11 = (TCreature *)0x0;
- }
- if (pTVar11 != (TCreature *)0x0) {
- SendFinishRequest(pTVar11->Connection,local_14);
- in_stack_ffffffd8 = local_14;
- }
- }
- this->Request = 0;
- }
- LeaveAllChannels((this->super_TCreature).ID);
- if (this->PartyLeavingRound == 0) {
- uVar7 = this->PartyLeader;
- }
- else {
- uVar7 = 0;
- }
- if (uVar7 != 0) {
- in_stack_ffffffd8 = (char *)0x1;
- ::LeaveParty((this->super_TCreature).ID,true);
- }
- ClearPlayerkillingMarks(this);
- DelInList(this);
- this->PlayerData->Dirty = true;
- pTVar10 = this->PlayerData;
- if (pTVar10 == (TPlayerData *)0x0) {
- error("DecreasePlayerPoolSlotSticky: Slot ist NULL.\n");
- }
- else {
- Semaphore::down(&PlayerDataPoolMutex);
- piVar14 = &pTVar10->Sticky;
- *piVar14 = *piVar14 + -1;
- Semaphore::up(&PlayerDataPoolMutex);
- }
- pTVar10 = this->PlayerData;
- if (pTVar10 == (TPlayerData *)0x0) {
- pcVar15 = "ReleasePlayerPoolSlot: Slot ist NULL.\n";
- }
- else {
- pcVar16 = (char *)pTVar10->CharacterID;
- in_stack_ffffffd8 = "Gebe Slot von Spieler %ld frei.\n";
- print();
- if (pTVar10->Locked == 0) {
- pcVar15 = "ReleasePlayerPoolSlot: Slot ist nicht gesperrt.\n";
- }
- else {
- _Var6 = getpid();
- if (pTVar10->Locked == _Var6) {
- pTVar10->Locked = 0;
- goto LAB_080aaa0c;
- }
- pcVar15 = "ReleasePlayerPoolSlot: Slot ist von einem anderen Thread gesperrt.\n";
- }
- }
- error(pcVar15,in_stack_ffffffd8,pcVar16);
-LAB_080aaa0c:
- puVar1 = (this->FormerAttackedPlayers).entry;
- if (puVar1 != (ulong *)0x0) {
- operator_delete__(puVar1);
- }
- puVar1 = (this->AttackedPlayers).entry;
- if (puVar1 != (ulong *)0x0) {
- operator_delete__(puVar1);
- }
- TCreature::~TCreature(&this->super_TCreature,(int)in_stack_ffffffd8);
- return;
-}
-
-
-
-// DWARF original prototype: void ~TPlayer(TPlayer * this, int __in_chrg)
-
-void __thiscall TPlayer::~TPlayer(TPlayer *this,int __in_chrg)
-
-{
- ulong *puVar1;
- anon_union_4_2_730cd3ca_for_TOutfit_2 aVar2;
- bool bVar3;
- TCreature *cr;
- time_t tVar4;
- TCreature *pTVar5;
- __pid_t _Var6;
- ulong uVar7;
- TSkill *pTVar8;
- int iVar9;
- TPlayerData *pTVar10;
- int i;
- TCreature *pTVar11;
- uint uVar12;
- uchar *puVar13;
- int *piVar14;
- char *pcVar15;
- char *in_stack_ffffffd8;
- char *pcVar16;
- char *local_14;
-
- (this->super_TCreature)._vptr_TCreature = (_func_int_varargs **)&PTR__TPlayer_08127c68;
- LogoutOrder(this);
- if (this->ConstructError != NOERROR) {
- DelInList(this);
- goto LAB_080aaedc;
- }
- pTVar10 = this->PlayerData;
- tVar4 = time((time_t *)0x0);
- pTVar10->LastLogoutTime = tVar4;
- SaveData(this);
- if ((this->super_TCreature).IsDead == false) {
- Log("game","Spieler %s loggt aus.\n",(this->super_TCreature).Name);
- pcVar16 = (char *)(this->super_TCreature).posz;
- GraphicalEffect();
- SaveInventory(this);
- }
- else {
- pcVar16 = (this->super_TCreature).Name;
- pcVar15 = pcVar16;
- Log("game","Spieler %s ist gestorben.\n",pcVar16);
- pTVar10 = this->PlayerData;
- if (pTVar10 == (TPlayerData *)0x0) {
- error("TPlayer::~TPlayer: PlayerData ist NULL.\n");
- pTVar10 = this->PlayerData;
- if (pTVar10 != (TPlayerData *)0x0) goto LAB_080aaf79;
- }
- else {
-LAB_080aaf79:
- if (pTVar10->Inventory != (uchar *)0x0) {
- operator_delete__(pTVar10->Inventory);
- this->PlayerData->Inventory = (uchar *)0x0;
- }
- }
- if (((this->super_TCreature).Profession == '\0') ||
- (iVar9 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[0]), 5 < iVar9)) {
- pTVar8 = (this->super_TCreature).super_TSkillBase.Skills[2];
- if (pTVar8->Max < 1) goto LAB_080ab193;
- pTVar10 = this->PlayerData;
- pcVar16 = pcVar15;
- }
- else {
- pTVar8 = (this->super_TCreature).super_TSkillBase.Skills[2];
-LAB_080ab193:
- if (pTVar8->Max < 1) {
- Log("game",&DAT_08103aa0,pcVar16);
- }
- Log("game",&DAT_08103a60,pcVar16);
- pTVar10 = this->PlayerData;
- if (pTVar10 != (TPlayerData *)0x0) {
- uVar12 = 2000;
- aVar2 = (pTVar10->OriginalOutfit).field_1;
- (pTVar10->CurrentOutfit).OutfitID = (pTVar10->OriginalOutfit).OutfitID;
- (pTVar10->CurrentOutfit).field_1 = aVar2;
- this->PlayerData->startx = 0;
- this->PlayerData->starty = 0;
- this->PlayerData->startz = 0;
- this->PlayerData->posx = 0;
- this->PlayerData->posy = 0;
- this->PlayerData->posz = 0;
- this->PlayerData->Profession = 0;
- puVar13 = this->PlayerData->SpellList;
- for (iVar9 = 0x40; iVar9 != 0; iVar9 = iVar9 + -1) {
- puVar13[0] = '\0';
- puVar13[1] = '\0';
- puVar13[2] = '\0';
- puVar13[3] = '\0';
- puVar13 = puVar13 + 4;
- }
- pTVar10 = this->PlayerData;
- piVar14 = pTVar10->QuestValues;
- if (((uint)piVar14 & 4) != 0) {
- piVar14 = pTVar10->QuestValues + 1;
- pTVar10->QuestValues[0] = 0;
- uVar12 = 0x7cc;
- }
- iVar9 = 0;
- for (uVar12 = uVar12 >> 2; uVar12 != 0; uVar12 = uVar12 - 1) {
- *piVar14 = 0;
- piVar14 = piVar14 + 1;
- }
- do {
- this->PlayerData->Minimum[iVar9] = -0x80000000;
- iVar9 = iVar9 + 1;
- } while (iVar9 < 0x19);
- pTVar10 = this->PlayerData;
- }
- (this->super_TCreature).LoseInventory = 2;
- }
- if (pTVar10->PlayerkillerEnd != 0) {
- (this->super_TCreature).LoseInventory = 2;
- }
- bVar3 = CheckRight((this->super_TCreature).ID,KEEP_INVENTORY);
- if (bVar3) {
- (this->super_TCreature).LoseInventory = 0;
- }
- }
- local_14 = (this->super_TCreature).Name;
- in_stack_ffffffd8 = (char *)0xe;
- bVar3 = CheckRight((this->super_TCreature).ID,READ_GAMEMASTER_CHANNEL);
- if (bVar3) {
- CloseProcessedRequests((this->super_TCreature).ID);
- }
- if (this->Request != 0) {
- if (this->RequestProcessingGamemaster == 0) {
- DeleteGamemasterRequest(local_14);
- }
- else {
- pTVar5 = GetCreature(this->RequestProcessingGamemaster);
- pTVar11 = (TCreature *)0x0;
- if ((pTVar5 != (TCreature *)0x0) && (pTVar11 = pTVar5, pTVar5->Type != PLAYER)) {
- error("GetPlayer: Kreatur ist kein Spieler.\n");
- pTVar11 = (TCreature *)0x0;
- }
- if (pTVar11 != (TCreature *)0x0) {
- SendFinishRequest(pTVar11->Connection,local_14);
- in_stack_ffffffd8 = local_14;
- }
- }
- this->Request = 0;
- }
- LeaveAllChannels((this->super_TCreature).ID);
- if (this->PartyLeavingRound == 0) {
- uVar7 = this->PartyLeader;
- }
- else {
- uVar7 = 0;
- }
- if (uVar7 != 0) {
- in_stack_ffffffd8 = (char *)0x1;
- ::LeaveParty((this->super_TCreature).ID,true);
- }
- ClearPlayerkillingMarks(this);
- DelInList(this);
- this->PlayerData->Dirty = true;
- pTVar10 = this->PlayerData;
- if (pTVar10 == (TPlayerData *)0x0) {
- error("DecreasePlayerPoolSlotSticky: Slot ist NULL.\n");
- }
- else {
- Semaphore::down(&PlayerDataPoolMutex);
- piVar14 = &pTVar10->Sticky;
- *piVar14 = *piVar14 + -1;
- Semaphore::up(&PlayerDataPoolMutex);
- }
- pTVar10 = this->PlayerData;
- if (pTVar10 == (TPlayerData *)0x0) {
- pcVar15 = "ReleasePlayerPoolSlot: Slot ist NULL.\n";
- }
- else {
- pcVar16 = (char *)pTVar10->CharacterID;
- in_stack_ffffffd8 = "Gebe Slot von Spieler %ld frei.\n";
- print();
- if (pTVar10->Locked == 0) {
- pcVar15 = "ReleasePlayerPoolSlot: Slot ist nicht gesperrt.\n";
- }
- else {
- _Var6 = getpid();
- if (pTVar10->Locked == _Var6) {
- pTVar10->Locked = 0;
- goto LAB_080aaedc;
- }
- pcVar15 = "ReleasePlayerPoolSlot: Slot ist von einem anderen Thread gesperrt.\n";
- }
- }
- error(pcVar15,in_stack_ffffffd8,pcVar16);
-LAB_080aaedc:
- puVar1 = (this->FormerAttackedPlayers).entry;
- if (puVar1 != (ulong *)0x0) {
- operator_delete__(puVar1);
- }
- puVar1 = (this->AttackedPlayers).entry;
- if (puVar1 != (ulong *)0x0) {
- operator_delete__(puVar1);
- }
- TCreature::~TCreature(&this->super_TCreature,(int)in_stack_ffffffd8);
- operator_delete(this);
- return;
-}
-
-
-
-// DWARF original prototype: void SetInList(TPlayer * this)
-
-void __thiscall TPlayer::SetInList(TPlayer *this)
-
-{
- TPlayer **ppTVar1;
-
- TCreature::SetInCrList(&this->super_TCreature);
- Semaphore::down(&PlayerMutex);
- ppTVar1 = vector<TPlayer*>::operator()(&PlayerList,FirstFreePlayer);
- FirstFreePlayer = FirstFreePlayer + 1;
- *ppTVar1 = this;
- Semaphore::up(&PlayerMutex);
- NotifyBuddies((this->super_TCreature).ID,(this->super_TCreature).Name,true);
- IncrementPlayersOnline();
- if ((this->super_TCreature).Profession != '\0') {
- return;
- }
- IncrementNewbiesOnline();
- return;
-}
-
-
-
-// DWARF original prototype: void DelInList(TPlayer * this)
-
-void __thiscall TPlayer::DelInList(TPlayer *this)
-
-{
- TPlayer **ppTVar1;
- TPlayer **ppTVar2;
- int i;
- int i_00;
-
- i_00 = 0;
- NotifyBuddies((this->super_TCreature).ID,(this->super_TCreature).Name,false);
- if (0 < FirstFreePlayer) {
- do {
- ppTVar1 = vector<TPlayer*>::operator()(&PlayerList,i_00);
- if (*ppTVar1 == this) {
- Semaphore::down(&PlayerMutex);
- ppTVar1 = vector<TPlayer*>::operator()(&PlayerList,i_00);
- ppTVar2 = vector<TPlayer*>::operator()(&PlayerList,FirstFreePlayer + -1);
- *ppTVar1 = *ppTVar2;
- ppTVar1 = vector<TPlayer*>::operator()(&PlayerList,FirstFreePlayer + -1);
- *ppTVar1 = (TPlayer *)0x0;
- FirstFreePlayer = FirstFreePlayer + -1;
- Semaphore::up(&PlayerMutex);
- DecrementPlayersOnline();
- if ((this->super_TCreature).Profession != '\0') {
- return;
- }
- DecrementNewbiesOnline();
- return;
- }
- i_00 = i_00 + 1;
- } while (i_00 < FirstFreePlayer);
- }
- return;
-}
-
-
-
// DWARF original prototype: void ClearConnection(TPlayer * this)
void __thiscall TPlayer::ClearConnection(TPlayer *this)
diff --git a/src/common.hh b/src/common.hh index 9800e6a..4737c54 100644 --- a/src/common.hh +++ b/src/common.hh @@ -9,6 +9,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <algorithm> @@ -139,6 +140,7 @@ char *Capitals(char *Text); // ============================================================================= extern uint32 RoundNr; extern uint32 ServerMilliseconds; +struct tm GetLocalTimeTM(time_t t); void GetRealTime(int *Hour, int *Minute); void GetTime(int *Hour, int *Minute); void GetDate(int *Year, int *Cycle, int *Day); diff --git a/src/connection.hh b/src/connection.hh index 44b7360..4a5e544 100644 --- a/src/connection.hh +++ b/src/connection.hh @@ -18,6 +18,8 @@ struct TConnection { TPlayer *GetPlayer(void); void Logout(int Delay, bool StopFight); bool IsVisible(int x, int y, int z); + void EnterGame(void); + const char *GetIPAddress(void); // DATA // ================= @@ -433,6 +433,12 @@ struct TFindCreatures { // TCreature // ============================================================================= +enum : int { + LOSE_INVENTORY_NONE = 0, + LOSE_INVENTORY_SOME = 1, + LOSE_INVENTORY_ALL = 2, +}; + struct TToDoEntry { ToDoType Code; union{ @@ -707,7 +713,11 @@ struct TPlayerIndexLeafNode: TPlayerIndexNode { }; struct TPlayer: TCreature { - //TPlayer(void); + TPlayer(TConnection *Connection, uint32 CharacterID); + void SetInList(void); + void DelInList(void); + +//== // TODO(fusion): Eventually sort these out when we implement player functions. uint8 GetRealProfession(void); @@ -716,22 +726,16 @@ struct TPlayer: TCreature { bool GetActivePromotion(void); void ClearProfession(void); void SetProfession(uint8 Profession); - int GetQuestValue(int Number); void SetQuestValue(int Number, int Value); - void JoinParty(uint32 Leader); void LeaveParty(void); uint32 GetPartyLeader(bool CheckFormer); - bool SpellKnown(int SpellNr); - bool IsAttackJustified(uint32 Victim); void RecordAttack(uint32 Victim); void RecordMurder(uint32 Victim); - void CheckState(void); - void ClearPlayerkillingMarks(void); void SaveInventory(void); Object GetOpenContainer(int ContainerNr); @@ -741,10 +745,16 @@ struct TPlayer: TCreature { int CheckForMuting(void); int RecordTalk(void); int RecordMessage(uint32 Addressee); + void LoadData(void); + void SaveData(void); + void CheckOutfit(void); + void Regenerate(void); + void LoadInventory(bool SetDefaultInventory); + void SendBuddies(void); // VIRTUAL FUNCTIONS // ================= - // TODO + ~TPlayer(void) override; // DATA // ================= @@ -843,6 +853,45 @@ void ExitNonplayer(); // crplayer.cc // ============================================================================= +int GetNumberOfPlayers(void); +TPlayer *GetPlayer(uint32 CharacterID); +TPlayer *GetPlayer(const char *Name); +bool IsPlayerOnline(const char *Name); +int IdentifyPlayer(const char *Name, bool ExactMatch, bool IgnoreGamemasters, TPlayer **OutPlayer); +void LogoutAllPlayers(void); +void CloseProcessedRequests(uint32 CharacterID); +void NotifyBuddies(uint32 CharacterID, const char *Name, bool Login); +void CreatePlayerList(bool Online); +void PrintPlayerPositions(void); +void LoadDepot(TPlayerData *PlayerData, int DepotNr, Object Con); +void SaveDepot(TPlayerData *PlayerData, int DepotNr, Object Con); +void GetProfessionName(char *Buffer, int Profession, bool Article, bool Capitals); +void SendExistingRequests(TConnection *Connection); + +void SavePlayerPoolSlot(TPlayerData *Slot); +void FreePlayerPoolSlot(TPlayerData *Slot); +TPlayerData *GetPlayerPoolSlot(uint32 CharacterID); +TPlayerData *AssignPlayerPoolSlot(uint32 CharacterID, bool DontWait); +TPlayerData *AttachPlayerPoolSlot(uint32 CharacterID, bool DontWait); +void AttachPlayerPoolSlot(TPlayerData *Slot, bool DontWait); +void IncreasePlayerPoolSlotSticky(TPlayerData *Slot); +void DecreasePlayerPoolSlotSticky(TPlayerData *Slot); +void DecreasePlayerPoolSlotSticky(uint32 CharacterID); +void ReleasePlayerPoolSlot(TPlayerData *Slot); +void SavePlayerPoolSlots(void); +void InitPlayerPool(void); +void ExitPlayerPool(void); + +int GetPlayerIndexEntryNumber(const char *Name, int Position); +void InsertPlayerIndex(TPlayerIndexInternalNode *Node, + int Position, const char *Name, uint32 CharacterID); +TPlayerIndexEntry *SearchPlayerIndex(const char *Name); +bool PlayerExists(const char *Name); +uint32 GetCharacterID(const char *Name); +const char *GetCharacterName(const char *Name); +void InitPlayerIndex(void); +void ExitPlayerIndex(void); + void InitPlayer(void); void ExitPlayer(void); diff --git a/src/crmain.cc b/src/crmain.cc index f29a992..ddf5393 100644 --- a/src/crmain.cc +++ b/src/crmain.cc @@ -7,7 +7,6 @@ #include "stubs.hh" #include <dirent.h> -#include <time.h> TRaceData RaceData[MAX_RACES]; priority_queue<uint32, uint32> ToDoQueue(5000, 1000); @@ -135,7 +134,7 @@ TCreature::TCreature(void) : this->Direction = 0; this->Radius = INT_MAX; this->IsDead = false; - this->LoseInventory = 2; + this->LoseInventory = LOSE_INVENTORY_ALL; this->LoggingOut = false; this->LogoutAllowed = false; this->EarliestLogoutRound = 0; @@ -226,7 +225,7 @@ TCreature::~TCreature(void){ Change(Corpse, TEXTSTRING, AddDynamicString(Help)); } - if(this->LoseInventory != 0){ // LOSE_INVENTORY_NONE ? + if(this->LoseInventory != LOSE_INVENTORY_NONE){ for(int Position = INVENTORY_FIRST; Position <= INVENTORY_LAST; Position += 1){ @@ -235,17 +234,15 @@ TCreature::~TCreature(void){ continue; } - if(this->LoseInventory != 2 // LOSE_INVENTORY_ALL ? - && !Item.getObjectType().getFlag(CONTAINER) - && random(0, 9) != 0){ - continue; + if(this->LoseInventory == LOSE_INVENTORY_ALL + || Item.getObjectType().getFlag(CONTAINER) + || random(0, 9) == 0){ + ::Move(0, Item, Corpse, -1, false, NONE); } - - ::Move(0, Item, Corpse, -1, false, NONE); } } - if(this->Type == PLAYER && this->LoseInventory != 2){ // LOSE_INVENTORY_ALL ? + if(this->Type == PLAYER && this->LoseInventory != LOSE_INVENTORY_ALL){ ((TPlayer*)this)->SaveInventory(); } }catch(RESULT r){ @@ -757,7 +754,7 @@ int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){ ObjectType AmuletOfLossType = GetNewObjectType(77, 12); if(ObjType == AmuletOfLossType){ Log("game", "%s stirbt mit Amulett of Loss.\n", this->Name); - this->LoseInventory = 0; + this->LoseInventory = LOSE_INVENTORY_NONE; try{ Delete(Obj, -1); // TODO(fusion): Shouldn't we break here? We could also diff --git a/src/crplayer.cc b/src/crplayer.cc index 3205e46..67ff996 100644 --- a/src/crplayer.cc +++ b/src/crplayer.cc @@ -19,6 +19,355 @@ static store<TPlayerIndexLeafNode, 100> PlayerIndexLeafNodes; // TPlayer // ============================================================================= +TPlayer::TPlayer(TConnection *Connection, uint32 CharacterID): + TCreature(), + AttackedPlayers(0, 10, 10), + FormerAttackedPlayers(0, 10, 10) +{ + this->Type = PLAYER; + this->LoseInventory = LOSE_INVENTORY_SOME; + this->Profession = PROFESSION_NONE; + this->AccountID = 0; + this->Guild[0] = 0; + this->Rank[0] = 0; + this->Title[0] = 0; + this->IPAddress[0] = 0; + this->Depot = NONE; + this->DepotNr = 0; + this->DepotSpace = 0; + this->ConstructError = NOERROR; + this->PlayerData = NULL; + this->TradeObject = NONE; + this->TradePartner = 0; + this->TradeAccepted = false; + this->OldState = 0; + this->Request = 0; + this->RequestTimestamp = 0; + this->RequestProcessingGamemaster = 0; + this->TutorActivities = 0; + this->NumberOfAttackedPlayers = 0; + this->Aggressor = false; + this->NumberOfFormerAttackedPlayers = 0; + this->FormerAggressor = false; + this->FormerLogoutRound = 0; + this->PartyLeader = 0; + this->PartyLeavingRound = 0; + this->TalkBufferFullTime = 0; + this->MutingEndRound = 0; + this->NumberOfMutings = 0; + + memset(this->Rights, 0, sizeof(this->Rights)); + + for(int SpellNr = 0; + SpellNr < NARRAY(this->SpellList); + SpellNr += 1){ + this->SpellList[SpellNr] = 0; + } + + for(int QuestNr = 0; + QuestNr < NARRAY(this->QuestValues); + QuestNr += 1){ + this->QuestValues[QuestNr] = 0; + } + + for(int ContainerNr = 0; + ContainerNr < NARRAY(this->OpenContainer); + ContainerNr += 1){ + this->OpenContainer[ContainerNr] = NONE; + } + + STATIC_ASSERT(NARRAY(this->Addressees) == NARRAY(this->AddresseesTimes)); + for(int AddresseeNr = 0; + AddresseeNr < NARRAY(this->Addressees); + AddresseeNr += 1){ + this->Addressees[AddresseeNr] = 0; + this->AddresseesTimes[AddresseeNr] = 0; + } + + TPlayerData *Slot = AttachPlayerPoolSlot(CharacterID, false); + if(Slot == NULL){ + error("TPlayer::TPlayer: PlayerData-Slot nicht gefunden.\n"); + this->ConstructError = ERROR; + return; + } + + SendMails(Slot); + + this->PlayerData = Slot; + this->Connection = Connection; + strcpy(this->Name, Slot->Name); + this->SetID(CharacterID); + + InsertPlayerIndex(&PlayerIndexHead, 0, this->Name, CharacterID); + this->LoadData(); + this->AccountID = Slot->AccountID; + strcpy(this->IPAddress, Connection->GetIPAddress()); + + STATIC_ASSERT(sizeof(this->Rights) == sizeof(Slot->Rights)); + memcpy(this->Rights, Slot->Rights, sizeof(this->Rights)); + + this->Sex = Slot->Sex; + strcpy(this->Guild, Slot->Guild); + strcpy(this->Rank, Slot->Rank); + strcpy(this->Title, Slot->Title); + + if(Slot->PlayerkillerEnd < (int)time(NULL)){ + Slot->PlayerkillerEnd = 0; + } + + this->CheckOutfit(); + this->SetInList(); + + // NOTE(fusion): Soul regen. Could be some inlined function `CheckSoul`. + { + TSkill *Soul = this->Skills[SKILL_SOUL]; + Soul->Max = (this->GetActivePromotion() ? 200 : 100); + Soul->Check(); + + // TODO(fusion): We're rounding up to an extra regen cycle here but I'm + // not sure it is correct. + int Timer = Soul->TimerValue(); + if(Timer >= 15){ + int Interval = (this->GetActivePromotion() ? 15 : 120); + int Cycle = (Timer + Interval - 1) / Interval; + int Count = (Timer + Interval - 1) % Interval; + this->SetTimer(SKILL_SOUL, Cycle, Count, Interval, -1); + } + } + + // TODO(fusion): Handle login after death? + if(this->Skills[SKILL_HITPOINTS]->Get() <= 0){ + for(int SkillNr = 0; + SkillNr < NARRAY(this->Skills); + SkillNr += 1){ + this->DelTimer(SkillNr); + this->Skills[SkillNr]->SetMDAct(0); + this->Skills[SkillNr]->DAct = 0; + } + + this->Skills[SKILL_HITPOINTS]->Set(this->Skills[SKILL_HITPOINTS]->Max); + this->Skills[SKILL_MANA ]->Set(this->Skills[SKILL_MANA ]->Max); + this->Outfit = this->OrgOutfit; + this->posx = this->startx; + this->posy = this->starty; + this->posz = this->startz; + } + + if(Slot->LastLoginTime == 0 && CheckRight(CharacterID, GAMEMASTER_OUTFIT)){ + Log("game", "Gamemaster-Charakter %s loggt zum ersten Mal ein -> Level 2 setzen.\n", this->Name); + this->Skills[SKILL_LEVEL]->Act = 2; + this->Skills[SKILL_LEVEL]->Exp = 100; + this->Skills[SKILL_LEVEL]->LastLevel = 100; + this->Skills[SKILL_LEVEL]->NextLevel = 200; + } + + if(CoordinateFlag(this->posx, this->posy, this->posz, BED)){ + this->Regenerate(); + } + + uint16 HouseID = GetHouseID(this->posx, this->posy, this->posz); + if(HouseID != 0 + && !IsInvited(HouseID, this, Slot->LastLogoutTime) + && !CheckRight(CharacterID, ENTER_HOUSES)){ + GetExitPosition(HouseID, &this->posx, &this->posy, &this->posz); + } + + if(!CheckRight(CharacterID, PREMIUM_ACCOUNT)){ + if(IsPremiumArea(this->startx, this->starty, this->startz)){ + Log("game", "Spieler %s wird aus PayArea-Stadt ausgebürgert und erhält neue Heimatstadt.\n", this->Name); + GetStartPosition(&this->startx, &this->starty, &this->startz, (this->Profession == PROFESSION_NONE)); + } + + if(IsPremiumArea(this->posx, this->posy, this->posz)){ + Log("game", "Spieler %s wird aus PayArea geworfen und in seine Heimatstadt gesetzt.\n", this->Name); + this->posx = this->startx; + this->posy = this->starty; + this->posz = this->startz; + } + }else{ + Log("game", "Spieler besitzt Premium Account.\n"); + } + + this->SetOnMap(); + Connection->EnterGame(); + SendInitGame(Connection, CharacterID); + SendRights(Connection); + SendFullScreen(Connection); + GraphicalEffect(this->CrObject, EFFECT_ENERGY); + this->LoadInventory(Slot->LastLoginTime == 0); + this->NotifyChangeInventory(); + SendAmbiente(Connection); + AnnounceChangedCreature(CharacterID, CREATURE_LIGHT_CHANGED); + SendPlayerSkills(Connection); + this->CheckState(); + this->SendBuddies(); + + if(Slot->LastLoginTime != 0){ + char TimeString[100]; + struct tm LastLogin = GetLocalTimeTM(Slot->LastLoginTime); + strftime(TimeString, sizeof(TimeString), "%d. %b %Y %X %Z", &LastLogin); + SendMessage(Connection, TALK_LOGIN_MESSAGE, + "Your last visit in Tibia: %s.", TimeString); + }else if(!CheckRight(this->ID, GAMEMASTER_OUTFIT)){ + Log("game", "Spieler %s loggt zum ersten Mal ein -> Outfitwahl.\n", this->Name); + SendMessage(Connection, TALK_LOGIN_MESSAGE, + "Welcome to Tibia! Please choose your outfit."); + SendOutfit(Connection); + } + + Slot->LastLoginTime = time(NULL); +} + +TPlayer::~TPlayer(void){ + LogoutOrder(this); + if(this->ConstructError != NOERROR){ + this->DelInList(); + return; + } + + ASSERT(this->PlayerData); + TPlayerData *Slot = this->PlayerData; + Slot->LastLogoutTime = time(NULL); + this->SaveData(); + + if(!this->IsDead){ + Log("game", "Spieler %s loggt aus.\n", this->Name); + GraphicalEffect(this->posx, this->posy, this->posz, EFFECT_POFF); + this->SaveInventory(); + }else{ + Log("game", "Spieler %s ist gestorben.\n", this->Name); + + // NOTE(fusion): This is a disaster. We're deleting the slot's inventory + // here so `~TCreature` can handle dropping loot and then re-generate it + // with `SaveInventory` if `LoseInventory` is not `LOSE_INVENTORY_ALL`, + // which makes sense but is poorly executed. + delete[] Slot->Inventory; + Slot->Inventory = NULL; + + bool ResetCharacter = false; + if(this->Profession != PROFESSION_NONE && this->Skills[SKILL_LEVEL]->Get() <= 5){ + Log("game", "Setze Spieler %s komplett zurück wegen Level.\n", this->Name); + ResetCharacter = true; + }else if(this->Skills[SKILL_HITPOINTS]->Max <= 0){ + Log("game", "Setze Spieler %s komplett zurück wegen MaxHitpoints.\n", this->Name); + ResetCharacter = true; + } + + if(ResetCharacter){ + Slot->CurrentOutfit = Slot->OriginalOutfit; + Slot->startx = 0; + Slot->starty = 0; + Slot->startz = 0; + Slot->posx = 0; + Slot->posy = 0; + Slot->posz = 0; + Slot->Profession = PROFESSION_NONE; + + for(int SpellNr = 0; + SpellNr < NARRAY(Slot->SpellList); + SpellNr += 1){ + Slot->SpellList[SpellNr] = 0; + } + + for(int QuestNr = 0; + QuestNr < NARRAY(Slot->QuestValues); + QuestNr += 1){ + Slot->QuestValues[QuestNr] = 0; + } + + // TODO(fusion): This one looks sketchy. + for(int SkillNr = 0; + SkillNr < NARRAY(Slot->Minimum); + SkillNr += 1){ + Slot->Minimum[SkillNr] = INT_MIN; + } + + this->LoseInventory = LOSE_INVENTORY_ALL; + } + + if(Slot->PlayerkillerEnd != 0){ + this->LoseInventory = LOSE_INVENTORY_ALL; + } + + if(CheckRight(this->ID, KEEP_INVENTORY)){ + this->LoseInventory = LOSE_INVENTORY_NONE; + } + } + + if(CheckRight(this->ID, READ_GAMEMASTER_CHANNEL)){ + CloseProcessedRequests(this->ID); + } + + if(this->Request != 0){ + if(this->RequestProcessingGamemaster == 0){ + DeleteGamemasterRequest(this->Name); + }else{ + TCreature *Gamemaster = GetCreature(this->RequestProcessingGamemaster); + if(Gamemaster != NULL){ + if(Gamemaster->Type == PLAYER){ + SendFinishRequest(Gamemaster->Connection, this->Name); + }else{ + error("GetPlayer: Kreatur ist kein Spieler.\n"); + } + } + } + this->Request = 0; + } + + LeaveAllChannels(this->ID); + + if(this->GetPartyLeader(false) != 0){ + ::LeaveParty(this->ID, true); + } + + this->ClearPlayerkillingMarks(); + this->DelInList(); + + Slot->Dirty = true; + // TODO(fusion): Something is telling me that `Slot->Sticky` is also poorly managed. + DecreasePlayerPoolSlotSticky(Slot); + ReleasePlayerPoolSlot(Slot); +} + +void TPlayer::SetInList(void){ + this->SetInCrList(); + + PlayerMutex.down(); + *PlayerList.at(FirstFreePlayer) = this; + FirstFreePlayer += 1; + PlayerMutex.up(); + + NotifyBuddies(this->ID, this->Name, true); + IncrementPlayersOnline(); + if(this->Profession == PROFESSION_NONE){ + IncrementNewbiesOnline(); + } +} + +void TPlayer::DelInList(void){ + NotifyBuddies(this->ID, this->Name, false); + + for(int Index = 0; Index < FirstFreePlayer; Index += 1){ + if(*PlayerList.at(Index) == this){ + // TODO(fusion): This can't be right? If the player at `Index` changes + // before entering the critical section, we could end up removing the + // wrong player from the list.. + PlayerMutex.down(); + FirstFreePlayer -= 1; + *PlayerList.at(Index) = *PlayerList.at(FirstFreePlayer); + *PlayerList.at(FirstFreePlayer) = NULL; + PlayerMutex.up(); + + DecrementPlayersOnline(); + if(this->Profession == PROFESSION_NONE){ + DecrementNewbiesOnline(); + } + + break; + } + } +} + uint8 TPlayer::GetRealProfession(void){ return this->Profession; } @@ -202,8 +551,10 @@ void CloseProcessedRequests(uint32 CharacterID){ continue; } - SendCloseRequest(Player->Connection); - Player->Request = 0; + if(Player->Request != 0 && Player->RequestProcessingGamemaster == CharacterID){ + SendCloseRequest(Player->Connection); + Player->Request = 0; + } } } @@ -930,8 +1281,8 @@ void InitPlayerIndex(void){ // be hardcoded. uint32 CharacterIDs[10000]; char Names[10000][30]; - TQueryManagerConnection *QueryManager = new TQueryManagerConnection(360007); - if(!QueryManager->isConnected()){ + TQueryManagerConnection QueryManager(360007); + if(!QueryManager.isConnected()){ error("InitPlayerIndex: Kann nicht zum Query-Manager verbinden.\n"); return; } @@ -939,7 +1290,7 @@ void InitPlayerIndex(void){ int MinimumCharacterID = 0; while(true){ int NumberOfPlayers; - int Ret = QueryManager->loadPlayers(MinimumCharacterID, + int Ret = QueryManager.loadPlayers(MinimumCharacterID, &NumberOfPlayers, Names, CharacterIDs); if(Ret != 0){ error("InitPlayerIndex: Kann Spielerdaten nicht ermitteln.\n"); @@ -956,8 +1307,6 @@ void InitPlayerIndex(void){ MinimumCharacterID = CharacterIDs[9999] + 1; } - - delete QueryManager; } void ExitPlayerIndex(void){ diff --git a/src/operate.cc b/src/operate.cc index 18829a3..7dc1fef 100644 --- a/src/operate.cc +++ b/src/operate.cc @@ -5,7 +5,6 @@ #include "stubs.hh" #include <dirent.h> -#include <time.h> static fifo<TStatement> Statements(1024); static fifo<TListener> Listeners(1024); diff --git a/src/stubs.hh b/src/stubs.hh index 719f88d..9c251ef 100644 --- a/src/stubs.hh +++ b/src/stubs.hh @@ -23,24 +23,20 @@ extern void CleanHouseField(int x, int y, int z); extern void ConvinceMonster(TCreature *Master, TCreature *Slave); extern void ChallengeMonster(TCreature *Challenger, TCreature *Monster); extern TCreature *CreateMonster(int Race, int x, int y, int z, int Home, uint32 Master, bool ShowEffect); -extern void CreatePlayerList(bool Online); -extern uint32 GetCharacterID(const char *Name); -extern const char *GetCharacterName(const char *Name); +extern void DeleteGamemasterRequest(const char *Name); extern void GetExitPosition(uint16 HouseID, int *x, int *y, int *z); extern TConnection *GetFirstConnection(void); extern TConnection *GetNextConnection(void); extern const char *GetHouseName(uint16 HouseID); extern const char *GetHouseOwner(uint16 HouseID); -extern TPlayer *GetPlayer(uint32 CreatureID); -extern void GetProfessionName(char *Buffer, int Profession, bool Article, bool Capitals); -extern int IdentifyPlayer(const char *Name, bool ExactMatch, bool IgnoreGamemasters, TPlayer **Player); extern void InitLog(const char *ProtocolName); +extern bool IsInvited(uint16 HouseID, TPlayer *Player, int TimeStamp); extern void KickGuest(uint16 HouseID, TPlayer *Host, TPlayer *Guest); extern void KillStatisticsOrder(int NumberOfRaces, const char *RaceNames, int *KilledPlayers, int *KilledCreatures); extern bool LagDetected(void); extern void LoadSectorOrder(int SectorX, int SectorY, int SectorZ); extern void Log(const char *ProtocolName, const char *Text, ...) ATTR_PRINTF(2, 3); -extern void LogoutAllPlayers(void); +extern void LogoutOrder(TPlayer *Player); extern void NetLoadCheck(void); extern void NetLoadSummary(void); extern void PrepareHouseCleanup(void); @@ -80,8 +76,12 @@ extern void SendChangeInContainer(TConnection *Connection, int ContainerNr, Obje extern void SendDeleteInventory(TConnection *Connection, int Position); extern void SendSetInventory(TConnection *Connection, int Position, Object Obj); extern void SendEditList(TConnection *Connection, uint8 ListType, uint32 ID, const char *Text); +extern void SendFinishRequest(TConnection *Connection, const char *Name); extern void SendFullScreen(TConnection *Connection); extern void SendFloors(TConnection *Connection, bool Up); +extern void SendInitGame(TConnection *Connection, uint32 CharacterID); +extern void SendRights(TConnection *Connection); +extern void SendOutfit(TConnection *Connection); extern void SendGraphicalEffect(TConnection *Connection, int x, int y, int z, int Type); extern void SendTextualEffect(TConnection *Connection, int x, int y, int z, int Color, const char *Text); extern void SendMissileEffect(TConnection *Connection, int OrigX, int OrigY, int OrigZ, int DestX, int DestY, int DestZ, int Type); diff --git a/src/time.cc b/src/time.cc index 0003c39..ad42c47 100644 --- a/src/time.cc +++ b/src/time.cc @@ -1,7 +1,5 @@ #include "common.hh" -#include <time.h> - // IMPORTANT(fusion): `RoundNr` is just the number of seconds since startup which // is why `GetRoundAtTime` and `GetRoundForNextMinute` straight up uses it as // seconds. It is incremented every 1 second inside `AdvanceGame`. @@ -12,12 +10,12 @@ uint32 ServerMilliseconds = 0; // NOTE(fusion): This isn't strictly required because each server process is // single threaded and don't share static memory, which is what the result of // the regular `localtime` function uses. -static struct tm GetLocalTimeTM(time_t timer){ +struct tm GetLocalTimeTM(time_t t){ struct tm result; #if COMPILER_MSVC - localtime_s(&result, &timer); + localtime_s(&result, &t); #else - localtime_r(&timer, &result); + localtime_r(&t, &result); #endif return result; } |
