Gridarta Editor
DaimoninAITokenMarker.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2015 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.textedit.textarea.tokenmarker;
21 
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.regex.Pattern;
29 import javax.swing.text.Segment;
32 import org.jetbrains.annotations.NotNull;
33 import org.jetbrains.annotations.Nullable;
34 
39 public class DaimoninAITokenMarker extends TokenMarker {
40 
45  @NotNull
46  private static final Map<String, Spec> FIXED_SPECS = new HashMap<>();
47 
52  @NotNull
53  private static final Map<Pattern, Spec> REGEX_SPECS = new HashMap<>();
54 
55  static {
56  FIXED_SPECS.put("actions:", new Spec(Token.LABEL));
57  FIXED_SPECS.put("moves:", new Spec(Token.LABEL));
58  FIXED_SPECS.put("processes:", new Spec(Token.LABEL));
59  FIXED_SPECS.put("bow_attack_enemy", new Spec(Token.KEYWORD1));
60  FIXED_SPECS.put("choose_enemy", new Spec(Token.KEYWORD1, new Parameter("antilure_distance", Token.KEYWORD2, ParameterType.INTEGER)));
61  FIXED_SPECS.put("dont_stand_still", new Spec(Token.KEYWORD1, new Parameter("max_idle_time", Token.KEYWORD2, ParameterType.INTEGER)));
63  FIXED_SPECS.put("groups", new Spec(Token.KEYWORD1, new Parameter("name", Token.KEYWORD2, ParameterType.STRING)));
64  FIXED_SPECS.put("heal_friend", new Spec(Token.KEYWORD1, new Parameter("healing_min_friendship", Token.KEYWORD2, ParameterType.INTEGER)));
65  FIXED_SPECS.put("look_for_other_mobs", new Spec(Token.KEYWORD1));
66  REGEX_SPECS.put(Pattern.compile("lua:.*"), new Spec(Token.KEYWORD1));
67  FIXED_SPECS.put("melee_attack_enemy", new Spec(Token.KEYWORD1));
68  FIXED_SPECS.put("move_randomly", new Spec(Token.KEYWORD1, new Parameter("xlimit", Token.KEYWORD2, ParameterType.INTEGER), new Parameter("ylimit", Token.KEYWORD2, ParameterType.INTEGER)));
69  FIXED_SPECS.put("move_towards_enemy", new Spec(Token.KEYWORD1));
70  FIXED_SPECS.put("move_towards_enemy_last_known_pos", new Spec(Token.KEYWORD1));
71  FIXED_SPECS.put("move_towards_home", new Spec(Token.KEYWORD1));
72  FIXED_SPECS.put("move_towards_waypoint", new Spec(Token.KEYWORD1));
73  FIXED_SPECS.put("run_away_from_enemy", new Spec(Token.KEYWORD1, new Parameter("hp_threshold", Token.KEYWORD2, ParameterType.INTEGER)));
74  FIXED_SPECS.put("search_for_lost_enemy", new Spec(Token.KEYWORD1));
75  FIXED_SPECS.put("sleep", new Spec(Token.KEYWORD1));
76  FIXED_SPECS.put("spell_attack_enemy", new Spec(Token.KEYWORD1));
77  FIXED_SPECS.put("stand_still", new Spec(Token.KEYWORD1));
78  }
79 
80  @Override
81  public byte markTokensImpl(final byte token, @NotNull final Segment line) {
82  final char[] array = line.array;
83  int offset = line.offset;
84  final int end = line.count + offset;
85  if (offset >= end) {
86  // empty line ==> mark nothing
87  } else if (array[offset] == '#') {
88  // comment line
89  addToken(line.count, Token.COMMENT1);
90  } else if (array[offset] == ' ') {
91  // syntax error
92  addToken(line.count, Token.INVALID);
93  } else {
94  // normal line
95 
96  // 1. parse line into segments
97 
98  // Collects parsed segments: command, space, parameter, space,
99  // parameter, space, ...
100  final Collection<Integer> segments = new ArrayList<>();
101 
102  while (offset < end) {
103  final int commandStart = offset;
104  while (offset < end && array[offset] != ' ') {
105  offset++;
106  }
107  segments.add(offset - commandStart);
108 
109  final int spacesStart = offset;
110  while (offset < end && array[offset] == ' ') {
111  offset++;
112  }
113  segments.add(offset - spacesStart);
114  }
115 
116  // 2. create tokens
117  final Iterator<Integer> it = segments.iterator();
118  int offset2 = line.offset;
119 
120  final int commandLength = it.next();
121  final String command = new String(array, offset2, commandLength);
122  final Spec spec = getSpec(command);
123  addToken(commandLength, spec == null ? Token.INVALID : spec.getId());
124  offset2 += commandLength;
125 
126  final int spacesLength1 = it.next();
127  addToken(spacesLength1, Token.NULL);
128  offset2 += spacesLength1;
129 
130  while (it.hasNext()) {
131  final int parameterLength = it.next();
132  final String[] tmp = StringUtils.PATTERN_EQUAL.split(new String(array, offset2, parameterLength), 2);
133  if (tmp.length == 2) {
134  final String parameterString = tmp[0];
135  final String valueString = tmp[1];
136 
137  final Parameter parameter = spec == null ? null : spec.getParameter(parameterString);
138  final boolean parameterValid = parameter != null;
139  final boolean valueValid = parameter == null || parameter.getParameterType().getPattern().matcher(valueString).matches();
140  addToken(parameterString.length(), parameterValid ? parameter.getId() : Token.INVALID);
141  addToken(1, (parameterString.isEmpty() && !parameterValid) || (valueString.isEmpty() && !valueValid) ? Token.INVALID : Token.OPERATOR);
142  addToken(valueString.length(), valueValid ? Token.NULL : Token.INVALID);
143  } else {
144  // missing '=' sign ==> syntax error
145  addToken(parameterLength, Token.INVALID);
146  }
147  offset2 += parameterLength;
148 
149  final int spacesLength2 = it.next();
150  addToken(spacesLength2, Token.NULL);
151  offset2 += spacesLength2;
152  }
153  }
154 
155  return Token.NULL;
156  }
157 
164  @Nullable
165  private static Spec getSpec(@NotNull final String command) {
166  final Spec fixedSpec = FIXED_SPECS.get(command);
167  if (fixedSpec != null) {
168  return fixedSpec;
169  }
170 
171  for (final Entry<Pattern, Spec> entry : REGEX_SPECS.entrySet()) {
172  if (entry.getKey().matcher(command).matches()) {
173  return entry.getValue();
174  }
175  }
176 
177  return null;
178  }
179 
180 }
net.sf.gridarta.textedit.textarea
net.sf.gridarta.textedit.textarea.tokenmarker.Spec.getId
byte getId()
Definition: Spec.java:59
net.sf.gridarta
net.sf.gridarta.textedit.textarea.tokenmarker.DaimoninAITokenMarker
Definition: DaimoninAITokenMarker.java:39
net.sf.gridarta.textedit.textarea.tokenmarker.TokenMarker.addToken
void addToken(final int length, final byte id)
Definition: TokenMarker.java:225
net.sf.gridarta.textedit.textarea.Token.NULL
static final byte NULL
Definition: Token.java:26
net.sf
net.sf.gridarta.textedit.textarea.tokenmarker.ParameterType.INTEGER
INTEGER
Definition: ParameterType.java:33
net.sf.gridarta.textedit.textarea.tokenmarker.DaimoninAITokenMarker.markTokensImpl
byte markTokensImpl(final byte token, @NotNull final Segment line)
Definition: DaimoninAITokenMarker.java:81
net.sf.gridarta.textedit
net.sf.gridarta.textedit.textarea.tokenmarker.ParameterType.STRING
STRING
Definition: ParameterType.java:38
net.sf.gridarta.textedit.textarea.Token
Definition: Token.java:21
net.sf.gridarta.textedit.textarea.Token.OPERATOR
static final byte OPERATOR
Definition: Token.java:78
net
net.sf.gridarta.textedit.textarea.Token.LABEL
static final byte LABEL
Definition: Token.java:54
net.sf.gridarta.textedit.textarea.tokenmarker.ParameterType.STRING_INTEGER
STRING_INTEGER
Definition: ParameterType.java:43
net.sf.gridarta.textedit.textarea.tokenmarker.Parameter
Definition: Parameter.java:26
net.sf.gridarta.textedit.textarea.Token.INVALID
static final byte INVALID
Definition: Token.java:84
net.sf.gridarta.textedit.textarea.Token.KEYWORD2
static final byte KEYWORD2
Definition: Token.java:66
net.sf.gridarta.textedit.textarea.tokenmarker.Parameter.getParameterType
ParameterType getParameterType()
Definition: Parameter.java:75
net.sf.gridarta.textedit.textarea.tokenmarker.Parameter.getId
byte getId()
Definition: Parameter.java:67
net.sf.gridarta.textedit.textarea.Token.KEYWORD1
static final byte KEYWORD1
Definition: Token.java:60
net.sf.gridarta.utils.StringUtils
Definition: StringUtils.java:31
net.sf.gridarta.textedit.textarea.tokenmarker.Spec.getParameter
Parameter getParameter(final String name)
Definition: Spec.java:69
net.sf.gridarta.textedit.textarea.tokenmarker.Spec
Definition: Spec.java:29
net.sf.gridarta.textedit.textarea.tokenmarker.DaimoninAITokenMarker.FIXED_SPECS
static final Map< String, Spec > FIXED_SPECS
Definition: DaimoninAITokenMarker.java:46
net.sf.gridarta.textedit.textarea.tokenmarker.DaimoninAITokenMarker.getSpec
static Spec getSpec(@NotNull final String command)
Definition: DaimoninAITokenMarker.java:165
net.sf.gridarta.textedit.textarea.tokenmarker.ParameterType.getPattern
Pattern getPattern()
Definition: ParameterType.java:62
net.sf.gridarta.textedit.textarea.tokenmarker.TokenMarker
Definition: TokenMarker.java:32
net.sf.gridarta.textedit.textarea.tokenmarker.DaimoninAITokenMarker.REGEX_SPECS
static final Map< Pattern, Spec > REGEX_SPECS
Definition: DaimoninAITokenMarker.java:53
net.sf.gridarta.textedit.textarea.tokenmarker.ParameterType
Definition: ParameterType.java:28
net.sf.gridarta.textedit.textarea.Token.COMMENT1
static final byte COMMENT1
Definition: Token.java:31
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.utils.StringUtils.PATTERN_EQUAL
static final Pattern PATTERN_EQUAL
Definition: StringUtils.java:103