MODULE: expression-speech-style v0.3

Started by Shade, Tue 01/11/2005 19:13:52

Previous topic - Next topic

Shade

ever thought of having diferent expressions with the sierra-speech-style? till now the sierra-speech-style is not very comfortable i think so i made this tiny thing. with this you are more flexible i think. some links:

http://www.adventuregamestudio.co.uk/yabb/index.php?topic=23197.0
http://www.adventuregamestudio.co.uk/yabb/index.php?topic=23300.0

it's not much but well...here it is:

http://www.freewebs.com/sh4d3/expression-speech-style.zip

everything you need to know is in the module but i put it here too:

how to set it up?

1) create a new gui and call it "Dispgui"
2) create a button wherever you want and call it "btnPortrait"
3) create a label wherever you want and call it "lblText"
4) put the different expressions into the characters' speech views

how to use it?

first of all this script is used in the way of the "displayspeech" or the "player.say" command.
"Who" is the one who talks, "expression" is the loop number of the character speech view, "message" is the message"
if you want to use this in dialogs it gets a little bit more complicated.
1) for every dialog option you have to set up a "run-script x" command.
2) then go to the "dialog_request" section in your global-script
3) do something like this:

if (param == 1){
conversation
}
if (param == 2){...

the params are your dialog options now. you just have to keep track on which param belongs to which dialog option.
as you should have noticed you don't have to use the dialog editor for the conversations.

Thanks to Ashen for putting this into new style scripting and for improving it!

monkey0506

#1
I'd have to test it to see, but this sounds like it might work with the ScrollingDialog module.

It would, of course, require some customization over the default settings (used by the demo), but it sounds like it would work well, and you wouldn't have to keep track of which parameter was which dialog option because with the ScrollingDialog module you set up your interactions like:

if (dialog == #) {
  if (option == #) {
    }
  }

But...school's out...I have to go.

Pumaman

Good idea for a module, simple and yet effective :)

Janik

I like how your solution gives complete control over placement, etc. But I have an idea that the expression changing system could be made to work with the usual dialogs, but it would require a plugin. Basically, the plugin would edit loop 0 of the speech view. You send a command to switch to loop 2, and the plugin replaces all the sprite numbers in loop 0 to those in loop 2.

Everything else could essentially stay the same. Conceivably, the expression could be changed within one line of dialog, but giving a delay before applying the effect. Of course, the plugin would make it non portable.
Play pen and paper D&D? Then try DM Genie - software for Dungeons and Dragons!

SSH

I'm not sure that plugins can go and change sprites assigned to views anyway.
12

Shade

all right here is a little update. voicespeech is now supported! use the link in my first post to get the new version.

