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

#101
Quote from: shakume on Sat 15/07/2023 09:02:44Edited to add a link to a quick sketch of what I'm thinking:

OK, so given that description and sketch, I wouldn't use the AGS dialog system for the combat. The UI is too different, for one thing.

The way I would write it, I would have a struct that stores all the details for a boss:

-The name of the boss, any related graphics you need to display
-What the dialog options are in each round (for example as four string arrays, one for each button—or six if you have a third unlockable option for each character)
-What the outcome of each dialog option is, i.e. the effect on HP and any kind of comeback or response the boss has—either a dialog response or animation (if the outcome depends on the combination of Char 1 and Char 2's options, it gets more complicated, but still doable)
-The win condition for this boss

I would make an array of this struct, with one entry for each boss in the game. Then you need to initialize it: set it up with all the data for each boss. You'd normally do this as a function that gets called at game startup.

I would have some variables to store the current state of the combat (which boss you're currently "fighting", the current round, how many hitpoints the boss currently has, whether you have used the special combi option already, etc.; to keep things organized I would add all these variables to a struct, but that's more a personal preference than an architectural requirement), and then I would have a function that does the combat logic: based on the dialog options chosen and the data in the current boss's struct, update the state of the combat. I would also have functions to do whatever the feedback to the player should be (e.g. play animation/music), and to set up the screen appropriately (show the boss's NPC pic, fill in the right text in the option buttons, etc.). Also a function to start the combat and one to end it. Finally you just hook up the button handlers to run these functions when appropriate.

Oh, and about the graphics: I would strongly recommend you make a View for each boss, set up the same way for all of them. That way, you can just save which view to use for each boss (as part of its struct), and then use the same code to display different expressions, animations, etc. (Or if the bosses are already characters, you could use their Normal or Speech view, and just save a pointer to the character in the struct.)

Essentially, this is more like a combat system than a dialog system, so you can search for any posts that explain how to code a combat/battle system.
#102
Welcome!

You can certainly implement something like this in AGS, and it doesn't sound like it would be too difficult in principle.

Of course, when you hear "dialog-based combat" in an adventure game, everyone immediately thinks of insult swordfighting, and this sounds potentially quite similar, except with explicit HP (rather than the implicit advance/retreat score of insult swordfighting).

The big decision, as I see it, is whether to build it on top of the existing dialog system, or outside of that. I think that depends on exactly how the dialogs fit together, which you didn't really explain.

Like, are the dialog options static? Do they depend on what has been said earlier in the dialog? Can the same dialog option be used more than once? Do the options change depending on what kind of skills (or equipment, etc.) your character has, or do you need to unlock them somehow? How many possible options are there in total, and how many will you have to choose from each time? (All of them?) Is there a random component at all?
#103
The Rumpus Room / Re: What grinds my gears!
Fri 14/07/2023 14:57:20
That English has two verbs, "to rifle" and "to riffle," with, in some situations, very similar yet definitely distinct meanings:

rifle,
v. tr.
1. To search (an area or container, for example) thoroughly, especially using the hands with the intent to steal or remove something: rifled the desk, looking for the keys.
v. intr.
To search vigorously: rifling through my drawers to find matching socks.

Synonyms: search, comb, hunt, rummage, scour, rake

riffle
v. tr.
1. to flip hastily with the fingers; flutter: to riffle papers.
v. intr.
1. (often followed by through) to flick rapidly through (the pages of a book, magazine, etc), especially in a desultory manner: riffle through the catalog.

So if you are looking for something in a book you can rifle through it or you can riffle through it, and the difference is how energetic you are about it.
#104
Quote from: Stupot on Thu 13/07/2023 21:48:41
QuoteWas the mug already in the microwave because you had already microwaved it earlier too?
[close]
This was my immediate guess too but it seems a bit too obvious for its own forum thread.

I suppose it's a bit more obvious when posed as a mystery, particularly as I was obliged to mention the microwave (and no other places), since if it had turned out to be on the coffee table behind some clutter, it wouldn't really be a story.

Quote from: Ponch on Fri 14/07/2023 13:33:49Now that I'm 50, I have moments in my life like these more often than I'd like to admit.  :embarrassed:

