@Override
	public boolean tick(final Tickable ticking, final int tickID)
	{
		final int sailingTickID = amInTacticalMode() ? Tickable.TICKID_SPECIALMANEUVER : Tickable.TICKID_AREA;
		if(tickID == Tickable.TICKID_AREA)
		{
			if(amDestroyed())
				return false;
			Area area = this.getShipArea();
			if(area instanceof BoardableShip)
			{
				if((this.tenderShip != null)
				&&(this.tenderShip.owner()==owner())
				&&(this.targetedShip==null)
				&&(this.tenderShip instanceof GenSailingShip)
				&&(((GenSailingShip)this.tenderShip).targetedShip==null))
				{
					// yay!
				}
				else
				{
					this.tenderShip=null;
					if((((BoardableShip)area).getIsDocked() != owner())
					&&(owner() instanceof Room))
					{
						this.dockHere((Room)owner());
					}
				}
			}
		}
		if(tickID == sailingTickID)
		{
			ticksSinceMove++;
			if((!this.anchorDown) 
			&& (area != null) 
			&& (courseDirection != -1) )
			{
				final int speed=getShipSpeed();
				for(int s=0;s<speed && (courseDirection>=0);s++)
				{
					switch(sail(courseDirection & 127))
					{
					case CANCEL:
					{
						courseDirection=-1;
						break;
					}
					case CONTINUE:
					{
						if(this.courseDirections.size()>0)
						{
							final Integer newDir=this.courseDirections.remove(0);
							courseDirection = newDir.intValue();
						}
						else
						{
							if((courseDirection & COURSE_STEER_MASK) == 0)
								courseDirection = -1;
						}
						break;
					}
					case REPEAT:
					{
						break;
					}
					}
				}
				if(tickID == Tickable.TICKID_SPECIALMANEUVER)
				{
					final Room combatRoom=this.shipCombatRoom;
					if(combatRoom != null)
					{
						final MOB mob = CMClass.getFactoryMOB(name(),phyStats().level(),null);
						try
						{
							mob.setRiding(this);
							mob.basePhyStats().setDisposition(mob.basePhyStats().disposition()|PhyStats.IS_SWIMMING);
							mob.phyStats().setDisposition(mob.phyStats().disposition()|PhyStats.IS_SWIMMING);
							combatRoom.show(mob, this, CMMsg.MSG_ACTIVATE|CMMsg.MASK_MALICIOUS, null);
						}
						finally
						{
							mob.destroy();
						}
					}
					PairList<Item,int[]> coords = this.coordinates;
					if(coords != null)
					{
						for(Iterator<Item> i= coords.firstIterator(); i.hasNext();)
						{
							Item I=i.next();
							if((I instanceof GenSailingShip)
							&&(((GenSailingShip)I).targetedShip == this))
								((GenSailingShip)I).announceToDeck(((GenSailingShip)I).getTargetedShipInfo());
						}
					}
				}
				
			}
		}
		if(tickID == Tickable.TICKID_SPECIALCOMBAT)
		{
			if(this.amInTacticalMode())
			{
				final List<Weapon> weapons = new LinkedList<Weapon>();
				for(Enumeration<Room> r=this.getShipArea().getProperMap();r.hasMoreElements();)
				{
					try
					{
						final Room R=r.nextElement();
						if(R!=null)
						{
							for(Enumeration<Item> i=R.items();i.hasMoreElements();)
							{
								try
								{
									final Item I=i.nextElement();
									if(isAShipSiegeWeaponReadyToFire(I))
										weapons.add((Weapon)I);
								}
								catch(NoSuchElementException ne)
								{
								}
							}
						}
					}
					catch(NoSuchElementException ne)
					{
					}
				}
				if(weapons.size()>0)
				{
					final MOB mob = CMClass.getFactoryMOB(name(),phyStats().level(),null);
					final int[] coordsToHit;
					if(this.targetedShip instanceof GenSailingShip)
						coordsToHit = ((GenSailingShip)this.targetedShip).getMyCoords();
					else
						coordsToHit = new int[2];
					try
					{
						mob.setRiding(this);
						mob.basePhyStats().setDisposition(mob.basePhyStats().disposition()|PhyStats.IS_SWIMMING);
						mob.phyStats().setDisposition(mob.phyStats().disposition()|PhyStats.IS_SWIMMING);
						int notLoaded = 0;
						int notAimed = 0;
						for(Weapon w : weapons)
						{
							final Room R=CMLib.map().roomLocation(w);
							if(R!=null)
							{
								mob.setLocation(R);
								if((w instanceof AmmunitionWeapon)
								&&(((AmmunitionWeapon)w).requiresAmmunition())
								&&(((AmmunitionWeapon)w).ammunitionRemaining() <=0))
									notLoaded++;
								else
								{
									//mob.setRangeToTarget(0);
									int index = aimings.indexOfFirst(w);
									if(index >= 0)
									{
										int[] coordsAimedAt = aimings.remove(index).second;
										boolean wasHit = Arrays.equals(coordsAimedAt, coordsToHit);
										CMLib.combat().postShipAttack(mob, this, this.targetedShip, w, wasHit);
									}
									else
										notAimed++;
								}
							}
						}
						final String spamMsg;
						if((notLoaded > 0) && (notAimed > 0))
							spamMsg = L("@x1 of your weapons were not loaded, and @x2 were ready but not aimed.",""+notLoaded, ""+notAimed);
						else
						if(notLoaded > 0)
							spamMsg = L("@x1 of your weapons were not loaded.",""+notLoaded);
						else
						if(notAimed > 0)
							spamMsg = L("@x1 of your weapons were ready but not aimed.",""+notAimed);
						else
							spamMsg = "";
						if(spamMsg.length()>0)
						{
							if(spamMsg.equals(lastSpamMsg))
							{
								if(lastSpamCt < 3)
								{
									announceToDeck(spamMsg);
									lastSpamCt++;
								}
							}
							else
							{
								announceToDeck(spamMsg);
								lastSpamCt=0;
							}
						}
						lastSpamMsg=spamMsg;
					}
					finally
					{
						mob.setRangeToTarget(0);
						mob.destroy();
					}
				}
			}
		}
		return super.tick(ticking, tickID);
	}