Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - Scorpiorus

#1
This topic has been moved to Beginners Technical Questions.

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




By the way, I think it could be a good idea to extend the example(s) of the dialog_request usage in the AGS manual, where it could be:

Code: ags
function dialog_request (int parameter)  { 
    if (parameter == 1) {...}
    else if (parameter == 2) {...}
}


instead of just

Code: ags
function dialog_request (int xvalue) {
    // your code here
  }


as people seem to make a common mistake of putting parameter value into the function header.

An older topic discussing the issue: http://www.adventuregamestudio.co.uk/yabb/index.php?topic=13915
#2
Ã,  Ã, At present, working on a game project being constantly improved a developer may find that it becomes rather difficult to control the scripts. The idea of having modules is to surely help with scripting and later maintaing the source code but it also requires quite a few efforts to be put into its implementation.
   So, I thought, what if the AGS Editor would allow us to define our own sections, so that we could put them around the script and then easily navigate through the sections menu to be provided.
With a section has been chosen, only a relevant portion of code becomes accessible (just like with interactions) but, the thing is, what if we could assign a section for not only one function. Thus, it could be possible to isolate parts of the code which are (and not) worked on.
   It could also be useful for templates. A developer of the template provides menus with a list of sections that an end-user can look in. It could be some sort of a complicated battle system with several event functions that are provided to define the behaviour when they are invoked. These functions could be put into one section to be shown as soon as an appropriate section is chosen.
   Each script file could have its own number of sections. Currently, it's one for the global script, one for the script header, and others, those for each room script.


Example:

// room script file


...
...
if (...) some_event_function(10, 2);
...
...

#usersectionstart On event section

function some_event_function(int x, int y) {

// TODO

}

function some_other_event_function(int x, int y) {

// TODO

}

#usersectionend On event section
...
...
...

#usersectionstart Info

// This template provides...
// ....
// Some other info on the template.
// ....
// ....


#usersectionend Info




Room 1 sections:
1. Info
2. On event section

The same for the global and the script header files.

I appreciate it may not be of high priority, just a suggestion, so what do you guys think? :)
#3
Let me, If I may, suggest the following script functions:

These to get the number of GUIs, characters and objects:

int GetNumGUIs()
int GetNumCharacters()
int GetNumObjects() // this one has been already suggested I believe


The next listbox function would be very handy to have for changing the text of already added (existing) item. Currently, in order to change a slot we have to clear listbox and add all the items once again:

void ListBoxChangeText(int gui, int object, int item, string text)


Writing to file a single raw char would allow, for example, exporting of palettes (in a raw rgb format) at the run-time:

void FileWriteRawChar(int handle, char value)


We could script an automatic blocking walk-off/walk-on for the player character. And knowing room edges coordinate can be used to determine how far the player needs to be moved when he is walking on from the outside of the screen:

game.edge_top
game.edge_right
game.edge_bottom
game.edge_left

Cheers,
Alex


EDIT: Thanks CJ :)
#4
I'm fiddling with Allegro and AGS trying to draw (working at 16bit color) a translucient image directly onto the virtual screen by means of Allegro functions, so I have:

...
if (event == AGSE_POSTSCREENDRAW) {

   //getting virtual screen:
   BITMAP* virt = engine->GetVirtualScreen();

   //set blender functions for (16bit)
   set_blender_mode(0,0,0, 100); //a = 100

   //setting drawing mode to use the blender functions
   drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);

   //draw a rectangle (with a=100)
   rectfill(virt, x1,y1,x2,y2, color);
}

...but filled rectangle turns out solid like it would ignore DRAW_MODE_TRANS but uses DRAW_MODE_SOLID instead. No other modes like DRAW_MODE_XOR orÃ,  DRAW_MODE_xxx_PATTERN work as well.

So, I create a temporary memory bitmap (exactly the same as the virtual screen), fill it with the virtual screen content, draw the rectangleÃ,  onto it and then blit it back to the virtual screen:

