-
Notifications
You must be signed in to change notification settings - Fork 248
Expand file tree
/
Copy pathConversationManager.java
More file actions
180 lines (166 loc) · 7.23 KB
/
ConversationManager.java
File metadata and controls
180 lines (166 loc) · 7.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package com.jadventure.game.conversation;
import com.jadventure.game.GameBeans;
import com.jadventure.game.entities.NPC;
import com.jadventure.game.entities.Player;
import com.jadventure.game.items.Item;
import com.jadventure.game.repository.EncounteredNpcRepository;
import com.jadventure.game.repository.ItemRepository;
import com.jadventure.game.DeathException;
import com.jadventure.game.Trading;
import com.jadventure.game.queueprovider.QueueProvider;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.jadventure.game.repository.NpcRepository;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ConversationManager {
private static NpcRepository npcRepository = EncounteredNpcRepository.createRepo();
private static ConversationManager instance = null;
private Map<NPC, List<Line>> lines = new HashMap<NPC, List<Line>>();
private static final Map<String, ActionType> ACTION_TYPE_MAP = new HashMap<>();
private static final Map<String, ConditionType> CONDITION_TYPE_MAP = new HashMap<>();
static {
ACTION_TYPE_MAP.put("none", ActionType.NONE);
ACTION_TYPE_MAP.put("attack", ActionType.ATTACK);
ACTION_TYPE_MAP.put("buy", ActionType.BUY);
ACTION_TYPE_MAP.put("sell", ActionType.SELL);
ACTION_TYPE_MAP.put("trade", ActionType.TRADE);
ACTION_TYPE_MAP.put("give", ActionType.GIVE);
ACTION_TYPE_MAP.put("take", ActionType.TAKE);
CONDITION_TYPE_MAP.put("none", ConditionType.NONE);
CONDITION_TYPE_MAP.put("ally", ConditionType.ALLY);
CONDITION_TYPE_MAP.put("enemy", ConditionType.ENEMY);
CONDITION_TYPE_MAP.put("level", ConditionType.LEVEL);
CONDITION_TYPE_MAP.put("item", ConditionType.ITEM);
CONDITION_TYPE_MAP.put("char type", ConditionType.CHAR_TYPE);
}
public ConversationManager() {
load();
}
public static ConversationManager getInstance() {
if (instance == null) {
instance = new ConversationManager();
}
return instance;
}
private void load() {
String fileName = "json/original_data/npcs.json";
JsonParser parser = new JsonParser();
try {
Reader reader = new FileReader(fileName);
JsonObject json = parser.parse(reader).getAsJsonObject();
json = json.get("npcs").getAsJsonObject();
Set<Map.Entry<String, JsonElement>> entries = json.entrySet();
for (Map.Entry<String, JsonElement> entry : entries) {
NPC npc = npcRepository.getNpc(entry.getKey());
JsonObject details = entry.getValue().getAsJsonObject();
if (details.get("conversations") != null) {
JsonArray conversation = details.get("conversations").getAsJsonArray();
addConversation(npc, conversation);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void addConversation(NPC npc, JsonArray conversation) {
List<Line> start = new ArrayList<>();
int i = 0;
for (JsonElement entry : conversation) {
JsonObject details = entry.getAsJsonObject();
start.add(getLine(i++, conversation));
}
lines.put(npc, start);
}
private Line getLine(int index, JsonArray conversation) {
JsonObject line = conversation.get(index).getAsJsonObject();
List<Integer> responses = new ArrayList<>();
if (line.get("response") != null) {
for (JsonElement i : line.get("response").getAsJsonArray()) {
responses.add(i.getAsInt());
}
}
String playerPrompt = line.get("player").getAsString();
String text = line.get("text").getAsString();
String[] con = line.get("condition").getAsString().split("=");
ConditionType condition = CONDITION_TYPE_MAP.get(con[0]);
String conditionParameter = (con.length == 1) ? "" : con[1];
ActionType action = ACTION_TYPE_MAP.get(line.get("action").getAsString());
return new Line(index, playerPrompt, text, condition, conditionParameter, responses, action);
}
public void startConversation(NPC npc, Player player) throws DeathException {
List<Line> conversation = null;
//Workaround as <code>lines.get(npc)</code> is not working.
Iterator it = lines.entrySet().iterator();
while (it.hasNext()) {
@SuppressWarnings("unchecked")
Map.Entry<NPC, List<Line>> entry = (Map.Entry<NPC, List<Line>>) it.next();
if (entry.getKey().equals(npc)) {
conversation = entry.getValue();
}
it.remove();
}
if (conversation != null) {
Line start = null;
for (Line l : conversation) {
if ("".equals(l.getPlayerPrompt()) &&
ConversationManager.matchesConditions(npc, player, l)) {
start = l;
break;
}
}
if (start != null) {
QueueProvider.getInstance().offer(start.getText());
Line response = start.display(npc, player, conversation);
triggerAction(start, npc, player);
while (response != null) {
QueueProvider.getInstance().offer(response.getText());
triggerAction(response, npc, player);
Line temp_response = response.display(npc, player, conversation);
response = temp_response;
}
}
}
}
private void triggerAction(Line line, NPC npc, Player player) throws DeathException {
switch (line.getAction()) {
case ATTACK:
QueueProvider.getInstance().offer("\n" + npc.getName() + " is now attacking you!\n");
player.attack(npc.getName());
break;
case TRADE:
Trading t = new Trading(npc, player);
t.trade(true, true);
break;
}
}
public static boolean matchesConditions(NPC npc, Player player, Line line) {
switch(line.getCondition()) {
case ALLY:
return npc.getAllies().contains(player.getCurrentCharacterType());
case ENEMY:
return npc.getEnemies().contains(player.getCurrentCharacterType());
case LEVEL:
int requiredLevel = Integer.parseInt(line.getConditionParameter());
return player.getLevel() >= requiredLevel;
case ITEM:
ItemRepository itemRepo = GameBeans.getItemRepository();
Item requiredItem = itemRepo.getItem(line.getConditionParameter());
return player.hasItem(requiredItem);
case CHAR_TYPE:
String charType = line.getConditionParameter();
return charType.equals(player.getCurrentCharacterType());
default: // No condition
return true;
}
}
}