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

Messages - DBoyWheeler

#41
Okay.  For the directions, do I need to use the X and Y coordinates of the buttons to get them set up right?
#42
So I saw the newer verb coin set up when you start making a new game.  But the way it set up with directions (North, West, etc.) might not work well with the verb coin I want to use.

Here's what I plan as a set up.

(I've made separate buttons with a snowflake style background--the bottom three are special buttons.)

And I've already commented out the stuff in the verb coin code for directions.
Spoiler
Code: ags
// Script header for VerbCoin script module
#define VERBCOIN_DEFAULT_RADIUS 38
#define VERBCOIN_DEFAULT_BACKGROUND_TRANSPARENCY 80
#define VERBCOIN_DEFAULT_BACKGROUND_COLOR 32089
#define VERBCOIN_DEFAULT_BORDER_COLOR 19248
#define VERBCOIN_DEFAULT_BORDER_WIDTH 1

#ifdef SCRIPT_API_v3507
#define SCREEN_WIDTH Screen.Width
#define SCREEN_HEIGHT Screen.Height
#endif
#ifndef SCRIPT_API_v3507
#define SCREEN_WIDTH System.ViewportWidth
#define SCREEN_HEIGHT System.ViewportHeight
#endif

//enum VerbCoinPosition {
//  eVerbCoinPositionNorth,
//  eVerbCoinPositionEast,
//  eVerbCoinPositionSouth,
//  eVerbCoinPositionWest
//};

struct VerbCoin {
  import static attribute int Radius;
  import static attribute int BackgroundTransparency;
  import static attribute int BackgroundColor;
  import static attribute int BorderColor;
  import static attribute int BorderWidth;
  import static function OnClick(GUIControl* control, MouseButton button);
  import static function RegisterButton(GUIControl* control, VerbCoinPosition position, CursorMode mode, String verbtext);
  import static attribute GUI* InterfaceGui;
  import static attribute GUI* InventoryGui;
  import static attribute Label* ActionLabel;
  import static function Enable();
  import static function Disable();
  import static function IsEnabled();
  import static function Open();
  import static function Close();
  import static function IsOpen();
  import static function CleanUp();
  import static attribute bool ButtonAutoDisable;
};
[close]
And
Spoiler
Code: ags
// sprite for the GUI background
DynamicSprite* sprite;

// GUI to use for the verbcoin
GUI* interface;

// inventory GUI to use
GUI* interface_inv;

// label to use for text actions
Label* action_label;

// default settings
int radius = VERBCOIN_DEFAULT_RADIUS;
int background_color = VERBCOIN_DEFAULT_BACKGROUND_COLOR;
int background_transparency = VERBCOIN_DEFAULT_BACKGROUND_TRANSPARENCY;
int border_color = VERBCOIN_DEFAULT_BORDER_COLOR;
int border_width = VERBCOIN_DEFAULT_BORDER_WIDTH;
int redraw = false;

// track where the interface was opened from
int context_x;
int context_y;
String context_text;

// map GUI controls against cursor modes
int modemap[];

// map GUI controls against text descrptions
String actionmap[];

// enable click handling and action label updates
bool enabled = false;

// whether buttons will be disabled if clicking them would result in an unhandled event
bool button_auto_disable = false;

function Clamp(static Maths, int value, int min, int max)
{
  if (value < min)
  {
    value = min;
  }

  if (value > max)
  {
    value = max;
  }

  return value;
}

function Min(static Maths, int value1, int value2)
{
  if (value1 > value2)
  {
    return value2;
  }

  return value1;
}

function set_buttons_enabled(bool state)
{
  for (int i; i < interface.ControlCount; i ++)
  {
    if (interface.Controls[i].AsButton != null)
    {
      interface.Controls[i].Enabled = state;
    }
  }
}

void set_Radius(static VerbCoin, int newradius)
{
  if (newradius < 1)
  {
    newradius = 1;
  }

  if (newradius != radius)
  {
    radius = newradius;
    redraw = true;
  }
}

int get_Radius(static VerbCoin)
{
  return radius;
}

void set_BackgroundTransparency(static VerbCoin, int transparency)
{
  transparency = Maths.Clamp(transparency, 0, 100);

  if (transparency != background_transparency)
  {
    background_transparency = transparency;
    redraw = true;
  }
}

int get_BackgroundTransparency(static VerbCoin)
{
  return background_transparency;
}

void set_BackgroundColor(static VerbCoin, int color)
{
  color = Maths.Clamp(color, 0, 65535);

  if (color != background_color)
  {
    background_color = color;
    redraw = true;
  }
}

int get_BackgroundColor(static VerbCoin)
{
  return background_color;
}

void set_BorderColor(static VerbCoin, int color)
{
  color = Maths.Clamp(color, 0, 65535);

  if (color != border_color)
  {
    border_color = color;
    redraw = true;
  }
}

int get_BorderColor(static VerbCoin)
{
  return border_color;
}

void set_BorderWidth(static VerbCoin, int width)
{
  width = Maths.Clamp(width, 0, radius);

  if (width != border_width)
  {
    border_width = width;
    redraw = true;
  }
}

int get_BorderWidth(static VerbCoin)
{
  return border_width;
}

static function VerbCoin::OnClick(GUIControl* control, MouseButton button)
{
  if (interface != null)
  {
    interface.Visible = false;
  }

  if (modemap != null && (button == eMouseLeft || button == eMouseRight))
  {
    Room.ProcessClick(context_x, context_y, modemap[control.ID]);
  }
}

function place_button(GUIControl* control, VerbCoinPosition position)
{
  float edge;

  if (position == eVerbCoinPositionNorth || position == eVerbCoinPositionSouth)
  {
    edge = IntToFloat(control.Width) / 2.0;
  }
  else
  {
    edge = IntToFloat(control.Height) / 2.0;
  }

  float squared = Maths.RaiseToPower(IntToFloat(radius), 2.0) - Maths.RaiseToPower(edge, 2.0);

  if (squared < 0.0)
  {
    squared = 0.0;
  }

  float offset = Maths.Sqrt(squared);

  //if (position == eVerbCoinPositionNorth)
  //{
  //  control.X = radius - FloatToInt(edge);
  //  control.Y = radius - FloatToInt(offset, eRoundDown);
  //}
  //else if (position == eVerbCoinPositionEast)
  //{
  //  control.X = radius + FloatToInt(offset, eRoundUp) - control.Width;
  //  control.Y = radius - FloatToInt(edge);
  //}
  //else if (position == eVerbCoinPositionSouth)
  //{
  //  control.X = radius - FloatToInt(edge);
  //  control.Y = radius + FloatToInt(offset, eRoundUp) - control.Height;
  //}
  //else if (position == eVerbCoinPositionWest)
  //{
  //  control.X = radius - FloatToInt(offset, eRoundDown);
  //  control.Y = radius - FloatToInt(edge);
  //}
}

//static function VerbCoin::RegisterButton(GUIControl* control, VerbCoinPosition position, CursorMode mode, String action)
//{
//  if (control.OwningGUI == interface && control.AsButton != null)
//  {
//    place_button(control, position);
//    modemap[control.ID] = mode;
//    actionmap[control.ID] = action;
//    control.Visible = true;
//  }
//}

function render()
{
  // resize the GUI to fit the sprite
  int gui_size = radius * 2;
  gui_size = Maths.Min(gui_size, SCREEN_HEIGHT);
  gui_size = Maths.Min(gui_size, SCREEN_WIDTH);
  gui_size ++;
  interface.Width = gui_size;
  interface.Height = gui_size;

  DynamicSprite* background = DynamicSprite.Create(interface.Width, interface.Height, true);
  DrawingSurface* surface;

  // redraw the sprite
  surface = background.GetDrawingSurface();
  surface.DrawingColor = border_color;
  surface.DrawCircle(radius, radius, radius);
  surface.DrawingColor = background_color;
  surface.DrawCircle(radius, radius, radius - border_width);
  surface.Release();

  sprite = DynamicSprite.Create(interface.Width, interface.Height, true);
  surface = sprite.GetDrawingSurface();
  surface.DrawImage(0, 0, background.Graphic, background_transparency);
  background.Delete();
  surface.Release();
  interface.BackgroundGraphic = sprite.Graphic;
}

void set_InterfaceGui(static VerbCoin, GUI* interface_gui)
{
  interface = interface_gui;

  for (int i; i < interface.ControlCount; i ++)
  {
    if (interface.Controls[i].AsButton != null)
    {
      interface.Controls[i].Visible = false;
    }
  }

  modemap = new int[interface.ControlCount];
  actionmap = new String[interface.ControlCount];
  enabled = true;
  render();
}

GUI* get_InterfaceGui(static VerbCoin)
{
  return interface;
}

void set_InventoryGui(static VerbCoin, GUI* inventory_gui)
{
  interface_inv = inventory_gui;
}

GUI* get_InventoryGui(static VerbCoin)
{
  return interface_inv;
}

void set_ActionLabel(static VerbCoin, Label* label)
{
  action_label = label;
  action_label.Text = "";
}

Label* get_ActionLabel(static VerbCoin)
{
  return action_label;
}

static function VerbCoin::Enable()
{
  enabled = true;
  set_buttons_enabled(true);
}

static function VerbCoin::Disable()
{
  enabled = false;
  set_buttons_enabled(false);
}

static function VerbCoin::IsEnabled()
{
  return enabled;
}

static function VerbCoin::Open()
{
  if (interface != null)
  {
    interface.Visible = true;
  }
}

static function VerbCoin::Close()
{
  if (interface != null)
  {
    interface.Visible = false;
  }
}

static function VerbCoin::IsOpen()
{
  return interface != null && interface.Visible;
}

static function VerbCoin::CleanUp() {
  if (sprite != null) sprite.Delete();
}

void set_ButtonAutoDisable(static VerbCoin, bool autodisable)
{
  button_auto_disable = autodisable;
}

bool get_ButtonAutoDisable(static VerbCoin)
{
  return button_auto_disable;
}

function on_mouse_click(MouseButton button)
{
  if (interface == null || !enabled)
  {
    // don't do anything if GUI isn't set or is disabled
  }
  else if (button == eMouseLeft)
  {
    if (GetLocationType(mouse.x, mouse.y) != eLocationNothing)
    {
      if (player.ActiveInventory != null)
      {
        Room.ProcessClick(mouse.x, mouse.y, eModeUseinv);
      }
      else if (interface.Visible)
      {
        interface.Visible = false;
      }
      else if (interface_inv != null && interface_inv.Visible)
      {
        interface_inv.Visible = false;
      }
      else if (Character.GetAtScreenXY(mouse.x, mouse.y) != player)
      {
        context_x = mouse.x;
        context_y = mouse.y;
        interface.X = Maths.Clamp(context_x - radius, 0, SCREEN_WIDTH - interface.Width);
        interface.Y = Maths.Clamp(context_y - radius, 0, SCREEN_HEIGHT - interface.Height);

        if (button_auto_disable)
        {
          for (int i; i < interface.ControlCount; i ++)
          {
            if (interface.Controls[i].AsButton != null)
            {
              interface.Controls[i].Enabled = IsInteractionAvailable(context_x, context_y, modemap[interface.Controls[i].ID]);
            }
          }
        }

        interface.Visible = true;
      }
    }
    // close windows or unset the active inventory item
    else if (interface.Visible)
    {
      interface.Visible = false;
    }
    else if (interface_inv != null && interface_inv.Visible)
    {
      interface_inv.Visible = false;
    }
    else if (player.ActiveInventory != null)
    {
      player.ActiveInventory = null;
    }
    else
    {
      // ...except when there is no nothing to deselect or close,
      // so just walk to this position
      Room.ProcessClick(mouse.x, mouse.y, eModeWalkto);
    }
  }
  else if (button == eMouseRight)
  {
    // close windows or unset the active inventory item
    if (interface.Visible)
    {
      interface.Visible = false;
    }
    else if (player.ActiveInventory != null)
    {
      player.ActiveInventory = null;
    }
    else if (interface_inv != null && interface_inv.Visible)
    {
      interface_inv.Visible = false;
    }
    else if (interface_inv != null)
    {
      // ...except when there is no nothing to deselect or close,
      // so a right click is also how the inventory is opened
      interface_inv.Visible = true;
    }
  }
  else if (button == eMouseLeftInv)
  {
    // InventoryItem.GetAtScreenXY could return null here
    // so using game.inv_activated instead is a safer option
    InventoryItem* item = inventory[game.inv_activated];

    if (player.ActiveInventory == null)
    {
      // left click to set active inventory
      player.ActiveInventory = item;
    }
    else if (item.ID != player.ActiveInventory.ID)
    {
      // left click to 'combine' items
      item.RunInteraction(eModeUseinv);
    }
    else if (interface_inv != null)
    {
      // clicking an item on itself closes the inventory window
      // (this is just a shortcut to avoid moving the cursor, as it means
      // you can just double click an item to also close the window)
      interface_inv.Visible = false;
    }
  }
  else if (button == eMouseRightInv)
  {
    // InventoryItem.GetAtScreenXY could return null here
    // so using game.inv_activated instead is a safer option
    InventoryItem* item = inventory[game.inv_activated];

    if (player.ActiveInventory == null && item != null)
    {
      // right click to look at item
      item.RunInteraction(eModeLookat);
    }
    else
    {
      // right click to deselect
      player.ActiveInventory = null;
    }
  }
}

function repeatedly_execute_always()
{
  if (redraw)
  {
    render();
    redraw = false;
  }
}

function repeatedly_execute()
{
  if (interface == null || !enabled)
  {
    // don't do anything if GUI isn't set or is disabled
  }
  else if (player.ActiveInventory == null)
  {
    if (interface.Visible)
    {
      // update text label for verb coin actions
      GUIControl* control = GUIControl.GetAtScreenXY(mouse.x, mouse.y);

      if (action_label == null)
      {
        // pass
      }
      else if (control != null && control.AsButton != null && control.Enabled && context_text != null)
      {
        action_label.Text = String.Format("%s %s", actionmap[control.ID], context_text);
      }
      else if (context_text != null)
      {
        action_label.Text = context_text;
      }
    }
    else if ((interface_inv != null && !interface_inv.Visible) || GetLocationType(mouse.x, mouse.y) == eLocationNothing)
    {
      // update regular text label
      context_text = Game.GetLocationName(mouse.x, mouse.y);

      if (action_label != null)
      {
        action_label.Text = context_text;
      }
    }
  }
  else
  {
    if (interface_inv != null && interface_inv.Visible && GUI.GetAtScreenXY(mouse.x, mouse.y) != interface_inv)
    {
      // close inventory window once the cursor leaves
      interface_inv.Visible = false;
    }

    // update text label for 'combining' items
    String location = Game.GetLocationName(mouse.x, mouse.y);
    InventoryItem *i = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);

    if ((i != null && i.ID == player.ActiveInventory.ID) || location == "")
    {
      location = "...";
    }

    if (action_label != null)
    {
      action_label.Text = String.Format("Use %s with %s", player.ActiveInventory.Name, location);
    }
  }
}