...
if (event == AGSE_POSTSCREENDRAW) {

   //getting virtual screen:
   BITMAP* virt = engine->GetVirtualScreen();

   //creating a temporary canvas to draw onto:
   BITMAP* temp = create_bitmap_ex(16, 640, 480);

   //fill it with what on the virtual screen:
   blit(virt, temp, 0,0,0,0,640,480);

   //set blender functions for (16bit)
   set_blender_mode(0,0,0, 100); //alpha = 100

   //setting drawing mode to use the blender functions:
   drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);

   //draw a rectangle onto temp:
   rectfill(temp, x1,y1,x2,y2, color);

   //blit back to the virtual screen:
   blit(temp, vert, 0,0,0,0,640,480);

   //destroy temp as we finished with it:
   destroy_bitmap(temp);
}

And that works just fine but affects the perfomance. Although Allegro initialized with SYSTEM_NONE all the drawing routines work well (I just need to specify some things like color depth here and there).


AGS plugin API states that IAGSEngine::GetVirtualScreen() function returns a pointer to the Allegro memory bitmap (checking its with Allegro says the same: linear/memory/640x480x16bit).

So, is virtual screen a true Allegro bitmap?
If so, how does plugin api BlitSpriteTranslucent() function work?
I'd use it, btw, but I'm actually trying to render polygons. Allegro manual states that in FLAT rendering mode they are drawn using the same mode from drawing_mode() - i.e. DRAW_MODE_TRANS in that case. And drawing into a temporary bitmap, then blitting to virtual screen works with them as well.

~Cheers
#5
Having seen a couple of topics regarding background speech reminded me about an old script I had. I made some modifications so it could play talking animations - here it is:

Note: Only one speech queue can be run at a time, i.e. you can have only one conversation being run at background.

LAST UPDATE (23.05.04):
//
// Revision history:
//===================
// v1.02Ã,  [23.05.04]:
// - Added qSkipCurrentMessage() function to skip the message being currently displayed;
// - Play sound was added: qDisplaySpeech(EGO, "@3 hey"); will play "sound3.xxx" file;
//
//==============================================
// v1.01+ [06.04.04]:
// - Fixed import function Delay (should be import string Delay)
//
//==============================================
// v1.01Ã,  [25.02.04]:
// - Delay(int time) directive was added;
// - Fixed qIsTalking() returning 0 when the *last* phrase is being said;
// - Changed the repeatedly execute part of the script;
//



Script header:
import function qDisplaySpeech(int CharID, string message);
import function qStopSpeech();
import function qIsTalking();
import stringÃ,  Ã, Delay(int time);
import function qSkipCurrentMessage();



Main global script file (at the very top of it):
///////////////////////////////////////
// Background queued talking v1.02
///////////////////////////////////////


#define BUFFER_SIZE 300
#define AGS_STRING_LENGTH 200

struct MESSAGESTRING {
   intÃ,  CharID;
   intÃ,  anim_disabled;
   char byte[AGS_STRING_LENGTH];
};

MESSAGESTRING Buffer[BUFFER_SIZE];

function mod(int a, int b) { return a - (b*(a/b)); }

function BufferSetString(int sID, string text) {
   if (sID<0 || sID>=BUFFER_SIZE) { Display("error: SetString buffer error!"); QuitGame(0); }
   StrCopy(Buffer[sID].byte, text);
   return StrLen(text);
}

function BufferGetString(int sID, string buf) {
   if (sID<0 || sID>=BUFFER_SIZE) { Display("error: GetString buffer error!"); QuitGame(0); }
   StrCopy(buf, Buffer[sID].byte);
   return StrLen(buf);
}


int cur_str=0;
int cur_say=0;

int cur_overlay = -1;
int stop_talkÃ,  Ã, =Ã,  0;
int prev_charÃ,  Ã, = -1;
int cur_channel = -1;

function qDisplaySpeech(int CharID, string message) {
Ã, 
   int i = mod(cur_str, BUFFER_SIZE);

   BufferSetString(i, message);
   Buffer[ i ].CharID = CharID;
   cur_str++;
   //if (cur_str >= BUFFER_SIZE) cur_str = 0;
}

function qIsTalking() {
   return IsOverlayValid(cur_overlay);
}

