Fisherman Daily Schedule JS

Need help with your JScripts? Got questions concerning the DFNs? Come forward, step inside :)
Post Reply
Mindless Automaton
UOX3 Apprentice
Posts: 189
Joined: Wed May 10, 2006 3:48 am
Has thanked: 0
Been thanked: 1 time
Contact:

Fisherman Daily Schedule JS

Post by Mindless Automaton »

I did this a while back. The guy walks around Britain, does fishing, etc.
Some issues:
- as far as I know, only time anyone lies down is if they die, so no sleeping in bed.
- if he walks into another npc, he gets stuck until the next scheduled event assuming that takes him a different route.
- need code to check above and blocked seats if trying to sit somewhere.

Code: Select all

//  Fisherman in Britain job script 3206
// Could be any NPC, but you probably won't want 2 fishing
// in the same spot.
// maybe an array of fishing spots & randomly pick one.

function onAISliver( tChar )
{
	var hour = GetHour();
	var minute = GetMinute();

	var hDisp = hour.toString();
	var mDisp = minute.toString();
	if( minute < 10 )
		mDisp = "0" + mDisp;

	var curr_time = hDisp + ":" + mDisp; //set up the clock

	if ( curr_time == "5:00" )
	{
		//get breakfast?
		// wake up and go fish
		tChar.WalkTo( 1468, 1711, 1000 ); //walk to door
	// open in door
		tChar.WalkTo( 1484, 1768, 1000 ); //walk to docks
		tChar.TextMessage( "Time for some fishin'." );
//		Turn character towards water set dir = 4?; DIRECTION=SE?
//		Casting animation
//		Skill checks for catching fish.
//		Need to open doors!

	}

	if ( curr_time == "12:00" )
	{
 	// go to pub for lunch
		tChar.TextMessage( "Time for some lunch." );
		tChar.WalkTo( 1432, 1731, 1000 ); //walk to inn door
	// open in door
	// check for if blocked (someone else is sitting there) choose another seat
		tChar.WalkTo( 1427, 1724, 1000 ); //walk to seat
	}

	if ( curr_time == "12:30" )
	{
	// go fish some more
		tChar.TextMessage( "Time for some fishin'." );
		tChar.WalkTo( 1431, 1771, 1000 ); //walk to door
	// open in door
		tChar.WalkTo( 1484, 1768, 1000 ); //walk to docks
	}

	if ( curr_time == "17:00" )
	{
 	// go to butcher & sell fish
		tChar.TextMessage( "Time for sellin' fish." );
		tChar.WalkTo( 1452, 1728, 1000 ); // walk to door
	// open in door
		tChar.WalkTo( 1451, 1723, 1000 ); // move to center
	}
	// fish sell for about 2 gold each
	// butcher sells fish steaks for 6 gold
	// need to find an inn that sells cooked fish for price
	// runner for the butcher that delivers products 1 or 2 gold per deliver?

	if ( curr_time == "18:00" )
	{
 	// go to pub for dinner
		tChar.TextMessage( "Time for dinner." );
		tChar.WalkTo( 1452, 1727, 1000 ); //walk to door
	// open in door
		tChar.WalkTo( 1432, 1731, 1000 ); //walk to inn door
	// open in door
	// check for if blocked (someone else is sitting there) choose another seat
		tChar.WalkTo( 1427, 1724, 1000 ); //walk to seat
	}
// time before/after dinner to do shopping or whatever..
// check for if blocked (someone else is sitting there)

	if ( curr_time == "21:00" )
	{
 	// go to home for sleep
		tChar.TextMessage( "Yawn, time for bed." );
		tChar.WalkTo( 1468, 1712, 1000 ); //walk to door
	// open in door
		tChar.WalkTo( 1468, 1705, 1000 ); //walk to bed
		tChar.TextMessage( "I'm sleeping, but I can't figure out how to lay down!" );
	}
}
Mindless Automaton
Linux - UOX3 - 0.99.5 dev branch
Win10Pro 19042.572 - UOX3 0.99.3a; Razor 1.0.14; Client 7.0.87.11 or 4.0.11c (Patch 0)
User avatar
Xuri
Site Admin
Posts: 3704
Joined: Mon Jun 02, 2003 9:11 am
Location: Norway
Has thanked: 48 times
Been thanked: 8 times
Contact:

