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 - js

#1
Hello,

In the callback  on_mouse_click(MouseButton button)

I try to detect which button has been pressed:

Code: ags
switch(button) {
  case eMouseLeft:
    Display("left button");
    break;
  default:
    Display("unknown button: %d", button);
    break;

The problem is when i press left button, it's not seen as a eMouseLeft code.

The enum is described like this in the documentation:

Code: ags
enum MouseButton {
  eMouseLeft,
  eMouseRight,
  eMouseMiddle,
  eMouseLeftInv,
  eMouseMiddleInv,
  eMouseRightInv,
  eMouseWheelNorth,
  eMouseWheelSouth
};

So eMouseLeft must be 0 or 1 i think (depending the start index).

When i press the buttons of my mouse, it triggers the default branch in my switch/case.

I get those values from my display box:
left : 5
right : 6
middle : 7
wheel up : 8
wheel down : 9 (note the value greater than the number of values in the enum)

Well... i don't understand what happens.

Thank you.
#2
Hello,

In debug build, i'd like to gather objects in all the room to check some relations between them, in their custom properties.

As objects are linked to rooms, i have made a shortcut key which start the check in the AGS game loop. The check changes room, gather objects and repeat until last room is reached.

At game startup, i fill the array (liste_room[]) with all the rooms index (when there are no more rooms, i put -1 as a value to indicate it's over).

Then, the keyboard shortcut initializes ask_for_objects_testing boolean to true.

And in the function repeatedly_execute() , i've put

Code: ags
  if (ask_for_objects_testing == true) {
    int initial_room = player.Room;
    for (int i=0; liste_room[i]>=0; i++) {
      log(String.Format("parsing room: %d", liste_room[i]));
      player.ChangeRoom(liste_room[i]);
    }
    // go back to initial room
    player.ChangeRoom(initial_room);
  }

But it hangs at the second call of player.ChangeRoom

I get this error:

NewRoom : Cannot run this command since there was a NewRoom command already queued to run in "GlobalScript.asc

So i think it's related a re-entrance issue in the internal loop of AGS, but i don't know how to handle this.

Thank you.
#3
Hello,

Not really a question, but a summary of an interesting discussion in Discord chan.
I’m just quoting what was said on discord-chan, with a bit of editing for readability (i’ve left curses and swears).

My question was:
« How to avoid multiples functions to be created in GlobalScript, cluttering it ? Especially for Characters signal handling ».

Laura Hunt had an excellent idea:

You could create a generic function cGenericCharacterInteract().
Then with a single switch, trigger the function corresponding to the character you just clicked on:

Code: ags

function cGenericCharacter_Interact()
{
   Character*char = Character.GetAtScreenXY(mouse.x, mouse.y);
   switch (char) {
     case cPeter: PeterTalk(); break;
     case cPaul: PaulTalk(); break;
     case cMary: MaryTalk(); break;
     // etc etc
   }
}


and of course, PeterTalk() , PaulTalk() , … would be placed in another castle script file.

That’s a great idea ! I adopted it immediately, but …

(play plot_twist.xm)

Enters crimson wizard:

The problem with the above approach is that theoretically this function may be called not when the character was clicked; or not when it is the one in front.
For example, there’s Character.RunInteraction() function. It will trigger this callback too, and it may be run regardless of the mouse cursor and clicks.

As a reminder,  Character.RunInteraction()  do that:
Fires the event script as if the player had clicked the mouse on the character in the specified cursor mode. This is one of the mouse cursor modes, as defined in your Cursors tab in the editor.

That means that your mouse cursor could be anywhere on the screen, and in this case, the code above (finding the character under the mouse cursor) won't work.

So the above method will break in such case.
It also won’t work in case of keyboard / gamepad controls.

Thinking more on this, in such case it may be worked around by saving the character you are interacting with in a global variable, whenever you call RunInteraction.

The ideal solution would be to have a Character pointer in the callbacks.
(like GUI OnClick callbacks, in which GUI pointer is already there).

A pointer would just tell which character is interacted with.

Then Crimson Wizard has opened a ticket for adding Character * passing to the callback.

https://github.com/adventuregamestudio/ags/issues/1765

(to be continued)
#4
Hello,

I was annoyed to put ID of item for doing comparisons in script.
The ID is error prone, it could change, etc.

I could compare the item name, but that's even more error prone and i have to get its translation, and it must be awfully slow.

So my idea was to define macro, with item name and ID.

My script parse the xml of Game.agf and input what it has found.
For example:

Code: ags

#define iCup 1
#define iKey 2


Now, i need to include this in each character scripts. Is there an include_file() function or something like that ?

Yes, i could do copy/paste, or modifying the scripts by appending generate define at the beginning (with another script), but that doesn't sound like a good idea.

Thank you.


For those interested, the extraction script (it's lua and you need to install lua-expat module)

Code: ags

#!/usr/bin/env lua

-- Archlinux users: community/lua-expat
-- doc: https://lunarmodules.github.io/luaexpat/manual.html#introduction
local lxp_totable = require("lxp.totable")

local function read_file(path)
    local hFile = assert(io.open(path, "rb"))
    local data = hFile:read "*a"
    hFile:close()
    return data
end

local function parse_table(t)
  for k,v in pairs(t) do
    if type(v) == "table" then
      parse_table(v)
    else
      if v == "InventoryItem" then
        local item = lxp_totable.torecord(t)
          print(string.format("#define %s %d",item.Name,item.ID))
      end
    end
  end
end

local xml_data = read_file("Game.agf")
local data = lxp_totable.parse(xml_data)
parse_table(data)
#5
Hello,

I'm finding Dispaly() functions family quite complete, but i cannot customize as i want (color, border, fonts…).

Doing a search in the forum, it seems that the GUI for those functions is hardcoded.

So i think i must use GUI text elements, but i miss some display facilities, like automatic resizing of the width of the text box.
Is there a function i have missed, or should i rewrite a helper function for that (computing size of the font * lenght of the longuest sentence in the buffer, etc…) ?

Thank you.
#6
Hello,

I'm doing my game in 640×360, using the Sierra template.

After some thoughts, i'd rather like to have a simple click (contextual) interface. And i'd like to redraw the gui, because sprites don't scale from 320×200.
And thinking even more (that hurts!) , i don't need Roger Wilco sprites, neither default room.
But i think i will keep the keyboard part (for player moving).

Should i restart from a « blank » template (just copying keyboard script), or can i just remove elements ?
Will they still be embedded (so, take precious bytes, even if it's probably not so much) in the data exported ?

Thank you
#7
Hello,

Disclaimer: my experience with AGS is to have completed the tutorial.

I wonder how to light the scene. That is, how to add light effects, and not a « fixed » light drawn on the background.

Of course, that could be done with pixel shaders, but there are no shaders (saw on discord it was planned for AGS 4).

I've browsed the documentation, and i've seen some things that may be interesting:
- changing the tinting of objects, for locals light effects.
- DynamicSprite: copy part or complete background, and displaying it over the background. Then, applying tint changes (blue/yellow tint for outside night/day cycle, or darken the scene when light bulb is off).

Of course, the sprites have to be tinted too (i think it's possible to tint a sprite, but i didn't find any functions for this in help. Should i use dynamic sprites everywhere ?). For a global light, that's easy, but what about when walking in raylights, for example ? I don't think «partial» lighting is possible.

Are the above some ways to explore ? And of course, i'm glad to read other ideas.

Thank you.
SMF spam blocked by CleanTalk