void Pulse() { if (!ppCharSpawn || !pCharSpawn) return; PSPAWNINFO pCharOrMount = NULL; PCHARINFO pCharInfo = GetCharInfo(); PSPAWNINFO pChar = pCharOrMount = (PSPAWNINFO)pCharSpawn; if (pCharInfo && pCharInfo->pSpawn) pChar = pCharInfo->pSpawn; static WORD LastZone = -1; static PSPAWNINFO pCharOld = NULL; static FLOAT LastX = 0.0f; static FLOAT LastY = 0.0f; static ULONGLONG LastMoveTick = 0; static DWORD MapDelay = 0; static DWORD LastHealth = 0; static DWORD LastMana = 0; static DWORD LastEndurance = 0; // Drop out here if we're waiting for something. if (!pChar || gZoning /* || gDelayZoning*/) return; if (!pCharInfo) { //DebugSpew("Pulse: no charinfo returning\n"); return; } if ((unsigned int)GetCharInfo()->charinfo_info & 0x80000000) return; if (pChar != pCharOld && WereWeZoning) { WereWeZoning = FALSE; pCharOld = pChar; gFaceAngle = 10000.0f; gLookAngle = 10000.0f; gbMoving = FALSE; LastX = pChar->X; LastY = pChar->Y; LastMoveTick = MQGetTickCount64(); EnviroTarget.Name[0] = 0; pGroundTarget = 0; DoorEnviroTarget.Name[0] = 0; pDoorTarget = 0; LastHealth = GetCurHPS(); LastMana = GetCharInfo2()->Mana; LastEndurance = GetCharInfo2()->Endurance; ManaGained = 0; HealthGained = 0; EnduranceGained = 0; // see if we're on a pvp server if (!_strnicmp(EQADDR_SERVERNAME, "tallon", 6) || !_strnicmp(EQADDR_SERVERNAME, "vallon", 6)) { PVPServer = PVP_TEAM; } else if (!_strnicmp(EQADDR_SERVERNAME, "sullon", 6)) { PVPServer = PVP_SULLON; } else if (!_strnicmp(EQADDR_SERVERNAME, "rallos", 6)) { PVPServer = PVP_RALLOS; } else PVPServer = PVP_NONE; srand((unsigned int)time(NULL) + (unsigned int)GetCurrentProcessId()); // reseed Benchmark(bmPluginsOnZoned, PluginsZoned()); } else if ((LastX != pChar->X) || (LastY != pChar->Y) || LastMoveTick>MQGetTickCount64() - 100) { if ((LastX != pChar->X) || (LastY != pChar->Y)) LastMoveTick = MQGetTickCount64(); gbMoving = TRUE; LastX = pChar->X; LastY = pChar->Y; } else { gbMoving = FALSE; } DWORD CurrentHealth = GetCurHPS(); if (LastHealth && CurrentHealth>LastHealth) { if ((int)pChar->HPCurrent != GetMaxHPS()) { // gained health, and not max HealthGained = CurrentHealth - LastHealth; } } LastHealth = CurrentHealth; if (LastMana && GetCharInfo2()->Mana > LastMana) { if ((int)GetCharInfo2()->Mana - LastMana > 0) { ManaGained = GetCharInfo2()->Mana - LastMana; } } LastMana = GetCharInfo2()->Mana; if (LastEndurance && GetCharInfo2()->Endurance > LastEndurance) { if (GetCharInfo2()->Endurance != GetMaxEndurance()) { EnduranceGained = GetCharInfo2()->Endurance - LastEndurance; } } LastEndurance = GetCharInfo2()->Endurance; if (gbDoAutoRun && pChar && pCharInfo) { gbDoAutoRun = FALSE; #ifndef EMU InitKeyRings(); #endif CHAR szServerAndName[MAX_STRING] = { 0 }; CHAR szAutoRun[MAX_STRING] = { 0 }; PCHAR pAutoRun = szAutoRun; /* autorun for everyone */ GetPrivateProfileString("AutoRun", "ALL", "", szAutoRun, MAX_STRING, gszINIFilename); while (pAutoRun[0] == ' ' || pAutoRun[0] == '\t') pAutoRun++; if (szAutoRun[0] != 0) DoCommand(pChar, pAutoRun); /* autorun for toon */ ZeroMemory(szAutoRun, MAX_STRING); pAutoRun = szAutoRun; sprintf(szServerAndName, "%s.%s", EQADDR_SERVERNAME, pCharInfo->Name); GetPrivateProfileString("AutoRun", szServerAndName, "", szAutoRun, MAX_STRING, gszINIFilename); while (pAutoRun[0] == ' ' || pAutoRun[0] == '\t') pAutoRun++; if (szAutoRun[0] != 0) DoCommand(pChar, pAutoRun); } if ((gFaceAngle != 10000.0f) || (gLookAngle != 10000.0f)) { TurnNotDone = FALSE; if (gFaceAngle != 10000.0f) { if (abs((INT)(pCharOrMount->Heading - gFaceAngle)) < 10.0f) { pCharOrMount->Heading = (FLOAT)gFaceAngle; pCharOrMount->SpeedHeading = 0.0f; gFaceAngle = 10000.0f; } else { TurnNotDone = TRUE; DOUBLE c1 = pCharOrMount->Heading + 256.0f; DOUBLE c2 = gFaceAngle; if (c2<pChar->Heading) c2 += 512.0f; DOUBLE turn = (DOUBLE)(rand() % 200) / 10; if (c2<c1) { pCharOrMount->Heading += (FLOAT)turn; pCharOrMount->SpeedHeading = 12.0f; if (pCharOrMount->Heading >= 512.0f) pCharOrMount->Heading -= 512.0f; } else { pCharOrMount->Heading -= (FLOAT)turn; pCharOrMount->SpeedHeading = -12.0f; if (pCharOrMount->Heading<0.0f) pCharOrMount->Heading += 512.0f; } } } if (gLookAngle != 10000.0f) { if (abs((INT)(pChar->CameraAngle - gLookAngle)) < 5.0f) { pChar->CameraAngle = (FLOAT)gLookAngle; gLookAngle = 10000.0f; TurnNotDone = FALSE; } else { TurnNotDone = TRUE; FLOAT c1 = pChar->CameraAngle; FLOAT c2 = (FLOAT)gLookAngle; DOUBLE turn = (DOUBLE)(rand() % 200) / 20; if (c1<c2) { pChar->CameraAngle += (FLOAT)turn; if (pChar->CameraAngle >= 128.0f) pChar->CameraAngle -= 128.0f; } else { pChar->CameraAngle -= (FLOAT)turn; if (pChar->CameraAngle <= -128.0f) pChar->CameraAngle += 128.0f; } } } if (TurnNotDone) { bRunNextCommand = FALSE; IsMouseWaiting(); return; } } }
int32 Client::CalcEnduranceRegen(bool bCombat) { int base = 0; if (!IsStarved()) { auto base_data = database.GetBaseData(GetLevel(), GetClass()); if (base_data) { base = static_cast<int>(base_data->end_regen); if (!auto_attack && base > 0) base += base / 2; } } // so when we are mounted, our local client SpeedRun is always 0, so this is always false, but the packets we process it to our own shit :P bool is_running = runmode && animation != 0 && GetHorseId() == 0; // TODO: animation is really what MQ2 calls SpeedRun int weight_limit = GetSTR(); auto level = GetLevel(); if (GetClass() == MONK) { if (level > 99) weight_limit = 58; else if (level > 94) weight_limit = 57; else if (level > 89) weight_limit = 56; else if (level > 84) weight_limit = 55; else if (level > 79) weight_limit = 54; else if (level > 64) weight_limit = 53; else if (level > 63) weight_limit = 50; else if (level > 61) weight_limit = 47; else if (level > 59) weight_limit = 45; else if (level > 54) weight_limit = 40; else if (level > 50) weight_limit = 38; else if (level > 44) weight_limit = 36; else if (level > 29) weight_limit = 34; else if (level > 14) weight_limit = 32; else weight_limit = 30; } bool encumbered = (CalcCurrentWeight() / 10) >= weight_limit; if (is_running) base += level / -15; if (encumbered) base += level / -15; auto item_bonus = GetHeroicAGI() + GetHeroicDEX() + GetHeroicSTA() + GetHeroicSTR(); item_bonus = item_bonus / 4 / 50; item_bonus += itembonuses.EnduranceRegen; // this is capped already base += item_bonus; base = base * AreaEndRegen + 0.5f; auto aa_regen = aabonuses.EnduranceRegen; int regen = base; if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) { auto max_end = GetMaxEndurance(); int fast_regen = 6 * (max_end / zone->newzone_data.FastRegenEndurance); if (aa_regen < fast_regen) // weird, but what the client is doing aa_regen = fast_regen; } regen += aa_regen; regen += spellbonuses.EnduranceRegen; // TODO: client does this in buff tick return (regen * RuleI(Character, EnduranceRegenMultiplier) / 100); }