So has a kyr system been created?

Started by Imc7r, Tue 20/02/2018 16:55:52

Previous topic - Next topic

Imc7r

Hello, I'm new here and to AGS but I did read rules and threads about what made me come here. I'm looking to find if someone has created a template or plug in or anything, something similar to Kyrandia's GUI of single pointer and inventory of up to 10 items (or more items if scrolling is allowed then that too). I did come across threads asking for that but in 2003-2005, I saw this thread but I am not sure if they are after the same kind. I just don't like the LucasArts system with right-click and texts that show you who you can interact with, I want to leave this to the player which is why I liked Kyrandia's system more.

I am asking because versions have changed and it is not clear if doable. Some threads mentioned you can drop objects if you do limit / room, which is fine, anything close to Kyr style. I read you can randomize things in a room, that's something I also will need but for another time.

Please let me know if there is a template or anything that can be used.

More useful links for this:
Script Manual
Day Night transition
Swapping BGs
Disabling Animated Background While wanting to use diff BG each game run
Calculate distance
Inventory Limit
Main Menu Start

P.S Disable room fade in/out from Settings - Visual - Default Transition When Changing Rooms to Instant.
day/night as done by me
Spoiler
Code: ags

bool nightFall;
int durationDayNight[2];
float lightTransparency;
float durationDay;
float durationNight;

//somewhere in starting funct
  if (season == 0 || season == 2) { durationDayNight[0] = 72000; durationDayNight[1] = 46080; } else { durationDayNight[0] = 52560; durationDayNight[1] = 65520; }

function repeatedly_execute_always() {
  
    //Day-Night system
    if (FloatToInt(durationDay, eRoundNearest) < durationDayNight[0] && nightFall == false )
    {
      durationDay++;  
      gNightOverlay.Visible = false;
      lightTransparency = 100.00;
    }
    
    //Calculated if 40 is 1 minute, 1200 is 30 mins for summer day light
    if (FloatToInt(durationDay, eRoundNearest) == durationDayNight[0])
    {
      gNightOverlay.Visible = true;
      
      //0.01 is around 3 mins of transition to full darkness
      lightTransparency = lightTransparency - 0.01;

      if (lightTransparency > 25.0) { gNightOverlay.Transparency = FloatToInt(lightTransparency, eRoundNearest); }
    }
    
    if (gNightOverlay.Transparency == 26)
    {
      durationDay = 0.0;
      durationNight++;
      nightFall = true;
    }
    
    //summer day light is 13 hours, transition 1.3 hours twice, night is 8.4 hrs, the same percentage of 72000 for night is 46080
    //fall day is 9.5 hours, or 52560, again twice 1.3 transition time, night is  11.9 hrs so 65520 for night
    if (FloatToInt(durationNight, eRoundNearest) == durationDayNight[1])
    {
      lightTransparency = lightTransparency + 0.01;
      if (lightTransparency < 100.0) { gNightOverlay.Transparency = FloatToInt(lightTransparency, eRoundNearest); }
    }

    if (gNightOverlay.Transparency == 100 && nightFall == true)
    {
      durationDay++;
      durationNight = 0.0;
      nightFall = false;
    }
  } //this bracket is from the if player room <= 300
}
[close]

Crimson Wizard

#1
Quote from: Imc7r on Tue 20/02/2018 16:55:52
Some threads mentioned you can drop objects if you do limit / room, which is fine, anything close to Kyr style.

