Compare commits
No commits in common. "6410de196faa252765d5a9d413275869f0a04a12" and "6bc9d4df9d2c843e94afaceef1e502c2e2091074" have entirely different histories.
6410de196f
...
6bc9d4df9d
@ -25,10 +25,11 @@ dependencies {
|
|||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
|
|
||||||
|
implementation 'org.yaml:snakeyaml:2.2'
|
||||||
implementation 'org.ojalgo:ojalgo:54.0.0'
|
implementation 'org.ojalgo:ojalgo:54.0.0'
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'
|
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'
|
||||||
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.17.1'
|
|
||||||
implementation 'org.json:json:20240303'
|
implementation 'org.json:json:20240303'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test') {
|
tasks.named('test') {
|
||||||
|
|||||||
@ -1,36 +1,19 @@
|
|||||||
package com.bernard.greposimu;
|
package com.bernard.greposimu;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
import com.bernard.greposimu.model.game.GrepoYaml;
|
|
||||||
import com.bernard.greposimu.model.simulator.objective.TownObjective;
|
|
||||||
import com.fasterxml.jackson.databind.JavaType;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class GrepoSimuApplication {
|
public class GrepoSimuApplication {
|
||||||
|
|
||||||
public static GameConfig GREPOLIS_GC;
|
public static GameConfig GREPOLIS_GC;
|
||||||
public static Map<String, TownObjective> OBJECTIVES;
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
GREPOLIS_GC = GrepoSimu.makeGameData();
|
GREPOLIS_GC = GrepoSimu.makeGameData();
|
||||||
File objectiveFile = new File("/home/mysaa/Documents/Projets/eclipse-workspace/GrepoSimu/src/test/resources/objectives.yml");
|
|
||||||
|
|
||||||
ObjectMapper om = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER));
|
|
||||||
om.registerModule(new GrepoYaml(GREPOLIS_GC));
|
|
||||||
|
|
||||||
JavaType objType = om.getTypeFactory().constructParametricType(Map.class, String.class,TownObjective.class);
|
|
||||||
OBJECTIVES = om.readValue(objectiveFile, objType);
|
|
||||||
|
|
||||||
SpringApplication.run(GrepoSimuApplication.class, args);
|
SpringApplication.run(GrepoSimuApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,8 @@ import java.util.Iterator;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
import com.bernard.greposimu.model.game.Identified;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
@ -27,12 +25,6 @@ public class Utils {
|
|||||||
public static final <T extends Identified> T getIdentified(Set<T> set, String id) {
|
public static final <T extends Identified> T getIdentified(Set<T> set, String id) {
|
||||||
return set.stream().filter(x -> x.getId().equals(id)).findAny().orElse(null);
|
return set.stream().filter(x -> x.getId().equals(id)).findAny().orElse(null);
|
||||||
}
|
}
|
||||||
public static final <T extends Identified> T throwingGetIdentified(String type, Set<T> set,String id){
|
|
||||||
if(id == null)return null;
|
|
||||||
T out = Utils.getIdentified(set, id);
|
|
||||||
if(out==null) throw new IllegalArgumentException("Could not find "+type+" of id "+id);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final <E extends Enum<E>> EnumSet<E> toEnumSet(Class<E> c,Set<E> set){
|
public static final <E extends Enum<E>> EnumSet<E> toEnumSet(Class<E> c,Set<E> set){
|
||||||
if(set.isEmpty())
|
if(set.isEmpty())
|
||||||
@ -41,12 +33,6 @@ public class Utils {
|
|||||||
return EnumSet.copyOf(set);
|
return EnumSet.copyOf(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final <K,E,F> Map<K,F> mapValue(Map<K,E> map,Function<E,F> f){
|
|
||||||
return map.keySet().stream().collect(Collectors.toMap(
|
|
||||||
Function.identity(),
|
|
||||||
k -> f.apply(map.get(k))));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final <T> Map<T,Boolean> setToMap(Set<T> set){
|
public static final <T> Map<T,Boolean> setToMap(Set<T> set){
|
||||||
return new AbstractMap<T,Boolean>() {
|
return new AbstractMap<T,Boolean>() {
|
||||||
|
|
||||||
|
|||||||
@ -9,22 +9,19 @@ import java.util.function.Function;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.Utils;
|
import com.bernard.greposimu.Utils;
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
import com.bernard.greposimu.model.game.God;
|
||||||
|
import com.bernard.greposimu.model.game.Resources;
|
||||||
import com.bernard.greposimu.model.game.powers.FuryPower;
|
import com.bernard.greposimu.model.game.powers.FuryPower;
|
||||||
import com.bernard.greposimu.model.game.powers.GodPower;
|
import com.bernard.greposimu.model.game.powers.GodPower;
|
||||||
|
import com.bernard.greposimu.model.game.powers.MultitypePower;
|
||||||
import com.bernard.greposimu.model.game.powers.Power;
|
import com.bernard.greposimu.model.game.powers.Power;
|
||||||
import com.bernard.greposimu.model.game.powers.Power.AreaOfEffect;
|
|
||||||
import com.bernard.greposimu.model.game.powers.Power.Effect;
|
|
||||||
import com.bernard.greposimu.model.game.powers.Power.Target;
|
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
import com.bernard.greposimu.model.game.units.FightType;
|
import com.bernard.greposimu.model.game.units.FightType;
|
||||||
import com.bernard.greposimu.model.game.units.Hero;
|
import com.bernard.greposimu.model.game.units.Hero;
|
||||||
import com.bernard.greposimu.model.game.units.Hero.HeroCategory;
|
import com.bernard.greposimu.model.game.units.Hero.HeroCategory;
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.game.units.NavalUnit;
|
import com.bernard.greposimu.model.game.units.NavalUnit;
|
||||||
import com.bernard.greposimu.model.game.units.TerrestrialUnit;
|
import com.bernard.greposimu.model.game.units.TerrestrialUnit;
|
||||||
import com.bernard.greposimu.model.game.units.TransportUnit;
|
import com.bernard.greposimu.model.game.units.TransportUnit;
|
||||||
@ -45,61 +42,111 @@ public class JSONReader {
|
|||||||
for(String p : powersJ.keySet()) {
|
for(String p : powersJ.keySet()) {
|
||||||
JSONObject power = powersJ.getJSONObject(p);
|
JSONObject power = powersJ.getJSONObject(p);
|
||||||
JSONObject metadefaults = power.isNull("meta_defaults")?null:power.getJSONObject("meta_defaults");
|
JSONObject metadefaults = power.isNull("meta_defaults")?null:power.getJSONObject("meta_defaults");
|
||||||
String id = power.getString("id");
|
if(power.isNull("god_id") || power.getString("god_id").isEmpty()) {
|
||||||
EnumSet<Target> targets = Utils.toEnumSet(Power.Target.class,power.getJSONArray("targets").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet()));
|
// DETECTING TYPE DEPEDENCY
|
||||||
EnumSet<Target> seedsTo = Utils.toEnumSet(Power.Target.class,power.getJSONArray("seeds_to").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet()));
|
boolean dependent =
|
||||||
|
power.optJSONObject("name")!=null ||
|
||||||
String shortEffect = power.isNull("short_effect")?null:power.getString("short_effect");
|
|
||||||
Power.Group powerGroup = getPowerGroup(power.getString("power_group"));
|
|
||||||
int powerGroupLevel = power.getInt("power_group_level");
|
|
||||||
|
|
||||||
//name
|
|
||||||
Set<String> metaFields = power.getJSONArray("meta_fields").toList().stream().map(v -> (String)v).collect(Collectors.toSet());
|
|
||||||
Map<String,Object> metaDefaults = metadefaults==null?Map.of():metadefaults.toMap();
|
|
||||||
|
|
||||||
|
|
||||||
int lifetime = power.getInt("lifetime");
|
|
||||||
|
|
||||||
EnumSet<Power.Tag> tags = getPowerTags(power);
|
|
||||||
EnumSet<Effect> effects = Utils.toEnumSet(Power.Effect.class,power.getJSONArray("effects").toList().stream().map(k -> getPowerEffect((String)k)).collect(Collectors.toSet()));
|
|
||||||
Set<String> compatiblePowers = power.isNull("compatible_powers")?Set.of():power.getJSONArray("compatible_powers").toList().stream().map(v -> (String)v).collect(Collectors.toSet());
|
|
||||||
EnumSet<AreaOfEffect> areaOfEffect = Utils.toEnumSet(Power.AreaOfEffect.class,power.getJSONArray("area_of_effect").toList().stream().map(k -> getPowerAOE((String)k)).collect(Collectors.toSet()));
|
|
||||||
|
|
||||||
boolean dependent =
|
|
||||||
power.optJSONObject("name")!=null ||
|
|
||||||
power.optJSONObject("effect")!=null ||
|
power.optJSONObject("effect")!=null ||
|
||||||
power.optJSONObject("description")!=null;
|
power.optJSONObject("description")!=null;
|
||||||
String configType = dependent?
|
String dependentKind = dependent?
|
||||||
(metadefaults != null && metadefaults.has("type"))?"type":
|
(metadefaults != null && metadefaults.has("type"))?"type":
|
||||||
(metadefaults != null && metadefaults.has("god"))?"god":"unknown"
|
(metadefaults != null && metadefaults.has("god"))?"god":"unknown"
|
||||||
:null;
|
:null;
|
||||||
|
|
||||||
// for each X, either X or XM should be null. if one XM is not null, configType should be set
|
if(dependent) {
|
||||||
String name = (power.optJSONObject("name")==null)?power.optString("name"):null;
|
Set<String> kinds =
|
||||||
String effect = (power.optJSONObject("effect")==null)?power.optString("effect"):null;
|
Optional.ofNullable(power.optJSONObject("name"))
|
||||||
String description = (power.optJSONObject("description")==null)?power.optString("description"):null;
|
.orElseGet(() -> Optional.ofNullable(power.optJSONObject("effect"))
|
||||||
|
.orElseGet(() -> power.optJSONObject("description"))
|
||||||
Map<String,String> nameM = (name==null)?Utils.mapValue(power.getJSONObject("name").getJSONObject(configType).toMap(),v -> (String)v):null;
|
).getJSONObject(dependentKind).keySet();
|
||||||
Map<String,String> effectM = (effect==null)?Utils.mapValue(power.getJSONObject("effect").getJSONObject(configType).toMap(),v -> (String)v):null;
|
for(String kind : kinds){
|
||||||
Map<String,String> descriptionM = (description==null)?Utils.mapValue(power.getJSONObject("description").getJSONObject(configType).toMap(),v -> (String)v):null;
|
powers.add(new MultitypePower(
|
||||||
|
power.getString("id")+":"+kind,
|
||||||
if(!power.isNull("god_id") && !power.getString("god_id").isEmpty()) {
|
Optional.ofNullable(power.optString("name")).orElseGet(() -> power.getJSONObject("name").getJSONObject(dependentKind).getString(kind)),
|
||||||
God god = gods.stream().filter(g -> g.getId().equals(power.getString("god_id"))).findAny().get();
|
Optional.ofNullable(power.optString("description")).orElseGet(() -> power.getJSONObject("description").getJSONObject(dependentKind).getString(kind)),
|
||||||
int favorCost = power.getInt("favor");
|
power.isNull("short_effect")?null:power.getString("short_effect"),
|
||||||
int templeLevelSumDepedency = power.isNull("temple_level_sum_dependency")?0:power.getInt("temple_level_sum_dependency");
|
Optional.ofNullable(power.optString("effect")).orElseGet(() -> power.getJSONObject("effect").getJSONObject(dependentKind).getString(kind)),
|
||||||
|
Utils.toEnumSet(Power.Target.class,power.getJSONArray("targets").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet())),
|
||||||
if(power.getInt("fury_percentage_cost") != 0) {
|
Utils.toEnumSet(Power.Target.class,power.getJSONArray("seeds_to").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet())),
|
||||||
// FuryPower
|
getPowerGroup(power.getString("power_group")),
|
||||||
int furyPercentageCost = power.getInt("fury_percentage_cost");
|
power.getBoolean("negative"),
|
||||||
powers.add(new FuryPower(id, targets, seedsTo, shortEffect, powerGroup, powerGroupLevel, metaFields, metaDefaults, lifetime, effects, tags, compatiblePowers, areaOfEffect, name, effect, description, configType, nameM, effectM, descriptionM,
|
power.getInt("power_group_level"),
|
||||||
god, favorCost, templeLevelSumDepedency, furyPercentageCost));
|
Utils.toEnumSet(Power.Effect.class,power.getJSONArray("effects").toList().stream().map(k -> getPowerEffect((String)k)).collect(Collectors.toSet())),
|
||||||
} else {
|
power.getBoolean("ignores_democritus"),
|
||||||
// GodPower
|
Utils.toEnumSet(Power.AreaOfEffect.class,power.getJSONArray("area_of_effect").toList().stream().map(k -> getPowerAOE((String)k)).collect(Collectors.toSet())),
|
||||||
powers.add(new GodPower(id, targets, seedsTo, shortEffect, powerGroup, powerGroupLevel, metaFields, metaDefaults, lifetime, effects, tags, compatiblePowers, areaOfEffect, name, effect, description, configType, nameM, effectM, descriptionM, god, favorCost, templeLevelSumDepedency));
|
getPowerTags(power),
|
||||||
}
|
power.getInt("lifetime"),
|
||||||
} else {
|
metadefaults==null?Map.of():metadefaults.toMap(),
|
||||||
powers.add(new Power(id, targets, seedsTo, shortEffect, powerGroup, powerGroupLevel, metaFields, metaDefaults, lifetime, effects, tags, compatiblePowers, areaOfEffect, name, effect, description, configType, nameM, effectM, descriptionM));
|
power.getString("id")
|
||||||
}
|
));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
powers.add(new Power(
|
||||||
|
power.getString("id"),
|
||||||
|
power.getString("name"),
|
||||||
|
power.getString("description"),
|
||||||
|
power.isNull("short_effect")?null:power.getString("short_effect"),
|
||||||
|
power.getString("effect"),
|
||||||
|
Utils.toEnumSet(Power.Target.class,power.getJSONArray("targets").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet())),
|
||||||
|
Utils.toEnumSet(Power.Target.class,power.getJSONArray("seeds_to").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet())),
|
||||||
|
getPowerGroup(power.getString("power_group")),
|
||||||
|
power.getBoolean("negative"),
|
||||||
|
power.getInt("power_group_level"),
|
||||||
|
Utils.toEnumSet(Power.Effect.class,power.getJSONArray("effects").toList().stream().map(k -> getPowerEffect((String)k)).collect(Collectors.toSet())),
|
||||||
|
power.getBoolean("ignores_democritus"),
|
||||||
|
Utils.toEnumSet(Power.AreaOfEffect.class,power.getJSONArray("area_of_effect").toList().stream().map(k -> getPowerAOE((String)k)).collect(Collectors.toSet())),
|
||||||
|
getPowerTags(power),
|
||||||
|
power.getInt("lifetime"),
|
||||||
|
metadefaults==null?Map.of():metadefaults.toMap()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(power.getInt("fury_percentage_cost") != 0) {
|
||||||
|
powers.add(new FuryPower(
|
||||||
|
power.getString("id"),
|
||||||
|
power.getString("name"),
|
||||||
|
power.getString("description"),
|
||||||
|
power.isNull("short_effect")?null:power.getString("short_effect"),
|
||||||
|
Optional.ofNullable(power.optString("effect")).orElseGet(() -> power.optJSONObject("effect").getString("not_cast")),
|
||||||
|
Utils.toEnumSet(Power.Target.class,power.getJSONArray("targets").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet())),
|
||||||
|
Utils.toEnumSet(Power.Target.class,power.getJSONArray("seeds_to").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet())),
|
||||||
|
getPowerGroup(power.getString("power_group")),
|
||||||
|
power.getBoolean("negative"),
|
||||||
|
power.getInt("power_group_level"),
|
||||||
|
Utils.toEnumSet(Power.Effect.class,power.getJSONArray("effects").toList().stream().map(k -> getPowerEffect((String)k)).collect(Collectors.toSet())),
|
||||||
|
power.getBoolean("ignores_democritus"),
|
||||||
|
Utils.toEnumSet(Power.AreaOfEffect.class,power.getJSONArray("area_of_effect").toList().stream().map(k -> getPowerAOE((String)k)).collect(Collectors.toSet())),
|
||||||
|
getPowerTags(power),
|
||||||
|
power.getInt("lifetime"),
|
||||||
|
metadefaults==null?Map.of():metadefaults.toMap(),
|
||||||
|
power.isNull("god_id")?null:gods.stream().filter(g -> g.getId().equals(power.getString("god_id"))).findAny().get(),
|
||||||
|
power.getInt("favor"),
|
||||||
|
power.isNull("temple_level_sum_dependency")?0:power.getInt("temple_level_sum_dependency"),
|
||||||
|
power.getInt("fury_percentage_cost")/100.0
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
powers.add(new GodPower(
|
||||||
|
power.getString("id"),
|
||||||
|
power.getString("name"),
|
||||||
|
power.getString("description"),
|
||||||
|
power.isNull("short_effect")?null:power.getString("short_effect"),
|
||||||
|
Optional.ofNullable(power.optString("effect")).orElseGet(() -> power.optJSONObject("effect").getString("not_cast")),
|
||||||
|
Utils.toEnumSet(Power.Target.class,power.getJSONArray("targets").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet())),
|
||||||
|
Utils.toEnumSet(Power.Target.class,power.getJSONArray("seeds_to").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet())),
|
||||||
|
getPowerGroup(power.getString("power_group")),
|
||||||
|
power.getBoolean("negative"),
|
||||||
|
power.getInt("power_group_level"),
|
||||||
|
Utils.toEnumSet(Power.Effect.class,power.getJSONArray("effects").toList().stream().map(k -> getPowerEffect((String)k)).collect(Collectors.toSet())),
|
||||||
|
power.getBoolean("ignores_democritus"),
|
||||||
|
Utils.toEnumSet(Power.AreaOfEffect.class,power.getJSONArray("area_of_effect").toList().stream().map(k -> getPowerAOE((String)k)).collect(Collectors.toSet())),
|
||||||
|
getPowerTags(power),
|
||||||
|
power.getInt("lifetime"),
|
||||||
|
metadefaults==null?Map.of():metadefaults.toMap(),
|
||||||
|
power.isNull("god_id")?null:gods.stream().filter(g -> g.getId().equals(power.getString("god_id"))).findAny().get(),
|
||||||
|
power.getInt("favor"),
|
||||||
|
power.isNull("temple_level_sum_dependency")?0:power.getInt("temple_level_sum_dependency")
|
||||||
|
));}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONObject researchesJ = json.getJSONObject("researches");
|
JSONObject researchesJ = json.getJSONObject("researches");
|
||||||
@ -258,13 +305,8 @@ public class JSONReader {
|
|||||||
if(o.getBoolean("removed_on_target_loss"))out.add(Power.Tag.REMOVED_ON_TARGET_LOSS);
|
if(o.getBoolean("removed_on_target_loss"))out.add(Power.Tag.REMOVED_ON_TARGET_LOSS);
|
||||||
if(o.getBoolean("requires_god"))out.add(Power.Tag.REQUIRES_GOD);
|
if(o.getBoolean("requires_god"))out.add(Power.Tag.REQUIRES_GOD);
|
||||||
if(o.getBoolean("no_lifetime"))out.add(Power.Tag.NO_LIFETIME);
|
if(o.getBoolean("no_lifetime"))out.add(Power.Tag.NO_LIFETIME);
|
||||||
if(o.getBoolean("only_own_towns"))out.add(Power.Tag.ONLY_OWN_TOWNS);
|
|
||||||
if(o.getBoolean("negative"))out.add(Power.Tag.NEGATIVE);
|
|
||||||
if(o.getBoolean("ignores_democritus"))out.add(Power.Tag.IGNORES_DEMOCRITUS);
|
|
||||||
if(o.getBoolean("boost"))out.add(Power.Tag.BOOST);
|
|
||||||
return Utils.toEnumSet(Power.Tag.class,out);
|
return Utils.toEnumSet(Power.Tag.class,out);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Power.AreaOfEffect getPowerAOE(String s){
|
private static Power.AreaOfEffect getPowerAOE(String s){
|
||||||
switch(s) {
|
switch(s) {
|
||||||
case "area_of_effect_build_time": return Power.AreaOfEffect.BUILDTIME;
|
case "area_of_effect_build_time": return Power.AreaOfEffect.BUILDTIME;
|
||||||
|
|||||||
@ -1,76 +0,0 @@
|
|||||||
package com.bernard.greposimu.controller;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.GrepoSimuApplication;
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.simulator.command.Command;
|
|
||||||
import com.bernard.greposimu.model.simulator.command.TownCommand;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.SimulatorData;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Ville;
|
|
||||||
import com.bernard.greposimu.model.simulator.objective.TownObjective;
|
|
||||||
import com.bernard.greposimu.source.JSONSourcer;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
public class SchedulerController {
|
|
||||||
|
|
||||||
Map<UUID,SimulatorData> registered = new HashMap<>();
|
|
||||||
|
|
||||||
@CrossOrigin
|
|
||||||
@PostMapping(value = "/registerScheduler", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.TEXT_PLAIN_VALUE)
|
|
||||||
//@GetMapping(value = "/registerScheduler")
|
|
||||||
public @ResponseBody String register(Model model,@RequestBody String data) {
|
|
||||||
//System.out.println(data.toString());
|
|
||||||
GameConfig gc = GrepoSimuApplication.GREPOLIS_GC;
|
|
||||||
SimulatorData sd = JSONSourcer.makeSimulationData(data.toString(),gc);
|
|
||||||
|
|
||||||
UUID uuid = UUID.randomUUID();
|
|
||||||
registered.put(uuid, sd);
|
|
||||||
|
|
||||||
return uuid.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = "/scheduler/{uuid}")
|
|
||||||
public String simulator(Model model, @PathVariable("uuid") String uuidStr) {
|
|
||||||
UUID uuid = UUID.fromString(uuidStr);
|
|
||||||
|
|
||||||
GameConfig gc = GrepoSimuApplication.GREPOLIS_GC;
|
|
||||||
SimulatorData sd = registered.get(uuid);
|
|
||||||
|
|
||||||
TownObjective defObjective = GrepoSimuApplication.OBJECTIVES.get("defTerTown");
|
|
||||||
defObjective.setGc(gc);
|
|
||||||
|
|
||||||
StringBuilder out = new StringBuilder();
|
|
||||||
for(Ville v : sd.getVilles().values()) {
|
|
||||||
out.append("<h3>==== Ville "+v.getNom()+" ====</h3>\n");
|
|
||||||
out.append("<ul>");
|
|
||||||
for(Command c : defObjective.getDifferences(v)){
|
|
||||||
out.append("<li>");
|
|
||||||
out.append(c.toString());
|
|
||||||
out.append("===>");
|
|
||||||
out.append(c.timeNeeded(sd));
|
|
||||||
if(c instanceof TownCommand)
|
|
||||||
out.append("///"+((TownCommand)c).neededResources(sd).toString());
|
|
||||||
out.append("</li>\n");
|
|
||||||
}
|
|
||||||
out.append(defObjective.getDifferences(v).stream().map(Command::toString).sorted().collect(Collectors.joining("<br/>\n")));
|
|
||||||
out.append("</ul>");
|
|
||||||
}
|
|
||||||
model.addAttribute("raw",out.toString());
|
|
||||||
return "debug";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -11,6 +11,7 @@ import org.springframework.stereotype.Controller;
|
|||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import com.bernard.greposimu.GrepoSimuApplication;
|
import com.bernard.greposimu.GrepoSimuApplication;
|
||||||
@ -20,7 +21,7 @@ import com.bernard.greposimu.model.DefContext;
|
|||||||
import com.bernard.greposimu.model.FightStats;
|
import com.bernard.greposimu.model.FightStats;
|
||||||
import com.bernard.greposimu.model.OffContext;
|
import com.bernard.greposimu.model.OffContext;
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
import com.bernard.greposimu.model.game.God;
|
||||||
import com.bernard.greposimu.model.game.units.Unit;
|
import com.bernard.greposimu.model.game.units.Unit;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
@ -47,6 +48,7 @@ public class SimulatorController {
|
|||||||
return "simulator";
|
return "simulator";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/simulate")
|
||||||
@GetMapping("/simulate")
|
@GetMapping("/simulate")
|
||||||
public String simulate(@ModelAttribute SimulatorParams params, Model model) throws IOException {
|
public String simulate(@ModelAttribute SimulatorParams params, Model model) throws IOException {
|
||||||
if(params == null)
|
if(params == null)
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import com.bernard.greposimu.model.DefContext;
|
|||||||
import com.bernard.greposimu.model.FightStats;
|
import com.bernard.greposimu.model.FightStats;
|
||||||
import com.bernard.greposimu.model.OffContext;
|
import com.bernard.greposimu.model.OffContext;
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
import com.bernard.greposimu.model.game.units.FightType;
|
import com.bernard.greposimu.model.game.units.FightType;
|
||||||
import com.bernard.greposimu.model.game.units.NavalUnit;
|
import com.bernard.greposimu.model.game.units.NavalUnit;
|
||||||
import com.bernard.greposimu.model.game.units.TerrestrialUnit;
|
import com.bernard.greposimu.model.game.units.TerrestrialUnit;
|
||||||
|
|||||||
26
src/main/java/com/bernard/greposimu/model/game/Building.java
Normal file
26
src/main/java/com/bernard/greposimu/model/game/Building.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package com.bernard.greposimu.model.game;
|
||||||
|
|
||||||
|
public enum Building {
|
||||||
|
AGORA,
|
||||||
|
SENAT,
|
||||||
|
SCIERIE,
|
||||||
|
FERME,
|
||||||
|
CARRIERE,
|
||||||
|
ENTREPOT,
|
||||||
|
MINE,
|
||||||
|
CASERNE,
|
||||||
|
TEMPLE,
|
||||||
|
MARCHE,
|
||||||
|
PORT,
|
||||||
|
ACADEMIE,
|
||||||
|
REMPARTS,
|
||||||
|
GROTTE,
|
||||||
|
THEATRE,
|
||||||
|
THERMES,
|
||||||
|
BIBLIOTHEQUE,
|
||||||
|
PHARE,
|
||||||
|
TOUR,
|
||||||
|
STATUE,
|
||||||
|
ORACLE,
|
||||||
|
COMPTOIR;
|
||||||
|
}
|
||||||
@ -1,22 +1,13 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
package com.bernard.greposimu.model.game;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.Utils;
|
import com.bernard.greposimu.Utils;
|
||||||
import com.bernard.greposimu.model.game.buildings.Building;
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
|
||||||
import com.bernard.greposimu.model.game.powers.Power;
|
import com.bernard.greposimu.model.game.powers.Power;
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
import com.bernard.greposimu.model.game.units.Hero;
|
import com.bernard.greposimu.model.game.units.Hero;
|
||||||
import com.bernard.greposimu.model.game.units.Unit;
|
import com.bernard.greposimu.model.game.units.Unit;
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.game.util.UnitResources;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.CastedPower;
|
|
||||||
|
|
||||||
public class GameConfig {
|
public class GameConfig {
|
||||||
|
|
||||||
@ -31,6 +22,8 @@ public class GameConfig {
|
|||||||
|
|
||||||
Set<Power> powers;
|
Set<Power> powers;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public GameConfig(Set<God> gods, Set<Unit> units, Set<Hero> heroes, Set<Research> researches, Set<Power> powers) {
|
public GameConfig(Set<God> gods, Set<Unit> units, Set<Hero> heroes, Set<Research> researches, Set<Power> powers) {
|
||||||
this.gods = gods;
|
this.gods = gods;
|
||||||
this.units = units;
|
this.units = units;
|
||||||
@ -48,260 +41,21 @@ public class GameConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Unit getUnit(String id) {
|
public Unit getUnit(String id) {
|
||||||
return Utils.throwingGetIdentified("unit",this.units, id);
|
return Utils.getIdentified(this.units, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Hero> getHeroes() {
|
public Set<Hero> getHeroes() {
|
||||||
return Collections.unmodifiableSet(this.heroes);
|
return Collections.unmodifiableSet(this.heroes);
|
||||||
}
|
}
|
||||||
public Hero getHero(String id) {
|
public Hero getHero(String id) {
|
||||||
return Utils.throwingGetIdentified("hero",this.heroes, id);
|
return Utils.getIdentified(this.heroes, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Research> getResearches() {
|
public Set<Research> getResearches() {
|
||||||
return Collections.unmodifiableSet(this.researches);
|
return Collections.unmodifiableSet(this.researches);
|
||||||
}
|
}
|
||||||
public Research getResearch(String id) {
|
public Research getResearch(String id) {
|
||||||
return Utils.throwingGetIdentified("research",this.researches, id);
|
return Utils.getIdentified(this.researches, id);
|
||||||
}
|
|
||||||
|
|
||||||
public Building getBuilding(String bid) {
|
|
||||||
return Utils.throwingGetIdentified("building", Set.of(Building.values()), bid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public God getGod(String god) {
|
|
||||||
return Utils.throwingGetIdentified("god", this.gods, god);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Building> getBuildings() {
|
|
||||||
return Set.of(Building.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Power> getPowers() {
|
|
||||||
return powers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Power getPower(String pid){
|
|
||||||
System.out.println(powers.stream().map(Power::getId).sorted().collect(Collectors.joining("\n")));
|
|
||||||
return Utils.throwingGetIdentified("power", powers, pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T extends Identified> T getIdentified(Class<T> clazz, String id) {
|
|
||||||
if(Unit.class.isAssignableFrom(clazz))
|
|
||||||
return (T)this.getUnit(id);
|
|
||||||
if(Hero.class.isAssignableFrom(clazz))
|
|
||||||
return (T)this.getHero(id);
|
|
||||||
if(Research.class.isAssignableFrom(clazz))
|
|
||||||
return (T)this.getResearch(id);
|
|
||||||
if(God.class.isAssignableFrom(clazz))
|
|
||||||
return (T)this.getGod(id);
|
|
||||||
if(Building.class.isAssignableFrom(clazz))
|
|
||||||
return (T)this.getBuilding(id);
|
|
||||||
if(Power.class.isAssignableFrom(clazz))
|
|
||||||
return (T)this.getPower(id);
|
|
||||||
throw new UnsupportedOperationException("Cannot get identified object of class "+clazz.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getTotalPop(int farmLevel, boolean thermal, boolean charrue, boolean pygmallion, int bonus) {
|
|
||||||
int tot = Building.getFarmPopulation(farmLevel);
|
|
||||||
if(thermal)tot = (int)Math.floor(tot*1.1);
|
|
||||||
if(charrue)tot += 200;
|
|
||||||
if(pygmallion)tot += 5*farmLevel;
|
|
||||||
tot += bonus;
|
|
||||||
return tot;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************/
|
|
||||||
/* COMPUTING METHODS */
|
|
||||||
/*********************/
|
|
||||||
|
|
||||||
private double callOfTheOceanBonus = 0.5;
|
|
||||||
private double fertilityImprovementBonus = 0.5;
|
|
||||||
private double shipwrightBonus = 0.1;
|
|
||||||
private double instructorBonus = 0.1;
|
|
||||||
private double conscriptionBonus = 0.1;
|
|
||||||
private double mathematicsBonus = 0.1;
|
|
||||||
private double architectureBonus = 0.1;
|
|
||||||
private double craneBonus = 0.15;
|
|
||||||
|
|
||||||
private double heroBonus(Hero h, int level) { return h.getPowerBaseValue() + level*h.getPowerValuePerLevel();}
|
|
||||||
|
|
||||||
private List<Double> senateReduction = List.of(1.000 , 0.986 , 0.970 , 0.953 , 0.935 , 0.915 , 0.895 , 0.874 , 0.852 , 0.830 , 0.808 , 0.785 , 0.761 , 0.737 , 0.712 , 0.685 , 0.661 , 0.636 , 0.620 , 0.584 , 0.561 , 0.537 , 0.502 , 0.476 , 0.450);
|
|
||||||
|
|
||||||
public long getUnitBuildTime(Unit u, int barracksLevel, int navalLevel, Set<CastedPower> powers, Set<Research> researches, Hero hero, int heroLevel){
|
|
||||||
// From helpers/general_modifications.js:169
|
|
||||||
double build_time = (u.getBuildTime() * (1 - Math.pow((u.isNaval()?navalLevel:barracksLevel) - 1, 1.1) / 100));
|
|
||||||
|
|
||||||
double modification_factor_by_powers = 1;
|
|
||||||
double modification_factor_by_researches = 1;
|
|
||||||
|
|
||||||
for(CastedPower p : powers){
|
|
||||||
if (u.isNaval() && p.getPower().getId().equals("call_of_the_ocean")) {
|
|
||||||
modification_factor_by_powers -= this.callOfTheOceanBonus;
|
|
||||||
} else if (!u.isNaval() && p.getPower().getId().equals("fertility_improvement")) {
|
|
||||||
modification_factor_by_powers -= this.fertilityImprovementBonus;
|
|
||||||
} else if ( Set.of("unit_order_boost", "longterm_unit_order_boost", "assassins_unit_order_boost", "mourning", "missions_power_2")
|
|
||||||
.contains(p.getPower().getId())) {
|
|
||||||
modification_factor_by_powers -= Integer.parseInt((String)p.getConfiguration().get("percent"), 10) / 100.0;
|
|
||||||
} else if (p.getPower().getId().equals("mourning")) {
|
|
||||||
modification_factor_by_powers += Integer.parseInt((String)p.getConfiguration().get("percent"), 10) / 100.0;
|
|
||||||
} else if(p.getPower().getId().equals("great_arming")) {
|
|
||||||
modification_factor_by_powers *= (1 - Integer.parseInt((String)p.getConfiguration().get("percent"), 10) / 100.0);
|
|
||||||
}
|
|
||||||
// Alliance boost powers
|
|
||||||
if (p.getPower().getId().equals("unit_order_boost_alliance") ||
|
|
||||||
p.getPower().getId().equals("unit_order_boost_alliance_hera")) {
|
|
||||||
String type = (String)p.getConfiguration().getOrDefault("type", "");
|
|
||||||
// The configured type must either be "all" or match the type of the current unit
|
|
||||||
if (type.equals("all") || (u.isNaval() ? type.equals("naval") : type.equals("ground"))) {
|
|
||||||
modification_factor_by_powers *= 0.01 * (100 - ((Integer)p.getConfiguration().getOrDefault("percent", 0)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (u.isNaval() && researches.contains(this.getResearch("shipwright"))) {
|
|
||||||
modification_factor_by_researches -= shipwrightBonus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!u.isNaval() && researches.contains(this.getResearch("instructor"))) {
|
|
||||||
modification_factor_by_researches -= instructorBonus;
|
|
||||||
}
|
|
||||||
|
|
||||||
build_time *= modification_factor_by_powers * modification_factor_by_researches;
|
|
||||||
|
|
||||||
//TODO implement augmentation bonus from benefits
|
|
||||||
//build_time *= this.getCollection("benefits").getAugmentationBonusForUnitBuildTime();
|
|
||||||
// Code in features/benefits/collections/benefits.js:12
|
|
||||||
|
|
||||||
//TODO implement augmentation bonus from world boosts
|
|
||||||
//build_time *= this.getCollection('world_boosts').getWorldBoostFactorForUnitRecruitTime(u);
|
|
||||||
// Code in collections/world_boosts.js:16
|
|
||||||
|
|
||||||
return Math.max(1, Math.round(build_time));
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnitResources getUnitBuildResources(Unit u, int barracksLevel, int navalLevel, Set<CastedPower> powers, Set<Research> researches,Hero hero,int heroLevel){
|
|
||||||
//TODO use the real application computation (helpers/general_modifications.js:221)
|
|
||||||
Resources base = u.getBuildCost();
|
|
||||||
|
|
||||||
double modification_factor = 1;
|
|
||||||
Optional<CastedPower> power;
|
|
||||||
//finished_wonders = us.last(MM.getCollections().Wonder);
|
|
||||||
|
|
||||||
if (!u.isNaval() && researches.contains(this.getResearch("conscription")))
|
|
||||||
modification_factor *= (1 - conscriptionBonus);
|
|
||||||
|
|
||||||
if (!u.isNaval()) {
|
|
||||||
power = powers.stream().filter(p -> p.getPower().getId().equals("passionate_training")).findAny();
|
|
||||||
if (power.isPresent())
|
|
||||||
modification_factor *= (1 - Integer.parseInt((String)power.get().getConfiguration().get("percent"), 10) / 100.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (u.isNaval()) {
|
|
||||||
power = powers.stream().filter(p -> p.getPower().getId().equals("help_of_the_nereids")).findAny();
|
|
||||||
if (power.isPresent())
|
|
||||||
modification_factor *= (1 - Integer.parseInt((String)power.get().getConfiguration().get("percent"), 10) / 100.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
power = powers.stream().filter(p -> p.getPower().getId().equals("great_arming")).findAny();
|
|
||||||
if (power.isPresent())
|
|
||||||
modification_factor *= (1 - Integer.parseInt((String)power.get().getConfiguration().get("percent"), 10) / 100.0);
|
|
||||||
|
|
||||||
if (u.isNaval() && researches.contains(this.getResearch("mathematics")))
|
|
||||||
modification_factor *= (1 - mathematicsBonus);
|
|
||||||
|
|
||||||
|
|
||||||
// TODO take wonders into account
|
|
||||||
// finished_wonders.hasWonder('mausoleum_of_halicarnassus')
|
|
||||||
|
|
||||||
if (u.getId().equals("hoplite") && heroLevel != 0 && hero.getId().equals("cheiron"))
|
|
||||||
modification_factor *= (1 - heroBonus(hero, heroLevel));
|
|
||||||
if (u.getId().equals("archer") && heroLevel != 0 && hero.getId().equals("philoctetes"))
|
|
||||||
modification_factor *= (1 - heroBonus(hero, heroLevel));
|
|
||||||
if (u.getId().equals("sword") && heroLevel != 0 && hero.getId().equals("odysseus"))
|
|
||||||
modification_factor *= (1 - heroBonus(hero, heroLevel));
|
|
||||||
if (u.getId().equals("attack_ship") && heroLevel != 0 && hero.getId().equals("aristotle"))
|
|
||||||
modification_factor *= (1 - heroBonus(hero, heroLevel));
|
|
||||||
if (u.getId().equals("bireme") && heroLevel != 0 && hero.getId().equals("daidalos"))
|
|
||||||
modification_factor *= (1 - heroBonus(hero, heroLevel));
|
|
||||||
if (u.getId().equals("trireme") && heroLevel != 0 && hero.getId().equals("eurybia"))
|
|
||||||
modification_factor *= (1 - heroBonus(hero, heroLevel));
|
|
||||||
|
|
||||||
if(u.isMythological()){
|
|
||||||
int favor_cost_modifier = 0;
|
|
||||||
|
|
||||||
power = powers.stream().filter(p -> p.getPower().getId().equals("favor_boost_alliance")).findAny();
|
|
||||||
if (power.isPresent())
|
|
||||||
favor_cost_modifier += (int)power.get().getConfiguration().get("percent");
|
|
||||||
|
|
||||||
if (heroLevel != 0 && hero.getId().equals("anysia"))
|
|
||||||
favor_cost_modifier += 10 + heroLevel * 1;
|
|
||||||
|
|
||||||
return new UnitResources(base.prod(modification_factor),
|
|
||||||
u.getGod(),(int)Math.ceil(u.getFavorCost() * (1 - (favor_cost_modifier/100))));//TODO modifier on favor cost
|
|
||||||
} else
|
|
||||||
return new UnitResources(base.prod(modification_factor));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getBuildingBuildingTime(Building b, int toLevel, int senateLevel, Set<CastedPower> powers, Set<Research> researches, Hero hero, int heroLevel){
|
|
||||||
//TODO check this function is correct
|
|
||||||
double modification_factor = 1.0;
|
|
||||||
//TODO take availability into consideration
|
|
||||||
// models/heroes/player_hero.js:165
|
|
||||||
if (heroLevel != 0 && hero.getId().equals("christopholus"))
|
|
||||||
modification_factor *= (1 - heroBonus(hero, heroLevel));
|
|
||||||
|
|
||||||
if (researches.contains(this.getResearch("building_crane"))) {
|
|
||||||
modification_factor -= craneBonus;
|
|
||||||
}
|
|
||||||
Optional<CastedPower> power = powers.stream().filter(p -> p.getPower().getId().endsWith("building_order_boost")).findAny();
|
|
||||||
if (power.isPresent())
|
|
||||||
modification_factor *= (1 - Integer.parseInt((String)power.get().getConfiguration().get("percent"), 10) / 100.0);
|
|
||||||
|
|
||||||
long time = (long) (b.getBuildTime(toLevel) * senateReduction.get(senateLevel-1));
|
|
||||||
time = (long) Math.floor(time * modification_factor);
|
|
||||||
if (time < 1) time = 1;
|
|
||||||
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Resources getBuildingBuildingResources(Building b, int toLevel, int senateLevel, Set<CastedPower> powers, Set<Research> researches, Hero hero, int heroLevel){
|
|
||||||
//TODO check this function is correct
|
|
||||||
double modification_factor = 1;
|
|
||||||
if (researches.contains(this.getResearch("architecture"))) {
|
|
||||||
modification_factor -= architectureBonus;
|
|
||||||
}
|
|
||||||
|
|
||||||
return b.getRequiredResources(toLevel).prod(modification_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getBuildingTearDownTime(Building b, int toLevel, int senateLevel, Set<CastedPower> powers, Set<Research> researches, Hero hero, int heroLevel){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getResearchTime(Research r, int academyLevel, Set<CastedPower> powers, Hero hero, int heroLevel){
|
|
||||||
double modification_factor = 1.0;
|
|
||||||
//TODO take availability into consideration
|
|
||||||
// models/heroes/player_hero.js:165
|
|
||||||
if (heroLevel != 0 && hero.getId().equals("apheledes"))
|
|
||||||
modification_factor *= (1 - heroBonus(hero, heroLevel));
|
|
||||||
|
|
||||||
long time = (long) (r.getRequiredTime() * ((100 - Math.pow(academyLevel, 1.1)) / 100));
|
|
||||||
time = (long) Math.floor(time * modification_factor);
|
|
||||||
if (time < 1) time = 1;
|
|
||||||
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Resources getResearchResources(Research r, int academyLevel, Set<CastedPower> powers, Hero hero, int heroLevel){
|
|
||||||
double modification_factor = 1.0;
|
|
||||||
//TODO take availability into consideration
|
|
||||||
// models/heroes/player_hero.js:165
|
|
||||||
if (heroLevel != 0 && hero.getId().equals("apheledes"))
|
|
||||||
modification_factor *= (1 - heroBonus(hero, heroLevel));
|
|
||||||
|
|
||||||
return r.getResources().prod(modification_factor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
package com.bernard.greposimu.model.game.gods;
|
package com.bernard.greposimu.model.game;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
|
||||||
|
|
||||||
public class God implements Identified,Comparable<God>{
|
public class God implements Identified,Comparable<God>{
|
||||||
|
|
||||||
String id;
|
String id;
|
||||||
@ -1,81 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.buildings.Building;
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
|
||||||
import com.bernard.greposimu.model.game.units.Hero;
|
|
||||||
import com.bernard.greposimu.model.game.units.Unit;
|
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
|
||||||
import com.fasterxml.jackson.core.JacksonException;
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
|
||||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
|
||||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
|
||||||
import com.fasterxml.jackson.databind.KeyDeserializer;
|
|
||||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
|
||||||
|
|
||||||
public class GrepoYaml extends SimpleModule {
|
|
||||||
|
|
||||||
GameConfig gc;
|
|
||||||
|
|
||||||
public GrepoYaml(GameConfig gc) {
|
|
||||||
this.gc = gc;
|
|
||||||
registerId(Unit.class);
|
|
||||||
registerId(Research.class);
|
|
||||||
registerId(Building.class);
|
|
||||||
registerId(God.class);
|
|
||||||
registerId(Hero.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T extends Identified> void registerId(Class<T> clazz){
|
|
||||||
this.addSerializer(clazz, new IdSerializer<T>());
|
|
||||||
this.addKeySerializer(clazz, new IdKeySerializer<T>());
|
|
||||||
this.addDeserializer(clazz, new IdDeserializer<T>(clazz));
|
|
||||||
this.addKeyDeserializer(clazz, new IdKeyDeserializer<T>(clazz));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class IdSerializer<T extends Identified> extends JsonSerializer<T>{
|
|
||||||
@Override
|
|
||||||
public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
|
||||||
gen.writeString(value.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class IdKeySerializer<T extends Identified> extends JsonSerializer<T>{
|
|
||||||
@Override
|
|
||||||
public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
|
||||||
gen.writeFieldName(value.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class IdDeserializer<T extends Identified> extends JsonDeserializer<T> {
|
|
||||||
|
|
||||||
Class<T> clazz;
|
|
||||||
|
|
||||||
public IdDeserializer(Class<T> clazz) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
|
|
||||||
String id = p.getText();
|
|
||||||
return gc.getIdentified(clazz, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class IdKeyDeserializer<T extends Identified> extends KeyDeserializer {
|
|
||||||
|
|
||||||
Class<T> clazz;
|
|
||||||
|
|
||||||
public IdKeyDeserializer(Class<T> clazz) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException {
|
|
||||||
return gc.getIdentified(clazz, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.bernard.greposimu.model.game.util;
|
package com.bernard.greposimu.model.game;
|
||||||
|
|
||||||
public interface Identified {
|
public interface Identified {
|
||||||
|
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.bernard.greposimu.model.game;
|
||||||
|
|
||||||
|
public class Resources {
|
||||||
|
|
||||||
|
int wood;
|
||||||
|
int stone;
|
||||||
|
int iron;
|
||||||
|
|
||||||
|
public Resources(int wood, int stone, int iron) {
|
||||||
|
this.wood = wood;
|
||||||
|
this.stone = stone;
|
||||||
|
this.iron = iron;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWood() {
|
||||||
|
return wood;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStone() {
|
||||||
|
return stone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIron() {
|
||||||
|
return iron;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,91 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game.buildings;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
|
|
||||||
public enum Building implements Identified{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* var s = ""
|
|
||||||
for(var b in GameData.buildings){
|
|
||||||
var bb = GameData.buildings[b];
|
|
||||||
s += b.toUpperCase()+'("'+b+'",'+bb.resources.wood+","+bb.wood_factor+","+bb.resources.stone+","+bb.stone_factor+","+bb.resources.iron+","+bb.iron_factor+","+bb.pop+","+bb.pop_factor+","+bb.points+","+bb.points_factor+bb.build_time+","+bb.build_time_factor+","+bb.build_time_reduction+"),\n";
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
MAIN("main",6.0,2.15,2.0,2.53,2.0,2.3,1.0,1.5,100.0,1.1300,1.8,0.3,25),
|
|
||||||
HIDE("hide",200.0,1.3,400.0,1,700.0,0.9,3.0,0.5,50.0,1.2420,1.456,0,10),
|
|
||||||
PLACE("place",10.0,2,0.0,2,0.0,2,1.0,0,30.0,1.111,2.17,0,1),
|
|
||||||
LUMBER("lumber",2.6,1.9,2.0,2.1,1.49,2.1,1.0,1.25,20.0,1.1120,1.9,1,40),
|
|
||||||
STONER("stoner",1.3,2.1,2.6,1.9,2.4,2.1,1.0,1.25,20.0,1.1300,1.62,1,40),
|
|
||||||
IRONER("ironer",5.0,1.9,2.0,2,4.0,1.8,1.0,1.25,20.0,1.1600,1.41,0.5,40),
|
|
||||||
MARKET("market",50.0,1.48,20.0,1.62,5.0,1.98,2.0,1.1,100.0,1.08480,1.6,0.4,30),
|
|
||||||
DOCKS("docks",400.0,0.9,200.0,0.98,100.0,1.1,4.0,1,60.0,1.11500,1.1,0,30),
|
|
||||||
BARRACKS("barracks",70.0,1.22,20.0,1.67,40.0,1.54,1.0,1.3,30.0,1.115900,1.25,0.5,30),
|
|
||||||
WALL("wall",400.0,0,350.0,1,200.0,1.1,2.0,1.16,30.0,1.12900,1.3,0,25),
|
|
||||||
STORAGE("storage",35.0,1.52,55.0,1.52,15.0,1.66,0.0,1,13.0,1.141800,1.23,0.4,35),
|
|
||||||
FARM("farm",8.0,1.87,5.0,2.03,1.0,2.4,0.0,0,15.0,1.12300,1.7,1,45),
|
|
||||||
ACADEMY("academy",100.0,1.21,200.0,1.1,120.0,1.2,3.0,1,60.0,1.121200,1.25,0,36),
|
|
||||||
TEMPLE("temple",500.0,0.865,900.0,0.7,600.0,0.82,5.0,1,200.0,1.083600,1.145,0,30),
|
|
||||||
THEATER("theater",8000.0,2,8000.0,2,8000.0,2,60.0,1,500.0,164800,2.17,0,1),
|
|
||||||
THERMAL("thermal",9000.0,2,6000.0,2,9000.0,2,60.0,1,500.0,164800,2.17,0,1),
|
|
||||||
LIBRARY("library",9500.0,2,7500.0,2,7000.0,2,60.0,1,500.0,164800,2.17,0,1),
|
|
||||||
LIGHTHOUSE("lighthouse",6000.0,2,10000.0,2,8000.0,2,60.0,1,500.0,164800.0,2.17,0,1),
|
|
||||||
TOWER("tower",8000.0,2,10000.0,2,6000.0,2,60.0,1,500.0,164800.0,2.17,0,1),
|
|
||||||
STATUE("statue",6000.0,2,10500.0,2,7500.0,2,60.0,1,500.0,164800.0,2.17,0,1),
|
|
||||||
ORACLE("oracle",6500.0,2,7000.0,2,9500.0,2,60.0,1,500.0,164800.0,2.17,0,1),
|
|
||||||
TRADE_OFFICE("trade_office",10500.0,2,7000.0,2,6500.0,2,60.0,1,500.0,164800.0,1,0,1);
|
|
||||||
|
|
||||||
String id;
|
|
||||||
|
|
||||||
private double wood0,woodF,stone0,stoneF,iron0,ironF,pop0,popF,pts0,ptsF,build0,buildF,buildR;
|
|
||||||
int maxLevel;
|
|
||||||
|
|
||||||
private Building(String id, double wood0, double woodF, double stone0, double stoneF, double iron0, double ironF,
|
|
||||||
double pop0, double popF, double pts0, double ptsF, double build0, double buildF, int maxLevel) {
|
|
||||||
this.id = id;
|
|
||||||
this.wood0 = wood0;
|
|
||||||
this.woodF = woodF;
|
|
||||||
this.stone0 = stone0;
|
|
||||||
this.stoneF = stoneF;
|
|
||||||
this.iron0 = iron0;
|
|
||||||
this.ironF = ironF;
|
|
||||||
this.pop0 = pop0;
|
|
||||||
this.popF = popF;
|
|
||||||
this.pts0 = pts0;
|
|
||||||
this.ptsF = ptsF;
|
|
||||||
this.build0 = build0;
|
|
||||||
this.buildF = buildF;
|
|
||||||
this.maxLevel = maxLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getFarmPopulation(int farm) {
|
|
||||||
return (int) Math.floor(Math.pow(farm, 1.455)*14);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRequiredPop(int level) {
|
|
||||||
return (int) Math.floor(pop0*Math.pow(level, popF));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Resources getRequiredResources(int level) {
|
|
||||||
return new Resources(
|
|
||||||
(int) Math.floor(wood0*Math.pow(level, woodF)),
|
|
||||||
(int) Math.floor(stone0*Math.pow(level, stoneF)),
|
|
||||||
(int) Math.floor(iron0*Math.pow(level, ironF)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getBuildTime(int level) {
|
|
||||||
//TODO check this, is build_time_reduction used ?
|
|
||||||
return (long) Math.floor(build0*Math.pow(level, buildF));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int popInBuildings(Map<Building,Integer> buildings) {
|
|
||||||
return buildings.entrySet().stream().mapToInt(e -> e.getKey().getRequiredPop(e.getValue())).sum();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -2,23 +2,19 @@ package com.bernard.greposimu.model.game.powers;
|
|||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
import com.bernard.greposimu.model.game.God;
|
||||||
|
|
||||||
public class FuryPower extends GodPower {
|
public class FuryPower extends GodPower {
|
||||||
double furyProportionCost;
|
double furyProportionCost;
|
||||||
|
|
||||||
public FuryPower(String id, EnumSet<Target> targets, EnumSet<Target> seedsTo, String shortEffect, Power.Group powerGroup,
|
public FuryPower(String id, String name, String description, String shortEffect, String effect,
|
||||||
int powerGroupLevel, Set<String> metaFields, Map<String, Object> metaDefaults, int lifetime, EnumSet<Effect> effects,
|
EnumSet<Target> targets, EnumSet<Target> seedsTo, Group powerGroup, boolean negative, int powerGroupLevel,
|
||||||
EnumSet<Tag> tags,
|
EnumSet<Effect> effects, boolean ignores_democritus, EnumSet<AreaOfEffect> areaOfEffect, EnumSet<Tag> tags,
|
||||||
Set<String> compatiblePowers, EnumSet<AreaOfEffect> areaOfEffect, String name, String effect,
|
int lifetime, Map<String, Object> metaDefaults, God god, int furyCost, int templeLevelSumDependency,
|
||||||
String description, String configType, Map<String, String> nameM, Map<String, String> effectM,
|
|
||||||
Map<String, String> descriptionM, God god2, int favorCost, int templeLevelSumDependency,
|
|
||||||
double furyProportionCost) {
|
double furyProportionCost) {
|
||||||
super(id, targets, seedsTo, shortEffect, powerGroup, powerGroupLevel, metaFields, metaDefaults, lifetime,
|
super(id, name, description, shortEffect, effect, targets, seedsTo, powerGroup, negative, powerGroupLevel,
|
||||||
effects, tags, compatiblePowers, areaOfEffect, name,
|
effects, ignores_democritus, areaOfEffect, tags, lifetime, metaDefaults, god, furyCost,
|
||||||
effect, description, configType, nameM, effectM, descriptionM, god2, favorCost,
|
|
||||||
templeLevelSumDependency);
|
templeLevelSumDependency);
|
||||||
this.furyProportionCost = furyProportionCost;
|
this.furyProportionCost = furyProportionCost;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,28 +2,26 @@ package com.bernard.greposimu.model.game.powers;
|
|||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
import com.bernard.greposimu.model.game.God;
|
||||||
|
|
||||||
public class GodPower extends Power {
|
public class GodPower extends Power {
|
||||||
|
|
||||||
God god;
|
God god;
|
||||||
int favorCost;
|
int furyCost;
|
||||||
|
|
||||||
int templeLevelSumDependency;
|
int templeLevelSumDependency;
|
||||||
|
|
||||||
public GodPower(String id, EnumSet<Target> targets, EnumSet<Target> seedsTo, String shortEffect, Power.Group powerGroup,
|
|
||||||
int powerGroupLevel, Set<String> metaFields, Map<String, Object> metaDefaults, int lifetime, EnumSet<Effect> effects,
|
|
||||||
EnumSet<Tag> tags,
|
public GodPower(String id, String name, String description, String shortEffect, String effect,
|
||||||
Set<String> compatiblePowers, EnumSet<AreaOfEffect> areaOfEffect, String name, String effect,
|
EnumSet<Target> targets, EnumSet<Target> seedsTo, Group powerGroup, boolean negative, int powerGroupLevel,
|
||||||
String description, String configType, Map<String, String> nameM, Map<String, String> effectM,
|
EnumSet<Effect> effects, boolean ignores_democritus, EnumSet<AreaOfEffect> areaOfEffect, EnumSet<Tag> tags,
|
||||||
Map<String, String> descriptionM, God god2, int favorCost, int templeLevelSumDependency) {
|
int lifetime, Map<String, Object> metaDefaults, God god, int furyCost, int templeLevelSumDependency) {
|
||||||
super(id, targets, seedsTo, shortEffect, powerGroup, powerGroupLevel, metaFields, metaDefaults, lifetime,
|
super(id, name, description, shortEffect, effect, targets, seedsTo, powerGroup, negative, powerGroupLevel,
|
||||||
effects, tags, compatiblePowers, areaOfEffect, name,
|
effects, ignores_democritus, areaOfEffect, tags, lifetime, metaDefaults);
|
||||||
effect, description, configType, nameM, effectM, descriptionM);
|
this.god = god;
|
||||||
god = god2;
|
this.furyCost = furyCost;
|
||||||
this.favorCost = favorCost;
|
|
||||||
this.templeLevelSumDependency = templeLevelSumDependency;
|
this.templeLevelSumDependency = templeLevelSumDependency;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,8 +29,8 @@ public class GodPower extends Power {
|
|||||||
return god;
|
return god;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFavorCost() {
|
public int getFuryCost() {
|
||||||
return favorCost;
|
return furyCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTempleLevelSumDependency() {
|
public int getTempleLevelSumDependency() {
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.bernard.greposimu.model.game.powers;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class MultitypePower extends Power{
|
||||||
|
String commonId;
|
||||||
|
|
||||||
|
public MultitypePower(String id, String name, String description, String shortEffect, String effect,
|
||||||
|
EnumSet<Target> targets, EnumSet<Target> seedsTo, Group powerGroup, boolean negative, int powerGroupLevel,
|
||||||
|
EnumSet<Effect> effects, boolean ignores_democritus, EnumSet<AreaOfEffect> areaOfEffect, EnumSet<Tag> tags,
|
||||||
|
int lifetime, Map<String, Object> metaDefaults, String commonId) {
|
||||||
|
super(id, name, description, shortEffect, effect, targets, seedsTo, powerGroup, negative, powerGroupLevel,
|
||||||
|
effects, ignores_democritus, areaOfEffect, tags, lifetime, metaDefaults);
|
||||||
|
this.commonId = commonId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommonId() {
|
||||||
|
return commonId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,48 +2,47 @@ package com.bernard.greposimu.model.game.powers;
|
|||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import com.bernard.greposimu.model.game.Identified;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
|
||||||
|
|
||||||
public class Power implements Identified {
|
public class Power implements Identified {
|
||||||
|
|
||||||
|
|
||||||
String id;
|
String id;
|
||||||
|
String name;
|
||||||
|
String description;
|
||||||
|
String shortEffect;
|
||||||
|
String effect;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The target it applies to
|
* The target it applies to
|
||||||
*/
|
*/
|
||||||
EnumSet<Target> targets;
|
EnumSet<Target> targets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The targets it is seeded to. For example, attack boost is targeted to towns, and is seeded to commands.
|
* The targets it is seeded to. For example, attack boost is targeted to towns, and is seeded to commands.
|
||||||
*/
|
*/
|
||||||
EnumSet<Target> seedsTo;
|
EnumSet<Target> seedsTo;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
String shortEffect;
|
// EFFECTS
|
||||||
Power.Group powerGroup;
|
Group powerGroup;
|
||||||
|
boolean negative;
|
||||||
int powerGroupLevel;
|
int powerGroupLevel;
|
||||||
|
|
||||||
//name
|
|
||||||
Set<String> metaFields;
|
|
||||||
Map<String,Object> metaDefaults;
|
|
||||||
|
|
||||||
int lifetime;
|
|
||||||
|
|
||||||
EnumSet<Tag> tags;
|
|
||||||
EnumSet<Effect> effects;
|
EnumSet<Effect> effects;
|
||||||
Set<String> compatiblePowers;
|
boolean ignores_democritus;
|
||||||
EnumSet<AreaOfEffect> areaOfEffect;
|
EnumSet<AreaOfEffect> areaOfEffect;
|
||||||
|
|
||||||
// for each X, either X or XM should be null. if one XM is not null, configType should be set
|
|
||||||
String name,effect,description;
|
|
||||||
String configType;
|
|
||||||
Map<String,String> nameM,effectM,descriptionM;
|
|
||||||
|
|
||||||
//display_amount -> ignore
|
// images -> IGNORE
|
||||||
|
EnumSet<Tag> tags;
|
||||||
|
int lifetime;
|
||||||
|
|
||||||
|
|
||||||
|
Map<String,Object> metaDefaults;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -64,101 +63,96 @@ public class Power implements Identified {
|
|||||||
RECREATE_ON_RESTART,
|
RECREATE_ON_RESTART,
|
||||||
REMOVED_ON_TARGET_LOSS,
|
REMOVED_ON_TARGET_LOSS,
|
||||||
REQUIRES_GOD,
|
REQUIRES_GOD,
|
||||||
NO_LIFETIME,
|
NO_LIFETIME;
|
||||||
ONLY_OWN_TOWNS,
|
|
||||||
NEGATIVE,
|
|
||||||
IGNORES_DEMOCRITUS,
|
|
||||||
BOOST;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Power(String id, EnumSet<Target> targets, EnumSet<Target> seedsTo, String shortEffect, Power.Group powerGroup,
|
|
||||||
int powerGroupLevel, Set<String> metaFields, Map<String, Object> metaDefaults, int lifetime,
|
|
||||||
EnumSet<Effect> effects, EnumSet<Tag> tags,
|
|
||||||
Set<String> compatiblePowers, EnumSet<AreaOfEffect> areaOfEffect, String name, String effect,
|
|
||||||
String description, String configType, Map<String, String> nameM, Map<String, String> effectM,
|
|
||||||
Map<String, String> descriptionM) {
|
|
||||||
this.id = id;
|
|
||||||
this.targets = targets;
|
|
||||||
this.seedsTo = seedsTo;
|
|
||||||
this.shortEffect = shortEffect;
|
|
||||||
this.powerGroup = powerGroup;
|
|
||||||
this.powerGroupLevel = powerGroupLevel;
|
|
||||||
this.metaFields = metaFields;
|
|
||||||
this.metaDefaults = metaDefaults;
|
|
||||||
this.lifetime = lifetime;
|
|
||||||
this.effects = effects;
|
|
||||||
this.tags = tags;
|
|
||||||
this.compatiblePowers = compatiblePowers;
|
|
||||||
this.areaOfEffect = areaOfEffect;
|
|
||||||
this.name = name;
|
|
||||||
this.effect = effect;
|
|
||||||
this.description = description;
|
|
||||||
this.configType = configType;
|
|
||||||
this.nameM = nameM;
|
|
||||||
this.effectM = effectM;
|
|
||||||
this.descriptionM = descriptionM;
|
|
||||||
}
|
|
||||||
public static enum AreaOfEffect {
|
public static enum AreaOfEffect {
|
||||||
BUILDTIME,COMMANDS,FAVOR,MILITIA,RESOURCES;
|
BUILDTIME,COMMANDS,FAVOR,MILITIA,RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum Effect {
|
public static enum Effect {
|
||||||
GROUND,NAVAL,WALL;
|
GROUND,NAVAL,WALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum Group {
|
public static enum Group {
|
||||||
ATTACK_BOOST,ATTACK_SHIP_ATTACK_BOOST,BATTLE_POINT_BOOST,BUILDING_BOOST,DEFENSE_BOOST,FAVOR_BOOST,RESOURCE_BOOST,UNIT_BOOST;
|
ATTACK_BOOST,ATTACK_SHIP_ATTACK_BOOST,BATTLE_POINT_BOOST,BUILDING_BOOST,DEFENSE_BOOST,FAVOR_BOOST,RESOURCE_BOOST,UNIT_BOOST;
|
||||||
}
|
}
|
||||||
public static enum Target {
|
public static enum Target {
|
||||||
ALLIANCE,COMMAND,PLAYER,SUPPORT_COMMAND,TOWN;
|
ALLIANCE,COMMAND,PLAYER,SUPPORT_COMMAND,TOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Power(String id, String name, String description, String shortEffect, String effect, EnumSet<Target> targets,
|
||||||
|
EnumSet<Target> seedsTo, Group powerGroup, boolean negative, int powerGroupLevel, EnumSet<Effect> effects,
|
||||||
|
boolean ignores_democritus, EnumSet<AreaOfEffect> areaOfEffect, EnumSet<Tag> tags, int lifetime,
|
||||||
|
Map<String, Object> metaDefaults) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.shortEffect = shortEffect;
|
||||||
|
this.effect = effect;
|
||||||
|
this.targets = targets;
|
||||||
|
this.seedsTo = seedsTo;
|
||||||
|
this.powerGroup = powerGroup;
|
||||||
|
this.negative = negative;
|
||||||
|
this.powerGroupLevel = powerGroupLevel;
|
||||||
|
this.effects = effects;
|
||||||
|
this.ignores_democritus = ignores_democritus;
|
||||||
|
this.areaOfEffect = areaOfEffect;
|
||||||
|
this.tags = tags;
|
||||||
|
this.lifetime = lifetime;
|
||||||
|
this.metaDefaults = metaDefaults;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
public String getShortEffect() {
|
||||||
|
return shortEffect;
|
||||||
|
}
|
||||||
|
public String getEffect() {
|
||||||
|
return effect;
|
||||||
|
}
|
||||||
public EnumSet<Target> getTargets() {
|
public EnumSet<Target> getTargets() {
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
public EnumSet<Target> getSeedsTo() {
|
public EnumSet<Target> getSeedsTo() {
|
||||||
return seedsTo;
|
return seedsTo;
|
||||||
}
|
}
|
||||||
public String getShortEffect() {
|
public Group getPowerGroup() {
|
||||||
return shortEffect;
|
|
||||||
}
|
|
||||||
public Power.Group getPowerGroup() {
|
|
||||||
return powerGroup;
|
return powerGroup;
|
||||||
}
|
}
|
||||||
|
public boolean isNegative() {
|
||||||
|
return negative;
|
||||||
|
}
|
||||||
public int getPowerGroupLevel() {
|
public int getPowerGroupLevel() {
|
||||||
return powerGroupLevel;
|
return powerGroupLevel;
|
||||||
}
|
}
|
||||||
public Set<String> getMetaFields() {
|
|
||||||
return metaFields;
|
|
||||||
}
|
|
||||||
public Map<String, Object> getMetaDefaults() {
|
|
||||||
return metaDefaults;
|
|
||||||
}
|
|
||||||
public int getLifetime() {
|
|
||||||
return lifetime;
|
|
||||||
}
|
|
||||||
public EnumSet<Effect> getEffects() {
|
public EnumSet<Effect> getEffects() {
|
||||||
return effects;
|
return effects;
|
||||||
}
|
}
|
||||||
public EnumSet<Tag> getTags() {
|
public boolean isIgnores_democritus() {
|
||||||
return tags;
|
return ignores_democritus;
|
||||||
}
|
|
||||||
public Set<String> getCompatiblePowers() {
|
|
||||||
return compatiblePowers;
|
|
||||||
}
|
}
|
||||||
public EnumSet<AreaOfEffect> getAreaOfEffect() {
|
public EnumSet<AreaOfEffect> getAreaOfEffect() {
|
||||||
return areaOfEffect;
|
return areaOfEffect;
|
||||||
}
|
}
|
||||||
public String getName(Map<String,Object> configuration) {
|
public EnumSet<Tag> getTags() {
|
||||||
return name!=null?name:(nameM.get(configuration.get(configType)));
|
return tags;
|
||||||
}
|
}
|
||||||
public String getEffect(Map<String,Object> configuration) {
|
public int getLifetime() {
|
||||||
return effect!=null?effect:(effectM.get(configuration.get(configType)));
|
return lifetime;
|
||||||
}
|
}
|
||||||
public String getDescription(Map<String,Object> configuration) {
|
public Map<String, Object> getMetaDefaults() {
|
||||||
return description!=null?description:(descriptionM.get(configuration.get(configType)));
|
return metaDefaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,55 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game.queues;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.buildings.Building;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.game.util.Timestamp;
|
|
||||||
|
|
||||||
public class BuildingQueueItem extends QueueItem {
|
|
||||||
|
|
||||||
public BuildingQueueItem(long buildingTime, Building building, boolean tearingDown, Timestamp beginTime,
|
|
||||||
Timestamp endTime, Resources refund, Resources cost) {
|
|
||||||
this.buildingTime = buildingTime;
|
|
||||||
this.building = building;
|
|
||||||
this.tearingDown = tearingDown;
|
|
||||||
this.beginTime = beginTime;
|
|
||||||
this.endTime = endTime;
|
|
||||||
this.refund = refund;
|
|
||||||
this.cost = cost;
|
|
||||||
}
|
|
||||||
long buildingTime;
|
|
||||||
|
|
||||||
// the building being built
|
|
||||||
Building building;
|
|
||||||
boolean tearingDown;
|
|
||||||
|
|
||||||
Timestamp beginTime;
|
|
||||||
Timestamp endTime;
|
|
||||||
|
|
||||||
Resources refund;
|
|
||||||
Resources cost;
|
|
||||||
|
|
||||||
public long getBuildingTime() {
|
|
||||||
return buildingTime;
|
|
||||||
}
|
|
||||||
public Building getBuilding() {
|
|
||||||
return building;
|
|
||||||
}
|
|
||||||
public boolean isTearingDown() {
|
|
||||||
return tearingDown;
|
|
||||||
}
|
|
||||||
public Timestamp getBeginTime() {
|
|
||||||
return beginTime;
|
|
||||||
}
|
|
||||||
public Timestamp getEndTime() {
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
public Resources getRefund() {
|
|
||||||
return refund;
|
|
||||||
}
|
|
||||||
public Resources getCost() {
|
|
||||||
return cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game.queues;
|
|
||||||
|
|
||||||
public class QueueItem {
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game.queues;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.units.Unit;
|
|
||||||
import com.bernard.greposimu.model.game.util.Timestamp;
|
|
||||||
import com.bernard.greposimu.model.game.util.UnitResources;
|
|
||||||
|
|
||||||
public class RecruitmentQueueItem extends QueueItem {
|
|
||||||
|
|
||||||
RecruitmentKind kind;
|
|
||||||
Unit unit;
|
|
||||||
|
|
||||||
// Number of units requested
|
|
||||||
int count;
|
|
||||||
// Number of units that have been done
|
|
||||||
int done;
|
|
||||||
|
|
||||||
|
|
||||||
Timestamp beginTime;
|
|
||||||
Timestamp endTime;
|
|
||||||
|
|
||||||
UnitResources refund;
|
|
||||||
UnitResources cost;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public RecruitmentQueueItem(RecruitmentKind kind, Unit unit, int count, int done, Timestamp beginTime,
|
|
||||||
Timestamp endTime, UnitResources refund, UnitResources cost) {
|
|
||||||
this.kind = kind;
|
|
||||||
this.unit = unit;
|
|
||||||
this.count = count;
|
|
||||||
this.done = done;
|
|
||||||
this.beginTime = beginTime;
|
|
||||||
this.endTime = endTime;
|
|
||||||
this.refund = refund;
|
|
||||||
this.cost = cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static enum RecruitmentKind {
|
|
||||||
GROUND,NAVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game.queues;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.game.util.Timestamp;
|
|
||||||
|
|
||||||
public class ResearchQueueItem extends QueueItem {
|
|
||||||
|
|
||||||
// the building being built
|
|
||||||
Research research;
|
|
||||||
|
|
||||||
Timestamp beginTime;
|
|
||||||
Timestamp endTime;
|
|
||||||
|
|
||||||
Resources refund;
|
|
||||||
|
|
||||||
public ResearchQueueItem(Research research, Timestamp beginTime, Timestamp endTime, Resources refund) {
|
|
||||||
this.research = research;
|
|
||||||
this.beginTime = beginTime;
|
|
||||||
this.endTime = endTime;
|
|
||||||
this.refund = refund;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Research getResearch() {
|
|
||||||
return research;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getBeginTime() {
|
|
||||||
return beginTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getEndTime() {
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Resources getRefund() {
|
|
||||||
return refund;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -3,8 +3,8 @@ package com.bernard.greposimu.model.game.researches;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
import com.bernard.greposimu.model.game.Identified;
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
import com.bernard.greposimu.model.game.Resources;
|
||||||
|
|
||||||
public class Research implements Identified{
|
public class Research implements Identified{
|
||||||
|
|
||||||
@ -62,4 +62,5 @@ public class Research implements Identified{
|
|||||||
return researchPoints;
|
return researchPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
import com.bernard.greposimu.model.game.Identified;
|
||||||
|
|
||||||
public class Hero extends TerrestrialUnit implements Comparable<Hero>{
|
public class Hero extends TerrestrialUnit implements Comparable<Hero>{
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,9 @@ package com.bernard.greposimu.model.game.units;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
import com.bernard.greposimu.model.game.God;
|
||||||
|
import com.bernard.greposimu.model.game.Resources;
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
|
|
||||||
public class NavalUnit extends Unit {
|
public class NavalUnit extends Unit {
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,9 @@ package com.bernard.greposimu.model.game.units;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
import com.bernard.greposimu.model.game.God;
|
||||||
|
import com.bernard.greposimu.model.game.Resources;
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
|
|
||||||
public class TerrestrialUnit extends Unit{
|
public class TerrestrialUnit extends Unit{
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,9 @@ package com.bernard.greposimu.model.game.units;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
import com.bernard.greposimu.model.game.God;
|
||||||
|
import com.bernard.greposimu.model.game.Resources;
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
|
|
||||||
public class TransportUnit extends NavalUnit {
|
public class TransportUnit extends NavalUnit {
|
||||||
int capacity;
|
int capacity;
|
||||||
|
|||||||
@ -3,10 +3,10 @@ package com.bernard.greposimu.model.game.units;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
import com.bernard.greposimu.model.game.God;
|
||||||
|
import com.bernard.greposimu.model.game.Identified;
|
||||||
|
import com.bernard.greposimu.model.game.Resources;
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
|
|
||||||
public abstract class Unit implements Identified{
|
public abstract class Unit implements Identified{
|
||||||
|
|
||||||
@ -92,9 +92,4 @@ public abstract class Unit implements Identified{
|
|||||||
return !this.isGround();
|
return !this.isGround();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,38 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game.util;
|
|
||||||
|
|
||||||
public class Resources {
|
|
||||||
|
|
||||||
public static final Resources empty = new Resources(0,0,0);
|
|
||||||
|
|
||||||
int wood;
|
|
||||||
int stone;
|
|
||||||
int iron;
|
|
||||||
|
|
||||||
public Resources(int wood, int stone, int iron) {
|
|
||||||
this.wood = wood;
|
|
||||||
this.stone = stone;
|
|
||||||
this.iron = iron;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWood() {
|
|
||||||
return wood;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStone() {
|
|
||||||
return stone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIron() {
|
|
||||||
return iron;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Resources prod(double p){
|
|
||||||
return new Resources((int)Math.ceil(p*wood), (int)Math.ceil(p*stone), (int)Math.ceil(p*iron));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "["+this.wood+";"+this.stone+";"+this.iron+"]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game.util;
|
|
||||||
|
|
||||||
public class Timestamp {
|
|
||||||
|
|
||||||
long timestamp;
|
|
||||||
|
|
||||||
public Timestamp(long timestamp) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game.util;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
|
||||||
|
|
||||||
public class UnitResources extends Resources {
|
|
||||||
|
|
||||||
God god;
|
|
||||||
int favor;
|
|
||||||
|
|
||||||
public UnitResources(int wood, int stone, int iron, God god, int favor) {
|
|
||||||
super(wood, stone, iron);
|
|
||||||
this.god = god;
|
|
||||||
this.favor = favor;
|
|
||||||
}
|
|
||||||
public UnitResources(int wood, int stone, int iron) {
|
|
||||||
this(wood, stone, iron, null, 0);
|
|
||||||
}
|
|
||||||
public UnitResources(Resources r, God god, int favor) {
|
|
||||||
this(r.getWood(), r.getStone(), r.getIron(),god,favor);
|
|
||||||
}
|
|
||||||
public UnitResources(Resources r) {
|
|
||||||
this(r.getWood(), r.getStone(), r.getIron(),null,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public God getGod() {
|
|
||||||
return god;
|
|
||||||
}
|
|
||||||
public int getFavor() {
|
|
||||||
return favor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package com.bernard.greposimu.model.runtime;
|
||||||
|
|
||||||
|
public class Alliance {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.bernard.greposimu.model.runtime;
|
||||||
|
|
||||||
|
public class Joueureuse {
|
||||||
|
|
||||||
|
String nom;
|
||||||
|
Alliance alliance;
|
||||||
|
int points;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package com.bernard.greposimu.model.runtime;
|
||||||
|
|
||||||
|
public class PositionVille {
|
||||||
|
|
||||||
|
int ileId;
|
||||||
|
int x,y,nr,ex,ey,fx,fy;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.bernard.greposimu.model.runtime;
|
||||||
|
|
||||||
|
public class Timestamp {
|
||||||
|
|
||||||
|
long timestamp;
|
||||||
|
|
||||||
|
}
|
||||||
18
src/main/java/com/bernard/greposimu/model/runtime/Ville.java
Normal file
18
src/main/java/com/bernard/greposimu/model/runtime/Ville.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package com.bernard.greposimu.model.runtime;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.Resources;
|
||||||
|
|
||||||
|
public class Ville {
|
||||||
|
|
||||||
|
int id;
|
||||||
|
|
||||||
|
// null -> Ville fantôme
|
||||||
|
Joueureuse proprietaire;
|
||||||
|
|
||||||
|
PositionVille ville;
|
||||||
|
|
||||||
|
Resources resources;
|
||||||
|
|
||||||
|
Map<String,Integer> batiments
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.bernard.greposimu.model.simulator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.God;
|
||||||
|
import com.bernard.greposimu.model.runtime.Timestamp;
|
||||||
|
|
||||||
|
public class Joueureuse {
|
||||||
|
|
||||||
|
// God
|
||||||
|
Map<God,Integer> favor;
|
||||||
|
int rage;
|
||||||
|
|
||||||
|
int gold;
|
||||||
|
|
||||||
|
// Heroes
|
||||||
|
// herosId -> townId
|
||||||
|
Map<String,Integer> heroes;
|
||||||
|
// herosId -> timeOfArrival
|
||||||
|
Map<String,Timestamp> heroesArrival;
|
||||||
|
// herosid -> level
|
||||||
|
Map<String,Integer> heroesLevel;
|
||||||
|
|
||||||
|
List<String> inventory;
|
||||||
|
|
||||||
|
//TODO quêtes
|
||||||
|
//TODO messages/rapports
|
||||||
|
//TODO profile
|
||||||
|
//TODO alliance + allianceMessages
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.bernard.greposimu.model.simulator;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Troupes {
|
||||||
|
|
||||||
|
Map<String,Integer> unites;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
package com.bernard.greposimu.model.simulator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.God;
|
||||||
|
import com.bernard.greposimu.model.game.Resources;
|
||||||
|
import com.bernard.greposimu.model.runtime.Timestamp;
|
||||||
|
|
||||||
|
public class Ville {
|
||||||
|
int id;
|
||||||
|
String nom;
|
||||||
|
|
||||||
|
Map<String,Integer> batiments;
|
||||||
|
|
||||||
|
Troupes troupes;
|
||||||
|
|
||||||
|
// origin town id -> troupes
|
||||||
|
Map<Integer,Troupes> soutiens;
|
||||||
|
|
||||||
|
// Destination town -> troupes
|
||||||
|
Map<Integer,Troupes> soutenus;
|
||||||
|
|
||||||
|
// sortilegeId -> effectEnd
|
||||||
|
Map<String,Timestamp> sortileges;
|
||||||
|
|
||||||
|
// Agora
|
||||||
|
Timestamp festivalEnd,olympiquesEnd,marchEnd,theaterEnd;
|
||||||
|
|
||||||
|
// Academie
|
||||||
|
Set<String> researches;
|
||||||
|
List<QueueItem> researchQueue;
|
||||||
|
|
||||||
|
// Senat
|
||||||
|
List<QueueItem> buildingQueue;
|
||||||
|
|
||||||
|
// Farm
|
||||||
|
Timestamp miliceAppel;
|
||||||
|
|
||||||
|
// Entrepôt
|
||||||
|
Resources storage;
|
||||||
|
|
||||||
|
// Caserne
|
||||||
|
List<QueueItem> terrestrialQueue;
|
||||||
|
|
||||||
|
// Temple
|
||||||
|
God god;
|
||||||
|
|
||||||
|
// Port
|
||||||
|
List<QueueItem> navalQueue;
|
||||||
|
|
||||||
|
// Remparts
|
||||||
|
Troupes slainAsOff,slainAsDef,lostAsOff,lostAsDef;
|
||||||
|
|
||||||
|
// Grotte
|
||||||
|
int piecesStoquees;
|
||||||
|
|
||||||
|
/* Ordres */
|
||||||
|
Set<UnitOrder> ordresMilitaires;
|
||||||
|
Set<TradeOrder> incomingTrade;
|
||||||
|
Set<TradeOrder> outgoingTrade;
|
||||||
|
|
||||||
|
public static class TradeOrder {
|
||||||
|
Resources resources;
|
||||||
|
Integer other;
|
||||||
|
}
|
||||||
|
public static class UnitOrder {
|
||||||
|
Troupes attq;
|
||||||
|
Timestamp arrivee;
|
||||||
|
OrderType type;
|
||||||
|
Set<String> sortileges;
|
||||||
|
}
|
||||||
|
public static enum OrderType {
|
||||||
|
ATTACK,
|
||||||
|
SUPPORT,
|
||||||
|
ATTACK_CANCELED,
|
||||||
|
ATTACK_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class QueueItem {
|
||||||
|
String buildingId;
|
||||||
|
Timestamp startTime;
|
||||||
|
Timestamp endTime;
|
||||||
|
long duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,70 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.command;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.game.buildings.Building;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.SimulatorData;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Ville;
|
|
||||||
|
|
||||||
public class BuildCommand extends TownCommand {
|
|
||||||
|
|
||||||
Building building;
|
|
||||||
|
|
||||||
// Destination level of the build
|
|
||||||
int level;
|
|
||||||
|
|
||||||
boolean tearingDown;
|
|
||||||
|
|
||||||
public BuildCommand(GameConfig gc, int town, Building building, int level, boolean tearingDown) {
|
|
||||||
super(gc,town);
|
|
||||||
this.building = building;
|
|
||||||
this.level = level;
|
|
||||||
this.tearingDown = tearingDown;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if(tearingDown)
|
|
||||||
return "[%d] Destroy %s from %d -> %d".formatted(this.town,this.building.name(),this.level+1,this.level);
|
|
||||||
else
|
|
||||||
return "[%d] Build %s from %d -> %d".formatted(this.town,this.building.name(),this.level-1,this.level);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resources neededResources(SimulatorData sd) {
|
|
||||||
if(this.tearingDown)return Resources.empty;
|
|
||||||
Ville v = sd.getVille(town);
|
|
||||||
return gc.getBuildingBuildingResources(
|
|
||||||
this.building,
|
|
||||||
this.level,
|
|
||||||
v.getBatiments().get(Building.MAIN),
|
|
||||||
v.getPowers(),
|
|
||||||
v.getResearches(),
|
|
||||||
v.getHero(),
|
|
||||||
v.getHeroLevel());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long timeNeeded(SimulatorData sd) {
|
|
||||||
Ville v = sd.getVille(town);
|
|
||||||
if(this.tearingDown)
|
|
||||||
return gc.getBuildingTearDownTime(
|
|
||||||
this.building,
|
|
||||||
this.level,
|
|
||||||
v.getBatiments().get(Building.MAIN),
|
|
||||||
v.getPowers(),
|
|
||||||
v.getResearches(),
|
|
||||||
v.getHero(),
|
|
||||||
v.getHeroLevel());
|
|
||||||
else
|
|
||||||
return gc.getBuildingBuildingTime(
|
|
||||||
this.building,
|
|
||||||
this.level,
|
|
||||||
v.getBatiments().get(Building.MAIN),
|
|
||||||
v.getPowers(),
|
|
||||||
v.getResearches(),
|
|
||||||
v.getHero(),
|
|
||||||
v.getHeroLevel());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.command;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.SimulatorData;
|
|
||||||
|
|
||||||
public abstract class Command {
|
|
||||||
|
|
||||||
GameConfig gc;
|
|
||||||
|
|
||||||
public Command(GameConfig gc) {
|
|
||||||
this.gc = gc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract long timeNeeded(SimulatorData sd);
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.command;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.SimulatorData;
|
|
||||||
|
|
||||||
public class HideStoreCommand extends TownCommand {
|
|
||||||
|
|
||||||
int amount;
|
|
||||||
|
|
||||||
public HideStoreCommand(GameConfig gc, int town, int amount) {
|
|
||||||
super(gc,town);
|
|
||||||
this.amount = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "[%d] Store %d iron in the hide".formatted(this.town,this.amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resources neededResources(SimulatorData sd) {
|
|
||||||
return new Resources(0, 0, this.amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long timeNeeded(SimulatorData sd) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.command;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.game.buildings.Building;
|
|
||||||
import com.bernard.greposimu.model.game.units.Unit;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.SimulatorData;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Ville;
|
|
||||||
|
|
||||||
public class RecruitCommand extends TownCommand{
|
|
||||||
|
|
||||||
Unit unit;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
public RecruitCommand(GameConfig gc,int town, Unit unit, int count) {
|
|
||||||
super(gc,town);
|
|
||||||
this.unit = unit;
|
|
||||||
this.count = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "[%d] Recruit %d %s".formatted(this.town,this.count, this.unit.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resources neededResources(SimulatorData sd) {
|
|
||||||
Ville v = sd.getVille(town);
|
|
||||||
return gc.getUnitBuildResources(
|
|
||||||
this.unit,
|
|
||||||
v.getBatiments().get(Building.BARRACKS),
|
|
||||||
v.getBatiments().get(Building.DOCKS),
|
|
||||||
v.getPowers(),
|
|
||||||
v.getResearches(),
|
|
||||||
v.getHero(),
|
|
||||||
v.getHeroLevel()).prod(this.count);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long timeNeeded(SimulatorData sd) {
|
|
||||||
Ville v = sd.getVille(town);
|
|
||||||
return gc.getUnitBuildTime(
|
|
||||||
this.unit,
|
|
||||||
v.getBatiments().get(Building.BARRACKS),
|
|
||||||
v.getBatiments().get(Building.DOCKS),
|
|
||||||
v.getPowers(),
|
|
||||||
v.getResearches(),
|
|
||||||
v.getHero(),
|
|
||||||
v.getHeroLevel()) * this.count;
|
|
||||||
}
|
|
||||||
// Store favor cost somewhere
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.command;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.game.buildings.Building;
|
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.SimulatorData;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Ville;
|
|
||||||
|
|
||||||
public class ResearchCommand extends TownCommand {
|
|
||||||
|
|
||||||
Research research;
|
|
||||||
boolean forget;
|
|
||||||
public ResearchCommand(GameConfig gc, int town, Resources need, Research research, boolean forget) {
|
|
||||||
super(gc,town);
|
|
||||||
this.research = research;
|
|
||||||
this.forget = forget;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if(forget)
|
|
||||||
return "[%d] Forget research %s".formatted(this.town,this.research.getName());
|
|
||||||
else
|
|
||||||
return "[%d] Research %s".formatted(this.town,this.research.getName());
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Resources neededResources(SimulatorData sd) {
|
|
||||||
if(this.forget)return Resources.empty;
|
|
||||||
Ville v = sd.getVille(town);
|
|
||||||
return gc.getResearchResources(
|
|
||||||
this.research,
|
|
||||||
v.getBatiments().get(Building.ACADEMY),
|
|
||||||
v.getPowers(),
|
|
||||||
v.getHero(),
|
|
||||||
v.getHeroLevel());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long timeNeeded(SimulatorData sd) {
|
|
||||||
Ville v = sd.getVille(town);
|
|
||||||
if(this.forget)
|
|
||||||
//TODO check this implementation correct
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return gc.getResearchTime(
|
|
||||||
this.research,
|
|
||||||
v.getBatiments().get(Building.ACADEMY),
|
|
||||||
v.getPowers(),
|
|
||||||
v.getHero(),
|
|
||||||
v.getHeroLevel());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.command;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.SimulatorData;
|
|
||||||
|
|
||||||
public abstract class TownCommand extends Command {
|
|
||||||
|
|
||||||
int town;
|
|
||||||
|
|
||||||
public TownCommand(GameConfig gc, int town) {
|
|
||||||
super(gc);
|
|
||||||
this.town = town;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract Resources neededResources(SimulatorData sd);
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.data;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.powers.Power;
|
|
||||||
import com.bernard.greposimu.model.game.util.Identified;
|
|
||||||
import com.bernard.greposimu.model.game.util.Timestamp;
|
|
||||||
|
|
||||||
public class CastedPower implements Identified{
|
|
||||||
|
|
||||||
long originPlayer;
|
|
||||||
Power power;
|
|
||||||
Timestamp end;
|
|
||||||
String id;
|
|
||||||
Integer level;
|
|
||||||
int extended;
|
|
||||||
|
|
||||||
// Replace with real OOP, depending on the power
|
|
||||||
Map<String,Object> configuration;
|
|
||||||
|
|
||||||
public CastedPower(long originPlayer, Power power, Timestamp end, String id, Integer level, int extended,
|
|
||||||
Map<String, Object> configuration) {
|
|
||||||
this.originPlayer = originPlayer;
|
|
||||||
this.power = power;
|
|
||||||
this.end = end;
|
|
||||||
this.id = id;
|
|
||||||
this.level = level;
|
|
||||||
this.extended = extended;
|
|
||||||
this.configuration = configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getOriginPlayer() {
|
|
||||||
return originPlayer;
|
|
||||||
}
|
|
||||||
public Power getPower() {
|
|
||||||
return power;
|
|
||||||
}
|
|
||||||
public Timestamp getEnd() {
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public Map<String, Object> getConfiguration() {
|
|
||||||
return configuration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.data;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
|
||||||
import com.bernard.greposimu.model.game.util.Timestamp;
|
|
||||||
|
|
||||||
public class Joueureuse {
|
|
||||||
|
|
||||||
// God
|
|
||||||
Map<God,Integer> favor;
|
|
||||||
int rage;
|
|
||||||
|
|
||||||
int gold;
|
|
||||||
|
|
||||||
// Heroes
|
|
||||||
// herosId -> townId
|
|
||||||
Map<String,Integer> heroes;
|
|
||||||
// herosId -> timeOfArrival
|
|
||||||
Map<String,Timestamp> heroesArrival;
|
|
||||||
// herosid -> level
|
|
||||||
Map<String,Integer> heroesLevel;
|
|
||||||
|
|
||||||
List<String> inventory;
|
|
||||||
|
|
||||||
// Remparts
|
|
||||||
Troupes slainAsOff,slainAsDef,lostAsOff,lostAsDef;
|
|
||||||
|
|
||||||
Set<Movements> movements;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Joueureuse(Map<God, Integer> favor, int rage, int gold, Map<String, Integer> heroes,
|
|
||||||
Map<String, Timestamp> heroesArrival, Map<String, Integer> heroesLevel, List<String> inventory,
|
|
||||||
Troupes slainAsOff, Troupes slainAsDef, Troupes lostAsOff, Troupes lostAsDef, Set<Movements> movements) {
|
|
||||||
this.favor = favor;
|
|
||||||
this.rage = rage;
|
|
||||||
this.gold = gold;
|
|
||||||
this.heroes = heroes;
|
|
||||||
this.heroesArrival = heroesArrival;
|
|
||||||
this.heroesLevel = heroesLevel;
|
|
||||||
this.inventory = inventory;
|
|
||||||
this.slainAsOff = slainAsOff;
|
|
||||||
this.slainAsDef = slainAsDef;
|
|
||||||
this.lostAsOff = lostAsOff;
|
|
||||||
this.lostAsDef = lostAsDef;
|
|
||||||
this.movements = movements;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<God, Integer> getFavor() {
|
|
||||||
return favor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRage() {
|
|
||||||
return rage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGold() {
|
|
||||||
return gold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Integer> getHeroes() {
|
|
||||||
return heroes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Timestamp> getHeroesArrival() {
|
|
||||||
return heroesArrival;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Integer> getHeroesLevel() {
|
|
||||||
return heroesLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getInventory() {
|
|
||||||
return inventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Troupes getSlainAsDef() {
|
|
||||||
return slainAsDef;
|
|
||||||
}
|
|
||||||
public Troupes getSlainAsOff() {
|
|
||||||
return slainAsOff;
|
|
||||||
}
|
|
||||||
public Troupes getLostAsDef() {
|
|
||||||
return lostAsDef;
|
|
||||||
}
|
|
||||||
public Troupes getLostAsOff() {
|
|
||||||
return lostAsOff;
|
|
||||||
}
|
|
||||||
public Set<Movements> getMovements() {
|
|
||||||
return movements;
|
|
||||||
}
|
|
||||||
//TODO quêtes
|
|
||||||
//TODO messages/rapports
|
|
||||||
//TODO profile
|
|
||||||
//TODO alliance + allianceMessages
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.data;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.util.Timestamp;
|
|
||||||
|
|
||||||
public class Movements {
|
|
||||||
|
|
||||||
Timestamp arrival;
|
|
||||||
Timestamp started;
|
|
||||||
|
|
||||||
Timestamp cancelableUntil;
|
|
||||||
|
|
||||||
Timestamp invisibleUntil;
|
|
||||||
|
|
||||||
boolean destIsAttack;
|
|
||||||
boolean origIsAttack;
|
|
||||||
int home;
|
|
||||||
int player;
|
|
||||||
int target;
|
|
||||||
|
|
||||||
String type;
|
|
||||||
|
|
||||||
Troupes troupes;
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.data;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class SimulatorData {
|
|
||||||
|
|
||||||
Map<Integer,Ville> villes;
|
|
||||||
Joueureuse joueureuse;
|
|
||||||
|
|
||||||
public SimulatorData(Map<Integer, Ville> villes, Joueureuse joueureuse) {
|
|
||||||
this.villes = villes;
|
|
||||||
this.joueureuse = joueureuse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Integer, Ville> getVilles() {
|
|
||||||
return villes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Ville getVille(int id) {
|
|
||||||
return villes.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Joueureuse getJoueureuse() {
|
|
||||||
return joueureuse;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.data;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.units.Unit;
|
|
||||||
|
|
||||||
public class Troupes {
|
|
||||||
|
|
||||||
Map<Unit,Integer> unites;
|
|
||||||
|
|
||||||
public Troupes(Map<Unit, Integer> unites) {
|
|
||||||
this.unites = unites;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Unit, Integer> getUnites() {
|
|
||||||
return unites;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Troupes add(Troupes a, Troupes b) {
|
|
||||||
return new Troupes(
|
|
||||||
Stream.concat(a.unites.keySet().stream(), b.unites.keySet().stream())
|
|
||||||
.distinct().collect(Collectors.toMap(Function.identity(),
|
|
||||||
u -> a.unites.getOrDefault(u, 0)+b.unites.getOrDefault(u, 0)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int pop() {
|
|
||||||
return unites.entrySet().stream().mapToInt(e -> e.getValue()*e.getKey().getPopulation()).sum();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Troupes [unites=" + unites + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,236 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.data;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.buildings.Building;
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
|
||||||
import com.bernard.greposimu.model.game.queues.BuildingQueueItem;
|
|
||||||
import com.bernard.greposimu.model.game.queues.RecruitmentQueueItem;
|
|
||||||
import com.bernard.greposimu.model.game.queues.ResearchQueueItem;
|
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
|
||||||
import com.bernard.greposimu.model.game.units.Hero;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.game.util.Timestamp;
|
|
||||||
|
|
||||||
public class Ville {
|
|
||||||
|
|
||||||
int id;
|
|
||||||
String nom;
|
|
||||||
|
|
||||||
Map<Building,Integer> batiments;
|
|
||||||
|
|
||||||
Troupes troupes;
|
|
||||||
|
|
||||||
// origin town id -> troupes
|
|
||||||
Map<Integer,Troupes> soutiens;
|
|
||||||
|
|
||||||
// Destination town -> troupes
|
|
||||||
Map<Integer,Troupes> soutenus;
|
|
||||||
|
|
||||||
Set<CastedPower> powers;
|
|
||||||
|
|
||||||
// Agora
|
|
||||||
Timestamp festivalEnd,olympiquesEnd,marchEnd,theaterEnd;
|
|
||||||
|
|
||||||
// Academie
|
|
||||||
Set<Research> researches;
|
|
||||||
List<ResearchQueueItem> researchQueue;
|
|
||||||
|
|
||||||
// Senat
|
|
||||||
List<BuildingQueueItem> buildingQueue;
|
|
||||||
|
|
||||||
// Farm
|
|
||||||
// End time of militia
|
|
||||||
Timestamp miliceUntil;
|
|
||||||
|
|
||||||
// Entrepôt
|
|
||||||
Resources storage;
|
|
||||||
|
|
||||||
// Caserne
|
|
||||||
List<RecruitmentQueueItem> terrestrialQueue;
|
|
||||||
|
|
||||||
// Temple
|
|
||||||
God god;
|
|
||||||
|
|
||||||
// Port
|
|
||||||
List<RecruitmentQueueItem> navalQueue;
|
|
||||||
|
|
||||||
// Grotte
|
|
||||||
int piecesStoquees;
|
|
||||||
|
|
||||||
/* Ordres */
|
|
||||||
Set<UnitOrder> ordresMilitaires;
|
|
||||||
Set<TradeOrder> incomingTrade;
|
|
||||||
Set<TradeOrder> outgoingTrade;
|
|
||||||
|
|
||||||
|
|
||||||
public Ville(int id, String nom, Map<Building, Integer> batiments, Troupes troupes, Map<Integer, Troupes> soutiens,
|
|
||||||
Map<Integer, Troupes> soutenus, Set<CastedPower> powers, Timestamp festivalEnd,
|
|
||||||
Timestamp olympiquesEnd, Timestamp marchEnd, Timestamp theaterEnd, Set<Research> researches,
|
|
||||||
List<ResearchQueueItem> researchQueue, List<BuildingQueueItem> buildingQueue, Timestamp miliceUntil,
|
|
||||||
Resources storage, List<RecruitmentQueueItem> terrestrialQueue, God god,
|
|
||||||
List<RecruitmentQueueItem> navalQueue, int piecesStoquees, Set<UnitOrder> ordresMilitaires, Set<TradeOrder> incomingTrade,
|
|
||||||
Set<TradeOrder> outgoingTrade) {
|
|
||||||
super();
|
|
||||||
this.id = id;
|
|
||||||
this.nom = nom;
|
|
||||||
this.batiments = batiments;
|
|
||||||
this.troupes = troupes;
|
|
||||||
this.soutiens = soutiens;
|
|
||||||
this.soutenus = soutenus;
|
|
||||||
this.powers = powers;
|
|
||||||
this.festivalEnd = festivalEnd;
|
|
||||||
this.olympiquesEnd = olympiquesEnd;
|
|
||||||
this.marchEnd = marchEnd;
|
|
||||||
this.theaterEnd = theaterEnd;
|
|
||||||
this.researches = researches;
|
|
||||||
this.researchQueue = researchQueue;
|
|
||||||
this.buildingQueue = buildingQueue;
|
|
||||||
this.miliceUntil = miliceUntil;
|
|
||||||
this.storage = storage;
|
|
||||||
this.terrestrialQueue = terrestrialQueue;
|
|
||||||
this.god = god;
|
|
||||||
this.navalQueue = navalQueue;
|
|
||||||
this.piecesStoquees = piecesStoquees;
|
|
||||||
this.ordresMilitaires = ordresMilitaires;
|
|
||||||
this.incomingTrade = incomingTrade;
|
|
||||||
this.outgoingTrade = outgoingTrade;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TradeOrder {
|
|
||||||
Resources resources;
|
|
||||||
Integer other;
|
|
||||||
public TradeOrder(Resources resources, Integer other) {
|
|
||||||
this.resources = resources;
|
|
||||||
this.other = other;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static class UnitOrder {
|
|
||||||
Troupes attq;
|
|
||||||
Timestamp arrivee;
|
|
||||||
OrderType type;
|
|
||||||
Set<String> sortileges;
|
|
||||||
}
|
|
||||||
public static enum OrderType {
|
|
||||||
ATTACK,
|
|
||||||
SUPPORT,
|
|
||||||
ATTACK_CANCELED,
|
|
||||||
ATTACK_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class QueueItem {
|
|
||||||
String buildingId;
|
|
||||||
Timestamp startTime;
|
|
||||||
Timestamp endTime;
|
|
||||||
long duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNom() {
|
|
||||||
return nom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Building, Integer> getBatiments() {
|
|
||||||
return batiments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Troupes getTroupes() {
|
|
||||||
return troupes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Integer, Troupes> getSoutiens() {
|
|
||||||
return soutiens;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Integer, Troupes> getSoutenus() {
|
|
||||||
return soutenus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<CastedPower> getPowers() {
|
|
||||||
return powers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getFestivalEnd() {
|
|
||||||
return festivalEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getOlympiquesEnd() {
|
|
||||||
return olympiquesEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getMarchEnd() {
|
|
||||||
return marchEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getTheaterEnd() {
|
|
||||||
return theaterEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Research> getResearches() {
|
|
||||||
return researches;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasResearch(Research r) {
|
|
||||||
return researches.contains(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResearchQueueItem> getResearchQueue() {
|
|
||||||
return researchQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BuildingQueueItem> getBuildingQueue() {
|
|
||||||
return buildingQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getMiliceUntil() {
|
|
||||||
return miliceUntil;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Resources getStorage() {
|
|
||||||
return storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<RecruitmentQueueItem> getTerrestrialQueue() {
|
|
||||||
return terrestrialQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public God getGod() {
|
|
||||||
return god;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<RecruitmentQueueItem> getNavalQueue() {
|
|
||||||
return navalQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPiecesStoquees() {
|
|
||||||
return piecesStoquees;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<UnitOrder> getOrdresMilitaires() {
|
|
||||||
return ordresMilitaires;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<TradeOrder> getIncomingTrade() {
|
|
||||||
return incomingTrade;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<TradeOrder> getOutgoingTrade() {
|
|
||||||
return outgoingTrade;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hero getHero(){
|
|
||||||
//TODO implement this
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHeroLevel() {
|
|
||||||
//TODO implement this
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,136 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.simulator.objective;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.game.buildings.Building;
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
|
||||||
import com.bernard.greposimu.model.game.units.Unit;
|
|
||||||
import com.bernard.greposimu.model.simulator.command.BuildCommand;
|
|
||||||
import com.bernard.greposimu.model.simulator.command.Command;
|
|
||||||
import com.bernard.greposimu.model.simulator.command.HideStoreCommand;
|
|
||||||
import com.bernard.greposimu.model.simulator.command.RecruitCommand;
|
|
||||||
import com.bernard.greposimu.model.simulator.command.ResearchCommand;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Troupes;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Ville;
|
|
||||||
|
|
||||||
public class TownObjective {
|
|
||||||
GameConfig gc;
|
|
||||||
|
|
||||||
Map<Building,Integer> buildings;
|
|
||||||
Map<Unit,Double> unitsProportions;
|
|
||||||
Set<Research> researches;
|
|
||||||
int hide;
|
|
||||||
God god;
|
|
||||||
|
|
||||||
TownObjective() {}
|
|
||||||
|
|
||||||
public TownObjective(GameConfig gc, Map<Building, Integer> buildings, Map<Unit, Double> unitsProportions,
|
|
||||||
Set<Research> researches, int hide, God god) {
|
|
||||||
this.gc = gc;
|
|
||||||
this.buildings = buildings;
|
|
||||||
this.unitsProportions = unitsProportions;
|
|
||||||
this.researches = researches;
|
|
||||||
this.hide = hide;
|
|
||||||
this.god = god;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int villeMaxPop(GameConfig gc, Ville v) {
|
|
||||||
return GameConfig.getTotalPop(
|
|
||||||
v.getBatiments().getOrDefault(Building.FARM,0),
|
|
||||||
v.getBatiments().getOrDefault(Building.THERMAL, 0)>=1,
|
|
||||||
v.getResearches().contains(gc.getResearch("plow")),
|
|
||||||
v.getGod().getId().equals("aphrodite"),
|
|
||||||
0); //TODO take popultion_boost into account
|
|
||||||
}
|
|
||||||
public Troupes targetTroupes() {
|
|
||||||
int popRest = GameConfig.getTotalPop(
|
|
||||||
this.buildings.getOrDefault(Building.FARM,0),
|
|
||||||
this.buildings.getOrDefault(Building.THERMAL, 0)>=1,
|
|
||||||
this.researches.contains(gc.getResearch("plow")),
|
|
||||||
this.god.getId().equals("aphrodite"),
|
|
||||||
0) //TODO take popultion_boost into account
|
|
||||||
-
|
|
||||||
this.buildings.entrySet().stream().mapToInt(e -> e.getKey().getRequiredPop(e.getValue())).sum();
|
|
||||||
double totalProp = this.unitsProportions.values().stream().collect(Collectors.summarizingDouble(d -> d)).getSum();
|
|
||||||
return new Troupes(this.unitsProportions.entrySet().stream().collect(Collectors.toMap(
|
|
||||||
e -> e.getKey(),
|
|
||||||
e -> (int)Math.floor(e.getValue()*popRest/totalProp/e.getKey().getPopulation()))));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Command> getDifferences(Ville v) {
|
|
||||||
|
|
||||||
Set<Command> commands = new HashSet<>();
|
|
||||||
|
|
||||||
for(Building b :gc.getBuildings()) {
|
|
||||||
int cur = v.getBatiments().getOrDefault(b, 0);
|
|
||||||
int obj = this.buildings.getOrDefault(b, 0);
|
|
||||||
if(cur != obj) {
|
|
||||||
if(obj>cur)
|
|
||||||
for(int i=cur+1;i<=obj;i++)
|
|
||||||
commands.add(new BuildCommand(gc,v.getId(), b, i, false));
|
|
||||||
else
|
|
||||||
for(int i=cur-1;i>=obj;i--)
|
|
||||||
commands.add(new BuildCommand(gc,v.getId(), b, i, true));
|
|
||||||
}
|
|
||||||
//TODO check queue
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Research r : gc.getResearches()) {
|
|
||||||
boolean cur = v.getResearches().contains(r);
|
|
||||||
boolean obj = this.researches.contains(r);
|
|
||||||
if(cur && !obj)
|
|
||||||
commands.add(new ResearchCommand(gc,v.getId(),null,r,true));
|
|
||||||
else if (!cur && obj)
|
|
||||||
commands.add(new ResearchCommand(gc,v.getId(),null,r,false));
|
|
||||||
//TODO check queue
|
|
||||||
}
|
|
||||||
Troupes tot = Troupes.add(v.getTroupes(),v.getSoutiens().values().stream().reduce(Troupes::add).orElse(new Troupes(Map.of())));
|
|
||||||
Troupes target = this.targetTroupes();
|
|
||||||
for(Unit u : gc.getUnits()) {
|
|
||||||
int diff = target.getUnites().getOrDefault(u,0) - tot.getUnites().getOrDefault(u,0);
|
|
||||||
if(diff > 0)
|
|
||||||
commands.add(new RecruitCommand(gc,v.getId(), u, diff));
|
|
||||||
//TODO manage unit removal planned
|
|
||||||
}
|
|
||||||
|
|
||||||
if(v.getPiecesStoquees() < hide)
|
|
||||||
commands.add(new HideStoreCommand(gc,v.getId(), hide - v.getPiecesStoquees()));
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Building, Integer> getBuildings() {
|
|
||||||
return buildings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Unit, Double> getUnitsProportions() {
|
|
||||||
return unitsProportions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Research> getResearches() {
|
|
||||||
return researches;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHide() {
|
|
||||||
return hide;
|
|
||||||
}
|
|
||||||
|
|
||||||
public God getGod() {
|
|
||||||
return god;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGc(GameConfig gc) {
|
|
||||||
this.gc = gc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "TownObjective [gc=" + gc + ", buildings=" + buildings + ", unitsProportions=" + unitsProportions
|
|
||||||
+ ", researches=" + researches + ", hide=" + hide + ", god=" + god + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,191 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.game.buildings.Building;
|
|
||||||
import com.bernard.greposimu.model.game.gods.God;
|
|
||||||
import com.bernard.greposimu.model.game.powers.Power;
|
|
||||||
import com.bernard.greposimu.model.game.queues.BuildingQueueItem;
|
|
||||||
import com.bernard.greposimu.model.game.queues.RecruitmentQueueItem;
|
|
||||||
import com.bernard.greposimu.model.game.queues.RecruitmentQueueItem.RecruitmentKind;
|
|
||||||
import com.bernard.greposimu.model.game.queues.ResearchQueueItem;
|
|
||||||
import com.bernard.greposimu.model.game.researches.Research;
|
|
||||||
import com.bernard.greposimu.model.game.units.Unit;
|
|
||||||
import com.bernard.greposimu.model.game.util.Resources;
|
|
||||||
import com.bernard.greposimu.model.game.util.Timestamp;
|
|
||||||
import com.bernard.greposimu.model.game.util.UnitResources;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.CastedPower;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Joueureuse;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.SimulatorData;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Troupes;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Ville;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.Ville.TradeOrder;
|
|
||||||
import com.fasterxml.jackson.core.exc.StreamReadException;
|
|
||||||
import com.fasterxml.jackson.databind.DatabindException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
public class JSONSourcer {
|
|
||||||
|
|
||||||
public static final void readSource(File file) {
|
|
||||||
ObjectMapper om = new ObjectMapper();
|
|
||||||
try {
|
|
||||||
SourcedData sd = om.readValue(file, SourcedData.class);
|
|
||||||
System.out.println(sd);
|
|
||||||
} catch (StreamReadException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (DatabindException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Troupes getTroupes(GameConfig gc, Map<String,Integer> count) {
|
|
||||||
Map<Unit,Integer> troup = new HashMap<>();
|
|
||||||
for(String u : count.keySet())troup.put(gc.getUnit(u), count.get(u));
|
|
||||||
return new Troupes(troup);
|
|
||||||
}
|
|
||||||
public static final Resources getResources(SourcedRessources res) {
|
|
||||||
return new Resources(res.wood, res.stone, res.iron);
|
|
||||||
}
|
|
||||||
public static final UnitResources getUnitResources(God god, SourcedFavRessources res) {
|
|
||||||
return new UnitResources(res.wood, res.stone, res.iron,god,res.favor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final SimulatorData makeSimulationData(String json, GameConfig gc) {
|
|
||||||
ObjectMapper om = new ObjectMapper();
|
|
||||||
try {
|
|
||||||
SourcedData sd = om.readValue(json, SourcedData.class);
|
|
||||||
|
|
||||||
Map<Integer,Ville> villes = new HashMap<>();
|
|
||||||
for(String idS : sd.towns.keySet()) {
|
|
||||||
Integer id = Integer.parseInt(idS);
|
|
||||||
SourcedTown st = sd.getTowns().get(idS);
|
|
||||||
|
|
||||||
Map<Building,Integer> buildings = new HashMap<>();
|
|
||||||
for(String bid : st.buildings.keySet())buildings.put(gc.getBuilding(bid), st.buildings.get(bid));
|
|
||||||
Set<Research> researches = new HashSet<>();
|
|
||||||
for(String rid : st.researches.keySet())if(!rid.equals("id") && st.researches.get(rid))researches.add(gc.getResearch(rid));
|
|
||||||
Map<Integer,Troupes> soutiens = new HashMap<Integer, Troupes>();
|
|
||||||
Map<Integer,Troupes> soutenus = new HashMap<Integer, Troupes>();
|
|
||||||
for(SourcedUnits uts : sd.units) {
|
|
||||||
if(uts.orig == id && uts.curr != id)
|
|
||||||
soutiens.put(uts.curr, getTroupes(gc, uts.getUnits()));
|
|
||||||
if(uts.curr == id && uts.orig != id)
|
|
||||||
soutenus.put(uts.orig, getTroupes(gc, uts.getUnits()));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<BuildingQueueItem> buildingQueue = new ArrayList<>();
|
|
||||||
for(SourcedBuildingOrder sbo : st.buildingOrders)
|
|
||||||
buildingQueue.add(new BuildingQueueItem(
|
|
||||||
sbo.getBuildingTime(),
|
|
||||||
gc.getBuilding(sbo.building),
|
|
||||||
sbo.isTearingDown(),
|
|
||||||
new Timestamp(sbo.getBeginTime()),
|
|
||||||
new Timestamp(sbo.getEndTime()),
|
|
||||||
getResources(sbo.getRefund()),
|
|
||||||
getResources(sbo.getCost())
|
|
||||||
));
|
|
||||||
List<RecruitmentQueueItem> terrestrialQueue = new ArrayList<>();
|
|
||||||
List<RecruitmentQueueItem> navalQueue = new ArrayList<>();
|
|
||||||
for(SourcedRecruitmentOrder sro : st.recruitingOrders) {
|
|
||||||
Unit u = gc.getUnit(sro.unit);
|
|
||||||
RecruitmentQueueItem rqi = new RecruitmentQueueItem(
|
|
||||||
sro.getKind().equals("ground")?RecruitmentKind.GROUND:RecruitmentKind.NAVAL,
|
|
||||||
u,
|
|
||||||
sro.getCount(),
|
|
||||||
sro.getDone(),
|
|
||||||
new Timestamp(sro.getBeginTime()),
|
|
||||||
new Timestamp(sro.getEndTime()),
|
|
||||||
getUnitResources(u.isMythological()?u.getGod():null, sro.getRefund()),
|
|
||||||
getUnitResources(null, sro.getCost())
|
|
||||||
);
|
|
||||||
if(sro.kind.equals("ground"))
|
|
||||||
terrestrialQueue.add(rqi);
|
|
||||||
else if(sro.kind.equals("naval"))
|
|
||||||
navalQueue.add(rqi);
|
|
||||||
}
|
|
||||||
List<ResearchQueueItem> researchQueue = new ArrayList<>();
|
|
||||||
for(SourcedResearchOrder sro : st.researchOrders)
|
|
||||||
researchQueue.add(new ResearchQueueItem(
|
|
||||||
gc.getResearch(sro.getResearch()),
|
|
||||||
new Timestamp(sro.getBeginTime()),
|
|
||||||
new Timestamp(sro.getEndTime()),
|
|
||||||
getResources(sro.getRefund())
|
|
||||||
));
|
|
||||||
|
|
||||||
Set<CastedPower> powers = new HashSet<>();
|
|
||||||
for(SourcedCastedPower sp : st.castedPowers)
|
|
||||||
powers.add(new CastedPower(
|
|
||||||
sp.getOriginPlayer(),
|
|
||||||
gc.getPower(sp.getPower()),
|
|
||||||
sp.getEndTime()==null?null:new Timestamp(sp.getEndTime()),
|
|
||||||
sp.getId(),
|
|
||||||
sp.getLevel(),
|
|
||||||
sp.getExtended(),
|
|
||||||
sp.getConfiguration()));
|
|
||||||
|
|
||||||
Set<TradeOrder> incomingTrade = new HashSet<>();
|
|
||||||
Set<TradeOrder> outgoingTrade = new HashSet<>();
|
|
||||||
for(SourcedTrades str : sd.trades) {
|
|
||||||
//TODO support farmtowns
|
|
||||||
if(str.destType.equals("town_trade") && str.origType.equals("town_trade")){
|
|
||||||
if(Integer.parseInt(str.dest) == id)
|
|
||||||
incomingTrade.add(new TradeOrder(new Resources(str.getWood(), str.getStone(), str.getIron()), Integer.parseInt(str.orig)));
|
|
||||||
if(Integer.parseInt(str.orig) == id)
|
|
||||||
incomingTrade.add(new TradeOrder(new Resources(str.getWood(), str.getStone(), str.getIron()), Integer.parseInt(str.dest)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<SourcedCelebration> townCele = sd.celebrations.stream().filter(c -> c.getTown() == id).collect(Collectors.toSet());
|
|
||||||
villes.put(id, new Ville(
|
|
||||||
id,
|
|
||||||
st.name,
|
|
||||||
buildings,
|
|
||||||
getTroupes(gc, st.getUnitsTotal()),
|
|
||||||
soutiens,
|
|
||||||
soutenus,
|
|
||||||
powers,
|
|
||||||
|
|
||||||
townCele.stream().filter(c -> c.type.equals("party")).map(SourcedCelebration::getEnd).map(Timestamp::new).findAny().orElse(null),
|
|
||||||
townCele.stream().filter(c -> c.type.equals("games")).map(SourcedCelebration::getEnd).map(Timestamp::new).findAny().orElse(null),
|
|
||||||
townCele.stream().filter(c -> c.type.equals("triumph")).map(SourcedCelebration::getEnd).map(Timestamp::new).findAny().orElse(null),
|
|
||||||
townCele.stream().filter(c -> c.type.equals("theater")).map(SourcedCelebration::getEnd).map(Timestamp::new).findAny().orElse(null),
|
|
||||||
|
|
||||||
researches,
|
|
||||||
researchQueue,
|
|
||||||
buildingQueue,
|
|
||||||
st.getMilitia()==null?null:new Timestamp(st.getMilitia().getEnd()),
|
|
||||||
new Resources(st.getResources().wood, st.getResources().stone, st.getResources().iron),
|
|
||||||
terrestrialQueue,
|
|
||||||
gc.getGod(st.god),
|
|
||||||
navalQueue,
|
|
||||||
st.espstorage,
|
|
||||||
null,//ordresMilitaires,
|
|
||||||
incomingTrade,
|
|
||||||
outgoingTrade));
|
|
||||||
|
|
||||||
}
|
|
||||||
Joueureuse joueureuse = new Joueureuse(null, 0, 0, null, null, null, null, null, null, null, null, null);
|
|
||||||
|
|
||||||
return new SimulatorData(villes, joueureuse);
|
|
||||||
} catch (StreamReadException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (DatabindException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedBuildingOrder {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SourcedBuildingOrder [buildingTime=" + buildingTime + ", building=" + building + ", beginTime="
|
|
||||||
+ beginTime + ", tearingDown=" + tearingDown + ", endTime=" + endTime + ", refund=" + refund + ", cost="
|
|
||||||
+ cost + "]";
|
|
||||||
}
|
|
||||||
long buildingTime;
|
|
||||||
|
|
||||||
// the id of the building being built
|
|
||||||
String building;
|
|
||||||
|
|
||||||
long beginTime;
|
|
||||||
boolean tearingDown;
|
|
||||||
long endTime;
|
|
||||||
|
|
||||||
SourcedRessources refund;
|
|
||||||
SourcedRessources cost;
|
|
||||||
|
|
||||||
public long getBuildingTime() {
|
|
||||||
return buildingTime;
|
|
||||||
}
|
|
||||||
public String getBuilding() {
|
|
||||||
return building;
|
|
||||||
}
|
|
||||||
public long getBeginTime() {
|
|
||||||
return beginTime;
|
|
||||||
}
|
|
||||||
public boolean isTearingDown() {
|
|
||||||
return tearingDown;
|
|
||||||
}
|
|
||||||
public long getEndTime() {
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
public SourcedRessources getRefund() {
|
|
||||||
return refund;
|
|
||||||
}
|
|
||||||
public SourcedRessources getCost() {
|
|
||||||
return cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class SourcedCastedPower {
|
|
||||||
|
|
||||||
Map<String,Object> configuration;
|
|
||||||
Long endTime;
|
|
||||||
int extended;
|
|
||||||
Integer level;
|
|
||||||
Long originPlayer;
|
|
||||||
String power;
|
|
||||||
String id;
|
|
||||||
|
|
||||||
public Map<String,Object> getConfiguration() {
|
|
||||||
return configuration;
|
|
||||||
}
|
|
||||||
public Long getEndTime() {
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
public int getExtended() {
|
|
||||||
return extended;
|
|
||||||
}
|
|
||||||
public Integer getLevel() {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
public Long getOriginPlayer() {
|
|
||||||
return originPlayer;
|
|
||||||
}
|
|
||||||
public String getPower() {
|
|
||||||
return power;
|
|
||||||
}
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedCelebration {
|
|
||||||
|
|
||||||
int town;
|
|
||||||
String type;
|
|
||||||
long end;
|
|
||||||
|
|
||||||
public int getTown() {
|
|
||||||
return town;
|
|
||||||
}
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
public long getEnd() {
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class SourcedData {
|
|
||||||
|
|
||||||
Map<String,SourcedTown> towns;
|
|
||||||
List<SourcedCelebration> celebrations;
|
|
||||||
List<SourcedMilitaryOrders> movements;
|
|
||||||
List<SourcedTrades> trades;
|
|
||||||
|
|
||||||
Map<String,Integer> favors;
|
|
||||||
List<SourcedUnits> units;
|
|
||||||
|
|
||||||
public Map<String, SourcedTown> getTowns() {
|
|
||||||
return towns;
|
|
||||||
}
|
|
||||||
public List<SourcedCelebration> getCelebrations() {
|
|
||||||
return celebrations;
|
|
||||||
}
|
|
||||||
public List<SourcedMilitaryOrders> getMovements() {
|
|
||||||
return movements;
|
|
||||||
}
|
|
||||||
public List<SourcedTrades> getTrades() {
|
|
||||||
return trades;
|
|
||||||
}
|
|
||||||
public Map<String, Integer> getFavors() {
|
|
||||||
return favors;
|
|
||||||
}
|
|
||||||
public List<SourcedUnits> getUnits() {
|
|
||||||
return units;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SourcedData [towns=" + towns + ", celebrations=" + celebrations + ", movements=" + movements
|
|
||||||
+ ", trades=" + trades + ", favors=" + favors + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedFavRessources {
|
|
||||||
int wood;
|
|
||||||
int iron;
|
|
||||||
int stone;
|
|
||||||
int favor;
|
|
||||||
int pop;
|
|
||||||
public int getWood() {
|
|
||||||
return wood;
|
|
||||||
}
|
|
||||||
public int getIron() {
|
|
||||||
return iron;
|
|
||||||
}
|
|
||||||
public int getStone() {
|
|
||||||
return stone;
|
|
||||||
}
|
|
||||||
public int getFavor() {
|
|
||||||
return favor;
|
|
||||||
}
|
|
||||||
public int getPop() {
|
|
||||||
return pop;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SourcedFavRessources [wood=" + wood + ", iron=" + iron + ", stone=" + stone + ", favor=" + favor
|
|
||||||
+ ", pop=" + pop + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedMilitaryOrders {
|
|
||||||
|
|
||||||
long start;
|
|
||||||
long arrival;
|
|
||||||
long cancelableUntil;
|
|
||||||
long invisibleUntil;
|
|
||||||
|
|
||||||
boolean destIsAttackSpot;
|
|
||||||
boolean origIsAttackSpot;
|
|
||||||
|
|
||||||
int player;
|
|
||||||
int homeId;
|
|
||||||
int targetId;
|
|
||||||
|
|
||||||
String type;
|
|
||||||
|
|
||||||
public long getArrival() {
|
|
||||||
return arrival;
|
|
||||||
}
|
|
||||||
public long getCancelableUntil() {
|
|
||||||
return cancelableUntil;
|
|
||||||
}
|
|
||||||
public long getInvisibleUntil() {
|
|
||||||
return invisibleUntil;
|
|
||||||
}
|
|
||||||
public boolean isDestIsAttackSpot() {
|
|
||||||
return destIsAttackSpot;
|
|
||||||
}
|
|
||||||
public boolean isOrigIsAttackSpot() {
|
|
||||||
return origIsAttackSpot;
|
|
||||||
}
|
|
||||||
public int getHomeId() {
|
|
||||||
return homeId;
|
|
||||||
}
|
|
||||||
public int getPlayer() {
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
public long getStart() {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
public int getTargetId() {
|
|
||||||
return targetId;
|
|
||||||
}
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedMilitiaTimes {
|
|
||||||
long start;
|
|
||||||
long end;
|
|
||||||
|
|
||||||
public long getStart() {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
public long getEnd() {
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedRecruitmentOrder {
|
|
||||||
|
|
||||||
int count;
|
|
||||||
|
|
||||||
int done;
|
|
||||||
|
|
||||||
String kind;
|
|
||||||
// the id of the building being built
|
|
||||||
String unit;
|
|
||||||
|
|
||||||
long beginTime;
|
|
||||||
long endTime;
|
|
||||||
|
|
||||||
SourcedFavRessources refund;
|
|
||||||
SourcedFavRessources cost;
|
|
||||||
public int getCount() {
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
public int getDone() {
|
|
||||||
return done;
|
|
||||||
}
|
|
||||||
public String getKind() {
|
|
||||||
return kind;
|
|
||||||
}
|
|
||||||
public String getUnit() {
|
|
||||||
return unit;
|
|
||||||
}
|
|
||||||
public long getBeginTime() {
|
|
||||||
return beginTime;
|
|
||||||
}
|
|
||||||
public long getEndTime() {
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
public SourcedFavRessources getRefund() {
|
|
||||||
return refund;
|
|
||||||
}
|
|
||||||
public SourcedFavRessources getCost() {
|
|
||||||
return cost;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SourcedRecruitmentOrder [count=" + count + ", done=" + done + ", kind=" + kind + ", unit=" + unit
|
|
||||||
+ ", beginTime=" + beginTime + ", endTime=" + endTime + ", refund=" + refund + ", cost=" + cost + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedResearchOrder {
|
|
||||||
|
|
||||||
// the id of the building being built
|
|
||||||
String research;
|
|
||||||
|
|
||||||
long beginTime;
|
|
||||||
long endTime;
|
|
||||||
|
|
||||||
SourcedRessources refund;
|
|
||||||
|
|
||||||
public String getResearch() {
|
|
||||||
return research;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getBeginTime() {
|
|
||||||
return beginTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getEndTime() {
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourcedRessources getRefund() {
|
|
||||||
return refund;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedRessources {
|
|
||||||
int wood;
|
|
||||||
int iron;
|
|
||||||
int stone;
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SourcedRessources [wood=" + wood + ", iron=" + iron + ", stone=" + stone + "]";
|
|
||||||
}
|
|
||||||
public int getWood() {
|
|
||||||
return wood;
|
|
||||||
}
|
|
||||||
public int getIron() {
|
|
||||||
return iron;
|
|
||||||
}
|
|
||||||
public int getStone() {
|
|
||||||
return stone;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class SourcedTown {
|
|
||||||
|
|
||||||
String name;
|
|
||||||
int points;
|
|
||||||
|
|
||||||
String god;
|
|
||||||
SourcedTownResources resources;
|
|
||||||
int espstorage;
|
|
||||||
|
|
||||||
/* GLOBAL UNITS */
|
|
||||||
// unit_id -> number of units
|
|
||||||
// TOTAL units defending this city
|
|
||||||
Map<String,Integer> unitsTotal;
|
|
||||||
// TOTAL units from this city defending another city
|
|
||||||
Map<String,Integer> outerTotal;
|
|
||||||
// TOTAL units from other cities defending this city
|
|
||||||
Map<String,Integer> supportTotal;
|
|
||||||
|
|
||||||
|
|
||||||
// building_id -> level
|
|
||||||
Map<String,Integer> buildings;
|
|
||||||
|
|
||||||
// research_id -> hasBeenResearched
|
|
||||||
Map<String,Boolean> researches;
|
|
||||||
|
|
||||||
List<SourcedCastedPower> castedPowers;
|
|
||||||
|
|
||||||
|
|
||||||
List<SourcedBuildingOrder> buildingOrders;
|
|
||||||
List<SourcedRecruitmentOrder> recruitingOrders;
|
|
||||||
List<SourcedResearchOrder> researchOrders;
|
|
||||||
|
|
||||||
SourcedMilitiaTimes militia;
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
public int getPoints() {
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
public Map<String, Integer> getUnitsTotal() {
|
|
||||||
return unitsTotal;
|
|
||||||
}
|
|
||||||
public Map<String, Integer> getOuterTotal() {
|
|
||||||
return outerTotal;
|
|
||||||
}
|
|
||||||
public Map<String, Integer> getSupportTotal() {
|
|
||||||
return supportTotal;
|
|
||||||
}
|
|
||||||
public Map<String, Integer> getBuildings() {
|
|
||||||
return buildings;
|
|
||||||
}
|
|
||||||
public Map<String, Boolean> getResearches() {
|
|
||||||
return researches;
|
|
||||||
}
|
|
||||||
public List<SourcedCastedPower> getCastedPowers() {
|
|
||||||
return castedPowers;
|
|
||||||
}
|
|
||||||
public List<SourcedBuildingOrder> getBuildingOrders() {
|
|
||||||
return buildingOrders;
|
|
||||||
}
|
|
||||||
public List<SourcedRecruitmentOrder> getRecruitingOrders() {
|
|
||||||
return recruitingOrders;
|
|
||||||
}
|
|
||||||
public List<SourcedResearchOrder> getResearchOrders() {
|
|
||||||
return researchOrders;
|
|
||||||
}
|
|
||||||
public SourcedTownResources getResources() {
|
|
||||||
return resources;
|
|
||||||
}
|
|
||||||
public int getEspstorage() {
|
|
||||||
return espstorage;
|
|
||||||
}
|
|
||||||
public SourcedMilitiaTimes getMilitia() {
|
|
||||||
return militia;
|
|
||||||
}
|
|
||||||
public String getGod() {
|
|
||||||
return god;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SourcedTown [name=" + name + ", points=" + points + ", god=" + god + ", resources=" + resources
|
|
||||||
+ ", espstorage=" + espstorage + ", unitsTotal=" + unitsTotal + ", outerTotal=" + outerTotal
|
|
||||||
+ ", supportTotal=" + supportTotal + ", buildings=" + buildings + ", researches=" + researches
|
|
||||||
+ ", castedPowers=" + castedPowers + ", buildingOrders=" + buildingOrders + ", recruitingOrders="
|
|
||||||
+ recruitingOrders + ", researchOrders=" + researchOrders + ", militia=" + militia + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedTownResources {
|
|
||||||
|
|
||||||
int wood,stone,iron,storage,population,favor;
|
|
||||||
|
|
||||||
public int getWood() {
|
|
||||||
return wood;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStone() {
|
|
||||||
return stone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIron() {
|
|
||||||
return iron;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStorage() {
|
|
||||||
return storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPopulation() {
|
|
||||||
return population;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SourcedTownResources [wood=" + wood + ", stone=" + stone + ", iron=" + iron + ", storage=" + storage
|
|
||||||
+ ", population=" + population + ", favor=" + favor + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFavor() {
|
|
||||||
return favor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
public class SourcedTrades {
|
|
||||||
|
|
||||||
long start;
|
|
||||||
long arrival;
|
|
||||||
String dest;
|
|
||||||
String destType;
|
|
||||||
String orig;
|
|
||||||
String origType;
|
|
||||||
|
|
||||||
int gold,stone,wood,iron;
|
|
||||||
|
|
||||||
boolean exchange;
|
|
||||||
|
|
||||||
public long getStart() {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getArrival() {
|
|
||||||
return arrival;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDest() {
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDestType() {
|
|
||||||
return destType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrig() {
|
|
||||||
return orig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrigType() {
|
|
||||||
return origType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGold() {
|
|
||||||
return gold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStone() {
|
|
||||||
return stone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWood() {
|
|
||||||
return wood;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIron() {
|
|
||||||
return iron;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isExchange() {
|
|
||||||
return exchange;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SourcedTrades [start=" + start + ", arrival=" + arrival + ", dest=" + dest + ", destType=" + destType
|
|
||||||
+ ", orig=" + orig + ", origType=" + origType + ", gold=" + gold + ", stone=" + stone + ", wood=" + wood
|
|
||||||
+ ", iron=" + iron + ", exchange=" + exchange + "]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
package com.bernard.greposimu.source;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class SourcedUnits {
|
|
||||||
int orig;
|
|
||||||
int curr;
|
|
||||||
Map<String,Integer> units;
|
|
||||||
boolean sameIsland;
|
|
||||||
|
|
||||||
public int getOrig() {
|
|
||||||
return orig;
|
|
||||||
}
|
|
||||||
public int getCurr() {
|
|
||||||
return curr;
|
|
||||||
}
|
|
||||||
public Map<String, Integer> getUnits() {
|
|
||||||
return units;
|
|
||||||
}
|
|
||||||
public boolean isSameIsland() {
|
|
||||||
return sameIsland;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,4 +1,3 @@
|
|||||||
spring.application.name=GrepoSimu
|
spring.application.name=GrepoSimu
|
||||||
spring.devtools.restart.pollInterval=10s
|
spring.devtools.restart.pollInterval=10s
|
||||||
spring.mvc.favicon.enabled=false
|
spring.mvc.favicon.enabled=false
|
||||||
spring.web.resources.static-locations=classpath:/static/
|
|
||||||
11
src/main/resources/greposource.js
Normal file
11
src/main/resources/greposource.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
out = {}
|
||||||
|
for(var townid in ITowns.towns) {
|
||||||
|
out[townid] = {}
|
||||||
|
out[townid].units = ITowns.towns[townid].units()
|
||||||
|
out[townid].support = ITowns.towns[townid].unitsSupport()
|
||||||
|
out[townid].outer = ITowns.towns[townid].unitsOuter()
|
||||||
|
out[townid].resources = ITowns.towns[townid].resources()
|
||||||
|
out[townid].buildings = ITowns.towns[townid].buildings().getBuildings()
|
||||||
|
out[townid].researches = ITowns.towns[townid].researches().attributes
|
||||||
|
}
|
||||||
|
var json = JSON.stringify(out)
|
||||||
@ -1,218 +0,0 @@
|
|||||||
// ==UserScript==
|
|
||||||
// @name GrepoSimu
|
|
||||||
// @namespace greposimu
|
|
||||||
// @version 1.0
|
|
||||||
// @author Mysaa Java
|
|
||||||
// @homepage https://greposimu.bernard.com.de
|
|
||||||
// @updateURL https://greposimu.bernard.com.de/userscript.js
|
|
||||||
// @downloadURL https://greposimu.bernard.com.de/userscript.js
|
|
||||||
// @description This script sends information on the town to greposimu
|
|
||||||
// @include https://*.grepolis.com/game/*
|
|
||||||
// @exclude view-source://*
|
|
||||||
// @icon https://greposimu.bernard.com.de/favicon.ico
|
|
||||||
// ==/UserScript==
|
|
||||||
|
|
||||||
function downloadObjectAsJson(exportObj, exportName){
|
|
||||||
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj,null,2));
|
|
||||||
var downloadAnchorNode = document.createElement('a');
|
|
||||||
downloadAnchorNode.setAttribute("href", dataStr);
|
|
||||||
downloadAnchorNode.setAttribute("download", exportName + ".json");
|
|
||||||
document.body.appendChild(downloadAnchorNode); // required for firefox
|
|
||||||
downloadAnchorNode.click();
|
|
||||||
downloadAnchorNode.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAllFragments() {
|
|
||||||
out = {}
|
|
||||||
for(var storename in ITowns){
|
|
||||||
|
|
||||||
if(typeof ITowns[storename] === 'object' && "fragments" in ITowns[storename]){
|
|
||||||
out[storename] = {}
|
|
||||||
store = ITowns[storename].fragments
|
|
||||||
for(var townid in store) {
|
|
||||||
out[storename][townid] = []
|
|
||||||
for(var i = 0; i < store[townid].models.length;i++){
|
|
||||||
out[storename][townid].push(store[townid].models[i].attributes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeObject() {
|
|
||||||
out = {}
|
|
||||||
for(var townid in ITowns.towns) {
|
|
||||||
out[townid] = {}
|
|
||||||
out[townid].name = ITowns.towns[townid].name
|
|
||||||
out[townid].points = ITowns.towns[townid].points
|
|
||||||
out[townid].god = ITowns.towns[townid].god()
|
|
||||||
out[townid].unitsTotal = ITowns.towns[townid].units()
|
|
||||||
out[townid].supportTotal = ITowns.towns[townid].unitsSupport()
|
|
||||||
out[townid].outerTotal = ITowns.towns[townid].unitsOuter()
|
|
||||||
out[townid].resources = ITowns.towns[townid].resources()
|
|
||||||
out[townid].buildings = ITowns.towns[townid].getBuildings().getBuildings()
|
|
||||||
out[townid].researches = ITowns.towns[townid].researches().attributes
|
|
||||||
out[townid].espstorage = ITowns.towns[townid].getEspionageStorage()
|
|
||||||
|
|
||||||
orderz = ITowns.towns[townid].buildingOrders()
|
|
||||||
out[townid].buildingOrders = []
|
|
||||||
for(var i = 0; i<orderz.length;i++) {
|
|
||||||
order = orderz.models[i].attributes
|
|
||||||
out[townid].buildingOrders.push({
|
|
||||||
buildingTime: order.building_time,
|
|
||||||
building: order.building_type,
|
|
||||||
beginTime: order.created_at,
|
|
||||||
tearingDown: order.tear_down,
|
|
||||||
endTime: order.to_be_completed_at,
|
|
||||||
refund: order.cancel_refund,
|
|
||||||
cost: {wood: order.wood, stone: order.stone, iron: order.iron}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
recruitments = ITowns.all_remaining_unit_orders.fragments[townid]
|
|
||||||
out[townid].recruitingOrders = []
|
|
||||||
for(var i = 0; i<recruitments.models.length; i++) {
|
|
||||||
order = recruitments.models[i].attributes
|
|
||||||
out[townid].recruitingOrders.push({
|
|
||||||
count: order.count,
|
|
||||||
beginTime: order.created_at,
|
|
||||||
kind: order.kind,
|
|
||||||
done: order.parts_done,
|
|
||||||
refund: order.refund_for_single_unit,
|
|
||||||
endTime: order.to_be_completed_at,
|
|
||||||
unit: order.unit_type,
|
|
||||||
cost: {wood: order.wood, stone: order.stone, iron: order.iron, favor: order.favor}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
castedPowers = ITowns.all_casted_powers.fragments[townid]
|
|
||||||
out[townid].castedPowers = []
|
|
||||||
for(var i = 0; i<castedPowers.models.length; i++) {
|
|
||||||
order = castedPowers.models[i].attributes
|
|
||||||
out[townid].castedPowers.push({
|
|
||||||
configuration: order.configuration,
|
|
||||||
endTime: order.to_be_completed_at,
|
|
||||||
extended: order.extended,
|
|
||||||
level: order.level,
|
|
||||||
originPlayer: order.origin_player_id,
|
|
||||||
power: order.power_id,
|
|
||||||
id: order.id
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
researches = MM.getTownAgnosticCollectionsByName("ResearchOrder")[0].fragments[townid]
|
|
||||||
out[townid].researchOrders = []
|
|
||||||
for(var i = 0; i<researches.models.length; i++) {
|
|
||||||
order = researches.models[i].attributes
|
|
||||||
out[townid].researchOrders.push({
|
|
||||||
research: order.research_type,
|
|
||||||
beginTime: order.created_at,
|
|
||||||
endTime: order.to_be_completed_at,
|
|
||||||
refund: order.cancel_refund
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
militia = MM.getModels().Militia
|
|
||||||
if(townid in militia){
|
|
||||||
out[townid].militia = {
|
|
||||||
start : militia[townid].attributes.started_at,
|
|
||||||
end: militia[townid].attributes.finished_at
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out[townid].militia = null
|
|
||||||
}*/
|
|
||||||
out[townid].militia = null
|
|
||||||
|
|
||||||
}
|
|
||||||
celebrations = MM.getModels().Celebration
|
|
||||||
outCele = []
|
|
||||||
for (var i in celebrations) {
|
|
||||||
outCele.push({
|
|
||||||
town: celebrations[i].attributes.townid,
|
|
||||||
type: celebrations[i].attributes.celebration_type,
|
|
||||||
end: celebrations[i].attributes.finished_at,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
mvts = MM.getModels().MovementsUnits
|
|
||||||
outMvts = []
|
|
||||||
for (var i in mvts) {
|
|
||||||
mvt = mvts[i].attributes
|
|
||||||
outMvts.push({
|
|
||||||
arrival: mvt.arrival_at,
|
|
||||||
cancelableUntil: mvt.cancelable_until,
|
|
||||||
invisibleUntil: mvt.cap_of_invisibility_effective_until,
|
|
||||||
destIsAttackSpot: mvt.destination_is_attack_spot,
|
|
||||||
origIsAttackSpot: mvt.origin_is_attack_spot,
|
|
||||||
homeId: mvt.home_town_id ,
|
|
||||||
player: mvt.player_id,
|
|
||||||
start: mvt.started_at,
|
|
||||||
targetId: mvt.target_town_id,
|
|
||||||
type: mvt.type,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
trdz = MM.getModels().Trade
|
|
||||||
outTrd = []
|
|
||||||
for (var i in trdz) {
|
|
||||||
trd = trdz[i].attributes
|
|
||||||
outTrd.push({
|
|
||||||
start: trd.started_at,
|
|
||||||
arrival: trd.arrival_at,
|
|
||||||
dest: trd.destination_town_id,
|
|
||||||
destType: trd.destination_town_type,
|
|
||||||
gold: trd.gold,
|
|
||||||
stone: trd.stone,
|
|
||||||
wood: trd.wood,
|
|
||||||
iron: trd.iron,
|
|
||||||
orig: trd.origin_town_id,
|
|
||||||
origType: trd.origin_town_type,
|
|
||||||
exchange: trd.in_exchange
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fav = MM.getModels().PlayerGods[Object.keys(MM.getModels().PlayerGods)[0]].attributes
|
|
||||||
outFav = {
|
|
||||||
aphrodite: fav.aphrodite_favor,
|
|
||||||
ares: fav.ares_favor,
|
|
||||||
artemis: fav.artemis_favor,
|
|
||||||
athena: fav.athena_favor,
|
|
||||||
fury: fav.fury,
|
|
||||||
hades: fav.hades_favor,
|
|
||||||
hera: fav.hera_favor,
|
|
||||||
poseidon: fav.poseidon_favor,
|
|
||||||
zeus: fav.zeus_favor
|
|
||||||
}
|
|
||||||
utz = MM.getModels().Units
|
|
||||||
outUts = []
|
|
||||||
for (var i in utz) {
|
|
||||||
outUts.push({
|
|
||||||
orig: utz[i].getOriginTownId(),
|
|
||||||
curr: utz[i].getCurrentTownId(),
|
|
||||||
units: utz[i].getUnits(),
|
|
||||||
sameIsland: utz[i].isSameIsland()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return {towns: out,celebrations: outCele, movements: outMvts, trades: outTrd, favors: outFav, units: outUts}
|
|
||||||
}
|
|
||||||
|
|
||||||
function greposimu() {
|
|
||||||
GREPOSIMURL="http://localhost:8080"
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
crossDomain: true,
|
|
||||||
contentType : "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify(makeObject()),
|
|
||||||
datatype : "application/json",
|
|
||||||
url: GREPOSIMURL+'/registerScheduler',
|
|
||||||
success: function(uuid){
|
|
||||||
window.open(GREPOSIMURL+'/scheduler/'+uuid, '_blank').focus();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function doc_keyUp(e) {
|
|
||||||
console.log("Keyup de greposimu")
|
|
||||||
if (e.keyCode == 79)
|
|
||||||
greposimu();
|
|
||||||
}
|
|
||||||
console.log("GrepoSimu loaded")
|
|
||||||
document.addEventListener('keyup', doc_keyUp, false)
|
|
||||||
@ -16,7 +16,6 @@ body {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre th:text="${content}"></pre>
|
<pre th:text="${content}"></pre>
|
||||||
<main th:utext="${raw}"></main>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@ -1,92 +1,16 @@
|
|||||||
package com.bernard.greposimu;
|
package com.bernard.greposimu;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameConfig;
|
|
||||||
import com.bernard.greposimu.model.game.GrepoYaml;
|
|
||||||
import com.bernard.greposimu.model.game.units.Unit;
|
|
||||||
import com.bernard.greposimu.model.simulator.data.SimulatorData;
|
|
||||||
import com.bernard.greposimu.model.simulator.objective.TownObjective;
|
|
||||||
import com.bernard.greposimu.source.JSONSourcer;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
|
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
class GrepoSimuApplicationTests {
|
class GrepoSimuApplicationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void loadGameData() throws IOException {
|
void loadGameData() throws IOException {
|
||||||
// System.out.println(GrepoSimu.makeGameData());
|
System.out.println(GrepoSimu.makeGameData());
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testJsonRead() throws IOException {
|
|
||||||
System.out.println("Test de sérialisation :");
|
|
||||||
GameConfig gc = GrepoSimu.makeGameData();
|
|
||||||
FileInputStream fis = new FileInputStream(new File("/home/mysaa/Downloads/greposimu.json"));
|
|
||||||
String data = new String(fis.readAllBytes());
|
|
||||||
fis.close();
|
|
||||||
SimulatorData sd = JSONSourcer.makeSimulationData(data,gc);
|
|
||||||
//System.out.println(sd);
|
|
||||||
}
|
|
||||||
|
|
||||||
TownObjective testObjective(GameConfig gc) {
|
|
||||||
return new TownObjective(gc, Map.of(
|
|
||||||
gc.getBuilding("main"), 24,
|
|
||||||
gc.getBuilding("wall"), 25,
|
|
||||||
gc.getBuilding("farm"), 45,
|
|
||||||
gc.getBuilding("academy"), 20,
|
|
||||||
gc.getBuilding("docks"), 1,
|
|
||||||
gc.getBuilding("barracks"), 30),
|
|
||||||
Map.of(
|
|
||||||
gc.getUnit("sword"), 8.0,
|
|
||||||
gc.getUnit("archer"), 8.0,
|
|
||||||
gc.getUnit("hoplite"), 16.0,
|
|
||||||
gc.getUnit("big_transporter"),7.0),
|
|
||||||
Set.of(
|
|
||||||
gc.getResearch("hoplite"),
|
|
||||||
gc.getResearch("archer"),
|
|
||||||
gc.getResearch("conscription")),
|
|
||||||
100_000,
|
|
||||||
gc.getGod("poseidon"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testDifferences() throws IOException {
|
|
||||||
GameConfig gc = GrepoSimu.makeGameData();
|
|
||||||
FileInputStream fis = new FileInputStream(new File("/home/mysaa/Downloads/greposimu.json"));
|
|
||||||
String data = new String(fis.readAllBytes());
|
|
||||||
fis.close();
|
|
||||||
SimulatorData sd = JSONSourcer.makeSimulationData(data,gc);
|
|
||||||
System.out.println(gc.getUnits().stream().map(Unit::getId).collect(Collectors.joining(",")));
|
|
||||||
TownObjective defObjective = testObjective(gc);
|
|
||||||
/*
|
|
||||||
for(Ville v : sd.getVilles().values()) {
|
|
||||||
System.out.println("==== Ville "+v.getNom()+" ====");
|
|
||||||
System.out.println(defObjective.getDifferences(v).stream().map(Command::toString).sorted().collect(Collectors.joining("\n")));
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void writeTestObjective() throws IOException {
|
|
||||||
ObjectMapper om = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER));
|
|
||||||
GameConfig gc = GrepoSimu.makeGameData();
|
|
||||||
om.registerModule(new GrepoYaml(gc));
|
|
||||||
|
|
||||||
om.writeValue(new File("/tmp/out.yml"), testObjective(gc));
|
|
||||||
|
|
||||||
TownObjective newObjective = om.readValue(new File("/tmp/out.yml"), TownObjective.class);
|
|
||||||
System.out.println("READ VALUE");
|
|
||||||
System.out.println(newObjective);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,67 +0,0 @@
|
|||||||
defTerTown:
|
|
||||||
buildings:
|
|
||||||
main: 24
|
|
||||||
lumber: 40
|
|
||||||
farm: 45
|
|
||||||
stoner: 40
|
|
||||||
storage: 35
|
|
||||||
ironer: 40
|
|
||||||
barracks: 30
|
|
||||||
temple: 10
|
|
||||||
market: 15
|
|
||||||
docks: 1
|
|
||||||
academy: 25
|
|
||||||
wall: 25
|
|
||||||
hide: 10
|
|
||||||
tower: 1
|
|
||||||
thermal: 1
|
|
||||||
unitsProportions:
|
|
||||||
sword: 8.0
|
|
||||||
big_transporter: 7.0
|
|
||||||
hoplite: 16.0
|
|
||||||
archer: 8.0
|
|
||||||
researches:
|
|
||||||
- "archer"
|
|
||||||
- "town_guard"
|
|
||||||
- "hoplite"
|
|
||||||
- "pottery"
|
|
||||||
- "instructor"
|
|
||||||
- "building_crane"
|
|
||||||
- "conscription"
|
|
||||||
- "cryptography"
|
|
||||||
- "plow"
|
|
||||||
- "berth"
|
|
||||||
- "phalanx"
|
|
||||||
hide: 100000
|
|
||||||
god: "ares"
|
|
||||||
|
|
||||||
defNavTown:
|
|
||||||
buildings:
|
|
||||||
main: 24
|
|
||||||
lumber: 40
|
|
||||||
farm: 45
|
|
||||||
stoner: 40
|
|
||||||
storage: 35
|
|
||||||
ironer: 40
|
|
||||||
barracks: 1
|
|
||||||
temple: 10
|
|
||||||
market: 15
|
|
||||||
docks: 30
|
|
||||||
academy: 28
|
|
||||||
wall: 0
|
|
||||||
hide: 10
|
|
||||||
thermal: 1
|
|
||||||
unitsProportions:
|
|
||||||
bireme: 1.0
|
|
||||||
researches:
|
|
||||||
- "town_guard"
|
|
||||||
- "pottery"
|
|
||||||
- "bireme"
|
|
||||||
- "shipwright"
|
|
||||||
- "cryptography"
|
|
||||||
- "plow"
|
|
||||||
- "mathematics"
|
|
||||||
- "ram"
|
|
||||||
- "cartography"
|
|
||||||
hide: 100000
|
|
||||||
god: "poseidon"
|
|
||||||
Loading…
x
Reference in New Issue
Block a user