Zdekompilowałem wykradziony serwer tibijski i pogrzebałem w kodzie. Muszę się poprawić, bo wygląda na to, że exhausty to jednak było dokładnie 1s i 2s dla normalnego pvp i 1/1 na enfo.
Funkcja CheckMana ma argument Delay, którym chyba jest nasz exhaust:
Kod:
// disasm -- show blocks -- show stats
void CheckMana(TCreature* cr, int Mana, int SoulPoints, int Delay)
{// addr = 0x0807EBD0 -- defined in 'magic.c' at line 294
TSkill* __ebp; // r6
TSkill* __esp; // r7
intOrPtr _v8; // _cfa_fffffff8
intOrPtr _v12; // _cfa_fffffff4
intOrPtr _v16; // _cfa_fffffff0
char _v20; // _cfa_ffffffec
_unknown_ _v36; // _cfa_ffffffdc (outparam)
int _v40; // _cfa_ffffffd8 (outparam)
int _t36; // _t36
char _t44; // _t44
TSkill* _t46; // _t46
TCreature* _t48; // _t48
struct TSkill* _t54; // _t54
struct TSkill* _t57; // _t57
_v16 = __ebx;
_t48 = cr;
_v12 = __esi;
_v8 = __edi;
if(_t48 == L00000000) {
*__esp = 135243392;
L17:
error();
__cxa_allocate_exception(4);
*_t36 = -1;
L14:
__cxa_throw(_t36, &_ZTI6RESULT, L00000000);
}
if(_t48->Type == L00000000) {
_t36 = Mana;
if(_t36 >= L00000000) {
_t57 = _t48->Skills[4];
_t54 = _t48->Skills[0x17];
if(_t57 == L00000000) {
*__esp = "CheckMana: Kein Skill MANA!\n";
goto L17;
}
if(_t54 == L00000000) {
*__esp = "CheckMana: Kein Skill SOULPOINTS!\n";
goto L17;
}
_t36 = CheckRight(_t48->ID, 62);
if(_t36 == L00000000) {
TSkill::Get(_t57);
__eflags = Mana - _t36;
if(Mana > _t36) {
__cxa_allocate_exception(4);
*_t36 = 35;
goto L14;
}
TSkill::Get(_t54);
__eflags = SoulPoints - _t36;
if(__eflags > 0) {
__cxa_allocate_exception(4);
*_t36 = 59;
goto L14;
}
TSkill::Change(_t57, ~Mana);
SoulPoints = ~SoulPoints;
TSkill::Change(_t54, SoulPoints);
}
if(Mana > L00000000) {
_t46 = _t48->Skills[2];
*__esp = _t46;
_v40 = Mana;
_t46->_vptr.TSkill[3]();
}
_t44 = Delay + ServerMilliseconds;
_v20 = _t44;
_t59 = _t48->EarliestSpellTime - _t44 >= 0 ? &(_t48->EarliestSpellTime) : &_v20;
_t45 = *(_t48->EarliestSpellTime - _t44 >= 0 ? &(_t48->EarliestSpellTime) : &_v20);
_t48->EarliestSpellTime = *(_t48->EarliestSpellTime - _t44 >= 0 ? &(_t48->EarliestSpellTime) : &_v20);
}
}
}
I w funkcji Heal mamy wywołanie CheckMana z argumentem 1000ms=1s
Kod:
// disasm -- show blocks -- show stats
void Heal(TCreature* cr, int Mana, int SoulPoints, int Healing)
{// addr = 0x08084880 -- defined in 'magic.c' at line 1728
TSkill* __edx; // r3
intOrPtr _v8; // _cfa_fffffff8
intOrPtr _v12; // _cfa_fffffff4
char _v28; // _cfa_ffffffe4
_unknown_ _v40; // _cfa_ffffffd8 (outparam)
_unknown_ _v44; // _cfa_ffffffd4 (outparam)
_unknown_ _v48; // _cfa_ffffffd0 (outparam)
_unknown_ _v52; // _cfa_ffffffcc (outparam)
intOrPtr _v56; // _cfa_ffffffc8 (outparam)
_None** _t29; // _t29
struct TSkill* _t39; // _t39
TCreature* _t42; // _t42
_v8 = __esi;
_t42 = cr;
_v12 = __ebx;
if(_t42 == L00000000) {
*__esp = 135248832;
L9:
error();
_t29 = __cxa_allocate_exception(4);
*_t29 = -1;
L10:
__cxa_throw(_t29, &_ZTI6RESULT, L00000000);
}
if(WorldType == 1) {
_t29 = _t42->_vptr.TCreature;
*__esp = _t42;
_t29[4]();
if(_t29 != L00000000) {
goto L2;
} else {
__cxa_allocate_exception(4);
*_t29 = 1;
goto L10;
}
L14:
}
L2:
CheckMana(_t42, Mana, SoulPoints, 1000);
_t39 = _t42->Skills[3];
if(_t39 == L00000000) {
*__esp = "Heal: Skill HITPOINTS existiert nicht.\n";
goto L9;
}
if(TSkill::Get(_t39) > L00000000) {
TSkill::Change(_t39, Healing);
if(_t42->Skills[5]->MDAct < L00000000) {
TSkillBase::SetTimer( &(_t42->Skills[1]), 4, L00000000, L00000000, L00000000, -1);
}
_v56 = 13;
_v28 = _t42->CrObject;
*__esp = &_v28;
GraphicalEffect();
}
return;
goto L14;
}
Natomiast w funkcji Combat mamy 2000 lub 1000 w zależności od typu serwera.
Kod:
// disasm -- show blocks -- show stats
void Combat(TCreature* cr, struct Object Target, int Mana, int SoulPoints, int Damage, int EffectNr, int AnimationNr, short unsigned int DmgType)
{// addr = 0x08080990 -- defined in 'magic.c' at line 802
intOrPtr _v8; // _cfa_fffffff8
intOrPtr _v12; // _cfa_fffffff4
intOrPtr _v16; // _cfa_fffffff0
intOrPtr _v44; // _cfa_ffffffd4
intOrPtr _v60; // _cfa_ffffffc4
intOrPtr _v76; // _cfa_ffffffb4
_unknown_ _v92; // _cfa_ffffffa4
_unknown_ _v96; // _cfa_ffffffa0
_unknown_ _v100; // _cfa_ffffff9c
_unknown_ _v104; // _cfa_ffffff98
struct TDamageImpact Impact; // _cfa_ffffff94
int z; // _cfa_ffffff90
int y; // _cfa_ffffff8c
int x; // _cfa_ffffff88
signed int _v124; // _cfa_ffffff84
int _v148; // _cfa_ffffff6c
int* _v152; // _cfa_ffffff68 (outparam)
void* _v156; // _cfa_ffffff64 (outparam)
int _v160; // _cfa_ffffff60 (outparam)
int* _v164; // _cfa_ffffff5c (outparam)
int _v168; // _cfa_ffffff58 (outparam)
int _v172; // _cfa_ffffff54 (outparam)
int _v176; // _cfa_ffffff50 (outparam)
void* _t82; // _t82
struct Object _t87; // _t87
struct ObjectType _t88; // _t88
struct Object* _t110; // _t110
TCreature* _t120; // _t120
_v16 = __ebx;
_t110 = Target.ObjectID;
_v8 = __edi;
_t120 = cr;
_v12 = __esi;
_v124 = DmgType & 65535;
if(Object::exists(_t110) == L00000000) {
*__esp = 135245312;
L11:
error();
_t82 = __cxa_allocate_exception(4);
*_t82 = -1;
L7:
__cxa_throw(_t82, &_ZTI6RESULT, L00000000);
}
if(_t120 == L00000000) {
*__esp = 135245248;
goto L11;
}
_v160 = &z;
_v44 = _t110->ObjectID;
_v164 = &y;
_v168 = &x;
*__esp = &_v44;
GetObjectCoordinates();
_v168 = _t110;
Object::getObjectType( &_v44);
__esp = __esp - 4;
if(_v44 != 99) {
ObjectType::setTypeID( &_v76, 99);
_v160 = &_v76;
GetFirstSpecObject( &_v60, x, y, z);
_t87 = _v60;
__esp = __esp - 4;
_t110->ObjectID = _t87;
_v44 = _t87;
}
_t88 = NONE;
_v76 = _t88;
if( *_t110 == _t88) {
_t82 = __cxa_allocate_exception(4);
*_t82 = 39;
goto L7;
}
CheckAffectedPlayers(_t120, x, y, z);
if(ThrowPossible(_t120->posx, _t120->posy, _t120->posz, x, y, z, L00000000) == L00000000) {
_t82 = __cxa_allocate_exception(4);
*_t82 = 7;
goto L7;
}
*__esp = _t120;
_t112 = WorldType != 2 ? 2000 : 1000;
_v168 = WorldType != 2 ? 2000 : 1000;
_v172 = SoulPoints;
_v176 = Mana;
CheckMana();
Impact._vptr.TImpact = 135428936;
Impact.Actor = _t120;
Impact.AllowDefense = L00000000;
Impact.DamageType = _v124;
_v152 = &(Impact._vptr.TImpact);
_v156 = L00000000;
Impact.Power = Damage;
_v164 = 2147483647;
*__esp = _t120;
_v148 = EffectNr;
_v160 = AnimationNr;
_v168 = z;
_v172 = y;
_v176 = x;
CircleShapeSpell();
}
Dziwne jest jednak to, że można było walnąć:
0s - bolt
0s - hmm
2s - hmm (przed boltem)
Ale exhaust faktycznie był 2 sekundy.
A jeśli chodzi o exhaust po manasie, to tak jak pisałem - był i wynosił też 1 sekundę.
Funkcja DrinkPotion dla manasa wywołuje funkcję RefreshMana, a ta z kolei CheckMana z argumentem 1000.
Kod:
// disasm -- show blocks -- show stats
void RefreshMana(TCreature* cr, int Mana, int SoulPoints, int AddMana)
{// addr = 0x08084FA0 -- defined in 'magic.c' at line 1831
TSkill* __ecx; // r2
intOrPtr _v8; // _cfa_fffffff8
char _v28; // _cfa_ffffffe4
_unknown_ _v32; // _cfa_ffffffe0 (outparam)
_unknown_ _v36; // _cfa_ffffffdc (outparam)
intOrPtr _v40; // _cfa_ffffffd8 (outparam)
void* _t18; // _t18
TCreature* _t24; // _t24
_v8 = __ebx;
_t24 = cr;
if(_t24 == L00000000) {
*__esp = 135249344;
L4:
error();
_t18 = __cxa_allocate_exception(4);
*_t18 = -1;
__cxa_throw(_t18, &_ZTI6RESULT, L00000000);
}
CheckMana(_t24, Mana, SoulPoints, 1000);
__edx = _t24->Skills[4];
if(__edx == L00000000) {
*__esp = "RefreshMana: Skill MANA existiert nicht.\n";
goto L4;
}
TSkill::Change(__edx, AddMana);
_v40 = 13;
_v28 = _t24->CrObject;
*__esp = &_v28;
GraphicalEffect();
}
Dotyczy to zresztą też life fluida, dla którego jest wywoływane Heal, tak jak wyżej.
pzdr
Zakładki