I've never seen such template around, but one thing I can say is that in AGS it would be much easier to use Characters for droppable/randomized items on ground, because -
1. Characters are unlimited, while objects are limited 40 per room (and you may have to use these not only for items)
2. Same characters can be moved into any room, and objects are restricted to room they are created in (so you'd have to create objects for dropped items in every room).

Other than that, I believe such system would not be too hard to script.

Snarky

As for the single-pointer UI, you can just use the left-click/right-click template and not use the right-click for anything.

Imc7r

#3
QuoteAs for the single-pointer UI, you can just use the left-click/right-click template and not use the right-click for anything.

Which one is that template? Oh this one

Quote from: Crimson Wizard on Tue 20/02/2018 17:28:54
I've never seen such template around, but one thing I can say is that in AGS it would be much easier to use Characters for droppable/randomized items on ground, because -
1. Characters are unlimited, while objects are limited 40 per room (and you may have to use these not only for items)

Thanks, that's a good workaround that I could use, as long as it also allows putting these characters in an inventory.

Crimson Wizard

#4
Quote from: Imc7r on Tue 20/02/2018 19:53:51
Thanks, that's a good workaround that I could use, as long as it also allows putting these characters in an inventory.

Characters cannot be put in inventory, but Objects cannot be put in the inventory either. In AGS inventory item is a separate entity that only exists in inventory, while room object, or character (or anything else) serve as item's representation in the room.
Common practice is to have an object in the room, which, when picked up, becomes invisible, while inventory item is added to inventory.
With character, you should probably move them to room -1, that's imaginary room which simply means that character is nowhere.

Imc7r

#5
QuoteCharacters cannot be put in inventory, but Objects cannot be put in the inventory either. In AGS inventory item is a separate entity that only exists in inventory, while room object, or character (or anything else) serve as item's representation in the room.
Common practice is to have an object in the room, which, when picked up, becomes invisible, while inventory item is added to inventory.
With character, you should probably move them to room -1, that's imaginary room which simply means that character is nowhere.

Thanks, im making my first tries and a lot more. I have a question about objects, I read that they cannot be created from script, you have to place objects in the room.

What if I placed the max number of Environment objects I want to have and use script to decide if all will be visible and what position. Im trying to generate the rooms with different position of trees and other props for the different rooms but these objects once created should stay the same for those rooms, not change every time the character gets back to them (for the same run of the game).

The plan is, since I even use seasons, if season var is e.g 0 for summer, in the room show/hide (random number between 3 and 5 tree Objects) and position them (in random X,Y  point area). If season is e.g 1, change their sprite from their summer sprites to their e.g autumn sprites. I am using this on pre-placed objects since these cant be created from script. It already works for the ground (room background image) changed based on the random season var.

So the code questions are down to:
- How to scale the objects? (I want to add condition if it is in the upper part (maybe like between Y 0 and Y 200 in 1080p screen) and that is further from the character, I will add code to scale them down as if further)
- Set tint color/opacity again for Background reasons so we dont need a separate sprite for every single difference in distance
- How to change the sprite it uses from the folder if (conditions  are met) from sprite ID whichever to sprite ID whichever? For change of season based sprites.
- Based on where the objects trees etc are (again condition if too above or not) make them front/behind character
- How to hide or position Objects out of the room that will not be displayed)?
- How can I create an object/character that will be used for item and inventory at random room? (my guess would be have a global var that checks if a certain number is met, if yes, create at this room, else, do not create, if it already exists, do not create) - this one I might be able to do at my own but it seems I need to place the items at the rooms I want and hide them since I cant actually SPAWN them with script).


dayowlron

I can answer of few of these:
Scaling objects? You can either create the actual size of the graphic and load it as a separate sprite or put it on its own walkable area and set scaling there. I believe if you do that you also have to change a setting in the object to tell it to "Use Scaling"
Changing the graphic? All you do is set the object's Graphic property to be the new sprite id.
Object in front or behind, just set it's Baseline to be higher on the screen to move it behind other objects, lower to put it in front.
Only way to position or hide objects if you are not in the room is set a variable that will be used to control the object and in the Load function for the room make the adjustments according to the value of that variable.
Creating object in another room you would have to use the idea just mentioned by setting a variable and referencing it in Room_Load.
Creating a Character in another room you can just tell that character to "ChangeRoom".
You are correct that you would have to have the objects in every room that it could be created in and just set its Visible property to be false if it is not supposed to be in that room.
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

Crimson Wizard

