Peoplemon  0.1.0
Peoplemon 3 game source documentation
Conversation.cpp
Go to the documentation of this file.
2 
6 
7 namespace core
8 {
9 namespace ai
10 {
11 namespace
12 {
13 file::Conversation::Node errorNode() {
14  file::Conversation::Node node;
15  node.setType(file::Conversation::Node::Talk);
16  node.message() = "<ERROR: Current node is invalid>";
17  return node;
18 }
19 } // namespace
20 
22 : systems(s)
23 , nodes(nullptr)
24 , current(0) {}
25 
26 void Conversation::setConversation(const file::Conversation& conv, bl::ecs::Entity e, bool t) {
27  nodes = &conv.nodes();
28  current = 0;
29  entity = e;
30  alreadyTalked = t;
31  followNodes();
32 }
33 
34 bool Conversation::finished() const { return nodes && current >= nodes->size(); }
35 
37  if (!finished()) return nodes->at(current);
38  static const file::Conversation::Node garbage = errorNode();
39  return garbage;
40 }
41 
43  if (!finished()) {
44  current = nodes->at(current).next();
45  followNodes();
46  }
47 }
48 
50  if (!finished()) {
51  current = nodes->at(current).nextOnPass();
52  followNodes();
53  }
54 }
55 
57  if (!finished()) {
58  current = nodes->at(current).nextOnReject();
59  followNodes();
60  }
61 }
62 
63 void Conversation::notifyChoiceMade(const std::string& choice) {
64  if (currentNode().getType() == file::Conversation::Node::Prompt) {
65  for (const auto& pair : nodes->at(current).choices()) {
66  if (pair.first == choice) {
67  current = pair.second;
68  followNodes();
69  break;
70  }
71  }
72  }
73 }
74 
75 void Conversation::followNodes() {
77  const auto isBlocking = [this](unsigned int i) {
78  switch (nodes->at(i).getType()) {
79  case E::CheckInteracted:
80  case E::CheckSaveFlag:
81  case E::RunScript:
82  case E::SetSaveFlag:
83  return false;
84 
85  default:
86  return true;
87  }
88  };
89 
90  while (!finished() && !isBlocking(current)) {
91  switch (nodes->at(current).getType()) {
92  case E::CheckInteracted:
93  current =
94  alreadyTalked ? nodes->at(current).nextOnPass() : nodes->at(current).nextOnReject();
95  break;
96 
97  case E::SetSaveFlag:
98  systems.interaction().setFlag(nodes->at(current).saveFlag());
99  current = nodes->at(current).next();
100  break;
101 
102  case E::CheckSaveFlag:
103  current = systems.interaction().flagSet(nodes->at(current).saveFlag()) ?
104  nodes->at(current).nextOnPass() :
105  nodes->at(current).nextOnReject();
106  break;
107 
108  case E::RunScript: {
109  const auto cb = [this](bl::ecs::Entity e) {
110  if (e != entity) return true;
111  return finished();
112  };
113 
114  script::LegacyWarn::warn(nodes->at(current).script());
115  bl::script::Script script(nodes->at(current).script(),
116  script::ConversationContext(systems, entity, cb));
117  if (nodes->at(current).runConcurrently()) {
118  script.runBackground(&systems.engine().scriptManager());
119  }
120  else {
121  script.run(&systems.engine().scriptManager());
122  }
123  current = nodes->at(current).next();
124  } break;
125 
126  default:
127  BL_LOG_ERROR << "Unhandled nonblocking node type " << nodes->at(current).getType()
128  << ", terminating";
129  current = nodes->size();
130  break;
131  }
132  }
133 }
134 
135 } // namespace ai
136 } // namespace core
Core classes and functionality for both the editor and game.
void notifyNext()
Continues to the next node on player input.
bool finished() const
Returns whether or not the conversation is finished.
void notifyCheckFailed()
Jumps to the node for a check pass (ie take item/money fail etc)
void notifyCheckPassed()
Jumps to the node for a check pass (ie take item/money success etc)
void notifyChoiceMade(const std::string &choice)
Jumps to the node for the given choice if the current node is a Prompt.
const file::Conversation::Node & currentNode() const
Returns the current node.
Conversation(system::Systems &systems)
Creates an empty conversation wrapper.
void setConversation(const file::Conversation &conversation, bl::ecs::Entity entity, bool talked)
Sets the wrapper to point to the given underlying. The underlying must remain in scope during the lif...
Stores a conversation that an NPC or trainer can have with the player.
const std::vector< Node > & nodes() const
Returns the list of nodes in the conversation.
Building block of conversations. A conversation is a tree of nodes and each node is an action that ha...
Type
Represents the different effects that nodes can have.
@ Prompt
This will output a message then prompt the player for a choice.
@ Talk
This just outputs a message.
static void warn(const std::string &script)
In debug mode logs a warning if the given script is detected to be legacy.
Definition: LegacyWarn.hpp:26
bool flagSet(const std::string &flag) const
Checks if the given conversation flag has been set.
void setFlag(const std::string &flag)
Sets the conversation flag.
Owns all primary systems and a reference to the engine.
Definition: Systems.hpp:47
const bl::engine::Engine & engine() const
Const accessor for the Engine.
Definition: Systems.cpp:35
Interaction & interaction()
Returns the interaction system.
Definition: Systems.cpp:67