Package games.stendhal.server.entity.npc
Class SpeakerNPC
java.lang.Object
- All Implemented Interfaces:
Killer
,Cloneable
,Iterable<String>
,Serializable
- Direct Known Subclasses:
AssassinRepairerAdder.AssassinRepairer
,CroupierNPC
,GhostNPCBase
,MarketManagerNPC
,RatKidsNPCBase
,ScriptingNPC
,SheepBuyerNPC.SheepBuyerSpeakerNPC
,TrainingArea.TrainerNPC
This is a finite state machine that implements a chat system. See:
https://en.wikipedia.org/wiki/Finite_state_machine In fact, it is a
transducer.
States are denoted by the enum ConversationStates. Input is the text
that the player says to the SpeakerNPC. Output is the text that the
SpeakerNPC answers.
See examples to understand how it works.
RULES:
State IDLE is both the start state and the state that will end the
conversation between the player and the SpeakerNPC.
State ATTENDING is the state where only one player can talk to NPC
and where the prior talk doesn't matter.
State ANY is a wildcard and is used to jump from any state whenever
the trigger is active. There are states that are reserved for
special behaviours and quests.
Example how it works: First we need to create a message to greet the player
and attend it. We add a hi event:
add(ConversationStates.IDLE, ConversationPhrases.GREETING_MESSAGES,
ConversationStates.ATTENDING, "Welcome, player!", null)
Once the NPC is in the IDLE state and hears the word "hi", it will say
"Welcome player!" and move to ATTENDING.
Now let's add some options when player is in ATTENDING_STATE, like job,
offer, buy, sell, etc.
add(ConversationStates.ATTENDING, ConversationPhrases.JOB_MESSAGES,
ConversationStates.ATTENDING, "I work as a part time example showman", null)
add(ConversationStates.ATTENDING_STATE, "offer",
ConversationStates.ATTENDING_STATE, "I sell best quality swords", null)
Ok, two new events: job and offer, they go from ATTENDING state to ATTENDING
state, because after reacting to "job" or "offer", the NPC can directly react
to one of these again.
add(ConversationStates.ATTENDING, "buy", ConversationStates.BUY_PRICE_OFFERED, null, new ChatAction() { public void fire(Player player, String text, SpeakerNPC npc) { int i = text.indexOf(" "); String item = text.substring(i + 1); if (item.equals("sword")) { npc.say(item + "costs 10 coins. Do you want to buy?"); } else { npc.say("Sorry, I don't sell " + item + "."); npc.setActualState(ConversationStates.ATTENDING); } } });Now the hard part. We listen to "buy", so we need to process the text, and for that we use the ChatAction class, we create a new class that will handle the event. Also see that we move to a new state, BUY_PRICE_OFFERED. The player is then replying to a question, so we only expect two possible replies: yes or no. add(ConversationStates.BUY_PRICE_OFFERED, ConversationPhrases.YES_MESSAGES, ConversationStates.ATTENDING, "Sorry, I changed my mind. I won't sell anything.", null); // See SellerBehaviour.java for a working example. Whatever the reply is, return to ATTENDING state so we can listen to new things. Finally we want to finish the conversation, so whatever state we are, we want to finish a conversation with "Bye!". add(ConversationStates.ANY, ConversationPhrases.GOODBYE_MESSAGES, ConversationStates.IDLE, "Bye!", null); We use the state ANY as a wildcard, so if the input text is "bye" the transition happens, no matter in which state the FSM really is, with the exception of the IDLE state.
-
Nested Class Summary
Nested classes/interfaces inherited from class marauroa.common.game.RPObject
RPObject.ID
-
Field Summary
Fields inherited from class games.stendhal.server.entity.npc.NPC
pauseDirection, pauseTurns, pauseTurnsRemaining, SOUND_RADIUS
Fields inherited from class games.stendhal.server.entity.RPEntity
atk, ATTR_TITLE, damageReceived, def, level, lv_cap, ratk, statusAttackers, statusList, totalDamageReceived
Fields inherited from class games.stendhal.server.entity.GuidedEntity
baseSpeed, pathnotifier
Fields inherited from class marauroa.common.game.RPObject
INVALID_ID
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
add(ConversationStates[] states, String trigger, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)
Adds a new set of transitions to the FSM.void
add(ConversationStates[] states, Collection<String> triggerStrings, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)
Adds a new set of transitions to the FSM.void
add(ConversationStates state, String trigger, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)
Adds a new transition to the FSM.void
add(ConversationStates state, String trigger, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action, String label)
Adds a new transition to the FSM.void
add(ConversationStates state, Collection<String> triggerStrings, ChatCondition condition, boolean secondary, ConversationStates nextState, String reply, ChatAction action)
Adds a new set of transitions to the FSM.void
add(ConversationStates state, Collection<String> triggerStrings, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)
Adds a new set of transitions to the FSM.void
add(ConversationStates state, Collection<String> triggerStrings, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action, String label)
Adds a new set of transitions to the FSM.void
add(ConversationStates state, Collection<String> triggerStrings, ConversationStates nextState, String reply, ChatAction action)
void
add(ConversationStates state, Collection<String> triggerStrings, ConversationStates nextState, String reply, ChatAction action, String label)
void
addEmotion(String trigger, String npcAction)
make npc's emotionvoid
addEmotion(Collection<String> triggerStrings, String npcAction)
make npc's emotionvoid
addEmotionReply(String playerAction, String npcAction)
make npc's emotion reply on player's emotionvoid
void
addGoodbye(String text)
void
Add default greeting transition with optional recognition of the NPC name.void
addGreeting(String text)
Add greeting transition with name recognition.void
addGreeting(String text, ChatAction action)
Add greeting transition with name recognition.void
void
addInitChatMessage(ChatCondition condition, ChatAction action)
void
void
addMatching(ConversationStates state, String trigger, ExpressionMatcher matcher, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)
Adds a new transition with explicit ExpressionMatcher to the FSM.void
void
void
Makes this NPC say a text when it hears a certain trigger during a conversation.void
addReply(String trigger, String text, ChatAction action)
Makes NPC say a text and/or do an action when a trigger is said.void
addReply(Collection<String> triggerStrings, String text)
void
addReply(Collection<String> triggerStrings, String text, ChatAction action)
Makes NPC say a text and/or do an action when a trigger is said.void
addReplyOnEmotion(String playerAction, String reply)
make npc's reply on player's emotionvoid
addWaitMessage(String text, ChatAction action)
Message when NPC is attending another player.protected void
boolean
delete transition that match labelprotected void
dropItemsOn(Corpse corpse)
void
gets an alternative image for example for the websiteThe entity who is currently talking to the NPC, or null if the NPC is currently not taking part in a conversation.getJob()
gets the answer to the "job" question in ATTENDING state.Retrieves string reply to trigger word when NPC is in attending state.getReply(String trigger, ConversationStates state, String expressionType)
Retrieves string reply to trigger word.Returns a copy of the transition table.boolean
boolean
boolean
void
void
logic()
Perform cycle logic.void
This method is called when this entity has been killed (hp == 0).protected void
Is called when the NPC stops chatting with a player.void
onRejectedAttackStart(RPEntity attacker)
someone tried to attack usvoid
preLogic()
void
protected void
void
setAllowToActAlone(boolean allow)
allow or disallow for npc to act without players in his zone.void
setAlternativeImage(String alternativeImage)
sets an alternative image for example for the websitevoid
setAttending(RPEntity rpentity)
Sets the rpentity to whom the NPC is currently listening.void
setCurrentState(ConversationStates state)
void
setIdleDirection(Direction dir)
Sets the direction the entity should face while idle (not moving & not attending).void
setPerceptionRange(int perceptionRange)
Set the perception range.void
setPlayerChatTimeout(long playerChatTimeout)
Sets the time a conversation can be paused before it will be terminated by the NPC.Methods inherited from class games.stendhal.server.entity.npc.PassiveNPC
createPath, handleObjectCollision, handleSimpleCollision, isTeleporter, onMoved, reroute, reversePath, setTeleportsFlag
Methods inherited from class games.stendhal.server.entity.npc.NPC
checkPause, generateRPClass, getIdea, getMovementRange, getPerceptionRange, getSounds, isAttackable, maybeMakeSound, maybeMakeSound, moveRandomly, onFinishedPath, setIdea, setMovement, setMovementRange, setPathCompletedPause, setPathCompletedPause, setRandomPathFrom, setSounds, setSounds
Methods inherited from class games.stendhal.server.entity.DressedEntity
getOriginalOutfit, getOutfit, getOutfitColors, isNaked, put, restoreOriginalOutfit, setOutfit, setOutfit, setOutfit, setOutfit, setOutfit, setOutfit, setOutfitColor, setOutfitColor, setOutfitColor, setOutfitColors, setOutfitWithDetail, unsetOutfitColor
Methods inherited from class games.stendhal.server.entity.RPEntity
addAtkXP, addBaseMana, addDefXP, addKarma, addMana, addRatkXP, addStatusAttacker, addXP, applyDefXP, applyDistanceAttackModifiers, attack, canDoRangeAttack, canHit, damage, damageDone, delayedDamage, describe, drop, drop, drop, dropDroppableItem, dropWithInfostring, dropWithInfostring, entityAsOnlinePlayer, entityAsPet, equip, equipOrPutOnGround, equipToInventoryOnly, getAllEquipped, getAllEquippedWithInfostring, getAmmunition, getArmor, getAtk, getAtkXP, getAttackingRPEntities, getAttackRate, getAttackSources, getAttackTarget, getBaseHP, getBaseMana, getBloodClass, getBoots, getCappedAtk, getCappedDef, getCappedRatk, getCloak, getCorpseDeserver, getCorpseHeight, getCorpseName, getCorpseWidth, getDamageType, getDeathSound, getDef, getDefenseItems, getDefXP, getDescriptionName, getDroppables, getEquippedItemClass, getFirstEquipped, getHarmlessCorpseName, getHelmet, getHP, getItemAtk, getItemDef, getItemRatk, getKarma, getLanguage, getLegs, getLevel, getLVCap, getMana, getMaxRangeForArcher, getMissileIfNotHoldingOtherWeapon, getName, getNumberOfEquipped, getRangedDamageType, getRangeWeapon, getRatk, getRatkXP, getRing, getsFightXpFrom, getShield, getSlotToEquip, getStatusList, getSusceptibility, getTitle, getTotalNumberOf, getWeapon, getWeapons, getXP, handleLifesteal, handlePortal, hasArmor, hasBoots, hasCloak, hasHelmet, hasLegs, hasLineOfSight, hasRing, hasShield, hasStatus, heal, heal, heal, incAtkXP, incDefXP, incRatkXP, initHP, isAttacked, isAttacking, isEquipped, isEquipped, isEquippedItemClass, isEquippedItemInSlot, isEquippedWithInfostring, isEquippedWithInfostring, isInvisibleToCreatures, makeCorpse, maybeDropDroppables, onAdded, onDamaged, onDead, onRemoved, rememberAttacker, rewardKillerAnimals, rewardKillers, sendPrivateText, sendPrivateText, setAtk, setAtkInternal, setAtkXP, setBaseHP, setBaseMana, setBlood, setDeathSound, setDef, setDefInternal, setDefXP, setHP, setLevel, setLVCap, setMana, setName, setRatk, setRatkInternal, setRatkXP, setRatkXPInternal, setShadowStyle, setTarget, setTitle, setXP, stopAttack, stopAttacking, subXP, update, updateItemAtkDef, updateLevel, useKarma, useKarma, useKarma
Methods inherited from class games.stendhal.server.entity.GuidedEntity
addSuspend, addSuspend, applyMovement, atMovementRadius, clearPath, followPath, getBaseSpeed, getCollisionAction, getDirectionFromOrigin, getDistanceFromOrigin, getGuide, getPath, getPathPosition, hasPath, isPathLoop, onNodeReached, onOutsideMovementRadius, removeSuspend, retracePath, setBaseSpeed, setCollisionAction, setPath, setPath, setPathAndPosition, setPathPosition, setRandomMovementRadius, setRandomMovementRadius, setRetracePath, setUsesRandomPath, stop, updateModifiedAttributes, usesRandomPath
Methods inherited from class games.stendhal.server.entity.ActiveEntity
canMoveTo, canMoveTo, faceto, faceToward, getDirection, getDirectionToward, getDirectionToward, getResistance, getSpeed, getStepsTaken, handleLeaveZone, ignoresCollision, isFacingToward, isGhost, isMoveCompleted, isZoneChangeAllowed, move, setDirection, setIgnoresCollision, setSpeed, stopped
Methods inherited from class games.stendhal.server.entity.Entity
getAdjacentNodes, getArea, getArea, getCursor, getDescription, getEntitySlot, getHeight, getOrigin, getResistance, getWidth, getX, getY, getZone, hasDescription, isInSight, isObstacle, nextTo, nextTo, notifyWorldAboutChanges, setCursor, setDescription, setEntityClass, setEntitySubclass, setMenu, setPosition, setResistance, setSize, setVisibility, slotIterator, slots, squaredDistance, squaredDistance
Methods inherited from class marauroa.common.game.RPObject
addEvent, addLink, addLink, addMap, addSlot, addSlot, applyDifferences, clearEvents, clearVisible, clone, containsKey, equals, events, eventsIterator, fill, get, getBaseContainer, getBoolean, getContainer, getContainerBaseOwner, getContainerOwner, getContainerSlot, getDifferences, getDouble, getFromSlots, getID, getInt, getLink, getLinkedObject, getMap, getSlot, has, hashCode, hasLink, hasMap, hasSlot, hide, isContained, isEmpty, isHidden, isStorable, maps, put, put, put, put, readObject, remove, removeLink, removeMap, removeSlot, resetAddedAndDeleted, resetAddedAndDeletedMaps, resetAddedAndDeletedRPLink, resetAddedAndDeletedRPSlot, setAddedMaps, setAddedRPSlot, setContainer, setDeletedMaps, setDeletedRPSlot, setID, size, slots, slotsIterator, store, toString, unhide, unstore, writeObject, writeObject, writeToJson
Methods inherited from class marauroa.common.game.SlotOwner
deserializeRPSlots, fill, serializeRPSlots
Methods inherited from class marauroa.common.game.Attributes
add, applyDifferences, get, getBool, getDouble, getInt, getList, getLong, getRPClass, has, instanceOf, iterator, put, put, put, put, readFromMap, remove, resetAddedAndDeletedAttributes, setAddedAttributes, setDeletedAttributes, setRPClass, setRPClass, toAttributeString
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Methods inherited from interface java.lang.Iterable
forEach, spliterator
-
Constructor Details
-
SpeakerNPC
Creates a new SpeakerNPC.- Parameters:
name
- The NPC's name. Please note that names should be unique.
-
-
Method Details
-
setAllowToActAlone
public void setAllowToActAlone(boolean allow)allow or disallow for npc to act without players in his zone.- Parameters:
allow
- - flag for allowing/disallowing npc's acting
-
isAllowedToActAlone
public boolean isAllowedToActAlone() -
createDialog
protected void createDialog() -
onGoodbye
Is called when the NPC stops chatting with a player. Override it if needed.- Parameters:
attending2
- who has been talked to.
-
getAttending
The entity who is currently talking to the NPC, or null if the NPC is currently not taking part in a conversation.- Returns:
- RPEntity
-
setAttending
Sets the rpentity to whom the NPC is currently listening. Note: You don't need to use this for most NPCs.- Parameters:
rpentity
- the entity with whom the NPC should be talking.
-
setIdleDirection
Sets the direction the entity should face while idle (not moving & not attending).- Parameters:
dir
- Direction to face.
-
onDead
Description copied from class:RPEntity
This method is called when this entity has been killed (hp == 0). -
dropItemsOn
- Overrides:
dropItemsOn
in classNPC
-
setPlayerChatTimeout
public void setPlayerChatTimeout(long playerChatTimeout)Sets the time a conversation can be paused before it will be terminated by the NPC.- Parameters:
playerChatTimeout
- the time, in seconds
-
setPerceptionRange
public void setPerceptionRange(int perceptionRange)Description copied from class:NPC
Set the perception range.- Overrides:
setPerceptionRange
in classNPC
-
logic
public void logic()Description copied from class:RPEntity
Perform cycle logic. -
preLogic
public void preLogic() -
endConversation
public void endConversation() -
inConversationRange
public boolean inConversationRange() -
isTalking
public boolean isTalking() -
say
-
say
-
addWaitMessage
Message when NPC is attending another player.- Parameters:
text
- to say to bothering playeraction
- to perform
-
addInitChatMessage
-
add
public void add(ConversationStates state, String trigger, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)Adds a new transition to the FSM.- Parameters:
state
- the starting state of the FSMtrigger
- input for this transitioncondition
- null or condition that has to return true for this transition to be considerednextState
- the new state of the FSMreply
- a simple text reply (may be null for no reply)action
- a special action to be taken (may be null)
-
add
public void add(ConversationStates state, String trigger, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action, String label)Adds a new transition to the FSM.- Parameters:
state
- the starting state of the FSMtrigger
- input for this transitioncondition
- null or condition that has to return true for this transition to be considerednextState
- the new state of the FSMreply
- a simple text reply (may be null for no reply)action
- a special action to be taken (may be null)label
- a label string to handle transitions
-
addMatching
public void addMatching(ConversationStates state, String trigger, ExpressionMatcher matcher, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)Adds a new transition with explicit ExpressionMatcher to the FSM.- Parameters:
state
-trigger
-matcher
-condition
-nextState
-reply
-action
-
-
add
public void add(ConversationStates state, Collection<String> triggerStrings, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action, String label)Adds a new set of transitions to the FSM.- Parameters:
state
- the starting state of the FSMtriggerStrings
- a list of inputs for this transitioncondition
- null or condition that has to return true for this transition to be considerednextState
- the new state of the FSMreply
- a simple text reply (may be null for no reply)action
- a special action to be taken (may be null)label
-
-
add
public void add(ConversationStates state, Collection<String> triggerStrings, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)Adds a new set of transitions to the FSM.- Parameters:
state
- the starting state of the FSMtriggerStrings
- a list of inputs for this transitioncondition
- null or condition that has to return true for this transition to be considerednextState
- the new state of the FSMreply
- a simple text reply (may be null for no reply)action
- a special action to be taken (may be null)
-
add
public void add(ConversationStates state, Collection<String> triggerStrings, ChatCondition condition, boolean secondary, ConversationStates nextState, String reply, ChatAction action)Adds a new set of transitions to the FSM.- Parameters:
state
- the starting state of the FSMtriggerStrings
- a list of inputs for this transitioncondition
- null or condition that has to return true for this transition to be consideredsecondary
- flag to mark secondary transitions to be taken into account after preferred transitionsnextState
- the new state of the FSMreply
- a simple text reply (may be null for no reply)action
- a special action to be taken (may be null)
-
add
public void add(ConversationStates[] states, String trigger, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)Adds a new set of transitions to the FSM.- Parameters:
states
- the starting states of the FSMtrigger
- input for this transitioncondition
- null or condition that has to return true for this transition to be considerednextState
- the new state of the FSMreply
- a simple text reply (may be null for no reply)action
- a special action to be taken (may be null)
-
add
public void add(ConversationStates[] states, Collection<String> triggerStrings, ChatCondition condition, ConversationStates nextState, String reply, ChatAction action)Adds a new set of transitions to the FSM.- Parameters:
states
- the starting states of the FSMtriggerStrings
- a list of inputs for this transitioncondition
- null or condition that has to return true for this transition to be considerednextState
- the new state of the FSMreply
- a simple text reply (may be null for no reply)action
- a special action to be taken (may be null)
-
add
public void add(ConversationStates state, Collection<String> triggerStrings, ConversationStates nextState, String reply, ChatAction action) -
add
public void add(ConversationStates state, Collection<String> triggerStrings, ConversationStates nextState, String reply, ChatAction action, String label) -
del
delete transition that match label- Parameters:
label
-- Returns:
- - deleting state
-
listenTo
-
setCurrentState
-
addGreeting
public void addGreeting()Add default greeting transition with optional recognition of the NPC name. -
addGreeting
Add greeting transition with name recognition.- Parameters:
text
-
-
addGreeting
Add greeting transition with name recognition.- Parameters:
text
-action
-
-
addReply
Makes this NPC say a text when it hears a certain trigger during a conversation.- Parameters:
trigger
- The text that causes the NPC to answertext
- The answer
-
addReply
- Parameters:
triggerStrings
-text
-
-
addReply
Makes NPC say a text and/or do an action when a trigger is said.- Parameters:
trigger
-text
-action
-
-
addReply
Makes NPC say a text and/or do an action when a trigger is said.- Parameters:
triggerStrings
-text
-action
-
-
addQuest
-
addJob
-
addHelp
-
addOffer
-
addEmotionReply
make npc's emotion reply on player's emotion- Parameters:
playerAction
- - what player doing with npcnpcAction
- - npc's emotion reply on player's emotion
-
addEmotion
make npc's emotion- Parameters:
triggerStrings
- - player's keywords for npc emotionnpcAction
- - npc's emotion
-
addEmotion
make npc's emotion- Parameters:
trigger
- - player's keywords for npc emotionnpcAction
- - npc's emotion
-
addReplyOnEmotion
make npc's reply on player's emotion- Parameters:
playerAction
- - what player doing with npcreply
- - npc's reply on player's emotion
-
addGoodbye
public void addGoodbye() -
addGoodbye
-
getTransitions
Returns a copy of the transition table.- Returns:
- list of transitions
-
getEngine
-
getAlternativeImage
gets an alternative image for example for the website- Returns:
- name of alternative image or
null
in case the normal image should be used.
-
setAlternativeImage
sets an alternative image for example for the website- Parameters:
alternativeImage
- name of alternative image ornull
in case the normal image should be used.
-
getJob
gets the answer to the "job" question in ATTENDING state.- Returns:
- the answer to the job question or null in case there is no job specified
-
getReply
Retrieves string reply to trigger word.- Parameters:
trigger
- Word or phrase that triggers reply.state
- The conversation state the NPC is in when trigger is activated.expressionType
-- Returns:
- String reply or
null
.
-
getReply
Retrieves string reply to trigger word when NPC is in attending state.- Parameters:
trigger
- Word or phrase that triggers reply.- Returns:
- String reply or
null
.
-
onRejectedAttackStart
someone tried to attack us- Parameters:
attacker
-
-