function GetSoundNumber(string text) { //return 0 if unsuccessful

   int pos = StrContains(text, "@");
   if (pos<0) return 0;
   int i = pos + 1;
   string str_rez; StrCopy(str_rez, "");
   int Char = StrGetCharAt(text, i);
   while (Char>='0' && Char<='9' && i<StrLen(text)) {
      StrFormat(str_rez, "%s%c", str_rez, Char);
      i++;
      Char = StrGetCharAt(text, i);
   }

   while (i<=StrLen(text)) {
      StrSetCharAt(text, pos, StrGetCharAt(text, i));
      i++;
      pos++;
   }

   return StringToInt(str_rez);
}

function GetFreeChannel() { // returns a channel number
   ifÃ,  Ã,  Ã,  (IsChannelPlaying(5)==0) return 5;
   else if (IsChannelPlaying(4)==0) return 4;
   else return 3;
}

function qStopSpeechChannel() {
   if (cur_channel>2)
      if (IsChannelPlaying(cur_channel)) {
         StopChannel(cur_channel);
         cur_channel = -1;
      }
}

function qStopSpeech() {
   if (qIsTalking()) {
      qStopSpeechChannel();
      RemoveOverlay(cur_overlay);
      int i = mod(cur_say, BUFFER_SIZE);
      int CharID = Buffer[ i ].CharID;
      ReleaseCharacterView(CharID);
      if (prev_char > -1) { ReleaseCharacterView(prev_char); prev_char = -1; }
      stop_talk = 0;
      cur_say = cur_str;
   }
}

function DisplaySpeechQ_RE() {

   if (qIsTalking()==0) { // wait for character to finish talking
      if (cur_say < cur_str) { // if something left to be said

         int i = mod(cur_say, BUFFER_SIZE);
         int CharID = Buffer[ i ].CharID;

         string buf;
         BufferGetString(i, buf);

         qStopSpeechChannel();
         int cur_sound = GetSoundNumber(buf);
         cur_channelÃ,  Ã, = GetFreeChannel();
         if (cur_sound>0) PlaySoundEx(cur_sound, cur_channel);

         cur_overlay = DisplaySpeechBackground(CharID, buf);
         stop_talk = 1;

         if (prev_char > -1) ReleaseCharacterView(prev_char);
         prev_char = CharID;

         if (character[CharID].animating==0 && Buffer[ i ].anim_disabled==0) {
            int view = character[CharID].talkview+1;
            if (view < 1) { Display("error: Talk view isn't assigned!"); QuitGame(0); }
            int loop = character[CharID].loop;
            int delay = character[CharID].animspeed;
            SetCharacterView(CharID, view);
            AnimateCharacterEx (CharID, loop, delay, 1, 0, 0);
         }

         Buffer[ i ].anim_disabled = 0;
         cur_say++;
         //if (cur_say >= BUFFER_SIZE) cur_say = 0;
      } else if (stop_talk) { //finish talk animation
         if (prev_char > -1) { ReleaseCharacterView(prev_char); prev_char = -1; }
         qStopSpeechChannel();
         stop_talk = 0;
      }
   } // end of if (qIsTalking()==0)
}

string str_delay;
string Delay(int time) {

   int n=time;
   if (n<1) n=1; else if (n>=AGS_STRING_LENGTH) n=AGS_STRING_LENGTH-1;

   string format;
   StrFormat(format, "%%%dc", n);
   StrFormat(str_delay, format, ' ');
   Buffer[mod(cur_str, BUFFER_SIZE)].anim_disabled = 1;
   return str_delay;
}

function qSkipCurrentMessage() {
   if (qIsTalking()) RemoveOverlay(cur_overlay);
}



Main global script file (Repeatedly execute):

function repeatedly_execute() {
Ã, // put anything you want to happen every game cycle here

Ã, 
   DisplaySpeechQ_RE(); // place it before any other script code in rep. exec.
Ã, 
}



Main global script file (on_event function):
function on_event(int event, int data) {

   if (event == LEAVE_ROOM) qStopSpeech();

}




Functions:

----------------------------------------------------------
qDisplaySpeech(int CharID, string message)

Displays a CharID's character speech message at the background and plays an appropriate talk animation. You can queue up multiple messages by typing in several functions one after another.

Example:

qDisplaySpeech(EGO, "hi there MAN!");
qDisplaySpeech(MAN, "hey Roger");
qDisplaySpeech(EGO, "blah");
qDisplaySpeech(MAN, "blah blah");