Post by Xuri »

That's cool! Reminds me of an emulator (UOX3 offshoot? Not sure) back in the day that made a big thing out of being able to setup NPC schedules.

For having the NPC lie down in a bed, there are a couple of approaches you can try:
  • See if it's possible to use animation packets to play the death animation backwards, so slow that it doesn't actually move at all 😅 Not sure if doable though.
  • Cheat! Turn the NPC invisible (and invulnerable, and frozen), add a corpse on the bed, duplicate the NPC's clothes/hair etc. and add those to the corpse container to dress like the NPC. Use item TextMessages to have the corpse item say "ZzzZzz". When it's time to wake up, delete the corpse, unhide the NPC and set him off walking again.
-= Ho Eyo He Hum =-
Mindless Automaton
UOX3 Apprentice
Posts: 189
Joined: Wed May 10, 2006 3:48 am
Has thanked: 0
Been thanked: 1 time
Contact:

Post by Mindless Automaton »

I saw on your Trello list you mentioned NPC schedules.
See if it's possible to use animation packets to play the death animation backwards, so slow that it doesn't actually move at all 😅 Not sure if doable though.
That's a possibility. I was thinking about using the death animation with the clumsy spell also which is why I was asking about the details of that spell in the other thread. Add an occasional chance for a face plant, dropped item from hand, etc. :)
Cheat! Turn the NPC invisible (and invulnerable, and frozen), add a corpse on the bed, duplicate the NPC's clothes/hair etc. and add those to the corpse container to dress like the NPC. Use item TextMessages to have the corpse item say "ZzzZzz". When it's time to wake up, delete the corpse, unhide the NPC and set him off walking again.
Yeah, I was thinking about that also, but teleport them to a storage pod somewhere. (A fiery area at -50 Z!)
Mindless Automaton
Linux - UOX3 - 0.99.5 dev branch
Win10Pro 19042.572 - UOX3 0.99.3a; Razor 1.0.14; Client 7.0.87.11 or 4.0.11c (Patch 0)
Mindless Automaton
UOX3 Apprentice
Posts: 189
Joined: Wed May 10, 2006 3:48 am
Has thanked: 0
Been thanked: 1 time
Contact:

Post by Mindless Automaton »

I'm doing some trouble that hopefully I can shoot.

Code: Select all

	if ( curr_time == "5:00" )
	{

		tChar.WalkTo( 1468, 1711, 100 ); //walk to door

		tChar.WalkTo( 1484, 1768, 100 ); //walk to docks

		tChar.TextMessage( "Time for some fishin'." );

	}

	if ( curr_time == "12:00" )
	{

		tChar.TextMessage( "Time for some lunch." );
		tChar.WalkTo( 1432, 1731, 100 ); //walk to inn door

		tChar.WalkTo( 1427, 1724, 100 ); //walk to seat

	}
  • The NPC will follow the 1st walkto and make it to the dock. Any additional do not happen.
  • The TextMessage event happens on schedule, but its repeated like 5 or 6 times.
People who text message all day and don't go do their jobs gets on my nerves.

So I am going to take an uneducated guess and say that the # of steps never gets reset between WalkTos and the character hits 100 steps and wont move anymore.

Thanks!
Mindless Automaton
Linux - UOX3 - 0.99.5 dev branch
Win10Pro 19042.572 - UOX3 0.99.3a; Razor 1.0.14; Client 7.0.87.11 or 4.0.11c (Patch 0)
User avatar
Xuri
Site Admin
Posts: 3704
Joined: Mon Jun 02, 2003 9:11 am
Location: Norway
Has thanked: 48 times
Been thanked: 8 times
Contact:

Post by Xuri »

