aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-06-08 02:16:45 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-06-08 02:16:45 -0300
commitab9f606371a1df23e9cacbffa0811db7a9e50100 (patch)
treeb5bca97b18977197eb4b5b33f1f1076dcd22e70b
parent0590a5f1b3e0ffe295d7894a16b9d8aff3fae586 (diff)
downloadgame-ab9f606371a1df23e9cacbffa0811db7a9e50100.tar.gz
game-ab9f606371a1df23e9cacbffa0811db7a9e50100.zip
more `cract.cc` functions
-rw-r--r--reference/game.c365
-rw-r--r--src/cr.hh3
-rw-r--r--src/cract.cc207
-rw-r--r--src/crplayer.cc9
-rw-r--r--src/crskill.cc2
-rw-r--r--src/enums.hh2
-rw-r--r--src/magic.cc6
-rw-r--r--src/stubs.hh3
8 files changed, 223 insertions, 374 deletions
diff --git a/reference/game.c b/reference/game.c
index 0a5a2e5..fec668b 100644
--- a/reference/game.c
+++ b/reference/game.c
@@ -43304,239 +43304,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
return;
}
-// DWARF original prototype: void Go(TCreature * this, int x, int y, int z)
-
-void __thiscall TCreature::Go(TCreature *this,int x,int y,int z)
-
-{
- TSkill *pTVar1;
- bool bVar2;
- uint uVar3;
- int iVar4;
- CreatureType CVar5;
- undefined4 *puVar6;
- int iVar7;
- int iVar8;
- int iVar9;
- int *piVar10;
- int iVar11;
- int Delay;
- int dy;
- int local_54;
- int local_50;
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c [7];
-
- if (z == this->posz) {
- uVar3 = x - this->posx;
- if (0x7fffffff < uVar3) {
- uVar3 = -uVar3;
- }
- if ((int)uVar3 < 2) {
- uVar3 = y - this->posy;
- if (0x7fffffff < uVar3) {
- uVar3 = -uVar3;
- }
- if ((int)uVar3 < 2) {
- pTVar1 = (this->super_TSkillBase).Skills[0x14];
- if (((pTVar1 != (TSkill *)0x0) &&
- (iVar8 = (*pTVar1->_vptr_TSkill[0xd])(pTVar1), 0 < iVar8)) &&
- (iVar8 = TSkill::Get((this->super_TSkillBase).Skills[0x14]), iVar8 == 0)) {
- iVar8 = rand();
- pTVar1 = (this->super_TSkillBase).Skills[0x14];
- iVar9 = (*pTVar1->_vptr_TSkill[0xd])(pTVar1);
- if (iVar8 % (7 - iVar9) == 0) {
- Delay = 0;
- iVar9 = 0;
- iVar8 = rand();
- iVar8 = iVar8 % 4;
- if (iVar8 == 1) {
- iVar9 = -1;
- }
- else if (iVar8 < 2) {
- if (iVar8 == 0) {
- iVar9 = 1;
- }
- }
- else if (iVar8 == 2) {
- Delay = 1;
- iVar9 = 0;
- }
- else if (iVar8 == 3) {
- Delay = -1;
- iVar9 = 0;
- }
- x = iVar9 + this->posx;
- y = Delay + this->posy;
- bVar2 = ToDoClear(this);
- if ((bVar2) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- ToDoTalk(this);
- if (this->NrToDo != 0) {
- this->LockToDo = true;
- this->ActToDo = 0;
- local_50 = CalculateDelay(this);
- local_54 = 1;
- piVar10 = &local_54;
- if (0 < local_50) {
- piVar10 = &local_50;
- }
- iVar8 = *piVar10;
- priority_queue<>::insert(&ToDoQueue);
- this->NextWakeup = iVar8 + ServerMilliseconds;
- }
- }
- }
- // try { // try from 080bf247 to 080bf65d has its CatchHandler @ 080bf6b8
- iVar9 = x;
- iVar8 = y;
- iVar11 = z;
- iVar4 = (*this->_vptr_TCreature[3])(this,x,y,z,1,0);
- if ((char)iVar4 != '\0') goto LAB_080bf2f7;
- if (this->Type == PLAYER) {
- CVar5 = PLAYER;
- if (0 < z) {
- iVar8 = this->posz;
- iVar9 = this->posy;
- iVar4 = GetHeight();
- if (0x17 < iVar4) {
- if (this->posx == x) {
- iVar4 = this->posy;
- }
- else {
- iVar4 = this->posy;
- if (iVar4 != y) goto LAB_080bf2a4;
- }
- iVar11 = 0;
- iVar7 = z + -1;
- iVar8 = iVar7;
- bVar2 = CoordinateFlag();
- iVar9 = iVar4;
- if (!bVar2) {
- iVar11 = 0x20;
- iVar9 = this->posy;
- iVar8 = iVar7;
- bVar2 = CoordinateFlag();
- if ((!bVar2) &&
- (iVar9 = x, iVar8 = y, iVar11 = iVar7,
- iVar4 = (*this->_vptr_TCreature[3])(this,x,y,iVar7,1,1),
- (char)iVar4 != '\0')) {
- z = iVar7;
- }
- }
- }
-LAB_080bf2a4:
- CVar5 = this->Type;
- }
- if ((CVar5 == PLAYER) && (z < 0xf)) {
- iVar4 = z + 1;
- iVar9 = y;
- iVar8 = iVar4;
- iVar7 = GetHeight();
- if ((0x17 < iVar7) && ((this->posx == x || (this->posy == y)))) {
- iVar11 = 0;
- iVar9 = y;
- iVar8 = z;
- bVar2 = CoordinateFlag();
- if (!bVar2) {
- iVar11 = 0x20;
- iVar9 = y;
- iVar8 = z;
- bVar2 = CoordinateFlag();
- if ((!bVar2) &&
- (iVar9 = x, iVar8 = y, iVar11 = iVar4,
- iVar7 = (*this->_vptr_TCreature[3])(this,x,y,iVar4,1,1),
- (char)iVar7 != '\0')) {
- z = iVar4;
- }
- }
- }
- }
- }
- if ((z != this->posz) &&
- (iVar9 = x, iVar8 = y, iVar4 = (*this->_vptr_TCreature[3])(this,x,y,z,1,1),
- iVar11 = z, (char)iVar4 != '\0')) {
-LAB_080bf2f7:
- local_2c[0].ObjectID = ::NONE.ObjectID;
- GetMapContainer((int)local_3c,x,y);
- local_4c[0].ObjectID = (this->CrObject).ObjectID;
- ::Move(this->ID,local_4c,local_3c,-1,false,local_2c);
- return;
- }
- puVar6 = (undefined4 *)__cxa_allocate_exception(4,iVar9,iVar8,iVar11);
- *puVar6 = 0x34;
- goto LAB_080bf372;
- }
- }
- }
- puVar6 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar6 = 1;
-LAB_080bf372:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar6,&RESULT::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void Rotate(TCreature * this, uchar Dir)
-
-void __thiscall TCreature::Rotate(TCreature *this,uchar Dir)
-
-{
- Object local_1c [6];
-
- local_1c[0].ObjectID = (this->CrObject).ObjectID;
- this->Direction = (uint)Dir;
- AnnounceChangedObject(local_1c,2);
- return;
-}
-
-
-
-// DWARF original prototype: void Rotate(TCreature * this, TCreature * Target)
-
-void __thiscall TCreature::Rotate(TCreature *this,TCreature *Target)
-
-{
- uint uVar1;
- int dy;
- uint uVar2;
- int iVar3;
- int dx;
- int iVar4;
- Object local_1c [4];
-
- if (Target == (TCreature *)0x0) {
- error("TCreature::Rotate: Target ist NULL.\n");
- }
- else {
- iVar4 = Target->posx - this->posx;
- uVar2 = Target->posy - this->posy;
- iVar3 = -iVar4;
- if (-1 < iVar4) {
- iVar3 = iVar4;
- }
- uVar1 = -uVar2;
- if (-1 < (int)uVar2) {
- uVar1 = uVar2;
- }
- if (iVar3 < (int)uVar1) {
- uVar2 = ((int)~uVar2 >> 0x1f) * -2;
- }
- else {
- uVar2 = (iVar4 >> 0x1f) * -2 + 1;
- }
- local_1c[0].ObjectID = (this->CrObject).ObjectID;
- this->Direction = uVar2 & 0xff;
- AnnounceChangedObject(local_1c,2);
- }
- return;
-}
-
-
-
// DWARF original prototype: void Move(TCreature * this, Object * Obj, int zx, int zy, int zz, uchar
// Count)
@@ -44509,138 +44276,6 @@ LAB_080c12f2:
return;
}
-// DWARF original prototype: void Execute(TCreature * this)
-
-void __thiscall TCreature::Execute(TCreature *this)
-
-{
- bool bVar1;
- int iVar2;
- TToDoEntry *pTVar3;
- undefined4 *puVar4;
- char *Addressee;
- int Delay;
- int Delay_1;
- char *pcVar5;
- bool SnapbackNecessary;
- TToDoEntry TD_1;
- Object local_5c [4];
- Object local_4c [4];
- ToDoType local_3c;
- TToDoEntry TD;
-
- do {
- if (this->LockToDo == false) {
- return;
- }
- if (this->IsDead != false) {
- return;
- }
- if (ServerMilliseconds < this->NextWakeup) {
- return;
- }
- if (this->NrToDo <= this->ActToDo) {
- ToDoClear(this);
- (*this->_vptr_TCreature[8])(this);
- return;
- }
- iVar2 = CalculateDelay(this);
- if (0 < iVar2) {
- if (this->Stop == false) {
- priority_queue<>::insert(&ToDoQueue);
- this->NextWakeup = iVar2 + ServerMilliseconds;
- return;
- }
- ToDoClear(this);
- if (this->Type != PLAYER) {
- return;
- }
- SendSnapback(this->Connection);
- return;
- }
- pTVar3 = vector<TToDoEntry>::operator()(&this->ToDoList,this->ActToDo);
- local_3c = pTVar3->Code;
- TD.Code = (pTVar3->field_1).Move.Obj;
- TD.field_1.Wait.Time =
- (anon_struct_4_1_898373eb_for_Wait)*(ToDoType *)((int)&pTVar3->field_1 + 4);
- TD.field_1.Go.y = *(int *)((int)&pTVar3->field_1 + 8);
- TD.field_1.Go.z = *(int *)((int)&pTVar3->field_1 + 0xc);
- TD.field_1.Move.z = *(int *)((int)&pTVar3->field_1 + 0x10);
- this->ActToDo = this->ActToDo + 1;
- switch(local_3c) {
- case TDGo:
- // try { // try from 080c1bb6 to 080c1ca3 has its CatchHandler @ 080c2050
- Go(this,TD.Code,TD.field_1.Go.x,TD.field_1.Go.y);
- break;
- case TDRotate:
- local_4c[0].ObjectID = (this->CrObject).ObjectID;
- this->Direction = TD.Code & 0xff;
- AnnounceChangedObject(local_4c,2);
- break;
- case TDMove:
- local_4c[0].ObjectID = TD.Code;
- Move(this,local_4c,TD.field_1.Go.x,TD.field_1.Go.y,TD.field_1.Go.z,
- (uchar)TD.field_1.Move.z);
- break;
- case TDTrade:
- local_4c[0].ObjectID = TD.Code;
- Trade(this,local_4c,TD.field_1.Move.Obj);
- break;
- case TDUse:
- local_5c[0].ObjectID = TD.Code;
- local_4c[0].ObjectID = (ulong)TD.field_1.Wait.Time;
- Use(this,local_5c,local_4c,(uchar)TD.field_1.Trade.Partner);
- break;
- case TDTurn:
- local_5c[0].ObjectID = TD.Code;
- // try { // try from 080c1cb5 to 080c1d07 has its CatchHandler @ 080c1e43
- bVar1 = Object::exists(local_5c);
- if (!bVar1) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x1f;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
- }
- local_4c[0].ObjectID = local_5c[0].ObjectID;
- ::Turn(this->ID,local_4c);
- break;
- case TDAttack:
- // try { // try from 080c1d11 to 080c1d15 has its CatchHandler @ 080c1e43
- TCombat::Attack(&this->Combat);
- break;
- case TDTalk:
- if (TD.Code == TDWait) {
- pcVar5 = "TCreature::Execute: TD.Text ist Null bei %s.\n";
-LAB_080c1d33:
- // try { // try from 080c1d33 to 080c1dc3 has its CatchHandler @ 080c2050
- error(pcVar5,this->Name);
- }
- else {
- pcVar5 = GetDynamicString(TD.Code);
- if (pcVar5 == (char *)0x0) {
- pcVar5 = "TCreature::Execute: Text ist NULL bei %s.\n";
- goto LAB_080c1d33;
- }
- }
- pcVar5 = GetDynamicString(TD.Code);
- Addressee = GetDynamicString(TD.field_1.Trade.Partner);
- Talk(this->ID,TD.field_1.Go.x,Addressee,pcVar5,SUB41(TD.field_1.Go.z,0));
- break;
- case TDChangeState:
- if (this->Type == NPC) {
- ChangeNPCState(this,TD.Code,true);
- }
- }
- if (this->Stop != false) {
- ToDoClear(this);
- if (this->Type == PLAYER) {
- SendSnapback(this->Connection);
- }
- return;
- }
- } while( true );
-}
-
// WARNING: Unknown calling convention -- yet parameter storage is locked
void _GLOBAL__I__ZN9TShortwayC2EP9TCreatureii(void)
diff --git a/src/cr.hh b/src/cr.hh
index e82b17b..37a9f3d 100644
--- a/src/cr.hh
+++ b/src/cr.hh
@@ -496,6 +496,9 @@ struct TCreature: TSkillBase {
// cract.cc
bool SetOnMap(void);
bool DelOnMap(void);
+ void Go(int DestX, int DestY, int DestZ);
+ void Rotate(int Direction);
+ void Rotate(TCreature *Target);
void Attack(void);
void Execute(void);
uint32 CalculateDelay(void);
diff --git a/src/cract.cc b/src/cract.cc
index cfbbe95..c4e85b6 100644
--- a/src/cract.cc
+++ b/src/cract.cc
@@ -326,11 +326,216 @@ bool TCreature::DelOnMap(void){
return Result;
}
+void TCreature::Go(int DestX, int DestY, int DestZ){
+ // NOTE(fusion): This is the execution function for `ToDoGo` which computes
+ // the path step by step. If the destination is outside the range of a single
+ // step, then it is an error.
+ int OrigX = this->posx;
+ int OrigY = this->posy;
+ int OrigZ = this->posz;
+ int Distance = std::max<int>(std::abs(OrigX - DestX), std::abs(OrigY - DestY));
+ if(Distance > 1 || OrigZ != DestZ){
+ throw NOTACCESSIBLE;
+ }
+
+ // TODO(fusion): See note in `TPlayer::CheckState`.
+ int DrunkLevel = this->Skills[SKILL_DRUNKEN]->TimerValue();
+ if(DrunkLevel > 0 && this->Skills[SKILL_DRUNKEN]->Get() == 0){
+ int StaggerChance = std::max<int>(7 - DrunkLevel, 1);
+ if(rand() % StaggerChance == 0){
+ DestX = OrigX;
+ DestY = OrigY;
+ switch(rand() % 4){
+ case DIRECTION_NORTH: DestY -= 1; break;
+ case DIRECTION_EAST: DestX += 1; break;
+ case DIRECTION_SOUTH: DestY += 1; break;
+ case DIRECTION_WEST: DestX -= 1; break;
+ }
+
+ if(this->ToDoClear() && this->Type == PLAYER){
+ SendSnapback(this->Connection);
+ }
+
+ int TalkMode = (this->Type == MONSTER) ? TALK_ANIMAL_LOW : TALK_SAY;
+ this->ToDoTalk(TalkMode, NULL, "Hicks!", false);
+ this->ToDoStart();
+ }
+ }
+
+ if(!this->MovePossible(DestX, DestY, DestZ, true, false)){
+ bool Diagonal = (OrigX != DestX && OrigY != DestY);
+ if(this->Type == PLAYER && !Diagonal){
+ // TODO(fusion): These are quite similar to `MagicClimbing`. Perhaps
+ // there is an inlined function here that checks whether climbing is
+ // possible.
+ if(DestZ > 0 && GetHeight(OrigX, OrigY, OrigZ) >= 24
+ && !CoordinateFlag(OrigX, OrigY, OrigZ - 1, BANK)
+ && !CoordinateFlag(OrigX, OrigY, OrigZ - 1, UNPASS)
+ && this->MovePossible(DestX, DestY, DestZ - 1, true, true)){
+ DestZ -= 1;
+ }else if(DestZ < 15 && GetHeight(DestX, DestY, DestZ + 1) >= 24
+ && !CoordinateFlag(DestX, DestY, DestZ, BANK)
+ && !CoordinateFlag(DestX, DestY, DestZ, UNPASS)
+ && this->MovePossible(DestX, DestY, DestZ + 1, true, true)){
+ DestZ += 1;
+ }
+ }
+
+ if(this->posz == DestZ){
+ throw MOVENOTPOSSIBLE;
+ }
+ }
+
+ Object Dest = GetMapContainer(DestX, DestY, DestZ);
+ Move(this->ID, this->CrObject, Dest, -1, false, NONE);
+}
+
+void TCreature::Rotate(int Direction){
+ this->Direction = Direction;
+ AnnounceChangedObject(this->CrObject, 2); // OBJECT_CHANGED ?
+}
+
+void TCreature::Rotate(TCreature *Target){
+ if(Target == NULL){
+ error("TCreature::Rotate: Target ist NULL.\n");
+ return;
+ }
+
+ int Direction = this->Direction;
+ int OffsetX = Target->posx - this->posx;
+ int OffsetY = Target->posy - this->posy;
+ int DistanceX = std::abs(OffsetX);
+ int DistanceY = std::abs(OffsetY);
+ if(DistanceY > DistanceX){
+ Direction = (OffsetY < 0) ? DIRECTION_NORTH : DIRECTION_SOUTH;
+ }else{
+ Direction = (OffsetX < 0) ? DIRECTION_WEST : DIRECTION_EAST;
+ }
+
+ this->Rotate(Direction);
+}
+
void TCreature::Attack(void){
this->Combat.Attack();
}
-//void TCreature::Execute(void);
+void TCreature::Execute(void){
+ while(true){
+ if(!this->LockToDo || this->IsDead || this->NextWakeup > ServerMilliseconds){
+ break;
+ }
+
+ if(this->NrToDo <= this->ActToDo){
+ this->ToDoClear();
+ this->IdleStimulus();
+ break;
+ }
+
+ uint32 Delay = this->CalculateDelay();
+ if(Delay > 0){
+ if(this->Stop){
+ this->ToDoClear();
+ if(this->Type == PLAYER){
+ SendSnapback(this->Connection);
+ }
+ }else{
+ this->NextWakeup = ServerMilliseconds + Delay;
+ ToDoQueue.insert(this->NextWakeup, this->ID);
+ }
+ break;
+ }
+
+ TToDoEntry TD = *this->ToDoList.at(this->ActToDo);
+ this->ActToDo += 1;
+ try{
+ switch(TD.Code){
+ case TDGo:{
+ this->Go(TD.Go.x, TD.Go.y, TD.Go.z);
+ break;
+ }
+
+ case TDRotate:{
+ this->Rotate(TD.Rotate.Direction);
+ break;
+ }
+
+ case TDMove:{
+ this->Move(TD.Move.Obj, TD.Move.x, TD.Move.y, TD.Move.z, TD.Move.Count);
+ break;
+ }
+
+ case TDTrade:{
+ this->Trade(TD.Trade.Obj, TD.Trade.Partner);
+ break;
+ }
+
+ case TDUse:{
+ this->Use(TD.Use.Obj1, TD.Use.Obj2, TD.Use.Dummy);
+ break;
+ }
+
+ case TDTurn:{
+ this->Turn(TD.Turn.Obj);
+ break;
+ }
+
+ case TDAttack:{
+ this->Attack();
+ break;
+ }
+
+ case TDTalk:{
+ const char *Text = GetDynamicString(TD.Talk.Text);
+ if(Text != NULL){
+ const char *Addressee = GetDynamicString(TD.Talk.Addressee);
+ Talk(this->ID, TD.Talk.Mode, Addressee, Text, TD.Talk.CheckSpamming);
+ }else{
+ error("TCreature::Execute: Text ist NULL bei %s.\n", this->Name);
+ }
+ break;
+ }
+
+ case TDChangeState:{
+ if(this->Type == NPC){
+ ChangeNPCState(this, TD.ChangeState.NewState, true);
+ }
+ break;
+ }
+
+ default:{
+ break;
+ }
+ }
+ }catch(RESULT r){
+ bool SnapbackNecessary = (this->ToDoClear() || this->Stop);
+ if(r == EXHAUSTED){
+ this->ToDoWait(1000);
+ this->ToDoStart();
+ }else{
+ this->ToDoYield();
+ }
+
+ if(this->Type == PLAYER){
+ SendResult(this->Connection, r);
+ if(SnapbackNecessary
+ && r != MOVENOTPOSSIBLE
+ && r != NOTINVITED
+ && r != ENTERPROTECTIONZONE){
+ SendSnapback(this->Connection);
+ }
+ }
+ break;
+ }
+
+ if(this->Stop){
+ this->ToDoClear();
+ if(this->Type == PLAYER){
+ SendSnapback(this->Connection);
+ }
+ break;
+ }
+ }
+}
uint32 TCreature::CalculateDelay(void){
uint32 Delay = 0;
diff --git a/src/crplayer.cc b/src/crplayer.cc
index 3193843..5b87ec8 100644
--- a/src/crplayer.cc
+++ b/src/crplayer.cc
@@ -45,12 +45,15 @@ void TPlayer::CheckState(void){
State |= 0x04;
}
- // TODO(fusion): Not sure about this one.
- if(this->Skills[SKILL_DRUNK]->TimerValue() > 0 && this->Skills[SKILL_DRUNK]->Get() == 0){
+ // TODO(fusion): I think the result from `Get()` here tells whether the
+ // player has some drunk suppression item equipped?
+ if(this->Skills[SKILL_DRUNKEN]->TimerValue() > 0
+ && this->Skills[SKILL_DRUNKEN]->Get() == 0){
State |= 0x08;
}
- if(this->Skills[SKILL_MANASHIELD]->TimerValue() > 0 || this->Skills[SKILL_MANASHIELD]->Get() > 0){
+ if(this->Skills[SKILL_MANASHIELD]->TimerValue() > 0
+ || this->Skills[SKILL_MANASHIELD]->Get() > 0){
State |= 0x10;
}
diff --git a/src/crskill.cc b/src/crskill.cc
index 84402ee..b1a9d42 100644
--- a/src/crskill.cc
+++ b/src/crskill.cc
@@ -1294,7 +1294,7 @@ int GetSkillByName(const char *Name){
}else if(strcmp(Name, "energy") == 0){
Result = SKILL_ENERGY;
}else if(strcmp(Name, "drunken") == 0){
- Result = SKILL_DRUNK;
+ Result = SKILL_DRUNKEN;
}else if(strcmp(Name, "manashield") == 0){
Result = SKILL_MANASHIELD;
}else if(strcmp(Name, "soulpoints") == 0){
diff --git a/src/enums.hh b/src/enums.hh
index 4801e49..2505618 100644
--- a/src/enums.hh
+++ b/src/enums.hh
@@ -430,7 +430,7 @@ enum Skill: int {
SKILL_POISON = 17,
SKILL_BURNING = 18,
SKILL_ENERGY = 19,
- SKILL_DRUNK = 20,
+ SKILL_DRUNKEN = 20,
SKILL_MANASHIELD = 21,
SKILL_SOUL = 22,
};
diff --git a/src/magic.cc b/src/magic.cc
index 53ec1da..1caf83b 100644
--- a/src/magic.cc
+++ b/src/magic.cc
@@ -279,9 +279,9 @@ void TDrunkenImpact::handleCreature(TCreature *Victim){
int Power = this->Power;
int Duration = this->Duration;
- TSkill *Drunk = Victim->Skills[SKILL_DRUNK];
- if(Drunk->TimerValue() <= Power){
- Victim->SetTimer(SKILL_DRUNK, Power, Duration, Duration, -1);
+ TSkill *Drunken = Victim->Skills[SKILL_DRUNKEN];
+ if(Drunken->TimerValue() <= Power){
+ Victim->SetTimer(SKILL_DRUNKEN, Power, Duration, Duration, -1);
}
}
diff --git a/src/stubs.hh b/src/stubs.hh
index d936ab5..f2f1f0b 100644
--- a/src/stubs.hh
+++ b/src/stubs.hh
@@ -16,6 +16,7 @@ typedef void TSendMailsFunction(TPlayerData *PlayerData);
extern void AbortWriter(void);
extern void AnnounceChangedCreature(uint32 CreatureID, int Type);
+extern void AnnounceChangedObject(Object Obj, int Type);
extern void BroadcastMessage(int Mode, const char *Text, ...) ATTR_PRINTF(2, 3);
extern void Change(Object Obj, ObjectType NewType, uint32 Value);
extern void ChangeNPCState(TCreature *Npc, int NewState, bool Stimulus);
@@ -37,6 +38,7 @@ extern Object GetBodyObject(uint32 CreatureID, int Position);
extern Object GetBodyContainer(uint32 CreatureID, int Position);
extern void GetExitPosition(uint16 HouseID, int *x, int *y, int *z);
extern TConnection *GetFirstConnection(void);
+extern int GetHeight(int x, int y, int z);
extern TConnection *GetNextConnection(void);
extern const char *GetName(Object Obj);
extern Object GetObject(uint32 CreatureID, int x, int y, int z, int RNum, ObjectType Type);
@@ -88,6 +90,7 @@ extern void SendSnapback(TConnection *Connection);
extern void ShowGuestList(uint16 HouseID, TPlayer *Player, char *Buffer);
extern void ShowSubownerList(uint16 HouseID, TPlayer *Player, char *Buffer);
extern void ShowNameDoor(Object Door, TPlayer *Player, char *Buffer);
+extern void Talk(uint32 CreatureID, int Mode, const char *Addressee, const char *Text, bool CheckSpamming);
extern void TextualEffect(Object Obj, int Color, const char *Text, ...) ATTR_PRINTF(3, 4);
extern bool ThrowPossible(int FromX, int FromY, int FromZ,
int ToX, int ToY, int ToZ, int Power);