#7
Quote from: Imc7r on Mon 26/02/2018 17:21:09
So the code questions are down to:
First thing I want to say, is that some of these questions are easily answered by simply reading a manual, specifically sections dedicated to functions and properties of characters and objects.

Quote from: Imc7r on Mon 26/02/2018 17:21:09
- Set tint color/opacity again for Background reasons so we dont need a separate sprite for every single difference in distance
Object has Tint function and Transparency property. Also there is SetAmbientTint function for everything on screen.
Alternatively, you may use GUI with certain background color and adjusted Transparency property used as a graphical overlay.

Quote from: Imc7r on Mon 26/02/2018 17:21:09
- How to change the sprite it uses from the folder if (conditions  are met) from sprite ID whichever to sprite ID whichever? For change of season based sprites.
Object.Graphic property.

Quote from: Imc7r on Mon 26/02/2018 17:21:09
- Based on where the objects trees etc are (again condition if too above or not) make them front/behind character
This is done automatically in AGS. If automatic result does not match desired one, use Object.Baseline property.

Quote from: Imc7r on Mon 26/02/2018 17:21:09
- How to hide or position Objects out of the room that will not be displayed)?
Object.Visible property.

Quote from: Imc7r on Mon 26/02/2018 17:21:09
- How to scale the objects? (I want to add condition if it is in the upper part (maybe like between Y 0 and Y 200 in 1080p screen) and that is further from the character, I will add code to scale them down as if further)
This is suddenly not simple.
The usual method of scaling things in AGS is to set up scaling properties of a walkable area these things are put on. Alternatively (and if you cannot have them on walkable area), characters may have individual scaling (properties are called ManualScaling and Scaling).
In your case, you probably won't be able to use walkable area scaling for trees, because you won't want characters to be able to walk there. Well, you may try, and also set "Solid" property for these objects to block character, but idk if that will work well.
What I suddenly realized, I've never paid attention to this fact, Objects do not have individual scaling for some reason. Probably engine author forgot to add this.
The only remaining solution I know is to use something called DynamicSprites. It works like this: you declare a number of DynamicSprite variables in the room, clone existing sprites into them, resized up or down, then apply DynamicSprite's ID to Object.Graphic. This sounds a bit complicated, but not overly difficult in practice.


Quote from: Imc7r on Mon 26/02/2018 17:21:09
- How can I create an object/character that will be used for item and inventory at random room? (my guess would be have a global var that checks if a certain number is met, if yes, create at this room, else, do not create, if it already exists, do not create) - this one I might be able to do at my own but it seems I need to place the items at the rooms I want and hide them since I cant actually SPAWN them with script).

My suggestion is this:
* Create a large number of dummy characters in your game (their quantity depends on how many items you want to allow in one room, but you may always add more).
* Create a global array of Character* pointers in global script, fill this array with dummy characters at game start, and use it as a "entity pool" to get available dummy characters for representing items lying in the rooms.
* You would need to save information about what items are lying on ground. Probably you will need some kind of item ID and coordinates.
* Upon entering a room, scan through this information and set up dummy characters, assigning them the appropriate looks.
* You may do this in every room, of course, but that may become tideous and require lots of copies of similar code, which is very bad. Much better, IMO, is to code a universal script module that would handle this task independent of room. There is a special built-in function callback in AGS called on_event, which is called in events like eEventEnterRoomBeforeFadein and eEventLeaveRoom, you may use it to run this script.

Imc7r

#8
Thanks for the detailed explanation and answers from the above posters, I will now deal with this one by one.

Quote from: Crimson Wizard on Mon 26/02/2018 18:22:12
The only remaining solution I know is to use something called DynamicSprites. It works like this: you declare a number of DynamicSprite variables in the room, clone existing sprites into them, resized up or down, then apply DynamicSprite's ID to Object.Graphic. This sounds a bit complicated, but not overly difficult in practice.

I read your post here about dynamic sprites and I also read in the manual that there are some functions for creating image and im not very sure if it has to be like in your post there.