At least I'm learning more and more where my things usually are if I misplace them. Anything I keep in my pockets is either in the pockets of another pair of trousers, or if I drove a car recently, I either took it out or it fell out there. Electronic gizmos are irresistibly drawn towards a certain drawer, where they camouflage themselves among their kind.

I'm still looking for the keys to my lockbox, though. The problem is that I hid them somewhere clever, and I have no idea where that might be.
#105
Well, you got it a lot quicker than I did, that's for sure! Yes, that's exactly what happened.

I looked everywhere for it. I checked bookshelves and window sills. I checked inside cupboards and wardrobes. I checked in the bathroom. I checked under chairs. I checked inside the fridge. Finally I gave up and got another mug, poured myself a cup and opened the microwave oven to put it inside...
#106
So, this isn't quite a Black Stories mystery, but a true-life tale that happened to me the other day and had me stumped for at least half an hour, and I thought it might be fun to see if you could solve it.

The Case
The other day I thought I'd make a pot of tea. (Since the pandemic I've switched from teabags to proper brewing of loose-leaf tea in a pot, though with a kind of wire basket to retrieve the leaves afterward.) But when I took the lid off the pot I discovered I had already made one earlier, which was now cold. I decided to just heat up a cup in the microwave—I know some people find reheating to be a crime against tea, but I honestly think it tastes just fine.

So I looked around for my favorite tea mug, but I couldn't find it.

Where was it?

(Ask me any such questions as might help, or propose places to look for it.)
#107
The Dialog Designer tool/plugin lets you reorder dialog options.

I haven't ever written any extensive dialogs in AGS, but to me it has always seemed like a must-have tool, that should really be distributed with AGS by default.
#108
The ID property is the array index of the character[] array. Meaning that if cSnarky.ID == 5, then a pointer to cSnarky is stored in position 5 in the character[] array, so that it can also be accessed as character[5].
#109
Yeah, the way running games from the editor works (in terms of which files/folders it references) is complex and confusing. Glad you found the reason for your problem!
#110
Are you running the game with F5 through the editor, or running the exe directly?
#111
To me it seems that a lot of the negative sides of AI being discussed are really general problems of capitalism, rather than something specific to the technology.
#112
Hot take: This is why Character.Think shouldn't exist in the first place.
#113
This looks great! I really like your treatment of the reeds, with the dash of purple, and also the gravel.

When it comes to the left-hand side, that's the sort of question for which I would consult photo reference. I think it's very important, because what you choose to put there will color how the whole landscape is perceived. If you put sheep or cattle or a barn or something, the whole thing will look like farmland (or at least grazing land). Personally I think the atmosphere is towards desolation (with that immense line of straight railroad disappearing in the distance), so I would try something that makes it look more like marshy moorland, e.g. tufts of heather or shrubs, or perhaps a small scree or patch of sand.

I think Ben (304) is right that you should break up the horizon a little, but IMO you should go a little more subtle, since the flatness of the landscape seems to be a point of the composition.

Personally, the bit that doesn't work for me is the sky. First, the clouds all line up against the edges, giving the impression that they are hemmed in by the 2D frame rather than existing in a 3D reality. (I see Matti also posted about this while I was writing.) The easy fix is to make some clouds be cut off by the edge.

Second, I feel that the sky and the ground don't entirely match. The dark coloring, soft shadows and lack of bright highlights on ground objects gives the impression of a somewhat dreary, overcast day, but you have a bright blue sky with only relatively distant clouds (which also don't seem to cast any shadows on the ground). I think if you replaced it with a gray sky, or at least toned it down to a hazier look, it would fit better. (I would also make particularly the more distant pond less blue, more gray, and note that at low angles, the notable thing about water surfaces is often their brightness against other terrain.)
#114
The problem is that you're missing the speed parameter, so the eNoBlock gets interpreted as the speed, and then eAnywhere gets interpreted as the blocking parameter, and is an illegal value for it.

For this kind of error, you should consult the built-in help. There's a quick-help tooltip when you edit the parameters or hover the mouse over the function that tells you the right format, or if you press F1 it should bring you to the relevant article in the manual.
#115
I suppose I should share the module I made here.

In implementing it, I realized a few things:

