• New Horizons on Maelstrom
    Maelstrom New Horizons


    Visit our website www.piratehorizons.com to quickly find download links for the newest versions of our New Horizons mods Beyond New Horizons and Maelstrom New Horizons!

trying to improve dialog writing

You can use the "d" shortcut reference, but you need to declare that it stands for the "Dialog" object at the top of the script (see above).
 
Is d.text something that doesn't work at all? Because I must have copied that from somewhere...
It works if you have these 2 things at the start of the dialog.c file:

Code:
ref NPChar, d;

makeref(d, Dialog);

I use only dialog.txt in my quest dialog files to make it less complicated.
 
Good point. :yes (My focus is clearly not what it used to be. :facepalm)

Nothing to do with NPChar per se (even though Dialog is technically a child of NPChar), rather:

Declare reference variable:
Code:
ref d;

Assign the new variable to the Dialog object:
Code:
makeref(d, Dialog);

The variable's name could be anything you like (e.g. "dg"). The point is that it is referencing the Dialog object.

Therefore "d.Text" is the same as "Dialog.Text", once this is set up -- or you can just use "Dialog.Text" directly instead. I agree with Jack, I prefer this as well -- more uniform and clearer to read. Not convinced that the shortcut is truly worth the trouble. But at least now you know how to create quick-shortcut references to specific objects and their attributes.
 
Last edited:
The variable's name could be anything you like (e.g. "dg").
Actually, I may be wrong about this, too. :facepalm

"ref d" may not be a new declaration so much as passing the already existing "d" global variable to this script, so that it can be used here. I'm not entirely sure (yet) what "d" exactly is on the global scale in the code (i.e. where it is defined).

To declare a new variable for your script, use "string myname" for a variable containing text and "int myname" for a variable containing whole numbers.

For example:
Code:
string Bob;

Bob = "Bob Snider";

int MyNum;

MyNum = 1;
 
Last edited:
I've got another question.

In the dialogue structure for tavern keepers, there's the case "quests" where you talk to him about business. Apart from the escort ship option and the "I want to talk about something else" option, there are always various lines, dependant on you being at the right point of a quest. Makes sense, there are the options to ask him about animists or Nigel Blythe or whatever, for when you're in that quest and need info from the tavern keeper.

They look like this: (2 examples)

if (CheckQuestAttribute("ANIMISTS", "to_muelle_for_rumors"))
{
link.l3 = DLG_TEXT[39];
link.l3.go = "to_muelle_for_rumors";
}

(------------------------)
if (CheckQuestAttribute("nigel_away_for_ship", "begin"))
{
link.l4 = DLG_TEXT[40];
link.l4.go = "nigel_away_for_ship";
}

Now, if I want to add a question for the tavern keeper at this point myself, I don't understand exactly how to work with that CheckQuestAttribute. In my examples, what does "ANIMISTS", "begin" etc. mean, how is that defined? I tried to do it as follows: In another dialogue AddDialogexitQuest("example"); then the case "example" in quest.reaction and last in the tavern keeper dialogue if (CheckQuestAttribute("example")). Doesn't work, the line doesn't show up.

For clarification: The whole tavern keeper stuff is just an example, I basically just need to know how to tie the availability of a line of dialogue to a certain condition.
 
Okay, I see what's wrong:
This needs to be:
Code:
#include "DIALOGS\Ramon Cabrera_dialog.h"
True for the original game.
The mod automatically loads the relevant .h files though, which is why those first lines are all commented out.

First thing I'd suggest to see what's in error.log in your main game folder.

It could be that there is a barely visible error inside the .h file.
For example, one line that doesn't have a comma at the end.

Dialog files are loaded completely on-the-fly.
So you can keep the game running in windowed mode and Alt+Tab back and forth trying different things.
That makes trial and error a lot quicker than having to close the game after every change.

Now, if I want to add a question for the tavern keeper at this point myself, I don't understand exactly how to work with that CheckQuestAttribute.
That function reads the PChar.quests.(yourname) attribute.
It's independent from the quest case names in the reaction file.
 
Somewhere this has been set:
Code:
pchar.quest.ANIMISTS = "to_muelle_for_rumors";

this line
Code:
if (CheckQuestAttribute("ANIMISTS", "to_muelle_for_rumors"))
just checks if that is the case. And makes something new happen.

the first line can be set to many different things. Depending on your quest progress. Example of two other ones:
Code:
pchar.quest.ANIMISTS = "to_greenford";
pchar.quest.ANIMISTS = "to_greenford_2";

So you change the status of ANIMISTS (in this case) along the way.

This is very useful when making quests.
 
That function reads the PChar.quests.(yourname) attribute.
It's independent from the quest case names in the reaction file.