What I did was created an object in the room, assigned a transparent image almost as big as the entire room, and this is where the images (dynamic sprites) would be drawn (trees and other props).

So how can I draw them in a way that they will remain so when the character reenters the room they will not change? Should it be in the global script ? It has to be generated once for every room for that game run and unless a new game is started they should remain as they are created once. Then I can probably change color, resize as I read that you can do this with the dynamic sprites drawn on object and changing baseline.

It's not clear how where the ID of the image i want to draw goes

Code: ags
// room script file

DynamicSprite * EnvironmentProps;

function Start() {
     

  
  EnvironmentProps = DynamicSprite.Create(Room.Width, Room.Height);
  DrawingSurface * EnvironmentPropsSurface = EnvironmentProps.GetDrawingSurface();
  EnvironmentPropsSurface.DrawImage (0, 0, 292);
  EnvironmentPropsSurface.Release ();
  ObjForDynamicSprite.Graphic = EnvironmentProps.Graphic; //arent Graphic supposed to be IDs of sprites?
  
}

Crimson Wizard

#9
Well, your code example is generally correct, but there are couple of things I need to mention.

First of all, if you have several "layers" of props at different distances, and characters or moving objects are allowed to move between these layers (i.e.: some trees are at background, and some are on foreground or in the middle of the room), then you cannot use only 1 dynamic sprite. You will have to use at least 1 dynamic sprite per layer. If trees are separated apart, then maybe even 1 dynamic sprite per tree, but that's rather a question of optimization.

Quote from: Imc7r on Mon 05/03/2018 12:18:32
So how can I draw them in a way that they will remain so when the character reenters the room they will not change? Should it be in the global script ? It has to be generated once for every room for that game run and unless a new game is started they should remain as they are created once.

If you declare DynamicSprite in the room script it will stay there forever, keeping the stuff you drawn upon it, just like all the room objects remain on the places you told them to be when you leave and return to the room.

This is good, but may cause problems as well if you have a lot of rooms with generated props like that. Because, obviously, all those images will be kept in computer memory. If this ever becomes an issue, you could just do following:
* recreate these "layers" every time in "room_Load" event.
* delete them in "room_Leave" event.

The latter approach may even be used to have limited number of rooms simulating larger number of areas. What I mean is that in theory you may even have only few rooms used to depict a large number of random locations, regenerated every time player enters it. This is how "random mazes" may be implemented in a game.
There could be complications with walkable areas, because different locations may require different paths, but that could be solved by creating a combination of areas and turning them on and off as room is generated on load.


Quote from: Imc7r on Mon 05/03/2018 12:18:32
It's not clear how where the ID of the image i want to draw goes
You did correct, Graphic property holds ID of image, both in Object class and DynamicSprite class. Object.Graphic is an id of an image this object should have, and DynamicSprite.Graphic is an ID this dynamic sprite was assigned.

Imc7r

Well, a sprite never creates.

Code: ags
DynamicSprite * EnvProp1;
DrawingSurface *EnvPropSurface1;


function Start() {
  
  EnvProp1 = DynamicSprite.Create(Room.Width, Room.Height);
  EnvPropSurface1 = Room.GetDrawingSurfaceForBackground();
  EnvPropSurface1.DrawImage(0, 0, 19); //19 is the ID im trying to display
  ObjForDynamicSprite.Graphic = EnvProp1.Graphic; //should it remain "Graphic" here? Otherwise error compiling
  //EnvPropSurface1.Release();
  //EnvProp1.Delete();
  
}


I don't see anything.

Crimson Wizard

#11
Is this literally the full contents of your room script? Function Start() won't be run automatically, it should be explicitly called from somewhere, or connected to a room event on the room properties panel.

EDIT: wait, I just realized you modified the code.
This was correct:
Code: ags

DrawingSurface * EnvironmentPropsSurface = EnvironmentProps.GetDrawingSurface();

Now it changed to this, which is incorrect:
Code: ags

EnvPropSurface1 = Room.GetDrawingSurfaceForBackground();


