Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/StarMonsterDatabase.hpp
blob: 0220267184512664e645a20be5b9f491342d6177 (plain)
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#pragma once

#include "StarNetworkedAnimator.hpp"
#include "StarActorMovementController.hpp"
#include "StarTtlCache.hpp"
#include "StarDamageTypes.hpp"
#include "StarStatusTypes.hpp"
#include "StarImageProcessing.hpp"
#include "StarEntityRenderingTypes.hpp"

namespace Star {

STAR_CLASS(RandomSource);
STAR_CLASS(Monster);
STAR_CLASS(MonsterDatabase);

STAR_EXCEPTION(MonsterException, StarException);

struct MonsterVariant {
  String type;
  uint64_t seed;
  Json uniqueParameters;

  Maybe<String> shortDescription;
  Maybe<String> description;

  Json animatorConfig;
  StringMap<String> animatorPartTags;
  float animatorZoom;
  // Is the animator specified Left facing?
  bool reversed;

  // Either is a String which specifies a dropPool, or a map which maps
  // damageSourceKind to the appropriate treasure pool for this monster, with a
  // "default" key as a catch-all.
  Json dropPoolConfig;

  // Every parameter specified in each section of the monster configuration is
  // stored here.  The base parameters, size parameters, variation parameters,
  // and part parameters are all merged together into one final configuration.
  Json parameters;

  // Parameters common to all Monsters

  StringList scripts;
  unsigned initialScriptDelta;
  StringList animationScripts;

  RectF metaBoundBox;
  EntityRenderLayer renderLayer;
  float scale;

  ActorMovementParameters movementSettings;
  float walkMultiplier;
  float runMultiplier;
  float jumpMultiplier;
  float weightMultiplier;
  float healthMultiplier;
  float touchDamageMultiplier;

  Json touchDamageConfig;
  StringMap<Json> animationDamageParts;
  Json statusSettings;
  Vec2F mouthOffset;
  Vec2F feetOffset;

  String powerLevelFunction;
  String healthLevelFunction;

  ClientEntityMode clientEntityMode;
  bool persistent;

  TeamType damageTeamType;
  uint8_t damageTeam;

  PolyF selfDamagePoly;

  Maybe<String> portraitIcon;

  float damageReceivedAggressiveDuration;
  float onDamagedOthersAggressiveDuration;
  float onFireAggressiveDuration;

  Vec3B nametagColor;
  Maybe<ColorReplaceMap> colorSwap;
};

class MonsterDatabase {
public:
  MonsterDatabase();

  void cleanup();

  StringList monsterTypes() const;

  MonsterVariant randomMonster(String const& typeName, Json const& uniqueParameters = JsonObject()) const;
  MonsterVariant monsterVariant(String const& typeName, uint64_t seed, Json const& uniqueParameters = JsonObject()) const;

  ByteArray writeMonsterVariant(MonsterVariant const& variant, NetCompatibilityRules rules = {}) const;
  MonsterVariant readMonsterVariant(ByteArray const& data, NetCompatibilityRules rules = {}) const;

  Json writeMonsterVariantToJson(MonsterVariant const& mVar) const;
  MonsterVariant readMonsterVariantFromJson(Json const& variant) const;

  // If level is 0, then the monster will start with the threat level of
  // whatever world they're spawned in.
  MonsterPtr createMonster(MonsterVariant monsterVariant, Maybe<float> level = {}, Json uniqueParameters = {}) const;
  MonsterPtr diskLoadMonster(Json const& diskStore) const;
  MonsterPtr netLoadMonster(ByteArray const& netStore, NetCompatibilityRules rules = {}) const;

  List<Drawable> monsterPortrait(MonsterVariant const& variant) const;

  pair<String, String> skillInfo(String const& skillName) const;
  Json skillConfigParameter(String const& skillName, String const& configParameterName) const;

  ColorReplaceMap colorSwap(String const& setName, uint64_t seed) const;

private:
  struct MonsterType {
    String typeName;
    Maybe<String> shortDescription;
    Maybe<String> description;

    StringList categories;
    StringList partTypes;

    String animationConfigPath;
    String colors;
    bool reversed;

    JsonArray dropPools;

    Json baseParameters;

    // Additional part-specific parameters which will override any part-specific
    // parameters (such as skills, sounds, etc.) defined in individual .monsterpart files
    Json partParameterOverrides;

    // Description of all part parameters, and how they are combined and with
    // what defaults.
    Json partParameterDescription;
  };

  struct MonsterPart {
    String name;
    String category;
    String type;

    String path;
    JsonObject frames;
    Json partParameters;
  };

  struct MonsterSkill {
    String name;
    String label;
    String image;

    Json config;
    Json parameters;
    Json animationParameters;
  };

  // Merges part configuration by the method specified in the part parameter
  // config.
  static Json mergePartParameters(Json const& partParameterDescription, JsonArray const& parameters);

  // Merges final monster variant parameters together according to the
  // hard-coded variant merge rules (handles things like scripts which are
  // combined rather than overwritten)
  static Json mergeFinalParameters(JsonArray const& parameters);

  // Reads common parameters out of parameters map
  static void readCommonParameters(MonsterVariant& monsterVariant);

  // Maps category name -> part type -> part name -> MonsterPart.  part name ->
  // MonsterPart needs to be be in a predictable order.
  typedef StringMap<StringMap<Map<String, MonsterPart>>> PartDirectory;

  MonsterVariant produceMonster(String const& typeName, uint64_t seed, Json const& uniqueParameters) const;

  // Given a variant including parameters for baseSkills and specialSkills,
  // returns a variant containing a final 'skills' list of chosen skills, also
  // merges animation configs from skills together.
  pair<Json, Json> chooseSkills(Json const& parameters, Json const& animatorConfig, RandomSource& rand) const;

  StringMap<MonsterType> m_monsterTypes;
  PartDirectory m_partDirectory;
  StringMap<MonsterSkill> m_skills;
  StringMap<List<ColorReplaceMap>> m_colorSwaps;

  mutable Mutex m_cacheMutex;

  // Key here is the type name, seed, and the serialized unique parameters JSON
  mutable HashTtlCache<tuple<String, uint64_t, Json>, MonsterVariant> m_monsterCache;
};

}