So you change the status of ANIMISTS (in this case) along the way.
Okay, thanks, I got it!

I was totally wondering where (in this example) that "title" ANIMISTS for the quest line comes from. But I did it just like in JRH's first two lines and it worked perfectly. Seems like the "quest title" like ANIMISTS is more a placeholder and can be set however I want. It works anyway...
 
Seems like the "quest title" like ANIMISTS is more a placeholder and can be set however I want. It works anyway...
In actual C programming, you would need to pre-define/declare the variables that hold your data inside the "quest" object, but the Storm Engine's interpreter is more lenient. You can declare/create any new variable for the object simply by setting it:
Code:
PChar.Quest.mysetting = "myvalue";
As you can see, another thing that the interpreter is lenient with is in the lettercasing with object naming. Both capital and lowercase lettering will be equally understood, but try to keep your coding the same just for best practice. Outside of POTC, in actual C programming, "var", "Var", and "VAR" will be understood as different objects/variables.
 
Last edited:
Next question :ahoy (You have all been VERY helpful!)

I want pchar when he enters a location to walk towards an NPC sitting (HuberType) in the back and automatically talk to him.

That's my code so far:

Code:
                case "told_about_alonso":
            RemovePassenger(Pchar, characterFromID("Ramon Cabrera"));
            RemoveOfficersIndex(pchar, GetCharacterIndex("Ramon Cabrera"));
            ChangeCharacterAddressGroup(characterFromID("Ramon Cabrera"), "Muelle04_HouseInsideR6", "goto", "goto3");
            LAi_SetStayType(characterFromID("Ramon Cabrera"));
            Characters[GetCharacterIndex("Baltasar Alonso")].Dialog.CurrentNode = "houseb_1";
            Pchar.quest.To_Baltasar_Housetalk.win_condition.l1 = "location";
            Pchar.quest.To_Baltasar_Housetalk.win_condition.l1.location = "Muelle04_HouseInsideR6";
            Pchar.quest.To_Baltasar_Housetalk.win_condition = "Baltasar_Housetalk";
        break;

                case "Baltasar_Housetalk":
            LAi_SetActorType(Pchar);
            LAi_SetActorType(characterFromID("Baltasar Alonso"));
            LAi_ActorFollow(pchar, characterFromID("Baltasar Alonso"), "Baltasar_Housetalk_2", 1.0);
            //LAi_ActorFollow(characterFromID("Baltasar Alonso"), pchar, "Baltasar_Housetalk_2", 1.0);
        break;
        
        case "Baltasar_Housetalk_2":
            LAi_ActorWaitDialog(Pchar, characterFromID("Baltasar Alonso"));
            LAi_ActorDialog(characterFromID("Baltasar Alonso"), Pchar, "", 5.0, 0);
        break;

What happens is: Pchar keeps standing right at the door and can't be moved (because right now he's still ActorType). The correct dialogue starts after a few seconds.

In the middle case I've commented out a line because I didn't know which of the two makes Pchar walk to NPC (NPC must keep sitting in his chair and I copied the code from a case where both walk towards each other) so I tried both seperately with the same result.

Also does setting the NPC to ActorType break him sitting in the chair as HuberType? I can't really see what happens in the house, because Pchar stays right at the door after entering.

(I might be on to something, with your help I have now about one third of a medium-sized quest already…)
 
You could add a check like my suggested logit to see if that case is read at all.
Code:
  case "Baltasar_Housetalk":
Logit("Baltasar_Housetalk");
            LAi_SetActorType(Pchar);
            LAi_SetActorType(characterFromID("Baltasar Alonso"));
            LAi_ActorFollow(pchar, characterFromID("Baltasar Alonso"), "Baltasar_Housetalk_2", 1.0);
            //LAi_ActorFollow(characterFromID("Baltasar Alonso"), pchar, "Baltasar_Housetalk_2", 1.0);
        break;

If it is, then something is wrong inside it. If not read you have to go back
and maybe move the block below to an earlier case. (If possible) This helps sometimes when these blocks don't do anything.

Code:
  Pchar.quest.To_Baltasar_Housetalk.win_condition.l1 = "location";
            Pchar.quest.To_Baltasar_Housetalk.win_condition.l1.location = "Muelle04_HouseInsideR6";
            Pchar.quest.To_Baltasar_Housetalk.win_condition = "Baltasar_Housetalk";
 
I'll try that. Can you clarify which of those two lines

Code:
LAi_ActorFollow(pchar, characterFromID("Baltasar Alonso"), "Baltasar_Housetalk_2", 1.0);
LAi_ActorFollow(characterFromID("Baltasar Alonso"), pchar, "Baltasar_Housetalk_2", 1.0);