~}Shade{~

Janik

Quote from: SSH on Wed 02/11/2005 14:19:32
I'm not sure that plugins can go and change sprites assigned to views anyway.
I believe it is possible, using:

AGSViewFrame* GetViewFrame (int view, int loop, int frame);

which returns a pointer to the AGSViewFrame object, which contains info such as the sprite slot #, the delay, the associated sound, etc. I think modifying data in the object will change the animation - I'm not sure though.
Play pen and paper D&D? Then try DM Genie - software for Dungeons and Dragons!

Shade

i don't know if this is still from interest but i added the option to have the text displayed in typewriter style. therefor i used spook1's script from this thread http://www.adventuregamestudio.co.uk/yabb/index.php?topic=14437.0

strazer

#8
Btw, the reason I have not moved this to the Tech Archive is that I think the fact that you can't use it in the built-in dialogs directly is a severe limitation. The run-script workaround is really uncomfortable.

But it has to do until set-speech-view-loop or script functions in dialog scripts get implemented.

Monsieur OUXX

An incompatibility with AGS 3.3+ has been reported. It's only a matter of changing a name somewhere so that it doesn't conflict with newer AGS built-in names. See here: http://www.adventuregamestudio.co.uk/forums/index.php?topic=52005.msg636511158#msg636511158
 

ChronicFreshman

That was actually my topic Monsieur OUXX linked to. Thank you for that, Monsieur.

Thanks to a couple of responses on that thread I was able to fix that specific problem I was referencing by changing every "Speech" in the expression module to "MySpeech". But once I fixed that another problem popped up not far down the script. I've been able to swap things out so far by looking up updates but now I'm stuck at a new error I can't quite figure out:

The error is this:

Error (line 22): must have an instance of the struct to access a non-static member.

Script Referenced:
21   String displayedline;
22   String.Copy(displayedline,"");

If anyone knows how to get around this issue, or if there's an updated version of this module floating around somewhere, I'd appreciate the assistance!

Thank you!

Crimson Wizard

#11
Quote from: ChronicFreshman on Thu 23/04/2015 17:14:09

Error (line 22): must have an instance of the struct to access a non-static member.

Script Referenced:
21   String displayedline;
22   String.Copy(displayedline,"");

This looks like a strange mixup of the old and new strings API. I guess they mean "StrCpy" instead of "String.Copy", unless there was really a version of AGS that had static "String.Copy" function (something I do not know about).

Try replacing two lines 21 and 22 with just one:
Code: ags

String displayedline = "";


E: Anyway, where is the working download link? The one at the first post in broken.

ChronicFreshman

Crimson, Thank you for the tip. I swapped it out. No error. Unfortunately it just hopped to the next issue in the script so I won't know how it plays until I've gotten all the errors sorted out.

As far as the download. You're right it's gone, but here is a link to the original version 3 script on it's Wiki page so you can take a look at it:

http://www.adventuregamestudio.co.uk/wiki/Expression-style_speech

It doesn't look right, I know. It wouldn't save to the page properly. I've worked my way down to where it says :

length=StrLen(message);

which I've changed to:

length = String.Length(message);

But I still get an error.
Please let me know if you see any other obvious changes that need to be made in order to use the module on current versions of AGS.

I really appreciate the help with this.

monkey0506

The only static functions that the new-style String class has are: String.Format and String.IsNullOrEmpty.

All other new-style String functions should be called on the object:

Code: ags
String message = "Hello World";
int length = message.Length;
message = message.Append(", from AGS!"); // just to preemptively point out that the Append function (etc.) does not modify the original
int newLength = message.Length;


There is a page in the manual on upgrading to 2.71 that talks about the new style Strings.

Crimson Wizard

#14
Quote from: ChronicFreshman on Thu 23/04/2015 18:13:45
It doesn't look right, I know. It wouldn't save to the page properly. I've worked my way down to where it says :

length=StrLen(message);

which I've changed to:

length = String.Length(message);

But I still get an error.

Uh, oh... Did you change the previous piece of code too, like from StrCpy to String.Copy? Did you also replace "string" with "String" maybe?
This would explain it... For some reason, I did not realize you were changing the string functions yourself.

(...I am being awfully slowly-thinking recently...)

Please, first change everything back, then go to General Settings and set "Backwards Compatibility -> Enforce new style strings" to "false", and see if that works.

Regardless, the module should be upgraded to latest version of AGS, but that's not a five minute job and requires proper understanding of how new string functions are different from old ones.
E: monkey_05_06 posted a related link to manual above.

ChronicFreshman

Crimson, yes I did do that. I guess I didn't elaborate that that's what I was doing. Well cool! I just changed everything back and tried what you suggested! No errors! Works great. That was much smoother than updating every line of code. Thank you so much :)

And thank you, Monkey for the reference material, very helpful.

Take care!


Monsieur OUXX

On a indirectly related topic : Sometimes, upgrading a module that was created for older version of AGS can be a pain in the back (e.g. replacing all "StrLen(...)" with "myString.Length").
What I usually do to perform a quick upgrade is to actually recreate custom functions with the exact same syntax as the missing ones:
Code: ags

//module QuickUpgrade
import int StrLen(String s);

int StrLen(String s)
{
    return s.Length;
}


The advantage of this is that sometimes the new functions can work in a very different way from the old ones(for example, code relying on the old sound system can be a pain to upgrade). So, you can do a quick upgrade, see if it works, and then if it's worth it, convert everything to the newer syntax.
Then you have all the time you
 

Crimson Wizard

#17
Quote from: Monsieur OUXX on Mon 27/04/2015 12:04:48
What I usually do to perform a quick upgrade is to actually recreate custom functions with the exact same syntax as the missing ones:

Erm, deleted old post, because it was a very silly question.

Thinking more on this, I see, this can be a nice idea.
Maybe it's even worth to distribute such module with AGS.

Monsieur OUXX