function on_event(EventType event, int data)
{
  if (event == eEventLeaveRoom && interface != null)
  {
    // hide interface when changing rooms
    interface.Visible = false;
  }
  else if (event == eEventGUIMouseDown &&
      interface_inv != null &&
      data == interface_inv.ID &&
      InventoryItem.GetAtScreenXY(mouse.x, mouse.y) == null)
  {
    // handle clicks in the inventory area that are not on an inventory item
    GUIControl* control = GUIControl.GetAtScreenXY(mouse.x, mouse.y);

    if (control == null || control.AsInvWindow == null)
    {
      // pass
    }
    else if (player.ActiveInventory != null)
    {
      player.ActiveInventory = null;
    }
    else
    {
      interface_inv.Visible = false;
    }
  }
}
[close]

What else do I need to change in the verb coin code to make my custom-made verb coin work?  (Once I know this part, I'll post the lines in the global script and ask what changes need to be there as well.)
#43
No way I could pull this off, let alone pull it off perfectly.  But good luck to those who do try it.
#44
General Discussion / Re: RIP Slasher
Tue 15/08/2023 22:13:23
Also, I've been thinking with others who had gone on before... somewhere in this forum we should have an "AGS-er Memorial Wall" to commemorate those who shuffled off the mortal coil.
#45
General Discussion / Re: RIP Slasher
Mon 14/08/2023 23:43:36
Quote from: bicilotti on Mon 14/08/2023 21:31:28I did not know Slasher very well. The sheer amount of games listed in his profile — eighty-seven! — and the kind words in this thread show how he valued the community and the commuinity valued him back.

 

87 games?!  8-0  Dang!

This makes his passing even more devastating.  To think how much more he could've accomplished, had he had more time in this world...
#46
General Discussion / Re: RIP Slasher
Sun 13/08/2023 00:48:51
Crap!  Another great lost.
#47
Good, we got a competition finally come voting time.  Looking forward to where this goes.
#48
Kinda gives the Gabriel Knight vibes.  Sweet work so far!
#49
I had one idea for if, hypothetically, I were to take part in it.

Maybe it's the last object of a particular material, and a scientist needs to find out what the chemical makeup of that material is so he/she could make that material again and the particular craft can be brought back to prominence.

Anyway, good luck to everyone taking part in this.
#50
Um, when's the due date?  I think we kinda forgot to include when the contest ends.
#51
Crap!  I... had no idea.

He will be dearly missed.
 :~(
#52
Congrats to RootBound!
#53
Hmm, hitboxes might come in handy for Quest for Glory style games too.  Might have to consider this.
#54
I briefly saw a playthrough of this on Future Vintage Gaming on YouTube.

Just the first few sightings of the Veiled Lady alone had me thinking "Where's our paranormal hero Trilby when you need him?"

Anyway, hats off to this game's creator.
#55
Aww, you didn't include the scene from QG4 where Toby sacrificed himself to bring Tanya back to life.

Still, quite an intense topic, for sure.
#56
So tell me have you heard... about the bird?

Anyway, good luck to all those entering.
#57
Aww, no Wraiths from Quest for Glory IV?

Anyhow, good luck to everyone entering.
#58
Yeah, real life kinda prevents me from joining these, but I do save these MAGS ideas so I can work on them on my own time, to be kind of "proofs of concept" for future game ideas.  But if I were to try this, I could imagine an Ancient Egyptian myth in modern day Japan (and no, Yu-Gi-Oh has nothing to do with this).

Anyhow, good luck to all who enter.
#59
I stumbled onto this a while back, and figured this would be a great group to be in alongside this one.

There is an Adventure Game Studio group in GameJolt, so if there are members here who are also on GameJolt, here is the link:
https://gamejolt.com/c/AGS-twxrcj
#60
So it's kinda like a MAGS version of "Quest for Infamy".  Kinda.

Well, good luck to the contestants.
SMF spam blocked by CleanTalk