makes the pchar walk to the NPC?

Edit: Sadly I couldn't solve it yet. With Logit I can't even start the game and when I move those lines to an earlier case it switches to ActorType later, but doesn't initiate the walk.

The ActorFollow must be the problem, that's the thing that's missing. Everything else works as intended. But the Player character doesn't walk to Alonso.
 
Last edited:
I have never used the LAi_ActorFollow so I can't say. But you only have two to choose between.
I wonder about the 1.0 sec in LAi_ActorFollow. Found the function and it's a timeout. Maybe it's just too short?
Make it 5.0 and see...

Put this in instead of the Logit:
Code:
PlaySound("OBJECTS\VOICES\DEAD\male\dead1.wav");
It should give a "oh oh" sound.
 
I'm not certain that you can use LAi_ActorFollow directly on a player character. Wouldn't you need to create an NPC copy of the player's character for the cutscene (because essentially that's what you're creating here, a short cutscene)?

Every time you take control of the player character, you take the player out of the game. Any valid reason why you're forcing the player to automatically walk to this NPC, and not just letting them walk to the NPC on their own?
 
I wonder about the 1.0 sec in LAi_ActorFollow. Found the function and it's a timeout. Maybe it's just too short?
Make it 5.0 and see...
I'll try that tomorrow! I was already noticing that timeout is different, in some cases it's 2.0, then it's 1.0...

Any valid reason why you're forcing the player to automatically walk to this NPC, and not just letting them walk to the NPC on their own?
Mostly cosmetic reasons. Makes it more of a nice cutscene as you say. Also there are three people in the room, but it would be much easier if the player just talked to the "correct" one first. Not so many eventualities. In stock PotC that tactic was used many times. Not quite sure about the newly modded storyline (JRH didn't use it in his two like he said), but in the standard it was used often and I'm rather sure it does use SetActor on the player and not the NPC copy thing...
 
In stock PotC that tactic was used many times. Not quite sure about the newly modded storyline (JRH didn't use it in his two like he said), but in the standard it was used often and I'm rather sure it does use SetActor on the player and not the NPC copy thing...
If that's the case, why not also look into how this was handled in the stock game before? The scripts are there and accessible. :) If you remember which NPC or event these cutscenes took place in, you can find the relevant scripts for them, and see how moving the player character was handled (among many other useful things you will likely pick up).

If this movement is something that existed in stock POTC, it should be quite easy to study and learn. :popcorn:

As for the use of cutscenes in video games in general, I would only use them if there was no way of telling the story using interactive player action. Cutscenes tend to distract from the gameplay experience -- to take you out of the imaginative personal story you were living.

If I can, unless used as a stylistic introduction or as a reward outro, I'll go the whole level/game without them. Everything that's done in simple cutscenes can be turned into actual gameplay -- and that makes it all the more interesting! :dance

In this instance, for example, you could have the NPC call out and wave to the player as they enter the area/room/tavern. That would make it clearly obvious where they need to go without taking them out of the game. And the one-on-one interaction would make it immersive.

Or if it's a secret meeting, you could make the NPC wear something noteworthy agreed upon and/or behave in a particular, agreed way -- so that the player searching for them can spot them.

You could also do a visual introduction by showing the NPC up-close first as the player enters the room, and then zooming out to the whole room, and handing control back to the player.

Many-many interesting interactive options that don't involve a fixed, standard cutscene sequence.
 
Last edited:
It should give a "oh oh" sound.
That worked… I also played around with the numbers but the result hasn't changed significantly.

If that's the case, why not also look into how this was handled in the stock game before?
Of course, but I can't blame the game that it still doesn't work. Those cases may have different distances and often let both characters walk towards each other etc. For this case I'd just like the have the short autowalk to initiate the dialogue. Anyway I let it be for the moment and continue without it. But I still hope there's solution (actually there must be).
 
Of course, but I can't blame the game that it still doesn't work. Those cases may have different distances and often let both characters walk towards each other etc. For this case I'd just like the have the short autowalk to initiate the dialogue. Anyway I let it be for the moment and continue without it. But I still hope there's solution (actually there must be).
One thing that comes to mind that may not be so obvious at first is that the game's maps/levels have waypoints for where NPCs can walk. If there is no waypoint between the player and the NPC you're directing them to walk to (or beyond) in the currently situated area, they may not walk at all.

The game is not treating waypoints on a strict basis (characters don't have to walk exactly to the waypoints and on designated paths), but a complete absence of waypoints can lead to the NPC AI considering that area off limits to walking -- this would be very much logical.
 
Last edited:
Back
Top