@Override
	public boolean tick(Tickable ticking, int tickID)
	{
		final MOB mob=getMakeMOB(ticking);
		final Item defaultItem=(ticking instanceof Item)?(Item)ticking:null;

		if((mob==null)||(lastKnownLocation==null))
		{
			altStatusTickable=null;
			return true;
		}

		final PhysicalAgent affecting=(ticking instanceof PhysicalAgent)?((PhysicalAgent)ticking):null;

		final List<DVector> scripts=getScripts();
		
		if(!runInPassiveAreas)
		{
			final Area A=CMLib.map().areaLocation(ticking);
			if((A!=null)&&(A.getAreaState() != Area.State.ACTIVE))
			{
				return true;
			}
		}

		int triggerCode=-1;
		String trigger="";
		String[] t=null;
		for(int thisScriptIndex=0;thisScriptIndex<scripts.size();thisScriptIndex++)
		{
			final DVector script=scripts.get(thisScriptIndex);
			if(script.size()<2)
				continue;
			trigger=((String)script.elementAt(0,1)).toUpperCase().trim();
			t=(String[])script.elementAt(0,2);
			triggerCode=getTriggerCode(trigger,t);
			tickStatus=Tickable.STATUS_SCRIPT+triggerCode;
			switch(triggerCode)
			{
			case 5: // rand_Prog
				if((!mob.amDead())&&canTrigger(5))
				{
					if(t==null)
						t=parseBits(script,0,"CR");
					if(t!=null)
					{
						final int prcnt=CMath.s_int(t[1]);
						if(CMLib.dice().rollPercentage()<prcnt)
							execute(affecting,mob,mob,mob,defaultItem,null,script,null,newObjs());
					}
				}
				break;
			case 16: // delay_prog
				if((!mob.amDead())&&canTrigger(16))
				{
					int targetTick=-1;
					if(delayTargetTimes.containsKey(Integer.valueOf(thisScriptIndex)))
						targetTick=delayTargetTimes.get(Integer.valueOf(thisScriptIndex)).intValue();
					else
					{
						if(t==null)
							t=parseBits(script,0,"CCR");
						if(t!=null)
						{
							final int low=CMath.s_int(t[1]);
							int high=CMath.s_int(t[2]);
							if(high<low)
								high=low;
							targetTick=CMLib.dice().roll(1,high-low+1,low-1);
							delayTargetTimes.put(Integer.valueOf(thisScriptIndex),Integer.valueOf(targetTick));
						}
					}
					int delayProgCounter=0;
					if(delayProgCounters.containsKey(Integer.valueOf(thisScriptIndex)))
						delayProgCounter=delayProgCounters.get(Integer.valueOf(thisScriptIndex)).intValue();
					else
						delayProgCounters.put(Integer.valueOf(thisScriptIndex),Integer.valueOf(0));
					if(delayProgCounter==targetTick)
					{
						execute(affecting,mob,mob,mob,defaultItem,null,script,null,newObjs());
						delayProgCounter=-1;
					}
					delayProgCounters.remove(Integer.valueOf(thisScriptIndex));
					delayProgCounters.put(Integer.valueOf(thisScriptIndex),Integer.valueOf(delayProgCounter+1));
				}
				break;
			case 7: // fightProg
				if((mob.isInCombat())&&(!mob.amDead())&&canTrigger(7))
				{
					if(t==null)
						t=parseBits(script,0,"CR");
					if(t!=null)
					{
						final int prcnt=CMath.s_int(t[1]);
						if(CMLib.dice().rollPercentage()<prcnt)
							execute(affecting,mob.getVictim(),mob,mob,defaultItem,null,script,null,newObjs());
					}
				}
				else
				if((ticking instanceof Item)
				&&canTrigger(7)
				&&(((Item)ticking).owner() instanceof MOB)
				&&(((MOB)((Item)ticking).owner()).isInCombat()))
				{
					if(t==null)
						t=parseBits(script,0,"CR");
					if(t!=null)
					{
						final int prcnt=CMath.s_int(t[1]);
						if(CMLib.dice().rollPercentage()<prcnt)
						{
							final MOB M=(MOB)((Item)ticking).owner();
							if(!M.amDead())
								execute(affecting,M,mob.getVictim(),mob,defaultItem,null,script,null,newObjs());
						}
					}
				}
				break;
			case 11: // hitprcnt
				if((mob.isInCombat())&&(!mob.amDead())&&canTrigger(11))
				{
					if(t==null)
						t=parseBits(script,0,"CR");
					if(t!=null)
					{
						final int prcnt=CMath.s_int(t[1]);
						final int floor=(int)Math.round(CMath.mul(CMath.div(prcnt,100.0),mob.maxState().getHitPoints()));
						if(mob.curState().getHitPoints()<=floor)
							execute(affecting,mob.getVictim(),mob,mob,defaultItem,null,script,null,newObjs());
					}
				}
				else
				if((ticking instanceof Item)
				&&canTrigger(11)
				&&(((Item)ticking).owner() instanceof MOB)
				&&(((MOB)((Item)ticking).owner()).isInCombat()))
				{
					final MOB M=(MOB)((Item)ticking).owner();
					if(!M.amDead())
					{
						if(t==null)
							t=parseBits(script,0,"CR");
						if(t!=null)
						{
							final int prcnt=CMath.s_int(t[1]);
							final int floor=(int)Math.round(CMath.mul(CMath.div(prcnt,100.0),M.maxState().getHitPoints()));
							if(M.curState().getHitPoints()<=floor)
								execute(affecting,M,mob.getVictim(),mob,defaultItem,null,script,null,newObjs());
						}
					}
				}
				break;
			case 6: // once_prog
				if(!oncesDone.contains(script)&&canTrigger(6))
				{
					if(t==null)
						t=parseBits(script,0,"C");
					oncesDone.add(script);
					execute(affecting,mob,mob,mob,defaultItem,null,script,null,newObjs());
				}
				break;
			case 14: // time_prog
				if((mob.location()!=null)
				&&canTrigger(14)
				&&(!mob.amDead()))
				{
					if(t==null)
						t=parseBits(script,0,"CT");
					int lastTimeProgDone=-1;
					if(lastTimeProgsDone.containsKey(Integer.valueOf(thisScriptIndex)))
						lastTimeProgDone=lastTimeProgsDone.get(Integer.valueOf(thisScriptIndex)).intValue();
					final int time=mob.location().getArea().getTimeObj().getHourOfDay();
					if((t!=null)&&(lastTimeProgDone!=time))
					{
						boolean done=false;
						for(int i=1;i<t.length;i++)
						{
							if(time==CMath.s_int(t[i]))
							{
								done=true;
								execute(affecting,mob,mob,mob,defaultItem,null,script,""+time,newObjs());
								lastTimeProgsDone.remove(Integer.valueOf(thisScriptIndex));
								lastTimeProgsDone.put(Integer.valueOf(thisScriptIndex),Integer.valueOf(time));
								break;
							}
						}
						if(!done)
							lastTimeProgsDone.remove(Integer.valueOf(thisScriptIndex));
					}
				}
				break;
			case 15: // day_prog
				if((mob.location()!=null)&&canTrigger(15)
				&&(!mob.amDead()))
				{
					if(t==null)
						t=parseBits(script,0,"CT");
					int lastDayProgDone=-1;
					if(lastDayProgsDone.containsKey(Integer.valueOf(thisScriptIndex)))
						lastDayProgDone=lastDayProgsDone.get(Integer.valueOf(thisScriptIndex)).intValue();
					final int day=mob.location().getArea().getTimeObj().getDayOfMonth();
					if((t!=null)&&(lastDayProgDone!=day))
					{
						boolean done=false;
						for(int i=1;i<t.length;i++)
						{
							if(day==CMath.s_int(t[i]))
							{
								done=true;
								execute(affecting,mob,mob,mob,defaultItem,null,script,null,newObjs());
								lastDayProgsDone.remove(Integer.valueOf(thisScriptIndex));
								lastDayProgsDone.put(Integer.valueOf(thisScriptIndex),Integer.valueOf(day));
								break;
							}
						}
						if(!done)
							lastDayProgsDone.remove(Integer.valueOf(thisScriptIndex));
					}
				}
				break;
			case 13: // quest time prog
				if(!oncesDone.contains(script)&&canTrigger(13))
				{
					if(t==null)
						t=parseBits(script,0,"CCC");
					if(t!=null)
					{
						final Quest Q=getQuest(t[1]);
						if((Q!=null)&&(Q.running())&&(!Q.stopping()))
						{
							final int time=CMath.s_int(t[2]);
							if(time>=Q.minsRemaining())
							{
								oncesDone.add(script);
								execute(affecting,mob,mob,mob,defaultItem,null,script,null,newObjs());
							}
						}
					}
				}
				break;
			default:
				break;
			}
		}
		tickStatus=Tickable.STATUS_SCRIPT+100;
		dequeResponses();
		altStatusTickable=null;
		return true;
	}