• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] NPC Interaction and Dialogue

Status
Not open for further replies.
Level 15
Joined
Aug 7, 2013
Messages
1,338
Hi,

What is the best way to do NPC interaction, i.e. have a player engage in coversation with an NPC character (merchant, quest giver, etc.)? What feels most natural for a player to do? In RPGS, you usually just face the NPC and press the engagement button (commonly "A").

How about if the player right clicks on the NPC with their hero (is this detectable?) within a certain range.

Then for conversation it would bring up a dialog with a set of buttons, e.g. "Buy", "Sell."

But how would we present information that the NPC gives (e.g. a quest giver) if there is a dialogue open? Do we just make it the title of the dialog, the name of a button that doesn't do anything, etc.?
 
The right-click is detectable. It is the "smart" command. It is definitely one option.

If you can afford it, I prefer an interact button (either through an item, or preferably an ability [easier hotkeys]).

If you have a dialog, then set the title to it. iirc, the dialog title can fit a decent amount of text. I remember playing Runes of Daerk, which used dialogs to display most of the information.

Apart from that, I usually display a game message. You can just cut it into lines so it looks like a paragraph. Try out TKoK. I like their way of doing it. I did a similar thing in a map of mine (it is just a fade filter to act as a "window"/container, and then you just format the text to fit inside).
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
Edit: Ok I did some digging and figured it out.

Here's what my trigger looks like:

JASS:
private function main takes nothing returns boolean
    if GetIssuedOrderId() == OrderId("smart") then
        call DisplayTimedTextToPlayer(Player(0), 0, 0, 10, "pointing to unit:" + GetUnitName(GetOrderTargetUnit()))
    elseif GetIssuedOrderId() == OrderId("patrol") then
        call DisplayTimedTextToPlayer(Player(0), 0, 0, 10, "detected a unit patrolling")
    endif
    return false
endfunction

private function init takes nothing returns nothing
   local trigger t = CreateTrigger()
   call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
   call TriggerAddCondition(t, Condition(function main))
endfunction

Questions:

1. When would I not want to do use TriggerRegisterAnyUnitEventBJ over say TriggeRegisterPlayerUnitEvent ?

2. What gives me the handle on the unit doing the "smart" command? Is it GetTriggeringUnit() ?

3. What is the best way to filter out the unit (e.g. I only want Paladins to be able to trigger this)?

4. What is the best way to make sure the trigger unit is within X distance of the target?
 
Last edited:
1. Usually you would just use TriggerRegisterAnyUnitEventBJ() to simplify the code. However, if you care about conserving handles, then sometimes you'll only want to register the event for players who are actually playing/have "user" slots. Each event is 1 handle, and TriggerRegisterAnyUnitEventBJ() generates 1 for each player (16 total). 16 handles really isn't as big of an issue as it seems, but if you know you only need to register it for certain players, then TriggerRegisterPlayerUnitEvent() might be a better option.

2. Yeah, GetTriggerUnit() will refer to the unit who was issued the order. You can just think of it as the unit who triggered the event.

3. Either (A) add a condition (B) add an if/then/else statement to the actions (or conditions, if you are using the condition function to do the actions). e.g.:
JASS:
if GetUnitTypeId(GetTriggerUnit()) == 'Hpal' then
 // actions
endif

4. This native:
JASS:
constant native IsUnitInRange       takes unit whichUnit, unit otherUnit, real distance returns boolean
 
Status
Not open for further replies.
Top