protected void subtickAttack(MOB fighter, Item weapon, int folrange)
	{
		if((weapon!=null)&&(weapon.amWearingAt(Wearable.IN_INVENTORY)))
			weapon=fighter.fetchWieldedItem();
		if((!fighter.isAttributeSet(MOB.Attrib.AUTOMELEE)))
			postAttack(fighter,fighter.getVictim(),weapon);
		else
		{
			boolean inminrange=(fighter.rangeToTarget()>=minRangeWith(fighter, weapon));
			boolean inmaxrange=(fighter.rangeToTarget()<=maxRangeWith(fighter, weapon));
			if((folrange>=0)&&(fighter.rangeToTarget()>=0)&&(folrange!=fighter.rangeToTarget()))
			{
				if(fighter.rangeToTarget()<folrange)
					inminrange=false;
				else
				if(fighter.rangeToTarget()>folrange)
				{
					// these settings are ONLY to ensure that neither of the
					// next two conditions evaluate to true.
					inminrange=true;
					inmaxrange=false;
					// we advance
					final CMMsg msg=CMClass.getMsg(fighter,fighter.getVictim(),CMMsg.MSG_ADVANCE,L("<S-NAME> advances(s) at <T-NAMESELF>."));
					if(fighter.location().okMessage(fighter,msg))
					{
						fighter.location().send(fighter,msg);
						fighter.setRangeToTarget(fighter.rangeToTarget()-1);
						if((fighter.getVictim()!=null)&&(fighter.getVictim().getVictim()==fighter))
						{
							fighter.getVictim().setRangeToTarget(fighter.rangeToTarget());
							fighter.getVictim().recoverPhyStats();
						}
					}
				}
			}

			if((!inminrange)&&(fighter.curState().getMovement()>=25))
			{
				final CMMsg msg=CMClass.getMsg(fighter,fighter.getVictim(),CMMsg.MSG_RETREAT,L("<S-NAME> retreat(s) before <T-NAME>."));
				if(fighter.location().okMessage(fighter,msg))
					fighter.location().send(fighter,msg);
			}
			else
			if(inminrange&&inmaxrange&&((weapon!=null)||(fighter.rangeToTarget()==0)))
				postAttack(fighter,fighter.getVictim(),weapon);
		}
	}