Note: You can have a pause in the conversation by specifying a special Delay(int time) directive. The time parameter tells how long to wait before proceeding further. The valid range is 1 through 199. Where time=1 is the shortest delay.

qDisplaySpeech(EGO, "hi there MAN!");
qDisplaySpeech(MAN, "hey Roger");
qDisplaySpeech(EGO, Delay(50));
qDisplaySpeech(MAN, "blah blah");

Note: You can also have a sound to be played. Put the character '@' followed by a sound number, for example:

qDisplaySpeech(EGO, "@3 what is that?");

would display "what is that?" text message and play sound3.xxx file. Note, however, it plays a normal sound, not a voice speech from the speech.vox file!


----------------------------------------------------------
qStopSpeech()

Just stops background conversation.


----------------------------------------------------------
qIsTalking()

Returns 1 if conversation is going on. Otherwise returns 0.


----------------------------------------------------------
qSkipCurrentMessage()

Calling this function will skip currently displayed message and force the next one to proceed with.
This is useful if you want, for example, to let the player skip messages by pressing a certain key:

on_key_press:

if ((keycode!=0) && (keycode==game.skip_speech_specific_key)) qSkipCurrentMessage();

Skips the message if the game.skip_speech_specific_key variable is set and the player pressed that key.


~Cheers
#6
Normally, it's impossible to assign to strings:

string str;
str = "hello world";

But making "initialization" would break that rule:

string str = "hello world";
str = "re-reference";


Compiler doesn't say anything!

At first I thought it's really how you can initialize a string (string s ="...";) but then I realized (trying to initialize the string outside the function) it's nothing like that but a waste of memory.

Chris?


~Cheers
#7
Hello,
Is there a way to change the original font (Courier) in the script editor for something else? I'd prefer to use Courier New font.

I had run AGS editor under Windows98 where there is a line in the [FontSubstitutes] section of win.ini file:

Courier,0=Courier New,204

that forces Windows to use Courier New instead of Courier.

But now I've switched to Win2k and I can't figure it out how to substitute fonts. Adding the [FontSubstitutes] section doesn't work for me.

thanks,
cheers
#8
The original thread by Quintaros is here.
The next demo explains the problem: test 320x200@hi-color (AGS 2.56.625)

Replicating:
- open sierra inventory screen
- look at the pink poster (fade in/out transition is played)
- close inventory window

Now the mouse cursor has disappeared.

It's only with the fade in/out or black box out transitions.

-Cheers
#9
General Discussion / Hello AGSers!
Wed 03/09/2003 15:15:10
Just want to say hello, fellows. Im back after a long-drawn holidays. :)

I was about to post the thread when I saw another two... Sorry for one more. :P

-Cheers
#10
I have noticed that if a game has several GUIs with differently-sized inventory windows AGS doesn't recalculate the positions of inv. items each time the new inventory GUI is displayed. It always uses the values of the inv window which was displayed the first. So game.items_per_line and game.num_inv_displayed are equal for all of the inventory windows.

-Cheers
#11
I tried to use '++', '--' shortcuts with character[].inv[] variable and seems like there is a bug appeared:

if I pass inventory index as a value (returned value) then all ok:
character[EGO].inv[ 4 ]++;
or
character[EGO].inv[ GetValue() ]++;

...but if it is a variable then the messy occurs:

character[EGO].inv[index]++;

The item index is increased and the next item index+1 is set to 0.

Decreasing '--' makes the similar thing:

character[EGO].inv[index]--;

but the next item can be decreased down to -1.



'+=1' and '-=1' works fine btw.

Also I declared a struct:
struct Cchar {
int inv[10];
};


Cchar Char[10];

and it works without problems.

Chris?

P.S. Here is a testgame (inv_bug.zip)
It shows inventory array for EGO, then processes character[EGO].inv[4]--; Then show the results. There is also some other tests in. I used 2.55 but the bug appears in 2.53 too.

-Cheers
#12
Sorry for bothering you CJ, but when I was looking for such a function like GetGameOption() I could'n find one. What I really need is to know whether the anti-glide mode is turned on, then execute depending on the result. Is there a chance you'll implement one? :P

-Cheers
#13
I would like to suggest a number of AGS script functions: :)

GetFrameSpd(int view, int loop, int frame)
returns the speed value specified for this frame in the editor.