Quote from: Crimson Wizard on Mon 27/04/2015 15:25:45
Maybe it's even worth to distribute such module with AGS.

Well I don't have it as a module, I just quickly re-write those functions whenever I need them. Sowwy...
 

monkey0506

Quote from: Monsieur OUXX on Mon 27/04/2015 12:04:48What I usually do to perform a quick upgrade is to actually recreate custom functions with the exact same syntax as the missing ones:

FALLLLLLSSSSEEE!

As SSH learned with the BackwardsCompatibility module (which was designed for this purpose), your function won't be called. All you need is the imports, e.g.:

Code: ags
import int StrLen(const string);


Actually, you had a different signature, so I'm not sure on that, but you should just import the built-ins rather than trying to emulate them, especially with String functions.[/code]

Crimson Wizard

#20
Quote from: monkey_05_06 on Tue 28/04/2015 18:08:46
Quote from: Monsieur OUXX on Mon 27/04/2015 12:04:48What I usually do to perform a quick upgrade is to actually recreate custom functions with the exact same syntax as the missing ones:

FALLLLLLSSSSEEE!

As SSH learned with the BackwardsCompatibility module (which was designed for this purpose), your function won't be called.

I made a test, it is actually called when the implementation is in the same script:
Example:
Code: ags

int StrLen(String s)
{
  return 10;
}

// called when the game starts, before the first room is loaded
function game_start() 
{
  String s = "aaa";
  int a = StrLen(s);
  Display("a = %d", a);
}

This code displays "10".

This is because script function in same script is called with different internal command.

However, if you put it into separate script, then import and call from another, then the built-in AGS function is called.
The reason is that AGS registers all functions, including deprecated ones, before loading your scripts, and they take the place of your "substitutes", since they have same names.


UPD: The possible solution could be to give them slightly different name, like StrLen2 or something. This way you will have to rename them everyone in script, but the rest of the script will stay the same.


Quote from: monkey_05_06 on Tue 28/04/2015 18:08:46
All you need is the imports, e.g.:

Code: ags
import int StrLen(const string);

If you go that way, it is easier to just turn Backwards compatibility mode on ("Enforce new style strings" to False in General Settings).


UPD2: Since my attention was brought to this, I think this is an incorrect behavior of AGS. It links functions that are not declared; this would cause problems if someone scripts function, using name of deprecated function, even if he did not know it is.
I think engine should not register old functions if they are not used in game.

Monsieur OUXX

I picked that example randomly, maybe it doesn't work for StrLen. As I said I do it only for functions that cause trouble. But it's good to know that the old functions are still there, just slightly hidden (well, unless it's a faulty behaviour, like CW pointed out).
 

monkey0506

Quote from: Crimson Wizard on Tue 28/04/2015 19:48:55UPD2: Since my attention was brought to this, I think this is an incorrect behavior of AGS. It links functions that are not declared; this would cause problems if someone scripts function, using name of deprecated function, even if he did not know it is.
I think engine should not register old functions if they are not used in game.

Just as a point of reference, this is what CJ said about it:

Quote from: Pumaman on Mon 26/02/2007 19:50:46The AGS engine still exports all the old-style functions, the only thing that happens when "Enforce object-based scripting" is ticked is that they are removed from the script header so that your script won't compile.

So in fact, all your BackwardsCompatible module needs to do is provide a script header with the appropriate import declarations in it ;)

He didn't seem to think it was problematic for the built-ins to still exist (be registered) even if not using them. I do agree that it could be useful to omit them...but I will also then have to admit that I have used some of the functions (old-style String functions, in particular) in modules which are designed to still use the old functions even if they are "disabled". Honestly, I don't recall if I did that in any production code, but there are cases where using StrCopy is faster than String.Append or String.Format, and I've toyed around with that a fair amount.

Monsieur OUXX

Quote from: monkey_05_06 on Wed 29/04/2015 19:25:22

Quote from: Pumaman on Mon 26/02/2007 19:50:46
So in fact, all your BackwardsCompatible module needs to do is provide a script header with the appropriate import declarations in it ;)

He didn't seem to think it was problematic for the built-ins to still exist (be registered) even if not using them.
Good to know.
I say leave them for now. There are still billions of old-yet-still useful modules out there.
 

monkey0506