Instead of drawing on dynamic sprite, you are now drawing on room background? Or you were just experimenting?

Note, that you do not have to (and better not at all) keep DrawingSurface as a global variable. It is enough to create it for the time of drawing, and release as soon as you finished drawing. calling Release() for the DrawingSurface it is a rule of thumb, because it ensures that image actually gets updated (it may not update in some circumsances if you forget to release surface).

Snarky

You're drawing to EnvPropSurface1, but that's not connected to EnvProp1, the dynamic sprite you're assigning to the object.

Also, you need to release the drawing surface before displaying it.

Imc7r

The room script runs immediately when it is started by the character right? If so, I added a function to run it:

QuoteDrawingSurface * EnvironmentPropsSurface = EnvironmentProps.GetDrawingSurface();

I correct this, thanks now it's like that

Code: ags
// room script file
DynamicSprite * EnvProp1;


function Start() {
  
  EnvProp1 = DynamicSprite.Create(Room.Width, Room.Height);
  DrawingSurface * EnvPropSurface1 = EnvProp1.GetDrawingSurface();
  EnvPropSurface1.DrawImage(0, 0, 19);
  ObjForDynamicSprite.Graphic = EnvProp1.Graphic;
  EnvPropSurface1.Release();
  //EnvProp1.Delete();
   
}

function startRoom() {
     
  Start();
   
}



As for this:

QuoteYou're drawing to EnvPropSurface1, but that's not connected to EnvProp1, the dynamic sprite you're assigning to the object.

Umm sorry how can I do that? I added blindly this definition EnvPropSurface1 and the one for the dynamic sprite EnvProp1 and the name of my object in the  room with transparent image is named 'ObjForDynamicSprite'

Crimson Wizard

#14
Quote from: Imc7r on Mon 05/03/2018 17:25:58
The room script runs immediately when it is started by the character right? If so, I added a function to run it:

No, sorry, it looks like you do not know the basics of how the room script works in AGS.
Have you tried doing some tutorials first?

The script function won't be run automatically if you just put it in the script. There are number of functions with predefined names, such as "game_start" or "on_key_press", these are run by the engine if found, but for room entering and leaving you must connect your functions to the events table. This is done in the room editor, there is a panel on the bottom-right by default, where you set up properties and events.

Imc7r

Well I started with some video that is 101 but it didn't mention that and it was likely to have gaps of even basics ^.^. But now that you showed this, I clicked to on the lightning and before-fade-in function room_Load put my code there and the sprite appeared also the EnvProp1 = DynamicSprite.Create(Room.Width, Room.Height, true); to make my png really transparent, thanks! I will try to repeat this with other objects to place them at different areas.

Khris

#16
How to create event handler functions is described in part 3 of the tutorial: http://www.adventuregamestudio.co.uk/manual/acintro3.htm
The tutorial section of the manual is mandatory reading before posting here, to avoid wasting time.

I'm referring to this: http://www.adventuregamestudio.co.uk/forums/index.php?topic=14373.0

Snarky

Well, it's a very useful read, anyway. ;)

Imc7r

#18
Can anyone tell me if I can do the script replacing the object name withing ObjectIDForScript with a string variable? Yes I have read the things about these vars.

Code: ags
ObjForDynamicSprite0.Graphic = EnvProp[i].Graphic;


It is because I repeat this for several objects in a While loop and all objects are called ObjForDynamicSprite0, ObjForDynamicSprite1, ObjForDynamicSprite5, etc. So im trying to combine string (same name + i where i is the increasing increment) but since it is ObjectIDforScript.Graphic im not sure if it can be read, I do like this:



Snarky

You can't do that. A variable name is just a label for the programmer: when the program is compiled the name is thrown away and you're just left with a particular memory location. Therefore you can't do any program logic on a variable name.

This sort of task is usually solved by using pointers and/or arrays. I can't give a more precise answer because I'm not sure exactly what you're trying to do.

SMF spam blocked by CleanTalk