@Override
	public void tickAging(final MOB mob, final long millisSinceLast)
	{
		if((mob==null)||(CMSecurity.isDisabled(CMSecurity.DisFlag.ALL_AGEING)))
			return;
		final long minutesEllapsed=(millisSinceLast / 60000);
		mob.setAgeMinutes(mob.getAgeMinutes()+minutesEllapsed); // this is really minutes
		if((minutesEllapsed>0)
		&&((!CMLib.flags().isCloaked(mob))
		  ||(!CMSecurity.isAllowed(mob, mob.location(), CMSecurity.SecFlag.CMDROOMS))))
			CMLib.players().bumpPrideStat(mob,AccountStats.PrideStat.MINUTES_ON, (int)minutesEllapsed);

		final PlayerStats stats = mob.playerStats();
		if(stats==null)
			return;
		final int[] birthDay = stats.getBirthday();
		if((mob.baseCharStats().getStat(CharStats.STAT_AGE)>0)
		&&(birthDay!=null))
		{
			final TimeClock clock=CMLib.time().localClock(mob.getStartRoom());
			final int currYear=clock.getYear();
			final int month=clock.getMonth();
			final int day=clock.getDayOfMonth();
			final int bday=birthDay[PlayerStats.BIRTHDEX_DAY];
			final int bmonth=birthDay[PlayerStats.BIRTHDEX_MONTH];
			while((currYear>birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED])
			||((currYear==birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED])&&((month>bmonth)||((month==bmonth)&&(day>=bday)))))
			{
				if(CMSecurity.isAllowed(mob,mob.location(),CMSecurity.SecFlag.IMMORT))
				{
					birthDay[PlayerStats.BIRTHDEX_YEAR]++;
				}
				else
				{
					if((month==bmonth)&&(day==bday))
						mob.tell(L("Happy Birthday!"));
					mob.baseCharStats().setStat(CharStats.STAT_AGE,mob.baseCharStats().getStat(CharStats.STAT_AGE)+1);
					mob.recoverCharStats();
					mob.recoverPhyStats();
					mob.recoverMaxState();
				}
				if(CMSecurity.isDisabled(CMSecurity.DisFlag.SLOW_AGEING) || (birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED]==currYear))
					birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED]++;
				else
					birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED]=currYear;
			}
			if(!CMSecurity.isAllowed(mob,mob.location(),CMSecurity.SecFlag.IMMORT))
			{
				if((mob.baseCharStats().ageCategory()>=Race.AGE_VENERABLE)
				&&(CMLib.dice().rollPercentage()==1)
				&&(CMLib.dice().rollPercentage()==1)
				&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))
				{
					final Ability A=CMClass.getAbility("Disease_Cancer");
					if((A!=null)&&(mob.fetchEffect(A.ID())==null)&&(!CMSecurity.isAbilityDisabled(A.ID())))
						A.invoke(mob,mob,true,0);
				}
				else
				if((mob.baseCharStats().ageCategory()>=Race.AGE_ANCIENT)
				&&(CMLib.dice().rollPercentage()==1)
				&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))
				{
					final Ability A=CMClass.getAbility("Disease_Arthritis");
					if((A!=null)&&(mob.fetchEffect(A.ID())==null)&&(!CMSecurity.isAbilityDisabled(A.ID())))
						A.invoke(mob,mob,true,0);
				}
				else
				if((mob.baseCharStats().ageCategory()>=Race.AGE_ANCIENT)
				&&(CMLib.dice().rollPercentage()==1)
				&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))
				{
					final Ability A=CMClass.getAbility("Disease_Alzheimers");
					if((A!=null)&&(mob.fetchEffect(A.ID())==null)&&(!CMSecurity.isAbilityDisabled(A.ID())))
						A.invoke(mob,mob,true,0);
				}
				else
				if(CMLib.dice().rollPercentage()<10)
				{
					final int max=CMProps.getIntVar(CMProps.Int.BASEMAXSTAT);
					for(final int i: CharStats.CODES.MAXCODES())
					{
						if((max+mob.charStats().getStat(i))<=0)
						{
							mob.tell(L("Your max @x1 has fallen below 1!",CharStats.CODES.DESC(CharStats.CODES.toMAXBASE(i)).toLowerCase()));
							CMLib.combat().postDeath(null,mob,null);
							break;
						}
					}
				}
			}
		}
	}