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

#2921
Site & Forum Reports / Re: Bug reports
Wed 30/08/2017 22:04:56
Hey,

is it just me, or the embedded youtube videos appear as text now instead of being embedded ?

"[embed=x,y] video link [/embed]" are the ones I am referencing... Like here: Blackwell Epiphany trailer embedded.
#2922
I am still waking up, but for me Linux build wasn't working and I had to manually copy the Linux engine and the .so files in the game folder. Can you test the Linux version and verify that your game executable isn't indeed executing under Linux?
#2923
Thanks arj0n ! Just downloaded both modules! :]
#2924
Thanks! Just sent him a message.

About the game Drowning In The Bitstream, the source is not available, am I missing something here?

Edit:

It seems Chicky didn't use any distortion, apparently it's all pre-made, as stated here.

Edit 2:

Holy Cow you guys are amazing! Thanks!
#2925
Hey, does someone has a backup of this code somewhere? I am really interested in the code :). Also the FakeScreen module, I couldn't find it's topic. :~(
#2926
Hey Crimson Wizard! Great module, that's the kind of thing I am looking for, distortion of the image while being able to move the character around and the character itself being effected by the distortion!

Unfortunately, the link to this underwater module is offline, so I couldn't check it's code. :/

Here is an example that I made, but I am using screenshot and it only works with stills, I would like to advance this effect:

Example video rewind effect

The messages on the forum tells something about a module called FakeScreen.
#2927
I really want the new OpenGL render and the risk it won't work two years from now.
#2928
Hey, these blend modes, what blocks them from moving into the main engine code? They would be very useful for my game.
#2929
Critics' Lounge / Re: Monster in a jar
Fri 11/08/2017 04:05:09
I think the jar is too squared. If you look up on Google Images for the terms Futurama+head+in+a+jar you will be met with a simplistic depiction of heads in a jar. Notice how in every scene they appear, the borders are rounded to imply the cylindrical shape.

Other than this, the purple look more witch/mage oriented while the yellowish look more mad bio scientist oriented.
#2930
NormRnd

NormRnd is a tiny (2.1kB) module adding a standard normal random number function. It uses Box-Muller method, which should be reasonably fast.

It exposes two functions:

float normrnd_unitary()
Returns a standard normal random number, as a float, with median 0, and variance 1.

int normrnd_asint(int median, int sigma, int clamp_ceil,  int clamp_floor)
Returns a standard normal random number, as a int, requires passing a defined median and sigma. It also allow clamping to restrict the possible returning values. If clamp_ceil and clamp_floor are equal, clamping is disabled.

NormRnd.asc

Spoiler
Code: ags

// normrnd
//
// This module allows returning standard Normal random number.
// This code is based on Box-Muller method, implemented in C
// by Prof Darren Wilkinson here:
//
// http://www.mas.ncl.ac.uk/~ndjw1/teaching/sim/transf/norm.html
//
// My work was porting to AGS and giving utilitary functions
// Author: Erico Porto
//

float surand()
{
  return ( IntToFloat(Random(1000))/1000.0 );
}

float urand(float low, float high)
{
  return(low+(high-low)*surand());
}

float genexp(float lambda)
{
  float u,x;
  u=surand();
  x=(-1.0/lambda)*Maths.Log(u);
  return(x);
}

float gennor()
{
  float theta,rsq,x;
  theta=urand(0.0,2.0*Maths.Pi);
  rsq=genexp(0.5);
  x=Maths.Sqrt(rsq)*Maths.Cos(theta);
  return(x);
}

//normrnd_unitary
//
// returns a float that is a standard Normal random number
float normrnd_unitary(){
  return gennor();
}

// returns an int that is a standard Normal random number
// first paramter, median, is the median of the distribution
// second parameter, sigma, is proportional to the variance of the distribution
// third and fourth parameter allow clamping the result if a hard limit is desired
int normrnd_asint(int median, int sigma, int clamp_ceil,  int clamp_floor){
  int return_value = FloatToInt(gennor()*IntToFloat(sigma)+IntToFloat(median));
  if( clamp_ceil != clamp_floor && clamp_ceil > clamp_floor){
    if (return_value > clamp_ceil){
      return_value = clamp_ceil;
    }
    if (return_value < clamp_floor){
      return_value = clamp_floor;
    }
  }
  
  return return_value;
}
[close]

NormRnd.ash

Spoiler
Code: ags

// normrnd
//
// This module allows returning standard Normal random number.
// This code is based on Box-Muller method, implemented in C
// by Prof Darren Wilkinson here:
//
// http://www.mas.ncl.ac.uk/~ndjw1/teaching/sim/transf/norm.html
//
// My work was porting to AGS and giving utilitary functions
// Author: Erico Porto
//
import float normrnd_unitary();
import int normrnd_asint(int median, int sigma, int clamp_ceil = 0,  int clamp_floor = 0);
[close]

Download NormRnd.scm here

Doc website

Github Repository
#2931
Hi guys,

I am trying to create an effect over the entire screen on room load, imagine like a old tube TV effect.

Right now my implementation uses DynamicSprite.CreateFromScreenShot(320, 180) to get the screen after the room is loaded, I create another DynamicSprite where I get this first image and apply the effects, then I use MyOverlay.Remove() and Overlay.CreateGraphical(0,0 , MyScreenFromSShot.Graphic, true) on the repeatedly_execute_always to generate my effect.

Ok so this approach has some problems:


  • I can only apply the dynamic effect from the first possible screenshot in the room, so I can use the effect only for a short transition;
  • The fade in has to be finished before I can take a screenshot;
  • The screenshot will include the game cursor, which is undesirable.

Also this is working slow under Direct Draw but working with no fps drop under Linux - I haven't tested OpenGL on Windows yet, so I am not that worried right now about performance.

Have you guys tried to do any over entire screen effect? Is there a way to capture the screen just before it's drawn and edit the painting without having to use screenshot, which essentially has to let the entire screen be painted at least one frame before being useful.

Example implementation of what I described above
Spoiler

Code: ags


// Effect on entire screen using overlay
DynamicSprite* Spr_ScreenShot;
DynamicSprite* Spr_EffectedSShot;
DrawingSurface* EffectedSShot_Surface;
Overlay* Effect_Overlay ;
bool Effect_enabled;

// Effect_start is exposed using import on header
function Effect_start(){
  Spr_ScreenShot = DynamicSprite.CreateFromScreenShot(320, 180);
  Spr_EffectedSShot = DynamicSprite.CreateFromExistingSprite(Spr_ScreenShot.Graphic, false);
  Effect_enabled=true;
  Effect_Overlay = Overlay.CreateGraphical(0,0 , Spr_EffectedSShot.Graphic, true);
}

// Effect_stop is exposed using import on header
function Effect_stop(){
  if(Effect_enabled){
    Effect_enabled=false;
    Effect_Overlay.Remove();
    Spr_EffectedSShot.Delete();
    Spr_ScreenShot.Delete();
  }
}



function renderEffect(){
  Effect_Overlay.Remove();
  EffectedSShot_Surface = Spr_EffectedSShot.GetDrawingSurface();
  
  //draw stuff on the surface and manipulate it ...
  
  EffectedSShot_Surface.Release();
  Effect_Overlay = Overlay.CreateGraphical(0,0 , Spr_EffectedSShot.Graphic, true);
  
}


// draws the effect once it's enabled
function repeatedly_execute_always()
{
  if (!IsGamePaused() && Effect_enabled)
  {
    renderEffect();
    
  }
}

// certify that effect stops when leaving the room
function on_event(EventType event, int data){
    if(event == eEventLeaveRoom){
      Effect_stop();
    }
}


[close]

EDIT: SOLVED

Link to mp4 video of it working!

Hey guys, thanks for pointing me in the right direction! I followed the Underwater module, arj0n gave me the source, and there was the FakeScreen module. I modified it to generate a constant FakeSprite and used it's graphic in my VHSEffect! :D
#2932
AGS Games in Production / Re: Future Flashback
Mon 07/08/2017 04:16:24
Guys you are all great, thanks for the positive responses! This community is awesome! :-D

The release date is a bit in the future, I know. We have already planned the whole game, we broke it in how many AGS rooms we are going to have, and extrapolated the time to end development from the time we spent in each room we already developed, so hopefully this is reasonably realistic.

The game interface will allow the player to interact and look using the mouse, and have an inventory to store and use items, we started from the BASS template and have been iterating from there. The game resolution is going to be 320x180, so it will scale nice in 16:9 screens.
#2933
AGS Games in Production / Future Flashback
Sun 30/07/2017 04:03:54

Story:

Behold a future where a drug is capable of recreate vivid memories. Untangle the obsessive mind of an ex surgeon, that after an accident starts reliving the memories of a girl he never met, seeing her past, looking into her dreams and unfolding the mysterious future they share together.

Expected Release date: 2020

Story by Guilherme Henrique
Programing by Erico Porto
Art by Ricardo Juchem
Music by Jordan Pool

Screenshots:





Blog | YouTube Channel | Facebook Page | Twitter @futureflashbck | presskit() | indieDB

Update Log:
0 - 30 Jul 2017 - Game Announcement
1 - 31 Aug 2017 - Theme Music Reveal
2 - 24 Sep 2017 - Game Menu is a Smartphone
3 - 02 Oct 2017 - Characters Portrait Reveal
4 - 19 Oct 2017 - Gameplay video of First Level
5 - 28 Oct 2017 - Title Screen and updated Theme Music
6 -  4 Nov 2017 - We Have a Website
7 - 10 Nov 2017 - The evolution of a background art
8 - 14 Nov 2017 - Social Networks + Ship of Theseus Development
9 - 17 Dec 2017 - Screenshot and New Background
10 -  8 Apr 2018 - More Screenshots
11 - 10 Jul 2018 - One more screenshot, art streaming and Future Flashback in a game event!
12 - 21 Aug 2018 - Geek & Game Rio Festival 2018
13 - 17 Sep 2018 - Going to AdventureX
14 - 18 Nov 2018 - Future Flashback on AdventureX
15 - 15 Dec 2018 - Library Screenshot
16 - 31 Dec 2018 - 2018 Recap
17 - 13 Feb 2019 - Steam Capsules poll
18 - 13 Jul 2019 - A small update of themes
#2934
I use Linux too, half a Linux port that already builds a .so ?
#2935
Khris you are awesome. Thanks!

EDIT:

Holy Damn, I have more than 20 interactive things per screen. :-\
#2936
Hey Crimson Wizard ! Thanks for the help, I moved the release to the show function, unfortunately, it's not that.

I can draw both characters name and objects name. Just the hotspots, they are drawn in position 500,500 (500 is probably the result of 999/2 rounded up as int, outside of the screen, my screen is 320x180).
#2937
Selmiak, your artwork is the one that prompts me to create a game.
#2938
Hello,

I am trying to create an InteractionDetector for my game, Objects and Characters are easy to get the X and Y positions, but Hotspots are trickier.

So I decided to go pixel by pixel on the screen, check which hotspot that pixel belongs to, and note down the minimal and maximum x and y positions, the idea is to later do:
y=miny+(maxy-miny)/2 .

But it's not working! I know the error is in the generate_hotspot_xy function, but I have no idea what's wrong.

Below is the full code, if you want to test it, just replace the font enumerator for your game. I think the rest is not dependent of game code.


Fullcode: InteractionDetector.asc
Spoiler

Code: ags

// new module script
DynamicSprite* interactionSprite;
DrawingSurface * interactionSurface;
Overlay* interactionOverlay ;
bool interactionShown;

int hotspot_minx[MAX_HOTSPOTS_PER_ROOM];
int hotspot_maxx[MAX_HOTSPOTS_PER_ROOM];
int hotspot_miny[MAX_HOTSPOTS_PER_ROOM];
int hotspot_maxy[MAX_HOTSPOTS_PER_ROOM];
int hotspot_x[MAX_HOTSPOTS_PER_ROOM];
int hotspot_y[MAX_HOTSPOTS_PER_ROOM];

//this is the function used to draw each label
function draw_label(String text, int textx,  int texty){
  int textcolor = Game.GetColorFromRGB(216,216, 216);
  if(textx+GetTextWidth(text, eFontSmallFont)+4>Room.Width){
    textx=Room.Width-GetTextWidth(text, eFontSmallFont)-4;
  }
  interactionSurface.DrawingColor = textcolor;
  interactionSurface.DrawString(textx, texty, eFontSmallFontOutlined, text);
}

//this function shows the interaction detector when pressed
static void InteractionDetector::show() {  
  int obj_count = Room.ObjectCount;
  int cha_count = Game.CharacterCount;
  int i;
  int textx,  texty;
  String text;
  interactionShown = true;
  interactionSprite = DynamicSprite.Create(Room.Width, Room.Height);
  interactionSurface = interactionSprite.GetDrawingSurface();
  Character *c;

  
  i=0;
  while(i<obj_count){
    if(object[i].Visible && object[i].Clickable){
      text = object[i].Name;
      textx=object[i].X;
      texty=object[i].Y;
      draw_label(text, textx, texty);
    }
    i++;
  }
  
 
  i=0;
  while(i<MAX_HOTSPOTS_PER_ROOM){
    text = hotspot[i].Name;
    if(hotspot[i].Enabled){
      if(text.Length > 1 && text.IndexOf("Hotspot") == -1){
        textx=hotspot_x[i];
        texty=hotspot_y[i];
        
        draw_label(text, textx, texty);
      }      
    }
    i++;
  }
  
  
  i=0;
  while (i < cha_count) {
    c = character[i];
    if (c.Room == player.Room && c.Clickable && c.ID != player.ID) {
      ViewFrame *cviewframe = Game.GetViewFrame(c.View, c.Loop, c.Frame);
      textx = c.x;
      texty = c.y - Game.SpriteHeight[cviewframe.Graphic]*c.Scaling/2*100;
      text = c.Name;
      if(text.Length>2){
        draw_label(text, textx, texty);
      }
    }
    i++;
  }
  
  interactionOverlay= Overlay.CreateGraphical(0, 0, interactionSprite.Graphic, true);
  player.Say("testx = %d, texty = %d",hotspot_x[2], hotspot_y[2]);
}

//hides the Interaction Detector Overlay
static void InteractionDetector::hide() { 
  interactionOverlay.Remove();
  interactionSurface.Release();
  interactionSprite.Delete();
  interactionShown = false;
}

//external function to check if the Interaction Detector Overlay is already shown
static bool InteractionDetector::isShown() {  
  return interactionShown;
}

//this allows toglin on and off the Interaction Detector Overlay
static void InteractionDetector::toggle() {  
  if(interactionShown){
    InteractionDetector.hide();
  } else {
    InteractionDetector.show();
  }
}

//this function calculates each hotspot position on the screen
function generate_hotspot_xy(){
  int i;
  Hotspot *h;
  
  i=0;
  while(i<MAX_HOTSPOTS_PER_ROOM){
    hotspot_minx[i]=999;
    hotspot_miny[i]=999;
    hotspot_maxx[i]=0;
    hotspot_maxy[i]=0;
    hotspot_x[i]=-1;
    hotspot_y[i]=-1;
    i++;
  }
  
  int x=0;
  int y=0;
  int step=3;
  int h_id;
  
  //we will walk the screen in steps
  //get the hotspot at the x,y point
  //and note down the smaller and bigger
  //x,y position for each hotspot
  while(y<System.ViewportHeight - 1){
    while(x<System.ViewportWidth - 1){

      h = Hotspot.GetAtScreenXY(x, y);
      h_id = h.ID;
      if(h_id>0){
        if(x < hotspot_minx[h_id] ){
          hotspot_minx[h_id] = x;
        } 
        
        if(y < hotspot_miny[h_id]){
          hotspot_miny[h_id] = y;
        } 
        
        if(x > hotspot_maxx[h_id]){
          hotspot_maxx[h_id] = x;
        } 
        
        if(y > hotspot_maxy[h_id]){
          hotspot_maxy[h_id] = y;
        } 
      }
      
      
      x+=step;
    }
    y+=step;
  }
  
  //using the previously obtained max and min x and y values
  //we calculate the center of the hotspot
  i=0;
  while(i<MAX_HOTSPOTS_PER_ROOM){
    hotspot_x[i]=hotspot_minx[i]+(hotspot_maxx[i]-hotspot_minx[i])/2;
    hotspot_y[i]=hotspot_miny[i]+(hotspot_maxy[i]-hotspot_miny[i])/2;
    i++;
  } 
}


//everytime a room is loaded, we must recalculate it's hotspot position.
function on_event (EventType event, int data)
{
  if (event == eEventEnterRoomBeforeFadein){
    generate_hotspot_xy();
  } 
}


[close]

Fullcode InteractionDetector.ash
Spoiler

Code: ags

// new module header
#define MAX_HOTSPOTS_PER_ROOM 49

struct InteractionDetector
{
  import static void show();
  import static void hide();  
  import static void toggle();  
  import static bool isShown();  
};

[close]

EDIT:

Fixed Code Below! Thanks Khris!

InteractionDetector.asc
Spoiler
Code: ags

// new module script
DynamicSprite* interactionSprite;
DrawingSurface * interactionSurface;
Overlay* interactionOverlay ;
bool interactionShown;

int hotspot_minx[MAX_HOTSPOTS_PER_ROOM];
int hotspot_maxx[MAX_HOTSPOTS_PER_ROOM];
int hotspot_miny[MAX_HOTSPOTS_PER_ROOM];
int hotspot_maxy[MAX_HOTSPOTS_PER_ROOM];
int hotspot_x[MAX_HOTSPOTS_PER_ROOM];
int hotspot_y[MAX_HOTSPOTS_PER_ROOM];

//this is the function used to draw each label
function draw_label(String text, int textx,  int texty){
  int textcolor = Game.GetColorFromRGB(216,216, 216);
  if(textx+GetTextWidth(text, eFontSmallFont)+4>Room.Width){
    textx=Room.Width-GetTextWidth(text, eFontSmallFont)-4;
  }
  interactionSurface.DrawingColor = textcolor;
  interactionSurface.DrawString(textx, texty, eFontSmallFontOutlined, text);
}

//this function shows the interaction detector when pressed
static void InteractionDetector::show() {  
  int obj_count = Room.ObjectCount;
  int cha_count = Game.CharacterCount;
  int i;
  int textx,  texty;
  String text;
  interactionShown = true;
  interactionSprite = DynamicSprite.Create(Room.Width, Room.Height);
  interactionSurface = interactionSprite.GetDrawingSurface();
  Character *c;

  
  i=0;
  while(i<obj_count){
    if(object[i].Visible && object[i].Clickable){
      text = object[i].Name;
      textx=object[i].X;
      texty=object[i].Y;
      draw_label(text, textx, texty);
    }
    i++;
  }
  
 
  i=0;
  while(i<MAX_HOTSPOTS_PER_ROOM){
    text = hotspot[i].Name;
    if(hotspot[i].Enabled){
      if(text.Length > 1 && text.IndexOf("Hotspot") == -1){
        textx=hotspot_x[i];
        texty=hotspot_y[i];
        
        draw_label(text, textx, texty);
      }      
    }
    i++;
  }
  
  
  i=0;
  while (i < cha_count) {
    c = character[i];
    if (c.Room == player.Room && c.Clickable && c.ID != player.ID) {
      ViewFrame *cviewframe = Game.GetViewFrame(c.View, c.Loop, c.Frame);
      textx = c.x;
      texty = c.y - Game.SpriteHeight[cviewframe.Graphic]*c.Scaling/2*100;
      text = c.Name;
      if(text.Length>2){
        draw_label(text, textx, texty);
      }
    }
    i++;
  }
  
  interactionSurface.Release();
  interactionOverlay= Overlay.CreateGraphical(0, 0, interactionSprite.Graphic, true);
}

//hides the Interaction Detector Overlay
static void InteractionDetector::hide() { 
  interactionOverlay.Remove();
  interactionSprite.Delete();
  interactionShown = false;
}

//external function to check if the Interaction Detector Overlay is already shown
static bool InteractionDetector::isShown() {  
  return interactionShown;
}

//this allows toglin on and off the Interaction Detector Overlay
static void InteractionDetector::toggle() {  
  if(interactionShown){
    InteractionDetector.hide();
  } else {
    InteractionDetector.show();
  }
}

//this function calculates each hotspot position on the screen
function generate_hotspot_xy(){
  int i;
  Hotspot *h;
  
  i=0;
  while(i<MAX_HOTSPOTS_PER_ROOM){
    hotspot_minx[i]=999;
    hotspot_miny[i]=999;
    hotspot_maxx[i]=0;
    hotspot_maxy[i]=0;
    hotspot_x[i]=-1;
    hotspot_y[i]=-1;
    i++;
  }
  
  int x=0;
  int y=0;
  int step=3;
  int h_id;
  
  //we will walk the screen in steps
  //get the hotspot at the x,y point
  //and note down the smaller and bigger
  //x,y position for each hotspot
  while(y<System.ViewportHeight - 1){
    x=0;
    while(x<System.ViewportWidth - 1){

      h = Hotspot.GetAtScreenXY(x, y);
      h_id = h.ID;
      if(h_id>0){
        if(x < hotspot_minx[h_id] ){
          hotspot_minx[h_id] = x;
        } 
        
        if(y < hotspot_miny[h_id]){
          hotspot_miny[h_id] = y;
        } 
        
        if(x > hotspot_maxx[h_id]){
          hotspot_maxx[h_id] = x;
        } 
        
        if(y > hotspot_maxy[h_id]){
          hotspot_maxy[h_id] = y;
        } 
      }
      
      
      x=x+step;
    }
    y=y+step;
  }
  
  //using the previously obtained max and min x and y values
  //we calculate the center of the hotspot
  i=0;
  while(i<MAX_HOTSPOTS_PER_ROOM){
    hotspot_x[i]=hotspot_minx[i]+(hotspot_maxx[i]-hotspot_minx[i])/2;
    hotspot_y[i]=hotspot_miny[i]+(hotspot_maxy[i]-hotspot_miny[i])/2;
    i++;
  } 
}


//everytime a room is loaded, we must recalculate it's hotspot position.
function on_event (EventType event, int data)
{
  if (event == eEventEnterRoomBeforeFadein){
    generate_hotspot_xy();
  } 
}
[close]


InteractionDetector.ash
Spoiler
Code: ags

// new module header
#define MAX_HOTSPOTS_PER_ROOM 49

struct InteractionDetector
{
  import static void show();
  import static void hide();  
  import static void toggle();  
  import static bool isShown();  
};

[close]


EDIT2:

This is my final version that solves label colision:

InteractionDetector.asc

Spoiler
Code: ags

// new module script
DynamicSprite* interactionSprite;
DrawingSurface * interactionSurface;
Overlay* interactionOverlay ;
bool interactionShown;

int hotspot_minx[MAX_HOTSPOTS_PER_ROOM];
int hotspot_maxx[MAX_HOTSPOTS_PER_ROOM];
int hotspot_miny[MAX_HOTSPOTS_PER_ROOM];
int hotspot_maxy[MAX_HOTSPOTS_PER_ROOM];
int hotspot_x[MAX_HOTSPOTS_PER_ROOM];
int hotspot_y[MAX_HOTSPOTS_PER_ROOM];


int textcolor;

int label_index;
String scheduled_text[MAX_LABELS];
bool scheduled_text_enabled[MAX_LABELS];
int scheduled_text_x[MAX_LABELS];
int scheduled_text_y[MAX_LABELS];

//this is the function used to draw each label
function schedule_drawing(String text, int textx,  int texty){
  scheduled_text[label_index]=text;
  scheduled_text_enabled[label_index]=true;
  scheduled_text_x[label_index] = textx;
  if(textx+GetTextWidth(text, eFontSmallFont)+4>System.ViewportWidth+40){
    scheduled_text_enabled[label_index]=false; 
  }
  
  if(textx+GetTextWidth(text, eFontSmallFont)+4>System.ViewportWidth){
    scheduled_text_x[label_index]=System.ViewportWidth-GetTextWidth(text, eFontSmallFont)-4;
  }
  scheduled_text_y[label_index] = texty;
  label_index++;
}


function draw_label(String text, int textx,  int texty){

  interactionSurface.DrawingColor = textcolor;
  interactionSurface.DrawString(textx, texty, eFontSmallFontOutlined, text);
}

function fix_label_positions(){
  int i;
  int j;
  i=0;
  j=0;
  int textwidth;
  while(i<MAX_LABELS){
    if(scheduled_text_enabled[i]){
      textwidth=GetTextWidth(scheduled_text[i], eFontSmallFont) ;
      j=0;
      while(j<MAX_LABELS){
        if(scheduled_text_enabled[j] && i!=j){
           if(scheduled_text_y[i]<scheduled_text_y[j]+9 && scheduled_text_y[i]>scheduled_text_y[j]-9){
             if(scheduled_text_x[i]<textwidth+scheduled_text_x[j]+8 && scheduled_text_x[i]>scheduled_text_x[j]-textwidth-8){
               scheduled_text_y[i]=scheduled_text_y[i]-6;
               scheduled_text_y[j]=scheduled_text_y[j]+2;
               break;
             }
           }
        }
        j++;
      }
    }
    i++;
  }  
}

function draw_all_labels(){
  textcolor = Game.GetColorFromRGB(216,216, 216);  
  int i;
  fix_label_positions();
  fix_label_positions();
  
  i=0;
  while(i<MAX_LABELS){
    if(scheduled_text_enabled[i]){
      draw_label(scheduled_text[i] ,scheduled_text_x[i], scheduled_text_y[i]);
    }
    i++;
  }
}


//this function calculates each hotspot position on the screen
function generate_hotspot_xy(){
  int i;
  Hotspot *h;
  
  i=0;
  while(i<MAX_HOTSPOTS_PER_ROOM){
    hotspot_minx[i]=999;
    hotspot_miny[i]=999;
    hotspot_maxx[i]=0;
    hotspot_maxy[i]=0;
    hotspot_x[i]=-1;
    hotspot_y[i]=-1;
    i++;
  }
  
  int x=0;
  int y=0;
  int step=3;
  int h_id;
  
  //we will walk the screen in steps
  //get the hotspot at the x,y point
  //and note down the smaller and bigger
  //x,y position for each hotspot
  while(y<System.ViewportHeight - 1){
    x=0;
    while(x<System.ViewportWidth - 1){

      h = Hotspot.GetAtScreenXY(x, y);
      h_id = h.ID;
      if(h_id>0){
        if(x < hotspot_minx[h_id] ){
          hotspot_minx[h_id] = x;
        } 
        
        if(y < hotspot_miny[h_id]){
          hotspot_miny[h_id] = y;
        } 
        
        if(x > hotspot_maxx[h_id]){
          hotspot_maxx[h_id] = x;
        } 
        
        if(y > hotspot_maxy[h_id]){
          hotspot_maxy[h_id] = y;
        } 
      }
      
      
      x=x+step;
    }
    y=y+step;
  }
  
  //using the previously obtained max and min x and y values
  //we calculate the center of the hotspot
  i=0;
  while(i<MAX_HOTSPOTS_PER_ROOM){
    hotspot_x[i]=hotspot_minx[i]+(hotspot_maxx[i]-hotspot_minx[i])/2;
    hotspot_y[i]=hotspot_miny[i]+(hotspot_maxy[i]-hotspot_miny[i])/2;
    i++;
  } 
}

//this function shows the interaction detector when pressed
static void InteractionDetector::show() {  
  int obj_count = Room.ObjectCount;
  int cha_count = Game.CharacterCount;
  int i;
  int textx,  texty;
  String text;
  interactionShown = true;
  interactionSprite = DynamicSprite.Create(System.ViewportWidth, System.ViewportHeight);
  interactionSurface = interactionSprite.GetDrawingSurface();
  Character *c;
  
  label_index=0;
  generate_hotspot_xy();

  i=0;
  while(i<MAX_LABELS){
    scheduled_text_enabled[i] = false;
    i++;
  }
  
  i=0;
  while(i<obj_count){
    if(object[i].Visible && object[i].Clickable){
      text = object[i].Name;
      textx=object[i].X-GetViewportX();
      texty=object[i].Y-GetViewportY();
      schedule_drawing(text, textx, texty);
    }
    i++;
  }
  
 
  i=0;
  while(i<MAX_HOTSPOTS_PER_ROOM){
    text = hotspot[i].Name;
    if(hotspot[i].Enabled){
      if(text.Length > 1 && text.IndexOf("Hotspot") == -1){
        textx=hotspot_x[i];
        texty=hotspot_y[i];
        
        schedule_drawing(text, textx, texty);
      }      
    }
    i++;
  }
  
  
  i=0;
  while (i < cha_count) {
    c = character[i];
    if (c.Room == player.Room && c.Clickable && c.ID != player.ID) {
      ViewFrame *cviewframe = Game.GetViewFrame(c.View, c.Loop, c.Frame);
      textx = c.x-GetViewportX();
      texty = c.y - Game.SpriteHeight[cviewframe.Graphic]*c.Scaling/2*100-GetViewportY();
      text = c.Name;
      if(text.Length>2){
        schedule_drawing(text, textx, texty);
      }
    }
    i++;
  }
  
  draw_all_labels();
  interactionSurface.Release();
  interactionOverlay= Overlay.CreateGraphical(0, 0, interactionSprite.Graphic, true);
}

//hides the Interaction Detector Overlay
static void InteractionDetector::hide() { 
  interactionOverlay.Remove();
  interactionSprite.Delete();
  interactionShown = false;
}

//external function to check if the Interaction Detector Overlay is already shown
static bool InteractionDetector::isShown() {  
  return interactionShown;
}

//this allows toglin on and off the Interaction Detector Overlay
static void InteractionDetector::toggle() {  
  if(interactionShown){
    InteractionDetector.hide();
  } else {
    InteractionDetector.show();
  }
}



//everytime a room is loaded, we must recalculate it's hotspot position.
function on_event (EventType event, int data)
{
  if (event == eEventLeaveRoom){
    if(interactionShown){
      InteractionDetector.hide();
    }
  } 
}

[close]
#2939
Hey,

I used to use pandoc and sphinx, I was passing on the AGS topics and this is the first thing I thought "I know how to automate this!"

I have a project here (it's slightly abandoned) that has a help file built from Markdown source: https://github.com/ericoporto/fgmk/tree/master/docs

I use pandoc to go from .md to .rst and sphinx to build my help files (QtHelp and html).

You can take a look at the generated html help here: http://ericoporto.github.io/fgmk/

Can someone point me the source files?
#2940
Right, thanks for the info!

If I want to send a game with a fixed configuration, is it just a matter of sending the setup.cfg file and no winsetup.exe together? I can't wait to have OpenGL out of beta :D
SMF spam blocked by CleanTalk