simple hotspot script: suggestions for improvement?

Started by EnterTheStory (aka tolworthy), Mon 03/12/2007 12:01:41

Previous topic - Next topic

EnterTheStory (aka tolworthy)

I don't know if this belongs in the beginner's forum (I'm a beginner) or the modules forum (it's from a module, but it's not of finished standard, and I can't see a "new thread" button) or general chat. Hopefully our friendly neighborhood mods will move it if necessary.

This is my first attempt at a module. Any ideas for improvement?

I like screens with plenty of hotspots. I like to look round and see the mouse responding to everything I see, even though really I won't want to click on everything, and if I do then I don't expect much more than ego saying "it's just an ordinary rock" or whatever. This code is designed to streamline common hotspots that only need a verbal string. Very common hotspots (like tree or house) have their strings in this code. Other hotspots have "say" or "use" responses added very quickly using custom "lookSay" and "useSay" properties. More complex hotspots of course have custom code.

// start script
Hotspot* myHotspot;
function generic_hotspots_click() {         // called from the global script mouse click
   myHotspot = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
   if(mouse.Mode ==eModeLookat)
   {      character[EGO].Say(myHotspot.GetTextProperty("lookSay") ); # lookSay is a custom property
         common_hotspots_lookSay();
   }
   else if(mouse.Mode ==eModeInteract)
   {      character[EGO].Say(myHotspot.GetTextProperty("useSay") );
         common_hotspots_useSay();
   }
}
function common_hotspots_lookSay() {         // long list
   if (maySay("house","this looks like a house")) return; 
   if (maySay("tree","this looks like a tree")) return;      // etc., etc.
}
function common_hotspots_useSay() {      // like 'lookSay' but many objects never get used
   if (maySay("house","I don't think I'll disturb the people who live there.")) return;
   if (maySay("tree","I don't feel like climbing trees right now.")) return;
   
}
function maySay(String name, String response) {
   bool done =false;      // to stop looking when we find a match
   if(myHotspot.Name == name) { character[EGO].Say(response); done =true;}
   return done;
}
// end script


Question: is there an easy way to give alternate options in the same string? E.g. so I can quickly type ' character[EGO].Say("option1/option2/option3") ' ?

SSH

12

Ashen

Well, your functions are in the wrong order for AGS (you're calling them before they're defined) - that doesn't really matter here, but it'll cause proplems in the game. character[EGO] could be shortened to cEgo, or player if they're the player character, but otherwise it doesn't look too bad.

One thing: In your description it sounds like you want to say either the Custom Property text (lookSay, useSay, etc) or the common_hotspots_(whatever) text, but the current script would display both. What about something like:

Code: ags

Hotspot* myHotspot;

function common_hotspots_lookSay(String name) {         // long list
   if (name =="house") player.Say("this looks like a house"); 
   if (name =="tree") player.Say("this looks like a tree");      // etc., etc.
}

function common_hotspots_useSay(String name) {      // like 'lookSay' but many objects never get used
   if (name =="house") player.Say("I don't think I'll disturb the people who live there.");
   if (name =="tree") player.Say("I don't feel like climbing trees right now.");
}


function generic_hotspots_click() {         // called from the global script mouse click
  myHotspot = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
  String Temp;
  if(mouse.Mode ==eModeLookat) {      
    Temp = myHotspot.GetTextProperty("lookSay");
    if (Temp != "") player.Say(Temp); // If there IS a custom lookSay response, use it.
    else common_hotspots_lookSay(myHotspot.Name); // Otherwise, get the generic response.
  }
  else if(mouse.Mode ==eModeInteract) {  
    Temp = myHotspot.GetTextProperty("useSay");
    if (Temp != "") player.Say(Temp);
    else common_hotspots_useSay(myHotspot.Name);
  }
}


I removed the maySay function, because I wasn't quite sure what it did, and merged the name-checking bit into the common_hotspots_(whatever) functions. Hopefully, this should still work as you want, if not just put maySay back.

And SSH beat me to linking his MultiResponse module, so I'll just agree with him...
I know what you're thinking ... Don't think that.

EnterTheStory (aka tolworthy)

Thanks for the suggestions. Yes, the "either or" makes a lot of sense.