Oh, also I'll note that it would be easy for the BackwardsCompatible module (if anyone still has it or wants to recreate it) to be updated with toggle-able features, based on macros. For example, if you wanted to import the old-style Character functions without fully adding the old-style code support, there could be a macro like BC_CHARACTER that, if defined, would import those functions, or otherwise would omit them.

Code: ags
// BackwardsCompatible.ash
#ifdef STRICT
#ifdef BC_CHARACTER
import void AddInventory(int item);
import void LoseInventory(int item);
import void SetActiveInventory(int item);
import void NewRoom(int roomNumber);
import void NewRoomEx(int roomNumber, int x, int y);
import void NewRoomNPC(CHARID, int roomNumber, int x, int y);
import int  GetCharacterProperty(CHARID, const string property);
import void GetCharacterPropertyText(CHARID, const string property, string buffer);
import void RunCharacterInteraction (CHARID, CursorMode);
import void DisplaySpeech (CHARID, const string message, ...);
import int  DisplaySpeechBackground(CHARID, const string message);
import void DisplaySpeechAt (int x, int y, int width, CHARID, const string message);
import void DisplayThought (CHARID, const string message, ...);
import void FollowCharacter(CHARID sheep, CHARID shepherd);
import void FollowCharacterEx(CHARID sheep, CHARID shepherd, int dist, int eagerness);
import void SetPlayerCharacter(CHARID);
import void AddInventoryToCharacter(CHARID, int item);
import void LoseInventoryFromCharacter(CHARID, int item);
import void AnimateCharacter (CHARID, int loop, int delay, int repeat);
import void AnimateCharacterEx (CHARID, int loop, int delay, int repeat, int direction, int blocking);
import void MoveCharacter(CHARID, int x, int y);
import void MoveCharacterDirect(CHARID, int x, int y);
import void MoveCharacterPath(CHARID, int x, int y);
import void MoveCharacterStraight(CHARID, int x,int y);
import void MoveCharacterToHotspot(CHARID, int hotspot);
import void MoveCharacterToObject(CHARID, int object);
import void MoveCharacterBlocking(CHARID, int x, int y, int direct);
import void MoveToWalkableArea(CHARID);
import void FaceCharacter(CHARID, CHARID toFace);
import void FaceLocation(CHARID, int x, int y);
import void SetCharacterView(CHARID, int view);
import void SetCharacterViewEx(CHARID, int view, int loop, int align);
import void SetCharacterViewOffset(CHARID, int view, int x_offset, int y_offset);
import void SetCharacterFrame(CHARID, int view, int loop, int frame);
import void ReleaseCharacterView(CHARID);
import void ChangeCharacterView(CHARID, int view);
import void SetCharacterSpeechView(CHARID, int view);
import void SetCharacterBlinkView(CHARID, int view, int interval);
import void SetCharacterIdle(CHARID, int idleView, int delay);
import void StopMoving(CHARID);
import int  AreCharObjColliding(CHARID, int object);
import int  AreCharactersColliding(CHARID, CHARID);
import void SetCharacterSpeed(CHARID, int speed);
import void SetCharacterSpeedEx(CHARID, int x_speed, int y_speed);
import void SetTalkingColor(CHARID, int colour);
import void SetCharacterTransparency(CHARID, int transparency);
import void SetCharacterClickable(CHARID, int clickable);
import void SetCharacterBaseline(CHARID, int baseline);
import void SetCharacterIgnoreLight (CHARID, int ignoreLight);
import void SetCharacterIgnoreWalkbehinds (CHARID, int ignoreWBs);
import void SetCharacterProperty (CHARID, int property, int newValue);
import int  GetPlayerCharacter();
#endif // BC_CHARACTER
#endif // STRICT


This could serve as a more powerful option than the catch-all "enforce object-based scripting".

Crimson Wizard

#25
Quote from: monkey_05_06 on Thu 30/04/2015 16:47:42
This could serve as a more powerful option than the catch-all "enforce object-based scripting".

And what is the actual benefit? You still won't be able to have function names identical to old function names without calling latter instead.
In fact, that can cause terrible confusion, if someone would make a module function with seemingly "unused" name and then catch all kinds of strange bugs in his game, when the hidden built-ins will be called.

The true solution would be to implement game option, that would enable/disable particular parts of the built-in header, and also be passed to engine to tell it not to link particular functions.

SMF spam blocked by CleanTalk