Hmm interesting. The multiple TextMessages might be because the in-game time might equal 5:00 or 12:00 multiple times (if script is checked multiple times)? Not sure about the WalkTo stuff though. I'll see if I can do some testing later today to see what's going on.
-= Ho Eyo He Hum =-
User avatar
Xuri
Site Admin
Posts: 3704
Joined: Mon Jun 02, 2003 9:11 am
Location: Norway
Has thanked: 48 times
Been thanked: 8 times
Contact:

Post by Xuri »

Ok a couple of things to consider:

First off, onAISliver can trigger and run multiple times per second. Potentially, it can be checked multiple times while in-game time is "5:00", which would cause NPC to execute any TextMessages and/or WalkTo functions multiple times in a very short amount of time. You can get around this to some extent by adding a global boolean flag in the NPC script, like... var npcMoving = false; at the top of the script. Then you check if it's false along with your check for time. If both time and flag passes check, you set npcMoving to true so the enclosed code won't trigger multiple times.

Example:
var walking = false;

function onAISliver( tChar )
{
    var hour = GetHour();
    var minute = GetMinute();
    var hDisp = hour.toString();
    var mDisp = minute.toString();
    mDisp = (mDisp < 10 ? "0" + mDisp : mDisp)
   
    var curr_time = hDisp + ":" + mDisp;
    if( curr_time == "10:00" && walking == false )
    {
        walking = true;
        tChar.TextMessage( "I'm off!" );
        tChar.WalkTo( tChar.x + 10, tChar.y, 20 );
    }
}
Secondly... calling functions like WalkTo and RunTo do not pause execution of the script or wait for any return value... when these functions are called, the server will calculate the path to the intended destination and then add the "steps" to get to that destination into a movement queue which is then gradually executed over time, step by step, until NPC reaches destination - or something else overrides the movement queue. That brings me to the next point:

Additional lines you put after the WalkTo/RunTo will trigger almost immediately as soon as WalkTo/RunTo has finished executing, and multiple WalkTo/RunTos in a series will essentially override one another, and only the final one will actually be added to the queue.

If you want the NPC to walk to multiple different locations, you need to make sure, somehow, that the "next" movement command is only triggered once the NPC has reached the intended destination and is ready to go to the next one. Maybe you can make use of the onCollide event on some invisible "triggerplates" to detect when the NPC reaches a certain point, and then continue from there? :X

Edit: We could potentially update the WalkTo/RunTo functions to accept an optional boolean flag that determines whether a call to these functions will clear existing pathfinding steps for the character, or add to them - though I'm not sure if that helps any for your scenario with the fisherman?
-= Ho Eyo He Hum =-
User avatar
Xuri
Site Admin
Posts: 3704
Joined: Mon Jun 02, 2003 9:11 am
Location: Norway
Has thanked: 48 times
Been thanked: 8 times
Contact:

Post by Xuri »

Or maybe we need another JS event... onPathfindEnd(), which triggers when pathfinding is halted for an NPC (for whatever reason - or maybe with a parameter that indicates the reason it was halted... reached destination vs got blocked vs combat happened, etc)
-= Ho Eyo He Hum =-
User avatar
Xuri
Site Admin
Posts: 3704
Joined: Mon Jun 02, 2003 9:11 am
Location: Norway
Has thanked: 48 times
Been thanked: 8 times
Contact:

Post by Xuri »

Committed a couple of improvements to pathfinding!

First of all, improved pathfinding when advanced pathfinding is enabled in uox.ini, so NPCs can try to recalculate path if they are suddenly blocked by characters that weren't there when original pathfinding calculations were done.

Secondly, added a new JS event that can be used to detect when NPC is done pathfinding - and will give some hints about why pathfinding ended:
onPathfindEnd( mNPC, pathfindResult )

pathfindResult will return -1 if no valid path could be found to target location, 0 if a partial pathfind could be done (but ultimately blocked by a character in the final location) and 1 if pathfinding was a success and NPC ended up in the intended location.
npcWalkToImproved.gif
npcRunToImproved.gif
-= Ho Eyo He Hum =-
Post Reply