Quote from: Ashen on Mon 03/12/2007 12:57:27
Well, your functions are in the wrong order for AGS (you're calling them before they're defined)

Yes, I should have mentioned that. I compiled and tested it the right way, but just reordered it for the post, because to me it was easier to follow if I put the overview function first.

Quote from: Ashen on Mon 03/12/2007 12:57:27
I removed the maySay function, because I wasn't quite sure what it did

That was just to minimise typing. I expect to have a couple of hundred lines in the function, and wanted the shortest possible lines. I didn't know about "cEgo" - that's very useful. Thanks.

EnterTheStory (aka tolworthy)

Quote from: SSH on Mon 03/12/2007 12:38:59
Use the MultiResponse module
Brilliant! That looks like exactly what I want! (Haven't checked it yet, but will soon). Many thanks. I wrote something to do the same in Sludge, but your AGS version seems far more elegant, and of course works in this engine.

Ashen

I spotted a few typos in my code, which I've corrected now. (I lost my original version and when I retyped it, I forgot to pass myHotspot.Name into the common_hotspots functions.)

Quote
That was just to minimise typing. I expect to have a couple of hundred lines in the function,

Ah, right. I make excessive use of copy/paste and the autocomplete, so that never occurs to me. However, if you want to miminise your typing a bit more, how about declaring the common_hotspots_(whatever)s as Strings instead of functions, and having them return the text to be said, e.g.:
Code: ags

String common_hotspots_lookSay(String name) {         // 'String', not 'function'
   if (name =="house") return "this looks like a house"; 
   if (name =="tree") return "this looks like a tree";      // etc., etc.
}

function generic_hotspots_click() {         // called from the global script mouse click
  myHotspot = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
  String Temp;
  if(mouse.Mode ==eModeLookat) {      
    Temp = myHotspot.GetTextProperty("lookSay");
    if (Temp != "") player.Say(Temp); // If there IS a custom lookSay response, use it.
    else player.Say(common_hotspots_lookSay(myHotspot.Name)); // Otherwise, get the generic response.
  }
  // ... Etc
}



That'd trim a little more off your work.
I know what you're thinking ... Don't think that.

EnterTheStory (aka tolworthy)


Khris

What about:

Code: ags
String house[6], tree[6], ... ;

function SetUpStrings() { // called in the module's game_start
  house[eModeLookat]="this looks like a house";
  house[eModeInteract]="I should use the door.";
  ...
  tree[eModeLookat]="this looks like a tree";
  ...
}

String common_hotspots_response(String name, int mousemode) {
  if (name =="house") return house[mousemode]; 
  if (name =="tree") return tree[mousemode];
  ...
}

function generic_hotspots_click() {         // called from the global script mouse click
  myHotspot = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
  String Temp;
  Temp = myHotspot.GetTextProperty(String.Format("%d", mouse.Mode));
  if (Temp == "p") myHotspot.RunInteraction(mouse.Mode);
  else if (Temp != "") player.Say(Temp);
  else player.Say(common_hotspots_response(myHotspot.Name, mouse.Mode)); 
}


In the scheme editor, the properties' names have to be set up as "1", "2", etc., corresponding to the int value of eModeLookat, eModeInteract, etc.
If the property's text is set to "p", the standard interaction is run, otherwise either the special or the generic response is used.

RickJ

There are some guidelines and templates that should help you cover all the bases when making a module. 

The Guidelines are stickied in the Technical FAQ forum and the templates are linked in the DemoQuest thread in the Games in Production forum.


subspark

Groovy Idea. I always liked a moderate amount of hotspots in rooms too. It gives the player better feedback about their environment while establishing a better connection to your world.
Important gameplay mechanics.  :)
That MultiResponse module looks pretty neat!

Is that AGS 3.0 code Ashen? If it is you're a wild fast learner! Did you get my PM, btw mate?

Cheers,
Paul.

Khris

subspark: As was mentioned pretty often around here already, there were made virtually NO changes to the scripting language.
The code should work with any version since and including 2.7.0.

subspark

Oh right. Forgive me.
I'll say it again I'm an artist and not much of a programmer so any code from 2.72 that doesn't work in 3.0 seems to me like a big change in the language where it really is not.
It's an artist thing... You can't hate me for it.  ;)

Paul.

SMF spam blocked by CleanTalk