void CPlayerCoreFactory::GetPlayers(const CFileItem& item, std::vector<std::string>&players) const { CURL url(item.GetPath()); CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers(%s)", CURL::GetRedacted(item.GetPath()).c_str()); std::vector<std::string>validPlayers; GetPlayers(validPlayers); // Process rules for (auto rule: m_vecCoreSelectionRules) rule->GetPlayers(item, validPlayers, players); CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers: matched {0} rules with players", players.size()); // Process defaults // Set video default player. Check whether it's video first (overrule audio and // game check). Also push these players in case it is NOT audio or game either. if (item.IsVideo() || (!item.IsAudio() && !item.IsGame())) { int idx = GetPlayerIndex("videodefaultplayer"); if (idx > -1) { std::string eVideoDefault = GetPlayerName(idx); CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers: adding videodefaultplayer (%s)", eVideoDefault.c_str()); players.push_back(eVideoDefault); } GetPlayers(players, false, true); // Video-only players GetPlayers(players, true, true); // Audio & video players } // Set audio default player // Pushback all audio players in case we don't know the type if (item.IsAudio()) { int idx = GetPlayerIndex("audiodefaultplayer"); if (idx > -1) { std::string eAudioDefault = GetPlayerName(idx); CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers: adding audiodefaultplayer (%s)", eAudioDefault.c_str()); players.push_back(eAudioDefault); } GetPlayers(players, true, false); // Audio-only players GetPlayers(players, true, true); // Audio & video players } if (item.IsGame()) { CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers: adding retroplayer"); players.push_back("RetroPlayer"); } CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers: added {0} players", players.size()); }
void CPlayerCoreFactory::OnPlayerDiscovered(const std::string& id, const std::string& name) { CSingleLock lock(m_section); std::vector<CPlayerCoreConfig *>::iterator it; for (it = m_vecPlayerConfigs.begin(); it != m_vecPlayerConfigs.end(); ++it) { if ((*it)->GetId() == id) { (*it)->m_name = name; (*it)->m_type = "remote"; return; } } int count = 0; std::string playername = name; while (GetPlayerIndex(playername) >= 0) { count++; std::stringstream itoa; itoa << count; playername = name + itoa.str(); } CPlayerCoreConfig* player = new CPlayerCoreConfig(playername, "remote", nullptr, id); player->m_bPlaysAudio = true; player->m_bPlaysVideo = true; m_vecPlayerConfigs.push_back(player); }
void main(void) { while ( ++num_items < MAX_PAGES ) selection_mem[num_items] = 0; while ( !IS_PLAYER_SCRIPT_CONTROL_ON(GetPlayerIndex()) ) WAIT(1000); //TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME("modmanager"); while ( TRUE ) { WAIT(0); SET_SLEEP_MODE_ACTIVE(TRUE); PRINT_MAIN_LOGO("GTA IV Mission Mod Pack v2.0", 0.30, 0.05); PRINT_DESC(0.28, 0.11, "Created by rodd1981 (c) www.facebook.com/gtamodz"); MenuSetup(); if (page != page_check ) { SetupPage(); } DrawPage(); Nav(); /* if (IS_GAME_KEYBOARD_KEY_JUST_PRESSED(KEY_F11)) { TERMINATE_THIS_SCRIPT(); } */ } }
IPlayer* CPlayerCoreFactory::CreatePlayer(const std::string& nameId, IPlayerCallback& callback) const { CSingleLock lock(m_section); size_t idx = GetPlayerIndex(nameId); if (m_vecPlayerConfigs.empty() || idx > m_vecPlayerConfigs.size()) return nullptr; return m_vecPlayerConfigs[idx]->CreatePlayer(callback); }
bool CPlayerCoreFactory::PlaysVideo(const std::string& player) const { CSingleLock lock(m_section); size_t idx = GetPlayerIndex(player); if (m_vecPlayerConfigs.empty() || idx > m_vecPlayerConfigs.size()) return false; return m_vecPlayerConfigs[idx]->m_bPlaysVideo; }
std::string CPlayerCoreFactory::GetPlayerType(const std::string& player) const { CSingleLock lock(m_section); size_t idx = GetPlayerIndex(player); if (m_vecPlayerConfigs.empty() || idx > m_vecPlayerConfigs.size()) return ""; return m_vecPlayerConfigs[idx]->m_type; }
void COMMAND_INFO() { int x, y; do { printf("Enter the coordinate of the cell: "); scanf("%d %d", &x, &y); } while (!isValidCoordinate(x, y)); Grid *grid = GetGrid(MakePOINT(x, y)); Type type = GetType(*grid); Player *gridOwner = GetOwner(*grid); Unit *unit = GetUnit(*grid); printf("== Cell Info ==\n"); if (type == Normal) { printf("Normal\n"); } else if (type == Tower) { printf("Tower\n"); } else if (type == Castle) { printf("Castle\n"); } else if (type == Village) { printf("Village\n"); } printf("Owned by Player %d\n", GetPlayerIndex(*gridOwner)); if (unit) { Player *unitOwner = GetPlayerFromColor(GetUnitColor(*unit)); char unitClassName[11]; UnitClassName(GetUnitClass(*unit), unitClassName); printf("== Unit Info ==\n"); printf("%s\n", unitClassName); printf("Owned by Player %d\n", GetPlayerIndex(*unitOwner)); printf("Health %d/%d | ATK %d\n", GetHealth(*unit), GetMaximumHealth(*unit), GetAttack(*unit) ); } printf("\n"); }
bool Aura::ShouldISpawnFor(Client *c) { if (spawn_type == AuraSpawns::Noone) return false; if (spawn_type == AuraSpawns::Everyone) return true; // hey, it's our owner! if (c->GetID() == m_owner) return true; // so this one is a bit trickier auto owner = GetOwner(); if (owner == nullptr) return false; // hmm owner = owner->GetOwnerOrSelf(); // pet auras we need the pet's owner if (owner == nullptr) // shouldn't really be needed return false; // gotta check again for pet aura case -.- if (owner == c) return true; if (owner->IsRaidGrouped() && owner->IsClient()) { auto raid = owner->GetRaid(); if (raid == nullptr) return false; // hmm auto group_id = raid->GetGroup(owner->CastToClient()); if (group_id == 0xFFFFFFFF) // owner handled above, and they're in a raid and groupless return false; auto idx = raid->GetPlayerIndex(c); if (idx == 0xFFFFFFFF) // they're not in our raid! return false; if (raid->members[idx].GroupNumber != group_id) // in our raid, but not our group return false; return true; // we got here so we know that 1 they're in our raid and 2 they're in our group! } else if (owner->IsGrouped()) { auto group = owner->GetGroup(); if (group == nullptr) return false; // hmm // easy, in our group return group->IsGroupMember(c); } // our owner is not raided or grouped, and they're handled above so we don't spawn! return false; }
void main(void) { TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME("scriptmgr"); ADD_ARMOUR_TO_CHAR(GetPlayerPed(), 100); CLEAR_ZONE(414.907, 28.0238, 8.79453, 200.0); SET_THIS_SCRIPT_CAN_REMOVE_BLIPS_CREATED_BY_ANY_SCRIPT(1); INIT_SETTINGS(420.828, 28.8978, 8.78683, 100.0); while ( ++num_items < MAX_PAGES ) selection_mem[num_items] = 0; while ( !IS_PLAYER_SCRIPT_CONTROL_ON(GetPlayerIndex()) ) WAIT(1000); while (TRUE) { WAIT(0); GET_CHAR_COORDINATES(GetPlayerPed(), &px, &py, &pz); GET_CHAR_HEADING(GetPlayerPed(), &ph); if(objrc == 0) { DRAW_MENU(); PRINT_MAIN_LOGO(0.43, 0.05, "Lost MC RIP"); PRINT_DESC(0.35, 0.11, "Recreation of GTA V Online mission \"Lost MC RIP\""); //PRINT_DESC(0.20, 0.13, "Test1"); //PRINT_DESC(0.20, 0.15, "Test2"); } if(objrc > objstart && objrc != objend) { PRINT_LIVES(); POLICE(0, 0); MANAGE_PLAYER(); MANAGE_ACTORS(14); ALTER_WANTED_LEVEL(GetPlayerIndex(), 0); } if(objrc == 1) { UNLOCK_FRONTEND_DISPLAYS(); APPLY_SELECTED_OPTIONS(level, weather, time); CLEAR_ZONE(480.671, 330.929, 8.57156, 50.0); SPAWN_VEHICLE(0, vehmodel, BLIP_COLOR_WHITE, 414.907, 28.0238, 8.79453, 10.0, 25000, 0); SPAWN_VEHICLE(1, MODEL_HELLFURY, NOBLIP, 480.671, 330.929, 8.57156, 287.0, vhealth, 1); SPAWN_VEHICLE(2, MODEL_HELLFURY, NOBLIP, 500.989, 331.218, 8.57157, 287.0, vhealth, 1); SPAWN_VEHICLE(3, MODEL_HELLFURY, NOBLIP, 462.637, 342.84, 8.57144, 287.0, vhealth, 1); SPAWN_VEHICLE(4, MODEL_HELLFURY, NOBLIP, 456.194, 328.523, 8.57156, 287.0, vhealth, 1); SPAWN_VEHICLE(5, MODEL_ROMERO, NOBLIP, 469.083, 341.918, 8.57143, 0.0, vhealth, 1); SPAWN_ACTOR(0, MODEL_M_M_GBIK_LO_03, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 477.765, 330.598, 8.57155, 0.0, 0); SPAWN_ACTOR(1, MODEL_M_Y_GBIK_HI_01, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 487.11, 332.822, 8.58402, 0.0, 0); SPAWN_ACTOR(2, MODEL_M_Y_GBIK_HI_02, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 462.72, 329.053, 8.57155, 0.0, 0); SPAWN_ACTOR(3, MODEL_M_Y_GBIK_LO_01, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 455.702, 331.683, 8.57326, 0.0, 0); SPAWN_ACTOR(4, MODEL_M_Y_GBIK_LO_02, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 453.886, 342.619, 8.57142, 0.0, 0); SPAWN_ACTOR(5, MODEL_M_M_GBIK_LO_03, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 455.879, 353.054, 8.57143, 0.0, 0); SPAWN_ACTOR(6, MODEL_M_Y_GBIK_HI_01, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 461.334, 354.282, 8.55088, 0.0, 0); SPAWN_ACTOR(7, MODEL_M_Y_GBIK_HI_02, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 452.701, 350.135, 8.57144, 0.0, 0); SPAWN_ACTOR(8, MODEL_M_Y_GBIK_LO_01, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 475.867, 352.833, 8.57144, 0.0, 0); SPAWN_ACTOR(9, MODEL_M_Y_GBIK_LO_02, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 485.464, 355.757, 8.57232, 0.0, 0); SPAWN_ACTOR(10, MODEL_M_M_GBIK_LO_03, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 494.51, 355.139, 8.57158, 0.0, 0); SPAWN_ACTOR(11, MODEL_M_Y_GBIK_HI_01, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 501.969, 343.139, 8.57158, 0.0, 0); SPAWN_ACTOR(12, MODEL_M_Y_GBIK_HI_02, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 510.718, 339.741, 8.57158, 0.0, 0); SPAWN_ACTOR(13, MODEL_M_Y_GBIK_LO_01, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 513.053, 328.065, 8.57157, 0.0, 0); SPAWN_ACTOR(14, MODEL_M_Y_GBIK_LO_02, WEAPON_M4, BLIP_COLOR_RED, accuracy, ehealth, armour, 0, 505.737, 314.082, 8.57796, 0.0, 0); PLAY_CHECKPOINT_SOUND(); objrc++; } if(objrc == 2) { PRINT_TXT("Take out the ~R~Lost~S~"); if(peds[0].retc == 2 && peds[1].retc == 2 && peds[2].retc == 2 && peds[3].retc == 2 && peds[4].retc == 2 && peds[5].retc == 2 && peds[6].retc == 2 && peds[7].retc == 2 && peds[8].retc == 2 && peds[9].retc == 2 && peds[10].retc == 2 && peds[11].retc == 2 && peds[12].retc == 2 && peds[13].retc == 2 && peds[14].retc == 2) { objrc++; } } if(objrc == 3) { MISSION_COMPLETE("", 13000); } } }
bool CPlayerCoreFactory::LoadConfiguration(const std::string &file, bool clear) { CSingleLock lock(m_section); CLog::Log(LOGNOTICE, "Loading player core factory settings from %s.", file.c_str()); if (!XFILE::CFile::Exists(file)) { // tell the user it doesn't exist CLog::Log(LOGNOTICE, "%s does not exist. Skipping.", file.c_str()); return false; } CXBMCTinyXML playerCoreFactoryXML; if (!playerCoreFactoryXML.LoadFile(file)) { CLog::Log(LOGERROR, "Error loading %s, Line %d (%s)", file.c_str(), playerCoreFactoryXML.ErrorRow(), playerCoreFactoryXML.ErrorDesc()); return false; } TiXmlElement *pConfig = playerCoreFactoryXML.RootElement(); if (pConfig == NULL) { CLog::Log(LOGERROR, "Error loading %s, Bad structure", file.c_str()); return false; } if (clear) { for (auto config: m_vecPlayerConfigs) delete config; m_vecPlayerConfigs.clear(); for (auto rule: m_vecCoreSelectionRules) delete rule; m_vecCoreSelectionRules.clear(); // Builtin players CPlayerCoreConfig* VideoPlayer = new CPlayerCoreConfig("VideoPlayer", "video", nullptr); VideoPlayer->m_bPlaysAudio = true; VideoPlayer->m_bPlaysVideo = true; m_vecPlayerConfigs.push_back(VideoPlayer); CPlayerCoreConfig* paplayer = new CPlayerCoreConfig("PAPlayer", "music", nullptr); paplayer->m_bPlaysAudio = true; m_vecPlayerConfigs.push_back(paplayer); } if (!pConfig || strcmpi(pConfig->Value(), "playercorefactory") != 0) { CLog::Log(LOGERROR, "Error loading configuration, no <playercorefactory> node"); return false; } TiXmlElement *pPlayers = pConfig->FirstChildElement("players"); if (pPlayers) { TiXmlElement* pPlayer = pPlayers->FirstChildElement("player"); while (pPlayer) { std::string name = XMLUtils::GetAttribute(pPlayer, "name"); std::string type = XMLUtils::GetAttribute(pPlayer, "type"); if (type.empty()) type = name; StringUtils::ToLower(type); std::string internaltype; if (type == "videoplayer") internaltype = "video"; else if (type == "paplayer") internaltype = "music"; else if (type == "externalplayer") internaltype = "external"; int count = 0; std::string playername = name; while (GetPlayerIndex(playername) >= 0) { count++; std::stringstream itoa; itoa << count; playername = name + itoa.str(); } if (!internaltype.empty()) { m_vecPlayerConfigs.push_back(new CPlayerCoreConfig(playername, internaltype, pPlayer)); } pPlayer = pPlayer->NextSiblingElement("player"); } } TiXmlElement *pRule = pConfig->FirstChildElement("rules"); while (pRule) { const char* szAction = pRule->Attribute("action"); if (szAction) { if (stricmp(szAction, "append") == 0) { m_vecCoreSelectionRules.push_back(new CPlayerSelectionRule(pRule)); } else if (stricmp(szAction, "prepend") == 0) { m_vecCoreSelectionRules.insert(m_vecCoreSelectionRules.begin(), 1, new CPlayerSelectionRule(pRule)); } else { m_vecCoreSelectionRules.clear(); m_vecCoreSelectionRules.push_back(new CPlayerSelectionRule(pRule)); } } else { m_vecCoreSelectionRules.push_back(new CPlayerSelectionRule(pRule)); } pRule = pRule->NextSiblingElement("rules"); } // succeeded - tell the user it worked CLog::Log(LOGNOTICE, "Loaded playercorefactory configuration"); return true; }
void FDirectInputJoystick::EventPov(const TSharedPtr<FGenericApplicationMessageHandler>& MessageHandler) { if(IsPush(POV_UP)) { MessageHandler->OnControllerButtonPressed(EKeysDirectInputPad::DIGamePad_POV_Up.GetFName(), GetPlayerIndex(), false); } else if(IsRelease(POV_UP)) { MessageHandler->OnControllerButtonReleased(EKeysDirectInputPad::DIGamePad_POV_Up.GetFName(), GetPlayerIndex(), false); } else if(IsPush(POV_DOWN)) { MessageHandler->OnControllerButtonPressed(EKeysDirectInputPad::DIGamePad_POV_Down.GetFName(), GetPlayerIndex(), false); } else if(IsRelease(POV_DOWN)) { MessageHandler->OnControllerButtonReleased(EKeysDirectInputPad::DIGamePad_POV_Down.GetFName(), GetPlayerIndex(), false); } if(IsPush(POV_RIGHT)) { MessageHandler->OnControllerButtonPressed(EKeysDirectInputPad::DIGamePad_POV_Right.GetFName(), GetPlayerIndex(), false); } else if(IsRelease(POV_RIGHT)) { MessageHandler->OnControllerButtonReleased(EKeysDirectInputPad::DIGamePad_POV_Right.GetFName(), GetPlayerIndex(), false); } else if(IsPush(POV_LEFT)) { MessageHandler->OnControllerButtonPressed(EKeysDirectInputPad::DIGamePad_POV_Left.GetFName(), GetPlayerIndex(), false); } else if(IsRelease(POV_LEFT)) { MessageHandler->OnControllerButtonReleased(EKeysDirectInputPad::DIGamePad_POV_Left.GetFName(), GetPlayerIndex(), false); } }
void FDirectInputJoystick::EventButtonReleased(const TSharedPtr<FGenericApplicationMessageHandler>& MessageHandler, EDirectInputPadKeyNames ePadName, FKey DIKey) { if(!IsRelease(ePadName-DIGamePad_Button1)) return; MessageHandler->OnControllerButtonReleased(DIKey.GetFName(), GetPlayerIndex(), false); }
void FDirectInputJoystick::EventAnalog(const TSharedPtr<FGenericApplicationMessageHandler>& MessageHandler, float Analog, EDirectInputPadKeyNames ePadName, FKey DIKey) { MessageHandler->OnControllerAnalog(DIKey.GetFName(), GetPlayerIndex(), Analog); }
void InitPlayer(void) { SET_PLAYER_CONTROL(GetPlayerIndex(), TRUE); SET_CHAR_RELATIONSHIP_GROUP(GetPlayerPed(), 0); }
void Aura::ProcessOnGroupMembersPets(Mob *owner) { auto &mob_list = entity_list.GetMobList(); // read only reference so we can do it all inline std::set<int> delayed_remove; bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter // This type can either live on the pet (level 55/70 MAG aura) or on the pet owner (level 85 MAG aura) auto group_member = owner->GetOwnerOrSelf(); if (group_member->IsRaidGrouped() && group_member->IsClient()) { // currently raids are just client, but safety check auto raid = group_member->GetRaid(); if (raid == nullptr) { // well shit owner->RemoveAura(GetID(), false, true); return; } auto group_id = raid->GetGroup(group_member->CastToClient()); // some lambdas so the for loop is less horrible ... auto verify_raid_client_pet = [&raid, &group_id, &group_member, this](Mob *m) { auto idx = raid->GetPlayerIndex(m->GetOwner()->CastToClient()); if (m->GetOwner()->GetID() == group_member->GetID()) { return DistanceSquared(GetPosition(), m->GetPosition()) <= distance; } else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || raid->members[idx].GroupNumber == 0xFFFFFFFF) { return false; } else if (DistanceSquared(GetPosition(), m->GetPosition()) > distance) { return false; } return true; }; auto verify_raid_client_swarm = [&raid, &group_id, &group_member, this](NPC *n) { auto owner = entity_list.GetMob(n->GetSwarmOwner()); if (owner == nullptr) return false; auto idx = raid->GetPlayerIndex(owner->CastToClient()); if (owner->GetID() == group_member->GetID()) { return DistanceSquared(GetPosition(), n->GetPosition()) <= distance; } else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || raid->members[idx].GroupNumber == 0xFFFFFFFF) { return false; } else if (DistanceSquared(GetPosition(), n->GetPosition()) > distance) { return false; } return true; }; for (auto &e : mob_list) { auto mob = e.second; // step 1: check if we're already managing this NPC's buff auto it = casted_on.find(mob->GetID()); if (it != casted_on.end()) { // verify still good! if (mob->IsPet() && mob->IsPetOwnerClient() && mob->GetOwner()) { if (!verify_raid_client_pet(mob)) delayed_remove.insert(mob->GetID()); } else if (mob->IsNPC() && mob->IsPetOwnerClient()) { auto npc = mob->CastToNPC(); if (!verify_raid_client_swarm(npc)) delayed_remove.insert(mob->GetID()); } } else { // we're not on it! if (mob->IsClient()) { continue; // never hit client } else if (mob->IsPet() && mob->IsPetOwnerClient() && mob->GetOwner() && verify_raid_client_pet(mob)) { casted_on.insert(mob->GetID()); if (is_buff) SpellFinished(spell_id, mob); } else if (mob->IsNPC() && mob->IsPetOwnerClient()) { auto npc = mob->CastToNPC(); if (verify_raid_client_swarm(npc)) { casted_on.insert(mob->GetID()); if (is_buff) SpellFinished(spell_id, mob); } } } } } else if (group_member->IsGrouped()) { auto group = group_member->GetGroup(); if (group == nullptr) { // uh oh owner->RemoveAura(GetID(), false, true); return; } // lambdas to make for loop less ugly auto verify_group_pet = [&group, this](Mob *m) { auto owner = m->GetOwner(); if (owner != nullptr && group->IsGroupMember(owner) && DistanceSquared(GetPosition(), m->GetPosition()) <= distance) return true; return false; }; auto verify_group_swarm = [&group, this](NPC *n) { auto owner = entity_list.GetMob(n->GetSwarmOwner()); if (owner != nullptr && group->IsGroupMember(owner) && DistanceSquared(GetPosition(), n->GetPosition()) <= distance) return true; return false; }; for (auto &e : mob_list) { auto mob = e.second; auto it = casted_on.find(mob->GetID()); if (it != casted_on.end()) { // make sure we're still valid if (mob->IsPet()) { if (!verify_group_pet(mob)) delayed_remove.insert(mob->GetID()); } else if (mob->IsNPC() && mob->CastToNPC()->GetSwarmInfo()) { if (!verify_group_swarm(mob->CastToNPC())) delayed_remove.insert(mob->GetID()); } } else { // not on, check if we should be! if (mob->IsClient()) { continue; } else if (mob->IsPet() && verify_group_pet(mob)) { casted_on.insert(mob->GetID()); if (is_buff) SpellFinished(spell_id, mob); } else if (mob->IsNPC() && mob->CastToNPC()->GetSwarmInfo() && verify_group_swarm(mob->CastToNPC())) { casted_on.insert(mob->GetID()); if (is_buff) SpellFinished(spell_id, mob); } } } } else { auto verify_solo = [&group_member, this](Mob *m) { if (m->IsPet() && m->GetOwnerID() == group_member->GetID()) return true; else if (m->IsNPC() && m->CastToNPC()->GetSwarmOwner() == group_member->GetID()) return true; else return false; }; for (auto &e : mob_list) { auto mob = e.second; auto it = casted_on.find(mob->GetID()); bool good = verify_solo(mob); if (it != casted_on.end()) { // make sure still valid if (!good || DistanceSquared(GetPosition(), mob->GetPosition()) > distance) { delayed_remove.insert(mob->GetID()); } } else if (good && DistanceSquared(GetPosition(), mob->GetPosition()) <= distance) { casted_on.insert(mob->GetID()); if (is_buff) SpellFinished(spell_id, mob); } } } for (auto &e : delayed_remove) { auto mob = entity_list.GetMob(e); if (mob != nullptr && is_buff) // some auras cast instant spells so no need to remove mob->BuffFadeBySpellIDAndCaster(spell_id, GetID()); casted_on.erase(e); } // so if we have a cast timer and our set isn't empty and timer is disabled we need to enable it if (cast_timer.GetDuration() > 0 && !cast_timer.Enabled() && !casted_on.empty()) cast_timer.Start(); if (!cast_timer.Enabled() || !cast_timer.Check()) return; // some auras have to recast (DRU for example, non-buff too) for (auto &e : casted_on) { auto mob = entity_list.GetMob(e); if (mob != nullptr) SpellFinished(spell_id, mob); } }