GetNumFrames(int view, int loop)
returns the number of frames for this loop.

GetNumLoops(int view)
returns the number of loops for this view.

IsRunNextLoopAfterThisChecked(int view, int loop)
returns the state of this option in the editor.

The reason I am asking it is I make a couple of functions which need to know that info. The first is MoveCharacterGlobal(CharId, x, y) (globalmove.txt) which moves the character at the any room. It's complete but when anti-glide mode is turned on I need to recalculate the speed of the character depending on that frame_spd value.
The second is AnimateCharacterGlobal(..) (globalanim.txt) doing the room-independent animation. I still need here GetFrameSpd() as well as GetNumFrames(), GetNumLoops() and IsRunNextLoopAfterThisChecked() functions.

btw I think it would be useful in general to get such info that was set in the editor at design time.

what do you think?

-Cheers
#14
When I was using the built-in FPS counter it just occured to me that game designer may want to provide his game with a special option to show frames per second (FPS) speed. Using the internal one is possible but there are two events when you can't:

1. Using built-in FPS counter (Debug(4,1);) is possible only if debug mode is turned on. But it should be disabled for finally released game.

2. You want to use another font/color for your game's fps textstring.

NOTE: You can't use GetGameSpeed() as it only returns currently set game speed not actual one.

So here is it:

GetFPS();
Returns current FPS speed.

Next the source script & installation instructions:

Place the next lines into the main global script:
// main global script file

int var_fps=0;
int var_fpslast=0;
int var_prevtime=0;

function GetFPS() {
  return var_fpslast;
}

function FPS_Repeatedly() {
  var_fps++;
  int curtime = GetRawTime();
  if (curtime-var_prevtime>=1) {
     var_fpslast = var_fps;
     var_prevtime = curtime;
     var_fps=0;
  }
}



Place the next line into repeatedly_execute() function:
// main global script file
function repeatedly_execute() {

   FPS_Repeatedly();


}


And finally into the script header part:
import function GetFPS();





Now you may use it to display FPS speed using TextOverlays or something else:

repeatedly execute the next code:
...
string FPS_string;
StrFormat(FPS_string, "Game speed (FPS): %d", GetFPS());
//SetTextOverlay (int overlay_id, int x, int y, int width, int font, int color, string text)
SetTextOverlay (id, 5, 170, 150, 0, 15, FPS_string);
//note: you have to create TextOverlay first: id = CreateTextOverlay(...);
...

or just use GUI labels.

That's all. Have fun ;)

EDIT:Since the GetFPS function calculates the number of calls (for each second) of repeatedly_execute() function it will not update the FPS value if the script is blocked. Just for reference.

-Cheers

Edit by strazer:

To make it update during blocking sequences, you can use repeatedly_execute_always now.
#15
AGS Snow/Rain plugin 2.02 (original version):

http://americangirlscouts.org/agsresources/AGS%20resources/plugins/ags_snowrain202.zip (supports AGS 3.4.1 - Beta 6 and above; also supports AGS 2.71 and AGS 2.72)

Many thanks to http://americangirlscouts.org/agsresources/ for hosting!



AGS Snow/Rain plugin 3.0.0 ALPHAs (work in progress):

Snow/Rain 3.0.0-ALPHA-2: unavailable at the moment, use v2.02 for now (ONLY supports AGS 3.4.0 - Patch 4, running in Direct3D 9 graphics mode!)

Size: ~2.1 MiB




ORIGINAL VERSION:

Snow/Rain plugin (version 2.02) released.

Update: The version 2.02 has been released. It should solve the problem with the plugin not working with AGS v2.71. This also means it requires AGS v2.71 or above in order to run properly.

I totally rebuilt it so all function names have been changed (sorry). What's new?
- Added rain;
- Improved snow/rain control;
- Added ability to animate snowflakes/raindrops;
- Added ability to set snow/rain transparency (HiColor only);

Note: Since version 2.02 the plugin does NOT require the alleg40.dll library anymore, so you can safely remove it from your game COMPILED folder in case you have upgraded to the latest version.

Some other notes:
You can set the wind speed for the rain but keep in mind that it doesn't rotate raindrop sprites (currently that's not supported), and you then have to change them manually with the srSetRainView() function.
SMF spam blocked by CleanTalk