int32 Client::GetMaxStat() const { if((RuleI(Character, StatCap)) > 0) return (RuleI(Character, StatCap)); return 255; }
//this is called whenever we are damaged to process possible fleeing void Mob::CheckFlee() { //if were allready fleeing, dont need to check more... if(flee_mode && curfp) return; //dont bother if we are immune to fleeing if(SpecAttacks[IMMUNE_FLEEING] || spellbonuses.ImmuneToFlee) return; if(!flee_timer.Check()) return; //only do all this stuff every little while, since //its not essential that we start running RIGHT away //see if were possibly hurt enough float ratio = GetHPRatio(); if(ratio >= RuleI(Combat, FleeHPRatio)) return; //we might be hurt enough, check con now.. Mob *hate_top = GetHateTop(); if(!hate_top) { //this should never happen... StartFleeing(); return; } float other_ratio = hate_top->GetHPRatio(); if(other_ratio < 20) { //our hate top is almost dead too... stay and fight return; } //base our flee ratio on our con. this is how the //attacker sees the mob, since this is all we can observe uint32 con = GetLevelCon(hate_top->GetLevel(), GetLevel()); float run_ratio; switch(con) { //these values are not 100% researched case CON_GREEN: run_ratio = RuleI(Combat, FleeHPRatio); break; case CON_LIGHTBLUE: run_ratio = RuleI(Combat, FleeHPRatio) * 8 / 10; break; case CON_BLUE: run_ratio = RuleI(Combat, FleeHPRatio) * 6 / 10; break; default: run_ratio = RuleI(Combat, FleeHPRatio) * 4 / 10; break; } if(ratio < run_ratio) { if( RuleB(Combat, FleeIfNotAlone) || ( !RuleB(Combat, FleeIfNotAlone) && (entity_list.GetHatedCount(hate_top, this) == 0))) StartFleeing(); } }
Client::Client(EQStreamInterface* ieqs) : autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)), CLE_keepalive_timer(RuleI(World, ClientKeepaliveTimeoutMS)), connect(1000), eqs(ieqs) { // Live does not send datarate as of 3/11/2005 //eqs->SetDataRate(7); ip = eqs->GetRemoteIP(); port = ntohs(eqs->GetRemotePort()); autobootup_timeout.Disable(); connect.Disable(); seencharsel = false; cle = 0; zoneID = 0; char_name[0] = 0; charid = 0; pwaitingforbootup = 0; StartInTutorial = false; ClientVersionBit = 0; numclients++; ClientVersionBit = 1 << (eqs->ClientVersion() - 1); }
//healing and buffing aggro int32 Mob::CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possible) { int32 AggroAmount = 0; auto target_level = target ? target->GetLevel() : 1; bool ignore_default_buff = false; // rune/hot don't use the default 9, HP buffs that heal (virtue) do use the default for (int o = 0; o < EFFECT_COUNT; o++) { switch (spells[spell_id].effectid[o]) { case SE_CurrentHP: { if (heal_possible == 0) { AggroAmount += 1; break; } // hate based on base healing power of the spell int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], GetLevel(), spell_id); if (val > 0) { if (heal_possible < val) val = heal_possible; // capped to amount healed val = 2 * val / 3; // 3:2 ratio if (target_level > 50 && val > 1500) val = 1500; // target 51+ seems ~1500 else if (target_level <= 50 && val > 800) val = 800; // per live patch notes, capped to 800 } AggroAmount += std::max(val, 1); break; } case SE_Rune: AggroAmount += CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], GetLevel(), spell_id) * 2; ignore_default_buff = true; break; case SE_HealOverTime: AggroAmount += 10; ignore_default_buff = true; break; default: break; } } if (GetOwner() && IsPet()) AggroAmount = AggroAmount * RuleI(Aggro, PetSpellAggroMod) / 100; if (!ignore_default_buff && IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id)) AggroAmount = IsBardSong(spell_id) ? 2 : 9; if (AggroAmount > 0) { int HateMod = RuleI(Aggro, SpellAggroMod); HateMod += GetFocusEffect(focusSpellHateMod, spell_id); //Live AA - Spell casting subtlety HateMod += aabonuses.hatemod + spellbonuses.hatemod + itembonuses.hatemod; AggroAmount = (AggroAmount * HateMod) / 100; } return std::max(0, AggroAmount); }
Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime) // vesuvias - appearence fix : Mob("Unnamed_Corpse","",0,0,in_npc->GetGender(),in_npc->GetRace(),in_npc->GetClass(),BT_Humanoid,//bodytype added in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0, in_npc->GetPosition(), in_npc->GetInnateLightValue(), in_npc->GetTexture(),in_npc->GetHelmTexture(), 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0), corpse_decay_timer(in_decaytime), corpse_rez_timer(0), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), corpse_graveyard_timer(0), loot_cooldown_timer(10) { corpse_graveyard_timer.Disable(); memset(item_tint, 0, sizeof(item_tint)); is_corpse_changed = false; is_player_corpse = false; is_locked = false; being_looted_by = 0xFFFFFFFF; if (in_itemlist) { itemlist = *in_itemlist; in_itemlist->clear(); } SetCash(in_npc->GetCopper(), in_npc->GetSilver(), in_npc->GetGold(), in_npc->GetPlatinum()); npctype_id = in_npctypeid; SetPlayerKillItemID(0); char_id = 0; corpse_db_id = 0; player_corpse_depop = false; strcpy(corpse_name, in_npc->GetName()); strcpy(name, in_npc->GetName()); for(int count = 0; count < 100; count++) { if ((level >= npcCorpseDecayTimes[count].minlvl) && (level <= npcCorpseDecayTimes[count].maxlvl)) { corpse_decay_timer.SetTimer(npcCorpseDecayTimes[count].seconds*1000); break; } } if(IsEmpty()) { corpse_decay_timer.SetTimer(RuleI(NPC,EmptyNPCCorpseDecayTimeMS)+1000); } if(in_npc->HasPrivateCorpse()) { corpse_delay_timer.SetTimer(corpse_decay_timer.GetRemainingTime() + 1000); } for (int i = 0; i < MAX_LOOTERS; i++){ allowed_looters[i] = 0; } this->rez_experience = 0; UpdateEquipLightValue(); spell_light = NOT_USED; UpdateActiveLightValue(); }
int32 Client::CalcHPRegenCap() { int cap = RuleI(Character, ItemHealthRegenCap) + itembonuses.HeroicSTA/25; cap += aabonuses.ItemHPRegenCap + spellbonuses.ItemHPRegenCap + itembonuses.ItemHPRegenCap; return (cap * RuleI(Character, HPRegenMultiplier) / 100); }
//healing and buffing aggro int32 Mob::CheckHealAggroAmount(uint16 spellid, uint32 heal_possible) { uint16 spell_id = spellid; int32 AggroAmount = 0; for (int o = 0; o < EFFECT_COUNT; o++) { switch(spells[spell_id].effectid[o]) { case SE_CurrentHP: { AggroAmount += spells[spell_id].mana; break; } case SE_Rune: { AggroAmount += CalcSpellEffectValue_formula(spells[spell_id].formula[0], spells[spell_id].base[0], spells[spell_id].max[o], this->GetLevel(), spellid) * 2; break; } case SE_HealOverTime:{ AggroAmount += CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], this->GetLevel(), spell_id); break; } default:{ break; } } } if (IsBardSong(spell_id)) AggroAmount = AggroAmount * RuleI(Aggro, SongAggroMod) / 100; if (GetOwner() && IsPet()) AggroAmount = AggroAmount * RuleI(Aggro, PetSpellAggroMod) / 100; if(AggroAmount > 0) { int HateMod = RuleI(Aggro, SpellAggroMod); if(IsClient()) { HateMod += CastToClient()->GetFocusEffect(focusSpellHateMod, spell_id); } //Live AA - Spell casting subtlety HateMod += aabonuses.hatemod + spellbonuses.hatemod + itembonuses.hatemod; AggroAmount = (AggroAmount * HateMod) / 100; //made up number probably scales a bit differently on live but it seems like it will be close enough //every time you cast on live you get a certain amount of "this is a spell" aggro //confirmed by EQ devs to be 100 exactly at level 85. From their wording it doesn't seem like it's affected //by hate modifiers either. //AggroAmount += (slevel*slevel/72); // Moved Below } if(AggroAmount < 0) return 0; else return AggroAmount; }
int32 Client::CalcHPRegenCap() { int cap = RuleI(Character, ItemHealthRegenCap); if (GetLevel() > 60) cap = std::max(cap, GetLevel() - 30); // if the rule is set greater than normal I guess if (GetLevel() > 65) cap += GetLevel() - 65; cap += aabonuses.ItemHPRegenCap + spellbonuses.ItemHPRegenCap + itembonuses.ItemHPRegenCap; return (cap * RuleI(Character, HPRegenMultiplier) / 100); }
int32 Client::CalcManaRegenCap() { int32 cap = RuleI(Character, ItemManaRegenCap) + aabonuses.ItemManaRegenCap; switch(GetCasterClass()) { case 'I': case 'W': break; } return (cap * RuleI(Character, ManaRegenMultiplier) / 100); }
void Mob::RemoveFromFeignMemory(Client* attacker) { feign_memory_list.erase(attacker->CharacterID()); if(feign_memory_list.empty() && AI_feign_remember_timer != nullptr) AI_feign_remember_timer->Disable(); if(feign_memory_list.empty()) { minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin); maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax); if(AI_feign_remember_timer != nullptr) AI_feign_remember_timer->Disable(); } }
void Mob::ClearFeignMemory() { std::set<uint32>::iterator RememberedCharID = feign_memory_list.begin(); while (RememberedCharID != feign_memory_list.end()) { Client* remember_client = entity_list.GetClientByCharID(*RememberedCharID); ++RememberedCharID; } feign_memory_list.clear(); minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin); maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax); if(AIfeignremember_timer != nullptr) AIfeignremember_timer->Disable(); }
bool ChatChannel::RemoveClient(Client *c) { if(!c) return false; _log(UCS__TRACE, "RemoveClient %s from channel %s", c->GetName().c_str(), GetName().c_str()); bool HideMe = c->GetHideMe(); int AccountStatus = c->GetAccountStatus(); int PlayersInChannel = 0; LinkedListIterator<Client*> iterator(ClientsInChannel); iterator.Reset(); while(iterator.MoreElements()) { Client *CurrentClient = iterator.GetData(); if(CurrentClient == c) { iterator.RemoveCurrent(false); } else if(CurrentClient) { PlayersInChannel++; if(CurrentClient->IsAnnounceOn()) if(!HideMe || (CurrentClient->GetAccountStatus() > AccountStatus)) CurrentClient->AnnounceLeave(this, c); iterator.Advance(); } } if((PlayersInChannel == 0) && !Permanent) { if((Password.length() == 0) || (RuleI(Channels, DeleteTimer) == 0)) return false; _log(UCS__TRACE, "Starting delete timer for empty password protected channel %s", Name.c_str()); DeleteTimer.Start(RuleI(Channels, DeleteTimer) * 60000); } return true; }
int32 Client::CalcHPRegen() { int32 regen = LevelRegen() + itembonuses.HPRegen + spellbonuses.HPRegen; regen += aabonuses.HPRegen + GroupLeadershipAAHealthRegeneration(); return (regen * RuleI(Character, HPRegenMultiplier) / 100); }
int32 Client::CalcManaRegen() { uint8 clevel = GetLevel(); int32 regen = 0; //this should be changed so we dont med while camping, etc... if (IsSitting() || (GetHorseId() != 0)) { BuffFadeBySitModifier(); if(HasSkill(SkillMeditate)) { this->medding = true; regen = (((GetSkill(SkillMeditate) / 10) + (clevel - (clevel / 4))) / 4) + 4; regen += spellbonuses.ManaRegen + itembonuses.ManaRegen; CheckIncreaseSkill(SkillMeditate, nullptr, -5); } else regen = 2 + spellbonuses.ManaRegen + itembonuses.ManaRegen; } else { this->medding = false; regen = 2 + spellbonuses.ManaRegen + itembonuses.ManaRegen; } //AAs regen += aabonuses.ManaRegen; return (regen * RuleI(Character, ManaRegenMultiplier) / 100); }
void Client::TradeskillSearchResults(const char *query, unsigned long qlen, unsigned long objtype, unsigned long someid) { char errbuf[MYSQL_ERRMSG_SIZE]; MYSQL_RES *result; MYSQL_ROW row; if (!database.RunQuery(query, qlen, errbuf, &result)) { LogFile->write(EQEMuLog::Error, "Error in TradeskillSearchResults query '%s': %s", query, errbuf); return; } uint8 qcount = 0; qcount = mysql_num_rows(result); if(qcount < 1) { //search gave no results... not an error return; } if(mysql_num_fields(result) != 6) { LogFile->write(EQEMuLog::Error, "Error in TradeskillSearchResults query '%s': Invalid column count in result", query); return; } uint8 r; for(r = 0; r < qcount; r++) { row = mysql_fetch_row(result); if(row == NULL || row[0] == NULL || row[1] == NULL || row[2] == NULL || row[3] == NULL || row[5] == NULL) continue; uint32 recipe = (uint32)atoi(row[0]); const char *name = row[1]; uint32 trivial = (uint32) atoi(row[2]); uint32 comp_count = (uint32) atoi(row[3]); uint32 tradeskill = (uint16) atoi(row[5]); // Skip the recipes that exceed the threshold in skill difference // Recipes that have either been made before or were // explicitly learned are excempt from that limit if (RuleB(Skills, UseLimitTradeskillSearchSkillDiff)) { if (((int32)trivial - (int32)GetSkill((SkillType)tradeskill)) > RuleI(Skills, MaxTradeskillSearchSkillDiff) && row[4] == NULL) { continue; } } EQApplicationPacket* outapp = new EQApplicationPacket(OP_RecipeReply, sizeof(RecipeReply_Struct)); RecipeReply_Struct *reply = (RecipeReply_Struct *) outapp->pBuffer; reply->object_type = objtype; reply->some_id = someid; reply->component_count = comp_count; reply->recipe_id = recipe; reply->trivial = trivial; strn0cpy(reply->recipe_name, name, sizeof(reply->recipe_name)); FastQueuePacket(&outapp); } mysql_free_result(result); }
bool EQEmu::ItemInstance::UpdateOrnamentationInfo() { if (!m_item || !m_item->IsClassCommon()) return false; bool ornamentSet = false; int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); if (GetOrnamentationAug(ornamentationAugtype)) { const ItemData* ornamentItem; ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem(); if (ornamentItem != nullptr) { SetOrnamentIcon(ornamentItem->Icon); SetOrnamentHeroModel(ornamentItem->HerosForgeModel); if (strlen(ornamentItem->IDFile) > 2) { SetOrnamentationIDFile(atoi(&ornamentItem->IDFile[2])); } else { SetOrnamentationIDFile(0); } ornamentSet = true; } } else { SetOrnamentIcon(0); SetOrnamentHeroModel(0); SetOrnamentationIDFile(0); } return ornamentSet; }
void Mob::ProcessFlee() { //Stop fleeing if effect is applied after they start to run. //When ImmuneToFlee effect fades it will turn fear back on and check if it can still flee. if (flee_mode && (GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) && !spellbonuses.IsFeared && !spellbonuses.IsBlind) { curfp = false; return; } //see if we are still dying, if so, do nothing float fleeratio = GetSpecialAbility(FLEE_PERCENT); fleeratio = fleeratio > 0 ? fleeratio : RuleI(Combat, FleeHPRatio); if (GetHPRatio() < fleeratio) return; //we are not dying anymore... see what we do next flee_mode = false; //see if we are legitimately feared or blind now if (!spellbonuses.IsFeared && !spellbonuses.IsBlind) { //not feared or blind... were done... curfp = false; return; } }
int32 Client::CalcHPRegen() { int32 regen = LevelRegen() + itembonuses.HPRegen + spellbonuses.HPRegen; regen += aabonuses.HPRegen; return (regen * RuleI(Character, HPRegenMultiplier) / 100); }
void Mob::ClearFeignMemory() { auto RememberedCharID = feign_memory_list.begin(); while (RememberedCharID != feign_memory_list.end()) { Client* remember_client = entity_list.GetClientByCharID(*RememberedCharID); if(remember_client != nullptr) //Still in zone remember_client->RemoveXTarget(this, false); ++RememberedCharID; } feign_memory_list.clear(); minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin); maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax); if(AI_feign_remember_timer != nullptr) AI_feign_remember_timer->Disable(); }
bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) { /* Charm formula is correct based on over 50 hours of personal live parsing - Kayen Charisma ONLY effects the initial resist check when charm is cast with 10 CHA = -1 Resist mod up to 255 CHA (min ~ 75 CHA) Charisma DOES NOT extend charm durations. Base effect value of charm spells in the spell file DOES NOT effect duration OR resist rate (unclear if does anything) Charm has a lower limit of 5% chance to break per tick, regardless of resist modifiers / level difference. */ if(!caster) return false; if(spells[spell_id].ResistDiff <= -600) return true; float resist_check = 0; if(IsCharmSpell(spell_id)) { if (spells[spell_id].no_resist) //If charm spell has this set(-1), it can not break till end of duration. return true; //1: The mob has a default 25% chance of being allowed a resistance check against the charm. if (zone->random.Int(0, 99) > RuleI(Spells, CharmBreakCheckChance)) return true; if (RuleB(Spells, CharismaCharmDuration)) resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster,false,0,true,true); else resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, false,0, false, true); //2: The mob makes a resistance check against the charm if (resist_check == 100) return true; else { if (caster->IsClient()) { //3: At maxed ability, Total Domination has a 50% chance of preventing the charm break that otherwise would have occurred. int16 TotalDominationBonus = caster->aabonuses.CharmBreakChance + caster->spellbonuses.CharmBreakChance + caster->itembonuses.CharmBreakChance; if (zone->random.Int(0, 99) < TotalDominationBonus) return true; } } } else { // Assume this is a harmony/pacify spell // If 'Lull' spell resists, do a second resist check with a charisma modifier AND regular resist checks. If resists agian you gain aggro. resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, false,0,true); if (resist_check == 100) return true; } return false; }
float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const { if (!imp) return BEST_Z_INVALID; glm::vec3 tmp; if(!result) result = &tmp; start.z += RuleI(Map, FindBestZHeightAdjust); glm::vec3 from(start.x, start.y, start.z); glm::vec3 to(start.x, start.y, BEST_Z_INVALID); float hit_distance; bool hit = false; hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance); if(hit) { return result->z; } // Find nearest Z above us to.z = -BEST_Z_INVALID; hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance); if (hit) { return result->z; } return BEST_Z_INVALID; }
bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) { AA::Ability *ability = rank->base_ability; if(!ability) return false; if(!(ability->classes & (1 << GetClass()))) { return false; } // Passive and Active Shroud AAs // For now we skip them if(ability->category == 3 || ability->category == 4) { return false; } //the one titanium hack i will allow //just to make sure we dont crash the client with newer aas //we'll exclude any expendable ones if(IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::maskTitaniumAndEarlier) { if(ability->charges > 0) { return false; } } if(IsClient()) { if(rank->expansion && !(CastToClient()->GetPP().expansions & (1 << (rank->expansion - 1)))) { return false; } } else { if(rank->expansion && !(RuleI(World, ExpansionSettings) & (1 << (rank->expansion - 1)))) { return false; } } auto race = GetPlayerRaceValue(GetBaseRace()); race = race > 16 ? 1 : race; if(!(ability->races & (1 << (race - 1)))) { return false; } auto deity = GetDeityBit(); if(!(ability->deities & deity)) { return false; } if(IsClient() && CastToClient()->Admin() < ability->status) { return false; } if(GetBaseRace() == 522) { //drakkin_heritage if(!(ability->drakkin_heritage & (1 << GetDrakkinHeritage()))) { return false; } } return true; }
void Adventure::IncrementAssassinationCount() { if(count >= RuleI(Adventure, NumberKillsForBossSpawn)) { return; } assassination_count++; }
void Corpse::LoadPlayerCorpseDecayTime(uint32 corpse_db_id){ if(!corpse_db_id) return; uint32 active_corpse_decay_timer = database.GetCharacterCorpseDecayTimer(corpse_db_id); if (active_corpse_decay_timer > 0 && RuleI(Character, CorpseDecayTimeMS) > (active_corpse_decay_timer * 1000)) { corpse_decay_timer.SetTimer(RuleI(Character, CorpseDecayTimeMS) - (active_corpse_decay_timer * 1000)); } else { corpse_decay_timer.SetTimer(2000); } if (active_corpse_decay_timer > 0 && RuleI(Zone, GraveyardTimeMS) > (active_corpse_decay_timer * 1000)) { corpse_graveyard_timer.SetTimer(RuleI(Zone, GraveyardTimeMS) - (active_corpse_decay_timer * 1000)); } else { corpse_graveyard_timer.SetTimer(3000); } }
//Account Limiting Code to limit the number of characters allowed on from a single account at once. void ClientList::EnforceSessionLimit(uint32 iLSAccountID) { ClientListEntry* ClientEntry = 0; LinkedListIterator<ClientListEntry*> iterator(clientlist, BACKWARD); int CharacterCount = 0; iterator.Reset(); while(iterator.MoreElements()) { ClientEntry = iterator.GetData(); if ((ClientEntry->LSAccountID() == iLSAccountID) && ((ClientEntry->Admin() <= (RuleI(World, ExemptAccountLimitStatus))) || (RuleI(World, ExemptAccountLimitStatus) < 0))) { CharacterCount++; if (CharacterCount >= (RuleI(World, AccountSessionLimit))){ // If we have a char name, they are in a zone, so send a kick to the zone server if(strlen(ClientEntry->name())) { auto pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct)); ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer; strcpy(skp->adminname, "SessionLimit"); strcpy(skp->name, ClientEntry->name()); skp->adminrank = 255; zoneserver_list.SendPacket(pack); safe_delete(pack); } ClientEntry->SetOnline(CLE_Status_Offline); iterator.RemoveCurrent(); continue; } } iterator.Advance(); } }
void WorldDatabase::SetSoFDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc){ if (in_cc->start_zone == RuleI(World, TutorialZoneID)) { in_pp->zone_id = in_cc->start_zone; } else { in_pp->x = in_pp->binds[0].x = -51; in_pp->y = in_pp->binds[0].y = -20; in_pp->z = in_pp->binds[0].z = 0.79; in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach. } }
int32 Client::GetMaxStat() const { if ((RuleI(Character, StatCap)) > 0) { return (RuleI(Character, StatCap)); } int level = GetLevel(); int32 base = 0; if (level < 61) { base = 255; } else if (GetClientVersion() >= ClientVersion::SoF) { base = 255 + 5 * (level - 60); } else if (level < 71) { base = 255 + 5 * (level - 60); } else { base = 330; } return (base); }
int32 Client::GetActSpellCasttime(uint16 spell_id, int32 casttime) { int32 cast_reducer = 0; cast_reducer += GetFocusEffect(focusSpellHaste, spell_id); //this function loops through the effects of spell_id many times //could easily be consolidated. if (GetLevel() >= 51 && casttime >= 3000 && !BeneficialSpell(spell_id) && (GetClass() == SHADOWKNIGHT || GetClass() == RANGER || GetClass() == PALADIN || GetClass() == BEASTLORD )) cast_reducer += (GetLevel()-50)*3; //LIVE AA SpellCastingDeftness, QuickBuff, QuickSummoning, QuickEvacuation, QuickDamage if (cast_reducer > RuleI(Spells, MaxCastTimeReduction)) cast_reducer = RuleI(Spells, MaxCastTimeReduction); casttime = (casttime*(100 - cast_reducer)/100); return casttime; }
void Database::ExpireMail() { _log(UCS__INIT, "Expiring mail..."); char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; MYSQL_RES *result; MYSQL_ROW row; uint32 AffectedRows; if (!RunQuery(query,MakeAnyLenString(&query, "select COUNT(*) from `mail` "),errbuf,&result)){ _log(UCS__ERROR, "Unable to get message count from database. %s %s", query, errbuf); safe_delete_array(query); return ; } safe_delete_array(query); row = mysql_fetch_row(result); _log(UCS__INIT, "There are %s messages in the database.", row[0]); mysql_free_result(result); // Expire Trash if(RuleI(Mail, ExpireTrash) >= 0) { if(RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `status`=4 and `timestamp` < %i", time(nullptr) - RuleI(Mail, ExpireTrash)), errbuf, 0, &AffectedRows)) { _log(UCS__INIT, "Expired %i trash messages.", AffectedRows); } else { _log(UCS__ERROR, "Error expiring trash messages, %s %s", query, errbuf); } safe_delete_array(query); } // Expire Read if(RuleI(Mail, ExpireRead) >= 0) { if(RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `status`=3 and `timestamp` < %i", time(nullptr) - RuleI(Mail, ExpireRead)), errbuf, 0, &AffectedRows)) { _log(UCS__INIT, "Expired %i read messages.", AffectedRows); } else { _log(UCS__ERROR, "Error expiring read messages, %s %s", query, errbuf); } safe_delete_array(query); } // Expire Unread if(RuleI(Mail, ExpireUnread) >= 0) { if(RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `status`=1 and `timestamp` < %i", time(nullptr) - RuleI(Mail, ExpireUnread)), errbuf, 0, &AffectedRows)) { _log(UCS__INIT, "Expired %i unread messages.", AffectedRows); } else { _log(UCS__ERROR, "Error expiring unread messages, %s %s", query, errbuf); } safe_delete_array(query); } }
void Client::SendLogServer() { EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogServer, sizeof(LogServer_Struct)); LogServer_Struct *l=(LogServer_Struct *)outapp->pBuffer; const char *wsn=WorldConfig::get()->ShortName.c_str(); memcpy(l->worldshortname,wsn,strlen(wsn)); if(RuleB(Mail, EnableMailSystem)) l->enablemail = 1; if(RuleB(Chat, EnableVoiceMacros)) l->enablevoicemacros = 1; l->enable_pvp = (RuleI(World, PVPSettings)); if(RuleB(World, IsGMPetitionWindowEnabled)) l->enable_petition_wnd = 1; if(RuleI(World, FVNoDropFlag) == 1 || RuleI(World, FVNoDropFlag) == 2 && GetAdmin() > RuleI(Character, MinStatusForNoDropExemptions)) l->enable_FV = 1; QueuePacket(outapp); safe_delete(outapp); }