While the logic to calculate the line width of LucasArts speech is relatively simple, the calculations for Sierra speech are far more complicated, depending both on Text Window settings and on the speaking character's Speech View. There are also a lot of different configuration settings and other properties that affect how text is displayed, so replicating the full logic would indeed be pretty complicated. I've taken a simpler approach of automatically calculating it for LucasArts speech, but just allowing users to set it as a static value for Sierra speech.

There are a few subtleties with "[" and "\n". The first is that if the player enters text via a TextBox, "\n" is not converted to a LF character, but remains a backslash-n sequence in the String (like when you escape it in Strings in the editor), and is displayed as such. (This is probably correct behavior for most normal purposes.) However, AGS still interprets a "[" entered in a TextBox as a linebreak for most String display purposes, so there is arguably some inconsistency there.

The second is that not all AGS controls allow linebreaks in Strings, and those that don't (Buttons, TextBoxes and ListBoxes, IIRC) treat "\n" and "[" differently. These controls render "[" normally as an open-square-bracket, while a "\n" (i.e., LF character) is ignored or turned into a space (I forget which).

Finally, the linewrapping code should check for the escape sequence "\[" that AGS uses to actually display an open-square-bracket, so that it doesn't incorrectly interpret this as a linebreak. The current version of the module does not correctly deal with this in RTL mode.
#116
I don't think there is any way to freeze the game in exactly the same way that Display() does (which is a "harder" pause than the other blocks in AGS), but it should be possible to make it wait in the same way as speech does, by... actually playing it as a speech line in that case:

Code: ags
  if(Speech.VoiceMode == eSpeechVoiceOnly && IsSpeechVoxAvailable())
    cNar.Say(String.Format("&%d",cue));
#117
I think this check is also necessary even if you do have a voice clip, in case the player doesn't click away the Display box until the clip has already finished playing.

Edit: No, I forgot that AudioChannels are persistent, and that if you get back a valid pointer, it will never turn into a null.
#118
In the mean time, you can use this function to reverse a String:

Code: ags
String Reverse(this String*)
{
  String reverse = "";
  for(int i=this.Length-1; i>=0; i--)
  {
    reverse = reverse.AppendChar(this.Chars[i]);
  }
  return reverse;
}

You call it like:

Code: ags
  myButton.Text = myString.Reverse();
  // ... Or if that doesn't work:
  String transString = GetTranslation(myString);
  myButton.Text = transString.Reverse();

(Untested, so let me know if you have any problems with it. The results may be unexpected if the String contains linebreaks.)
#119
Welcome!

This is not super-easy to do in AGS. (Though recent improvements have made it easier—I'll assume you're using the latest version of AGS, 3.6) You will have to write your own custom Say function that handles the display of the text and then waits to proceed until the line of dialog is over.

There are two basic alternative approaches:

1. Write something completely from scratch, probably using a GUI and a couple of labels to display the text (but you can also render it yourself as an Overlay), and one of the Wait functions (probably WaitInput) to pause while the dialog is displayed.
2. Write a helper function "around" a normal Say call (or more likely SayAt, to position the text): in this helper function you display the dialog box background and the speaker name, call SayAt (which then displays the text on top of the box), and once SayAt completes, removes the dialog box and name.

Which approach is easiest depends on a number of other factors. Will you have animated speech views? Will you have voiced speech? If so, will you have lip-sync? Should the text auto-advance after some period (depending on the length of the text, or on the length of the voice clip if you use voiced speech). Do you want a "typewriter" effect where the text appears letter by letter? Basically, the more of the features offered by the standard Say functionality you want—speech animation, voice, auto-advance, lipsync—the more it makes sense to build on top of the built-in functions, so you don't have to reimplement it yourself. While on the other hand if you need to dynamically manipulate the text, such as for typewriter animation, it probably makes more sense to build it from scratch.

My SpeechBubble module, although it doesn't allow you to set up this particular format, provides an example of how you can display speech in a different format (with things like different background colors for different characters). I'll also refer you to this post, which explains how you would do something similar using the second approach (a helper function).

Good luck!
#120
I think it's worth pointing out that in the example shown, the easiest solution is to pad out the background with a black bar on top so that it's 320x200.
SMF spam blocked by CleanTalk