diff options
| author | megamage <none@none> | 2009-04-08 16:34:38 -0500 | 
|---|---|---|
| committer | megamage <none@none> | 2009-04-08 16:34:38 -0500 | 
| commit | 371a58404743aa7294eee0096d7884018929e87b (patch) | |
| tree | ef3f3ca9602f8606cb3d443dda7a308490c7501b /src/game/AchievementMgr.cpp | |
| parent | 1294bbac41501407ab7226a141c69846555dcb56 (diff) | |
    [7633] Implement support multiply basic requirements for crireria in `achievement_criteria_data`. Author: VladimirMangos
    Also implement additional basic requirements for proper implementing checks for ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE
    Req. DB support.
--HG--
branch : trunk
Diffstat (limited to 'src/game/AchievementMgr.cpp')
| -rw-r--r-- | src/game/AchievementMgr.cpp | 127 | 
1 files changed, 88 insertions, 39 deletions
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index fc6be4603af..34ae3d1ae94 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -79,17 +79,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)      switch(criteria->requiredType)      {          case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: -            switch(dataType) -            { -                case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE: -                case ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE: -                case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE: -                case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH: -                    break; -                default: -                    sLog.outErrorDb( "Table `achievement_criteria_data` for criteria (Entry: %u Type: %u) have wrong data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType); -                    return false; -            } +        case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:              break;          default:              sLog.outErrorDb( "Table `achievement_criteria_data` have data for not supported criteria type (Entry: %u Type: %u), ignore.", criteria->ID, criteria->requiredType); @@ -100,7 +90,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)      {          case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:              return true; -        case ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE: +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:              if(!creature.id || !objmgr.GetCreatureTemplate(creature.id))              {                  sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) have not existed creature id in value1 (%u), ignore.", @@ -108,7 +98,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)                  return false;              }              return true; -        case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE: +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE:              if(!classRace.class_id && !classRace.race_id)              {                  sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE (%u) must have not 0 in one from value fields, ignore.", @@ -128,14 +118,48 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)                  return false;              }              return true; -        case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH: +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH:              if(health.percent < 1 || health.percent > 100)              { -                sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) have prong percent value in value1 (%u), ignore.", +                sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) have wrong percent value in value1 (%u), ignore.",                      criteria->ID, criteria->requiredType,dataType,health.percent);                  return false;              }              return true; +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD: +            return true; +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA: +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA: +        { +            SpellEntry const* spellEntry = sSpellStore.LookupEntry(aura.spell_id); +            if(!spellEntry) +            { +                sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have wrong spell id in value1 (%u), ignore.", +                    criteria->ID, criteria->requiredType,(dataType==ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"),dataType,aura.spell_id); +                return false; +            } +            if(aura.effect_idx >= 3) +            { +                sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have wrong spell effect index in value2 (%u), ignore.", +                    criteria->ID, criteria->requiredType,(dataType==ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"),dataType,aura.effect_idx); +                return false; +            } +            if(!spellEntry->EffectApplyAuraName[aura.effect_idx]) +            { +                sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have non-aura spell effect (ID: %u Effect: %u), ignore.", +                    criteria->ID, criteria->requiredType,(dataType==ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"),dataType,aura.spell_id,aura.effect_idx); +                return false; +            } +            return true; +        } +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA: +            if(!GetAreaEntryByAreaID(area.id)) +            { +                sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA (%u) have wrong area id in value1 (%u), ignore.", +                    criteria->ID, criteria->requiredType,dataType,area.id); +                return false; +            } +            return true;          default:              sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) have data for not supported data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType);              return false; @@ -143,38 +167,56 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)      return false;  } -bool AchievementCriteriaData::Meets( Unit const* target ) const +bool AchievementCriteriaData::Meets(Player const* source, Unit const* target) const  { -    if (!target) -        return false; -      switch(dataType)      {          case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:              return true; -        case ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE: -            if (target->GetTypeId()!=TYPEID_UNIT) +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE: +            if (!target || target->GetTypeId()!=TYPEID_UNIT)                  return false;              if (target->GetEntry() != creature.id)                  return false;              return true; -        case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE: -            if (target->GetTypeId()!=TYPEID_PLAYER) +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE: +            if (!target || target->GetTypeId()!=TYPEID_PLAYER)                  return false;              if(classRace.class_id && classRace.class_id != ((Player*)target)->getClass())                  return false;              if(classRace.race_id && classRace.race_id != ((Player*)target)->getRace())                  return false;              return true; -        case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH: -            if (target->GetTypeId()!=TYPEID_PLAYER) +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH: +            if (!target || target->GetTypeId()!=TYPEID_PLAYER)                  return false;              return target->GetHealth()*100 <= health.percent*target->GetMaxHealth(); +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD: +            return target && target->GetTypeId() == TYPEID_PLAYER && !target->isAlive() && ((Player*)target)->GetDeathTimer() != 0; +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA: +            return source->HasAura(aura.spell_id,aura.effect_idx); +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA: +        { +            uint32 zone_id,area_id; +            source->GetZoneAndAreaId(zone_id,area_id); +            return area.id==zone_id || area.id==area_id; +        } +        case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA: +            return target && target->HasAura(aura.spell_id,aura.effect_idx);      }      return false;  } +bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target) const +{ +    for(Storage::const_iterator itr = storage.begin(); itr != storage.end(); ++itr) +        if(!itr->Meets(source,target)) +            return false; + +    return true; +} +  AchievementMgr::AchievementMgr(Player *player)  {      m_player = player; @@ -863,22 +905,18 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui              case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:              {                  // miscvalue1 = emote -                // miscvalue2 = achievement->ID for special requirement                  if(!miscvalue1)                      continue;                  if(miscvalue1 != achievementCriteria->do_emote.emoteID)                      continue;                  if(achievementCriteria->do_emote.count)                  { -                    // harcoded case -                    if(achievement->ID==247) -                    { -                        if (!unit || unit->GetTypeId() != TYPEID_PLAYER || -                            unit->isAlive() || ((Player*)unit)->GetDeathTimer() == 0) -                            continue; -                    } -                    // expected as scripted case -                    else if(!miscvalue2 || !achievement->ID != miscvalue2) +                    // those requirements couldn't be found in the dbc +                    AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria); +                    if(!data) +                        continue; + +                    if(!data->Meets(GetPlayer(),unit))                          continue;                  } @@ -949,11 +987,11 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui                      continue;                  // those requirements couldn't be found in the dbc -                AchievementCriteriaData const* data = achievementmgr.GetCriteriaData(achievementCriteria); +                AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);                  if(!data)                      continue; -                if(!data->Meets(unit)) +                if(!data->Meets(GetPlayer(),unit))                      continue;                  SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); @@ -1478,7 +1516,14 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()          if(!data.IsValid(criteria))              continue; -        m_criteriaDataMap[criteria_id] = data; +        // this will allocate empty data set storage +        AchievementCriteriaDataSet& dataSet = m_criteriaDataMap[criteria_id]; + +        // add real data only for not NONE data types +        if(data.dataType!=ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE) +            dataSet.Add(data); + +        // counting data by and data types          ++count;      } while(result->NextRow()); @@ -1494,7 +1539,11 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()          switch(criteria->requiredType)          {              case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: -                if(!GetCriteriaData(criteria)) +                if(!GetCriteriaDataSet(criteria)) +                    sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for for criteria (Entry: %u Type: %u).", criteria->ID, criteria->requiredType); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:        // need skip generic cases +                if(criteria->do_emote.count && !GetCriteriaDataSet(criteria))                      sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for for criteria (Entry: %u Type: %u).", criteria->ID, criteria->requiredType);                  break;              default:                                        // unexpected case processed in IsValid check  | 
