Can printtextabove be recognised as event.speech?

Get Help on scripting in POL with configurations, config setups, script trouble shooting, etc.
Post Reply
Basara
Novice Poster
Posts: 47
Joined: Fri Oct 13, 2006 6:37 am

Can printtextabove be recognised as event.speech?

Post by Basara »

Hi all,

I'm wanting to try something with boats and have the tillerman respond to text printed above an item on deck with printtextabove(item, "Text");
Is there a way to get the tiller to recognise this as with event.speech?
Pierce
Forum Regular
Posts: 420
Joined: Thu Feb 02, 2006 8:33 am

Post by Pierce »

Is there a way to get the tiller to recognise this as with event.speech?
Not in a direct way. But you can use the process id (pid) of the boat.
So if you print the text over the item you also send a speech event to the boat process. That way it looks like the tillerman responds to that text.
Basara
Novice Poster
Posts: 47
Joined: Fri Oct 13, 2006 6:37 am

Post by Basara »

Pierce wrote:Not in a direct way. But you can use the process id (pid) of the boat.
So if you print the text over the item you also send a speech event to the boat process. That way it looks like the tillerman responds to that text.
Ok I kind of understand, where would I get the PID from?
I've had a look at a few other scripts but they seem to all deal with NPC's not items.

I've pasted my code below, so you can see what i'm trying but not sure where the PID part goes or if the sendevent i've tried would work without pointing to the PID.

Code: Select all

use uo;
use os;
include "include/eventid";

var tillerman := 0xF010;

program ferry(rune)
var tiller := FindTiller(rune);
var ev := struct;
	ev.+type;
	ev.+command;
	ev.type := EVID_SPEECH;
	ev.command := "Full Speed Ahead";
//sendevent(tiller, ev);
tiller.sendevent(ev);
endprogram

function FindTiller(rune)
foreach item in ListItemsNearLocation( rune.x, rune.y, rune.z, 3);
	if(item.objtype == tillerman)
		return item;
	endif
endforeach
endfunction
Pierce
Forum Regular
Posts: 420
Joined: Thu Feb 02, 2006 8:33 am

Post by Pierce »

You have to set it first. Perhaps your boat.src contains something like that:

Code: Select all

  var bpid := getpid();
  SetObjProperty(tillerman, "#boatpid", bpid);
This would get the PID of the boat process and set it to the tillerman at each server start. So it should be written at the beginning of your boat.src if it doesn't contain it yet.

If you want to get access from another script do something like that, e.g.:

Code: Select all

 var tillerpid := GetObjProperty(tillerman, "#boatpid");
 var boatprocess := getprocess( tillerpid );
Now you can do something like:

Code: Select all

   PrintTextAbove(item , "idontknow"); 
   if(dontknow == dontknow1) // just an example if you need an if
    var ev := struct; 
    ev.+ type; 
    ev.+ source; 
    ev.+ text; 
    ev.type := SYSEVENT_SPEECH; 
    ev.source := who; 
    ev.text := "idontknow"; 
    boatprocess.sendevent(ev);
   endif 
Surely you have to set the .inc and .em files yourself, whatever they are at your server :)
Basara
Novice Poster
Posts: 47
Joined: Fri Oct 13, 2006 6:37 am

Post by Basara »

Ok, I've followed what you suggested and the PID is being set on the tillerman correctly on POL startup.
I'm happy to say the script does make the boat move :)

Here is the script that sends the event:

Code: Select all

use uo;
use os;
include "include/sysevent";

var tillergfx := 0xF010;

program ferry(who, rune)
if(who.cmdlevel < 2)
	sendsysmessage(who, "This system is not ready for player use yet");
	return;
endif
var tillerman := FindTiller(rune);
var tillerpid := GetObjProperty(tillerman, "#boatpid"); 
var boatprocess := getprocess( tillerpid );

var ev := struct; 
    ev.+ type; 
    ev.+ source; 
    ev.+ text; 
    ev.type := SYSEVENT_SPEECH; 
    ev.source := rune; 
    ev.text := "Left"; 
    boatprocess.sendevent(ev);
endprogram

function FindTiller(rune)
foreach item in ListItemsNearLocation( rune.x, rune.y, rune.z, 3);
	if(item.objtype == tillergfx)
		return item;
	endif
endforeach
endfunction
I now plan to write a sequence of commands which will allow a boat to sail to a destination without user input, basically a ferry.
I'll let you know how that goes :)

Thanks so much for your help Pierce
Last edited by Basara on Wed Nov 28, 2007 3:19 am, edited 1 time in total.
Basara
Novice Poster
Posts: 47
Joined: Fri Oct 13, 2006 6:37 am

Post by Basara »

Ok, I've noticed something strange and just thought I'd share, at first I though the above script wasn't working then found out why.

If a player clicks the rune, the boat moves as it responds to the event sent via pid etc, if a concealed GM does it, it doesnt work, it will work if the GM is unconcealed.

If the ev.source was the person who clicked the rune - (program ferry(who, rune)) - I could understand it not responding to them whilst concealed, however the ev.source is the rune itself - ev.source := rune; -, so what's causing it to take the user's concealed state into account?

This isnt an issue as far as the script is concerned but it's been bugging me :)
User avatar
OldnGrey
POL Expert
Posts: 657
Joined: Sat Feb 04, 2006 6:26 pm

Post by OldnGrey »

A wild shot - take a look at the servspecopt.cfg file:

# EventVisibilityCoreChecks - If enabled, the core will not send system events
# to NPCs unless they are visible to the source.
# Visibility is based on:
# Source is logged in
# Source is not hidden / concealed
#
# If disabled, you will do the checks yourself in the scripts.


My guess is that the source being concealed by being on the gm is inheriting this property.
Basara
Novice Poster
Posts: 47
Joined: Fri Oct 13, 2006 6:37 am

Post by Basara »

OldnGrey wrote:My guess is that the source being concealed by being on the gm is inheriting this property.
That was my thought initially but the item is on the deck of the ship, not in the GM's pack, however, I've had a play and there's something still not right with the sendevent.

Code: Select all

use uo;
use os;
include "include/sysevent";

var tillergfx := 0xF010;

program ferry(who, rune)
printtextabove(who, "WHO");
printtextabove(rune, "RUNE");

var tillerman := FindTiller(rune);
var tillerpid := GetObjProperty(tillerman, "#boatpid"); 
var boatprocess := getprocess( tillerpid );

var ev := struct; 
    ev.+ type; 
    ev.+ source; 
    ev.+ text; 
    ev.type := SYSEVENT_SPEECH; 
    ev.source := rune; 
    ev.text := "Left"; 
    printtextabove(rune, "Activated");
    boatprocess.sendevent(ev);
endprogram

function FindTiller(rune)
foreach item in ListItemsNearLocation( rune.x, rune.y, rune.z, 3);
	if(item.objtype == tillergfx)
		return item;
	endif
endforeach
endfunction
The printtextabove(who, "WHO"); and printtextabove(rune, "RUNE"); shows it sees the user and the item the correct way round, but unless I change the ev.source := rune; to
ev.source := who; it doesnt send the event.

Similarly if I change the program to just program Ferry(rune) it works, but I assume thats cos it sees the player as the rune.

There is definatly still something wrong with sending the event from the item on the deck.
User avatar
OldnGrey
POL Expert
Posts: 657
Joined: Sat Feb 04, 2006 6:26 pm

Post by OldnGrey »

My guess is that you have tried this slight rewrite:

var ev := struct;
ev.+ type := SYSEVENT_SPEECH;
ev.+ source := rune; ;
ev.+ text := "Left";
printtextabove(rune, "Activated");
boatprocess.sendevent(ev);
Basara
Novice Poster
Posts: 47
Joined: Fri Oct 13, 2006 6:37 am

Post by Basara »

I have tried that, but no noticable difference.

Here's the code so far, so you can see how I'm passing the commands.
The actual direction commands are just "right" "5" "stop" and held in a cfg file.
But for whatever reason, it still won't accept the ev.source as "rune", only as "who".

Code: Select all

use uo;
use os;
use cfgfile;
include "include/sysevent";

var tillergfx := 0xF010;
var cfg := readconfigfile(":boat:directions");
var integers := {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120};
var destination;

program ferry(who, rune)
//printtextabove(who, "WHO");
//printtextabove(rune, "RUNE");

var layout := array(
 	"page 0",
	"resizepic 50 50 3600 200 200",
	"text 75 65 1154 0",

	"button 70 100 2103 2104 1 0 1",
	"text 90 95 500 1",
	"button 70 120 2103 2104 1 0 2",
	"text 90 115 500 2",
	"button 70 140 2103 2104 1 0 3",
	"text 90 135 500 3",
	"button 70 160 2103 2104 1 0 4",
	"text 90 155 500 4",
	"button 100 202 2121 2120 1 0 0"
);

var data := array(
	"Choose A Destination:",
	"North",
	"South",
	"East",
	"West"
);
	
var input := SendDialogGump( who, Layout, Data );
if ( (input[0]==0) )
	SendSysMessage(who, "Cancelled.");
	return;
elseif ( (input[1]==1) )
	destination := "North";
endif
var tillerman := FindTiller(rune);
var tillerpid := GetObjProperty(tillerman, "#boatpid"); 
var boatprocess := getprocess( tillerpid );
setobjproperty(tillerman, "#ferry", 1);
foreach entry in GetConfigStringKeys(cfg)
	if(entry == destination)
		var directions := getconfigstringarray(cfg[destination], "CMD");
		foreach commandline in directions
			BoatCommand(who, rune, boatprocess, commandline);
		endforeach
	endif
endforeach
endprogram

function FindTiller(rune)
foreach item in ListItemsNearLocation( rune.x, rune.y, rune.z, 3);
	if(item.objtype == tillergfx)
		return item;
	endif
endforeach
endfunction

function BoatCommand(who, rune, boatprocess, command)
var ev := struct; 
    ev.+ type; 
    ev.+ source; 
    ev.+ text; 
    ev.type := SYSEVENT_SPEECH; 
    ev.source := rune;
    ev.text := command;
    if(cint(command) in integers)
    	sleep(cint(command));
    else
    	ev.text := command;
    	boatprocess.sendevent(ev);
    endif 
    printtextabove(rune, ""+command);
endfunction
Pierce
Forum Regular
Posts: 420
Joined: Thu Feb 02, 2006 8:33 am

Post by Pierce »

That is possibly not the problem of your script. It looks more like a problem of your boat.src. Did you crosscheck that already?

What does your boat.src do with the speech event?
Perhaps it checks if the event.source is the owner of the ship or belongs to the owner account of the ship. In this case the rune as an item has no account and therefor the boat script won't accept the command.
Basara
Novice Poster
Posts: 47
Joined: Fri Oct 13, 2006 6:37 am

Post by Basara »

OMG I'm such an idiot! :)

That was exactly it, thanks :)
Post Reply