Merge commit 'origin/master' into 310

This commit is contained in:
tomrus88 2009-05-09 16:03:32 +04:00
commit 3c43e9dd52
14 changed files with 153 additions and 52 deletions

View file

@ -21,7 +21,7 @@
DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` (
`required_7644_01_characters_character_pet` bit(1) default NULL
`required_7802_02_characters_character_achievement_progress` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
--
@ -253,9 +253,9 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `character_achievement`;
CREATE TABLE `character_achievement` (
`guid` int(11) NOT NULL,
`achievement` int(11) NOT NULL,
`date` int(11) NOT NULL,
`guid` int(11) unsigned NOT NULL,
`achievement` int(11) unsigned NOT NULL,
`date` bigint(11) unsigned NOT NULL default '0',
PRIMARY KEY (`guid`,`achievement`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@ -274,10 +274,10 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `character_achievement_progress`;
CREATE TABLE `character_achievement_progress` (
`guid` int(11) NOT NULL,
`criteria` int(11) NOT NULL,
`counter` int(11) NOT NULL,
`date` int(11) NOT NULL,
`guid` int(11) unsigned NOT NULL,
`criteria` int(11) unsigned NOT NULL,
`counter` int(11) unsigned NOT NULL,
`date` bigint(11) unsigned NOT NULL default '0',
PRIMARY KEY (`guid`,`criteria`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

View file

@ -0,0 +1,6 @@
ALTER TABLE character_db_version CHANGE COLUMN required_7644_01_characters_character_pet required_7802_01_characters_character_achievement bit;
ALTER TABLE character_achievement
CHANGE COLUMN guid guid int(11) unsigned NOT NULL,
CHANGE COLUMN achievement achievement int(11) unsigned NOT NULL,
CHANGE COLUMN date date bigint(11) unsigned NOT NULL default '0';

View file

@ -0,0 +1,7 @@
ALTER TABLE character_db_version CHANGE COLUMN required_7802_01_characters_character_achievement required_7802_02_characters_character_achievement_progress bit;
ALTER TABLE character_achievement_progress
CHANGE COLUMN guid guid int(11) unsigned NOT NULL,
CHANGE COLUMN criteria criteria int(11) unsigned NOT NULL,
CHANGE COLUMN counter counter int(11) unsigned NOT NULL,
CHANGE COLUMN date date bigint(11) unsigned NOT NULL default '0';

View file

@ -182,6 +182,8 @@ pkgdata_DATA = \
7782_01_mangos_spell_proc_event.sql \
7796_01_mangos_command.sql \
7796_02_mangos_mangos_string.sql \
7802_01_characters_character_achievement.sql \
7802_02_characters_character_achievement_progress.sql \
README
## Additional files to include when running 'make dist'
@ -344,4 +346,6 @@ EXTRA_DIST = \
7782_01_mangos_spell_proc_event.sql \
7796_01_mangos_command.sql \
7796_02_mangos_mangos_string.sql \
7802_01_characters_character_achievement.sql \
7802_02_characters_character_achievement_progress.sql \
README

View file

@ -407,7 +407,14 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri
do
{
Field *fields = achievementResult->Fetch();
CompletedAchievementData& ca = m_completedAchievements[fields[0].GetUInt32()];
uint32 achievement_id = fields[0].GetUInt32();
// don't must happen: cleanup at server startup in achievementmgr.LoadCompletedAchievements()
if(!sAchievementStore.LookupEntry(achievement_id))
continue;
CompletedAchievementData& ca = m_completedAchievements[achievement_id];
ca.date = time_t(fields[1].GetUInt64());
ca.changed = false;
} while(achievementResult->NextRow());
@ -425,7 +432,15 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri
time_t date = time_t(fields[2].GetUInt64());
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id);
if (!criteria || (criteria->timeLimit && time_t(date + criteria->timeLimit) < time(NULL)))
if (!criteria)
{
// we will remove not existed criteria for all characters
sLog.outError("Not existed achievement creataria %u data removed from table `character_achievement_progress`.",id);
CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE criteria = %u",id);
continue;
}
if (criteria->timeLimit && time_t(date + criteria->timeLimit) < time(NULL))
continue;
CriteriaProgress& progress = m_criteriaProgress[id];
@ -1763,7 +1778,17 @@ void AchievementGlobalMgr::LoadCompletedAchievements()
{
bar.step();
Field *fields = result->Fetch();
m_allCompletedAchievements.insert(fields[0].GetUInt32());
uint32 achievement_id = fields[0].GetUInt32();
if(!sAchievementStore.LookupEntry(achievement_id))
{
// we will remove not existed achievement for all characters
sLog.outError("Not existed achievement %u data removed from table `character_achievement`.",achievement_id);
CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE achievement = %u",achievement_id);
continue;
}
m_allCompletedAchievements.insert(achievement_id);
} while(result->NextRow());
delete result;

View file

@ -1681,12 +1681,12 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args)
uint32 moneyuser = chr->GetMoney();
if(addmoney < 0)
if (addmoney < 0)
{
int32 newmoney = moneyuser + addmoney;
int32 newmoney = int32(moneyuser) + addmoney;
sLog.outDetail(GetMangosString(LANG_CURRENT_MONEY), moneyuser, addmoney, newmoney);
if(newmoney <= 0 )
if (newmoney <= 0 )
{
PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
@ -1696,6 +1696,9 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args)
}
else
{
if (newmoney > MAX_MONEY_AMOUNT)
newmoney = MAX_MONEY_AMOUNT;
PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), GetNameLink(chr).c_str());
if (needReportToTarget(chr))
ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, GetNameLink().c_str(), abs(addmoney));
@ -1707,7 +1710,11 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args)
PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, GetNameLink().c_str(), addmoney);
chr->ModifyMoney( addmoney );
if (addmoney >=MAX_MONEY_AMOUNT)
chr->SetMoney(MAX_MONEY_AMOUNT);
else
chr->ModifyMoney( addmoney );
}
sLog.outDetail(GetMangosString(LANG_NEW_MONEY), moneyuser, addmoney, chr->GetMoney() );

View file

@ -3418,31 +3418,34 @@ bool ChatHandler::HandleDamageCommand(const char * args)
Unit* target = getSelectedUnit();
if(!target || !m_session->GetPlayer()->GetSelection())
if (!target || !m_session->GetPlayer()->GetSelection())
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
}
if( !target->isAlive() )
if (!target->isAlive())
return true;
char* damageStr = strtok((char*)args, " ");
if(!damageStr)
if (!damageStr)
return false;
int32 damage = atoi((char*)damageStr);
if(damage <=0)
int32 damage_int = atoi((char*)damageStr);
if(damage_int <=0)
return true;
uint32 damage = damage_int;
char* schoolStr = strtok((char*)NULL, " ");
// flat melee damage without resistence/etc reduction
if(!schoolStr)
if (!schoolStr)
{
m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
if (target != m_session->GetPlayer())
m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
return true;
}
@ -3458,7 +3461,7 @@ bool ChatHandler::HandleDamageCommand(const char * args)
char* spellStr = strtok((char*)NULL, " ");
// melee damage by specific school
if(!spellStr)
if (!spellStr)
{
uint32 absorb = 0;
uint32 resist = 0;
@ -3470,6 +3473,7 @@ bool ChatHandler::HandleDamageCommand(const char * args)
damage -= absorb + resist;
m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
return true;
@ -3479,7 +3483,7 @@ bool ChatHandler::HandleDamageCommand(const char * args)
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint32 spellid = extractSpellIdFromLink((char*)args);
if(!spellid || !sSpellStore.LookupEntry(spellid))
if (!spellid || !sSpellStore.LookupEntry(spellid))
return false;
m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);

View file

@ -843,6 +843,8 @@ void Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
damage-=absorb+resist;
DealDamageMods(this,damage,&absorb);
WorldPacket data(SMSG_ENVIRONMENTALDAMAGELOG, (21));
data << uint64(GetGUID());
data << uint8(type!=DAMAGE_FALL_TO_VOID ? type : DAMAGE_FALL);
@ -9550,14 +9552,17 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
{
if( Item* pBag = GetItemByPos( INVENTORY_SLOT_BAG_0, i ) )
{
if( ItemPrototype const* pBagProto = pBag->GetProto() )
if( pBag != pItem )
{
if( pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot ) )
if( ItemPrototype const* pBagProto = pBag->GetProto() )
{
if(pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH)
return EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH;
else
return EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER;
if( pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot ) )
{
if(pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH)
return EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH;
else
return EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER;
}
}
}
}

View file

@ -1056,6 +1056,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Add bonuses and fill damageInfo struct
caster->CalculateSpellDamage(&damageInfo, m_damage, m_spellInfo);
caster->DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
// Send log damage message to client
caster->SendSpellNonMeleeDamageLog(&damageInfo);

View file

@ -5810,6 +5810,8 @@ void Aura::PeriodicTick()
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
pCaster->DealDamageMods(m_target,pdamage,&absorb);
WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
data.append(m_target->GetPackGUID());
data.appendPackGUID(GetCasterGUID());
@ -5988,10 +5990,13 @@ void Aura::PeriodicTick()
}
else
{
pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), gain, GetSpellSchoolMask(GetSpellProto()), 0, 0, false, 0, false);
uint32 damage = gain;
uint32 absorb = 0;
pCaster->DealDamageMods(pCaster,damage,&absorb);
pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), damage, GetSpellSchoolMask(GetSpellProto()), absorb, 0, false, 0, false);
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
pCaster->DealDamage(pCaster, gain, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
pCaster->DealDamage(pCaster, damage, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
}
}
@ -6173,6 +6178,9 @@ void Aura::PeriodicTick()
//maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
SpellNonMeleeDamage damageInfo(pCaster, m_target, spellProto->Id, spellProto->SchoolMask);
pCaster->CalculateSpellDamage(&damageInfo, gain, spellProto);
pCaster->DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
pCaster->SendSpellNonMeleeDamageLog(&damageInfo);
// Set trigger flag

View file

@ -282,8 +282,7 @@ void Spell::EffectInstaKill(uint32 /*i*/)
if(m_caster==unitTarget) // prevent interrupt message
finish();
uint32 health = unitTarget->GetHealth();
m_caster->DealDamage(unitTarget, health, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
m_caster->DealDamage(unitTarget, unitTarget->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
void Spell::EffectEnvirinmentalDMG(uint32 i)

View file

@ -374,10 +374,15 @@ void Unit::RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage)
RemoveSpellsCausingAura(auraType);
}
uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss)
void Unit::DealDamageMods(Unit *pVictim, uint32 &damage, uint32* absorb)
{
if (!pVictim->isAlive() || pVictim->isInFlight() || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
return 0;
{
if(absorb)
absorb += damage;
damage = 0;
return;
}
//You don't lose health from damage taken from another player while in a sanctuary
//You still see it in the combat log though
@ -385,9 +390,28 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
{
const AreaTableEntry *area = GetAreaEntryByAreaID(pVictim->GetAreaId());
if(area && area->flags & AREA_FLAG_SANCTUARY) //sanctuary
return 0;
{
if(absorb)
absorb += damage;
damage = 0;
}
}
uint32 originalDamage = damage;
//Script Event damage Deal
if( GetTypeId()== TYPEID_UNIT && ((Creature *)this)->AI())
((Creature *)this)->AI()->DamageDeal(pVictim, damage);
//Script Event damage taken
if( pVictim->GetTypeId()== TYPEID_UNIT && ((Creature *)pVictim)->AI() )
((Creature *)pVictim)->AI()->DamageTaken(this, damage);
if(absorb && originalDamage > damage)
absorb += (originalDamage - damage);
}
uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss)
{
// remove affects from victim (including from 0 damage and DoTs)
if(pVictim != this)
pVictim->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
@ -405,13 +429,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
pVictim->SetStandState(UNIT_STAND_STATE_STAND);
}
//Script Event damage Deal
if( GetTypeId()== TYPEID_UNIT && ((Creature *)this)->AI())
((Creature *)this)->AI()->DamageDeal(pVictim, damage);
//Script Event damage taken
if( pVictim->GetTypeId()== TYPEID_UNIT && ((Creature *)pVictim)->AI() )
((Creature *)pVictim)->AI()->DamageTaken(this, damage);
if(!damage)
{
// Rage from physical damage received .
@ -985,6 +1002,7 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID);
SpellNonMeleeDamage damageInfo(this, pVictim, spellInfo->Id, spellInfo->SchoolMask);
CalculateSpellDamage(&damageInfo, damage, spellInfo);
DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
SendSpellNonMeleeDamageLog(&damageInfo);
DealSpellDamage(&damageInfo, true);
return damageInfo.damage;
@ -1514,6 +1532,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
//CalcAbsorbResist(pVictim, SpellSchools(spellProto->School), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
//damage-=absorb + resist;
pVictim->DealDamageMods(this,damage,NULL);
WorldPacket data(SMSG_SPELLDAMAGESHIELD,(8+8+4+4+4+4));
data << uint64(pVictim->GetGUID());
data << uint64(GetGUID());
@ -1809,8 +1829,12 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
int32 canabsorb = caster->GetHealth();
if (canabsorb < absorbed)
absorbed = canabsorb;
DealDamage(caster, absorbed, NULL, damagetype, schoolMask, 0, false);
RemainingDamage -= absorbed;
uint32 ab_damage = absorbed;
DealDamageMods(caster,ab_damage,NULL);
DealDamage(caster, ab_damage, NULL, damagetype, schoolMask, 0, false);
continue;
}
break;
@ -1914,10 +1938,15 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
RemainingDamage -= currentAbsorb;
SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, currentAbsorb, schoolMask, 0, 0, false, 0, false);
CleanDamage cleanDamage = CleanDamage(currentAbsorb, BASE_ATTACK, MELEE_HIT_NORMAL);
DealDamage(caster, currentAbsorb, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false);
uint32 splitted = currentAbsorb;
uint32 splitted_absorb = 0;
DealDamageMods(caster,splitted,&splitted_absorb);
SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, splitted_absorb, 0, false, 0, false);
CleanDamage cleanDamage = CleanDamage(splitted, BASE_ATTACK, MELEE_HIT_NORMAL);
DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false);
}
AuraList const& vSplitDamagePct = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_PCT);
@ -1934,11 +1963,14 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
if(!caster || caster == pVictim || !caster->IsInWorld() || !caster->isAlive())
continue;
int32 splitted = int32(RemainingDamage * (*i)->GetModifier()->m_amount / 100.0f);
uint32 splitted = uint32(RemainingDamage * (*i)->GetModifier()->m_amount / 100.0f);
RemainingDamage -= splitted;
RemainingDamage -= int32(splitted);
SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, 0, 0, false, 0, false);
uint32 split_absorb = 0;
DealDamageMods(caster,splitted,&split_absorb);
SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, split_absorb, 0, false, 0, false);
CleanDamage cleanDamage = CleanDamage(splitted, BASE_ATTACK, MELEE_HIT_NORMAL);
DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false);
@ -2028,6 +2060,7 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
CalcDamageInfo damageInfo;
CalculateMeleeDamage(pVictim, 0, &damageInfo, attType);
// Send log damage message to client
DealDamageMods(pVictim,damageInfo.damage,&damageInfo.absorb);
SendAttackStateUpdate(&damageInfo);
ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, damageInfo.attackType);
DealMeleeDamage(&damageInfo,true);
@ -10656,6 +10689,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
sLog.outDebug("ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", auraModifier->m_amount, spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
SpellNonMeleeDamage damageInfo(this, pTarget, spellInfo->Id, spellInfo->SchoolMask);
CalculateSpellDamage(&damageInfo, auraModifier->m_amount, spellInfo);
DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
SendSpellNonMeleeDamageLog(&damageInfo);
DealSpellDamage(&damageInfo, true);
break;

View file

@ -988,6 +988,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void Unmount();
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
void DealDamageMods(Unit *pVictim, uint32 &damage, uint32* absorb);
uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss);
int32 DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellProto, bool critical = false);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7800"
#define REVISION_NR "7804"
#endif // __REVISION_NR_H__