Compare commits
12
Commits
f3bbeb8d4a
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6410de196f
|
||
|
|
acab58d0a3
|
||
|
|
0bcc1e3591
|
||
|
|
0686ab99c5
|
||
|
|
fa7d0362c7
|
||
|
|
6bc9d4df9d
|
||
|
|
26755f9ecd
|
||
|
|
6e2f916927
|
||
|
|
8454e3a711
|
||
|
|
b783361264
|
||
|
|
f9bc9e4fa5
|
||
|
|
a08c6e1c64
|
+2
-1
@@ -25,9 +25,10 @@ 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'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test') {
|
tasks.named('test') {
|
||||||
|
|||||||
@@ -4,117 +4,29 @@ import java.io.BufferedReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.bernard.greposimu.engine.Registerar;
|
import org.json.JSONObject;
|
||||||
import com.bernard.greposimu.engine.game.Buildings;
|
|
||||||
import com.bernard.greposimu.engine.json.MapJsonDeserializer;
|
import com.bernard.greposimu.controller.JSONReader;
|
||||||
import com.bernard.greposimu.model.Dieu;
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
import com.bernard.greposimu.model.Heros;
|
|
||||||
import com.bernard.greposimu.model.OffDefStats;
|
|
||||||
import com.bernard.greposimu.model.game.GameData;
|
|
||||||
import com.bernard.greposimu.model.game.Power;
|
|
||||||
import com.fasterxml.jackson.core.JsonFactory;
|
|
||||||
import com.fasterxml.jackson.core.StreamReadFeature;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
|
||||||
|
|
||||||
public class GrepoSimu {
|
public class GrepoSimu {
|
||||||
|
|
||||||
public static GameData readGameData() throws IOException {
|
public static GameConfig makeGameData() throws IOException {
|
||||||
|
|
||||||
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||||
try (InputStream is = classLoader.getResourceAsStream("gamedata.json")) {
|
try (InputStream is = classLoader.getResourceAsStream("gamedata.json")) {
|
||||||
if (is == null) return null;
|
if (is == null) return null;
|
||||||
try (InputStreamReader isr = new InputStreamReader(is);
|
try (InputStreamReader isr = new InputStreamReader(is);
|
||||||
BufferedReader reader = new BufferedReader(isr)) {
|
BufferedReader reader = new BufferedReader(isr)) {
|
||||||
|
|
||||||
// Reading the file
|
// Reading the file
|
||||||
String json = reader.lines().collect(Collectors.joining(System.lineSeparator()));
|
String json = reader.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||||
|
|
||||||
// De-serialize to an object
|
JSONObject obj = new JSONObject(json);
|
||||||
JsonFactory jsonFactory = JsonFactory.builder()
|
|
||||||
.enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION)
|
|
||||||
.build();
|
|
||||||
SimpleModule module = new SimpleModule();
|
|
||||||
module.addDeserializer(Map.class, new MapJsonDeserializer());
|
|
||||||
ObjectMapper mapper = new ObjectMapper(jsonFactory);
|
|
||||||
mapper.registerModule(module);
|
|
||||||
GameData data = mapper.readValue(json, GameData.class);
|
|
||||||
|
|
||||||
// Adapting power map
|
return JSONReader.makeGameConfig(obj);
|
||||||
Map<String,Power> pmap = new HashMap<>();
|
|
||||||
for(String id : data.powers.keySet()) {
|
|
||||||
Set<String> types = data.powers.get(id).getTypes();
|
|
||||||
if(types.isEmpty()) {
|
|
||||||
pmap.put(id, new Power(data.powers.get(id)));
|
|
||||||
} else {
|
|
||||||
for(String type : types) {
|
|
||||||
pmap.put(id+"."+type, new Power(data.powers.get(id), type));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
data.powers = pmap;
|
|
||||||
System.out.println(data.powers.get("effort_of_the_huntress"));
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
for(int i=0;i<26;i++)
|
|
||||||
System.out.println(i+"->"+Buildings.wallBonus(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void mainZ(String[] args) {
|
|
||||||
Registerar.regiter();
|
|
||||||
|
|
||||||
System.out.println(Registerar.unites.size());
|
|
||||||
OffDefStats scoring = new OffDefStats(0, 0, 0, 1.0, 0,0,0,0);
|
|
||||||
for(Heros h : withNull(Registerar.heros)) {
|
|
||||||
if(h!= null && h.getNom()!="Agamemnon")continue;
|
|
||||||
for(int l = 1;l<=20&&h!=null;l+=10-(l%10)) {
|
|
||||||
for(Dieu d : withNull(Arrays.asList(Dieu.values()))) {
|
|
||||||
|
|
||||||
//System.out.println("Héros: "+((c.h==null)?"aucun":("%s (lvl %d)".formatted(h.getNom(),l)))+" - Dieu: "+((d==null)?"aucun":d.getNom()));
|
|
||||||
//up.print(h, l, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final <T> Iterable<T> withNull(Iterable<T> itrble) {
|
|
||||||
return (Iterable<T>) new Iterable<T>() {
|
|
||||||
@Override
|
|
||||||
public Iterator<T> iterator() {
|
|
||||||
Iterator<T> it = itrble.iterator();
|
|
||||||
return new Iterator<T>() {
|
|
||||||
boolean pastNull = false;
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
return !pastNull || it.hasNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T next() {
|
|
||||||
if(pastNull)
|
|
||||||
return it.next();
|
|
||||||
else {
|
|
||||||
pastNull = true;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,36 @@
|
|||||||
package com.bernard.greposimu;
|
package com.bernard.greposimu;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
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.engine.Registerar;
|
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 void main(String[] args) {
|
public static GameConfig GREPOLIS_GC;
|
||||||
Registerar.regiter();
|
public static Map<String, TownObjective> OBJECTIVES;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
/*package com.bernard.greposimu;
|
|
||||||
|
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
|
||||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
|
||||||
|
|
||||||
public class ServletInitializer extends SpringBootServletInitializer {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
|
||||||
return application.sources(GrepoSimuApplication.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -2,9 +2,15 @@ package com.bernard.greposimu;
|
|||||||
|
|
||||||
import java.util.AbstractMap;
|
import java.util.AbstractMap;
|
||||||
import java.util.AbstractSet;
|
import java.util.AbstractSet;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
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;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
@@ -18,6 +24,29 @@ public class Utils {
|
|||||||
a5 * x * x * x * x * x;
|
a5 * x * x * x * x * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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){
|
||||||
|
if(set.isEmpty())
|
||||||
|
return EnumSet.noneOf(c);
|
||||||
|
else
|
||||||
|
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>() {
|
||||||
|
|
||||||
@@ -66,4 +95,8 @@ public class Utils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <E> E randFromSet(Random r, Set<E> set) {
|
||||||
|
E el = set.stream().sorted().skip(r.nextInt(set.size())).findFirst().get();
|
||||||
|
return el;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.bernard.greposimu.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.GrepoSimuApplication;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class GameDataController {
|
||||||
|
|
||||||
|
@GetMapping("/gamedata")
|
||||||
|
public String gamedata(Model model) {
|
||||||
|
System.out.println("Reading game data");
|
||||||
|
model.addAttribute("content",GrepoSimuApplication.GREPOLIS_GC);
|
||||||
|
return "debug";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,291 +0,0 @@
|
|||||||
package com.bernard.greposimu.controller;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.GrepoSimu;
|
|
||||||
import com.bernard.greposimu.engine.Optimizer;
|
|
||||||
import com.bernard.greposimu.engine.Optimizer.UnitesProportions;
|
|
||||||
import com.bernard.greposimu.engine.Registerar;
|
|
||||||
import com.bernard.greposimu.engine.game.Fight;
|
|
||||||
import com.bernard.greposimu.engine.game.Game;
|
|
||||||
import com.bernard.greposimu.model.DefContext;
|
|
||||||
import com.bernard.greposimu.model.Dieu;
|
|
||||||
import com.bernard.greposimu.model.FightStats;
|
|
||||||
import com.bernard.greposimu.model.Heros;
|
|
||||||
import com.bernard.greposimu.model.OffDefStats;
|
|
||||||
import com.bernard.greposimu.model.Unite;
|
|
||||||
import com.bernard.greposimu.model.game.GameData;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
public class GrepoSimuController {
|
|
||||||
|
|
||||||
@GetMapping("/gamedata")
|
|
||||||
public String gamedata(Model model) {
|
|
||||||
System.out.println("Reading game data");
|
|
||||||
GameData data;
|
|
||||||
try {
|
|
||||||
data = GrepoSimu.readGameData();
|
|
||||||
model.addAttribute("content",data.toString());
|
|
||||||
} catch (IOException e) {
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
e.printStackTrace(new PrintWriter(writer));
|
|
||||||
model.addAttribute("content",writer.toString());
|
|
||||||
}
|
|
||||||
return "debug";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/simulator")
|
|
||||||
public String simulator(Model model) throws IOException {
|
|
||||||
GameData data = GrepoSimu.readGameData();
|
|
||||||
model.addAttribute("heroes", data.heroes.values());
|
|
||||||
model.addAttribute("defUnits", Fight.relevantDefUnits(data));
|
|
||||||
model.addAttribute("defCounsellors",Fight.relevantDefCounsellors(data));
|
|
||||||
model.addAttribute("defResearches",Fight.relevantDefResearch(data));
|
|
||||||
model.addAttribute("defPowers",Fight.relevantDefPowers(data));
|
|
||||||
model.addAttribute("defCtx",new DefContext());
|
|
||||||
return "simulator";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/simulate")
|
|
||||||
@GetMapping("/simulate")
|
|
||||||
public String simulate(@ModelAttribute DefContext defCtx, Model model) throws IOException {
|
|
||||||
if(defCtx == null)
|
|
||||||
defCtx = new DefContext();
|
|
||||||
GameData data = GrepoSimu.readGameData();
|
|
||||||
Game g = new Game(data);
|
|
||||||
|
|
||||||
FightStats cityStats = g.fight.computeDefStats(defCtx);
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
|
||||||
|
|
||||||
model.addAttribute("content",cityStats.toString()+"\n"+mapper.writerWithDefaultPrettyPrinter().writeValueAsString(defCtx));
|
|
||||||
return "debug";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/optimizer")
|
|
||||||
public String greeting(Model model) {
|
|
||||||
model.addAttribute("heros", Registerar.heros);
|
|
||||||
|
|
||||||
// Liste des unités
|
|
||||||
Map<String,List<Unite>> godUnites = Registerar.unites.stream()
|
|
||||||
.filter(u -> u.getDieu() != null)
|
|
||||||
.collect(Collectors.groupingBy(u -> u.getDieu().getPname()));
|
|
||||||
List<Unite> otherUnites = Registerar.unites.stream()
|
|
||||||
.filter(u -> u.getDieu() == null)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
System.out.println(godUnites);
|
|
||||||
model.addAttribute("otherunites", otherUnites);
|
|
||||||
model.addAttribute("godunites", godUnites);
|
|
||||||
model.addAttribute("dieux", Arrays.stream(Dieu.values()).map(Dieu::getPname).collect(Collectors.toList()));
|
|
||||||
model.addAttribute("optinput", new OptimizerInput());
|
|
||||||
return "optimizer";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/optimizer")
|
|
||||||
public String greetingSubmit(@ModelAttribute OptimizerInput optinput, Model model) {
|
|
||||||
Optimizer.Contexte ctx = new Optimizer.Contexte();
|
|
||||||
ctx.h = Registerar.getHeros(optinput.heros);
|
|
||||||
ctx.level = optinput.herosLvl;
|
|
||||||
ctx.scoring = optinput.getOffDefStats();
|
|
||||||
ctx.d = null;
|
|
||||||
|
|
||||||
Set<Unite> unites = Registerar.unites.stream().filter(u -> optinput.unites.get(u.getPname())).collect(Collectors.toSet());
|
|
||||||
|
|
||||||
Map<String,OptimizerOutput> outputs = new HashMap<>();
|
|
||||||
outputs.put("none", new OptimizerOutput(Optimizer.optimize(ctx,unites), ctx.h, ctx.level, optinput.population));
|
|
||||||
for(Dieu d : Dieu.values()) {
|
|
||||||
ctx.d = d;
|
|
||||||
outputs.put(d.getPname(), new OptimizerOutput(Optimizer.optimize(ctx,unites), ctx.h, ctx.level, optinput.population));
|
|
||||||
}
|
|
||||||
model.addAttribute("dieux", Arrays.stream(Dieu.values()).map(Dieu::getPname).collect(Collectors.toList()));
|
|
||||||
model.addAttribute("outputs", outputs);
|
|
||||||
model.addAttribute("requestedPop",optinput.population);
|
|
||||||
return "optimizerResult";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class OptimizerInput {
|
|
||||||
|
|
||||||
public String heros = Registerar.heros.stream().map(Heros::getPname).min(Comparator.comparing(Function.identity())).get();
|
|
||||||
public int herosLvl = 1;
|
|
||||||
|
|
||||||
public double att_hack_proportion = 0.0;
|
|
||||||
public double att_pierce_proportion = 0.0;
|
|
||||||
public double att_distance_proportion = 0.0;
|
|
||||||
public double ship_attack_proportion = 0.0;
|
|
||||||
public double def_hack_proportion = 1.0;
|
|
||||||
public double def_pierce_proportion = 1.0;
|
|
||||||
public double def_distance_proportion = 1.0;
|
|
||||||
public double ship_defense_proportion = 1.0;
|
|
||||||
|
|
||||||
public int population = 1000;
|
|
||||||
|
|
||||||
public Map<String,Boolean> unites = Registerar.unites.stream().collect(Collectors.toMap(Unite::getPname, u -> true));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getHeros() {
|
|
||||||
return heros;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeros(String heros) {
|
|
||||||
this.heros = heros;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHerosLvl() {
|
|
||||||
return herosLvl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHerosLvl(int herosLvl) {
|
|
||||||
this.herosLvl = herosLvl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAtt_hack_proportion() {
|
|
||||||
return att_hack_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAtt_hack_proportion(double att_hack_proportion) {
|
|
||||||
this.att_hack_proportion = att_hack_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAtt_pierce_proportion() {
|
|
||||||
return att_pierce_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAtt_pierce_proportion(double att_pierce_proportion) {
|
|
||||||
this.att_pierce_proportion = att_pierce_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAtt_distance_proportion() {
|
|
||||||
return att_distance_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAtt_distance_proportion(double att_distance_proportion) {
|
|
||||||
this.att_distance_proportion = att_distance_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getShip_attack_proportion() {
|
|
||||||
return ship_attack_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShip_attack_proportion(double ship_attack_proportion) {
|
|
||||||
this.ship_attack_proportion = ship_attack_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDef_hack_proportion() {
|
|
||||||
return def_hack_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDef_hack_proportion(double def_hack_proportion) {
|
|
||||||
this.def_hack_proportion = def_hack_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDef_pierce_proportion() {
|
|
||||||
return def_pierce_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDef_pierce_proportion(double def_pierce_proportion) {
|
|
||||||
this.def_pierce_proportion = def_pierce_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDef_distance_proportion() {
|
|
||||||
return def_distance_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDef_distance_proportion(double def_distance_proportion) {
|
|
||||||
this.def_distance_proportion = def_distance_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getShip_defense_proportion() {
|
|
||||||
return ship_defense_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShip_defense_proportion(double ship_defense_proportion) {
|
|
||||||
this.ship_defense_proportion = ship_defense_proportion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPopulation() {
|
|
||||||
return population;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPopulation(int population) {
|
|
||||||
this.population = population;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Boolean> getUnites() {
|
|
||||||
return unites;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUnites(Map<String, Boolean> unites) {
|
|
||||||
this.unites = unites;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OffDefStats getOffDefStats() {
|
|
||||||
return new OffDefStats(att_hack_proportion, att_pierce_proportion, att_distance_proportion, ship_attack_proportion, def_hack_proportion, def_pierce_proportion, def_distance_proportion, ship_defense_proportion);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "OptimizerInput [heros=" + heros + ", herosLvl=" + herosLvl + ", att_hack_proportion="
|
|
||||||
+ att_hack_proportion + ", att_pierce_proportion=" + att_pierce_proportion
|
|
||||||
+ ", att_distance_proportion=" + att_distance_proportion + ", ship_attack_proportion="
|
|
||||||
+ ship_attack_proportion + ", def_hack_proportion=" + def_hack_proportion
|
|
||||||
+ ", def_pierce_proportion=" + def_pierce_proportion + ", def_distance_proportion="
|
|
||||||
+ def_distance_proportion + ", ship_defense_proportion=" + ship_defense_proportion + ", population="
|
|
||||||
+ population + ", unites=" + unites + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
public static class OptimizerOutput {
|
|
||||||
OffDefStats total;
|
|
||||||
int totalpop;
|
|
||||||
List<Unite> unites;
|
|
||||||
Map<Unite,Integer> ucounts;
|
|
||||||
|
|
||||||
public OptimizerOutput(UnitesProportions data, Heros h, int level, int pop) {
|
|
||||||
this.ucounts = new HashMap<>(data.getData().size());
|
|
||||||
for(Unite u : data.getData().keySet())
|
|
||||||
this.ucounts.put(u, (int) Math.floor((data.getData().get(u) * pop) / u.getPopulation()));
|
|
||||||
this.unites = Registerar.unites.stream().filter(u -> ucounts.containsKey(u)).toList();
|
|
||||||
this.totalpop = this.ucounts.entrySet().stream().mapToInt(e -> e.getKey().getPopulation() * e.getValue()).sum();
|
|
||||||
this.total = this.ucounts.entrySet().stream()
|
|
||||||
.map(e -> ((h==null)?e.getKey().getStats():h.applyToUnit(e.getKey(), level)).times(e.getValue()))
|
|
||||||
.reduce(OffDefStats.zero,(a,b) -> a.plus(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
public OffDefStats getTotal() {
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTotalpop() {
|
|
||||||
return totalpop;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Unite, Integer> getUcounts() {
|
|
||||||
return ucounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Unite> getUnites() {
|
|
||||||
return unites;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,313 @@
|
|||||||
|
package com.bernard.greposimu.controller;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.Utils;
|
||||||
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
|
import com.bernard.greposimu.model.game.gods.God;
|
||||||
|
import com.bernard.greposimu.model.game.powers.FuryPower;
|
||||||
|
import com.bernard.greposimu.model.game.powers.GodPower;
|
||||||
|
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.units.FightType;
|
||||||
|
import com.bernard.greposimu.model.game.units.Hero;
|
||||||
|
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.TerrestrialUnit;
|
||||||
|
import com.bernard.greposimu.model.game.units.TransportUnit;
|
||||||
|
import com.bernard.greposimu.model.game.units.Unit;
|
||||||
|
|
||||||
|
public class JSONReader {
|
||||||
|
|
||||||
|
public static GameConfig makeGameConfig(JSONObject json) {
|
||||||
|
JSONObject godsJ = json.getJSONObject("gods");
|
||||||
|
Set<God> gods = new HashSet<>();
|
||||||
|
for(String g : godsJ.keySet()) {
|
||||||
|
JSONObject godJ = godsJ.getJSONObject(g);
|
||||||
|
gods.add(new God(godJ.getString("id"), godJ.getString("name")));
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject powersJ = json.getJSONObject("powers");
|
||||||
|
Set<Power> powers = new HashSet<>();
|
||||||
|
for(String p : powersJ.keySet()) {
|
||||||
|
JSONObject power = powersJ.getJSONObject(p);
|
||||||
|
JSONObject metadefaults = power.isNull("meta_defaults")?null:power.getJSONObject("meta_defaults");
|
||||||
|
String id = power.getString("id");
|
||||||
|
EnumSet<Target> targets = Utils.toEnumSet(Power.Target.class,power.getJSONArray("targets").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet()));
|
||||||
|
EnumSet<Target> seedsTo = Utils.toEnumSet(Power.Target.class,power.getJSONArray("seeds_to").toList().stream().map(k -> getPowerTarget((String)k)).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
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("description")!=null;
|
||||||
|
String configType = dependent?
|
||||||
|
(metadefaults != null && metadefaults.has("type"))?"type":
|
||||||
|
(metadefaults != null && metadefaults.has("god"))?"god":"unknown"
|
||||||
|
:null;
|
||||||
|
|
||||||
|
// for each X, either X or XM should be null. if one XM is not null, configType should be set
|
||||||
|
String name = (power.optJSONObject("name")==null)?power.optString("name"):null;
|
||||||
|
String effect = (power.optJSONObject("effect")==null)?power.optString("effect"):null;
|
||||||
|
String description = (power.optJSONObject("description")==null)?power.optString("description"):null;
|
||||||
|
|
||||||
|
Map<String,String> nameM = (name==null)?Utils.mapValue(power.getJSONObject("name").getJSONObject(configType).toMap(),v -> (String)v):null;
|
||||||
|
Map<String,String> effectM = (effect==null)?Utils.mapValue(power.getJSONObject("effect").getJSONObject(configType).toMap(),v -> (String)v):null;
|
||||||
|
Map<String,String> descriptionM = (description==null)?Utils.mapValue(power.getJSONObject("description").getJSONObject(configType).toMap(),v -> (String)v):null;
|
||||||
|
|
||||||
|
if(!power.isNull("god_id") && !power.getString("god_id").isEmpty()) {
|
||||||
|
God god = gods.stream().filter(g -> g.getId().equals(power.getString("god_id"))).findAny().get();
|
||||||
|
int favorCost = power.getInt("favor");
|
||||||
|
int templeLevelSumDepedency = power.isNull("temple_level_sum_dependency")?0:power.getInt("temple_level_sum_dependency");
|
||||||
|
|
||||||
|
if(power.getInt("fury_percentage_cost") != 0) {
|
||||||
|
// FuryPower
|
||||||
|
int furyPercentageCost = power.getInt("fury_percentage_cost");
|
||||||
|
powers.add(new FuryPower(id, targets, seedsTo, shortEffect, powerGroup, powerGroupLevel, metaFields, metaDefaults, lifetime, effects, tags, compatiblePowers, areaOfEffect, name, effect, description, configType, nameM, effectM, descriptionM,
|
||||||
|
god, favorCost, templeLevelSumDepedency, furyPercentageCost));
|
||||||
|
} else {
|
||||||
|
// GodPower
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
powers.add(new Power(id, targets, seedsTo, shortEffect, powerGroup, powerGroupLevel, metaFields, metaDefaults, lifetime, effects, tags, compatiblePowers, areaOfEffect, name, effect, description, configType, nameM, effectM, descriptionM));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject researchesJ = json.getJSONObject("researches");
|
||||||
|
Set<Research> researches = new HashSet<>();
|
||||||
|
for(String r : researchesJ.keySet()) {
|
||||||
|
JSONObject research = researchesJ.getJSONObject(r);
|
||||||
|
researches.add(new Research(
|
||||||
|
research.getString("id"),
|
||||||
|
research.getString("name"),
|
||||||
|
research.getString("description"),
|
||||||
|
research.isNull("research_dependencies")?Set.of():research.getJSONArray("research_dependencies").toList().stream().map(k -> Utils.getIdentified(researches,(String)k)).collect(Collectors.toSet()),
|
||||||
|
research.isNull("building_dependencies")?Map.of():research.getJSONObject("building_dependencies").keySet().stream()
|
||||||
|
.collect(Collectors.toMap(Function.identity(), b -> research.getJSONObject("building_dependencies").getInt(b))),
|
||||||
|
research.isNull("resources")?null:new Resources(
|
||||||
|
research.getJSONObject("resources").getInt("wood"),
|
||||||
|
research.getJSONObject("resources").getInt("stone"),
|
||||||
|
research.getJSONObject("resources").getInt("iron")),
|
||||||
|
research.getInt("required_time"),
|
||||||
|
research.getInt("research_points")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject unitsJ = json.getJSONObject("units");
|
||||||
|
Set<Unit> units = new HashSet<>();
|
||||||
|
for(String u : unitsJ.keySet()) {
|
||||||
|
JSONObject unit = unitsJ.getJSONObject(u);
|
||||||
|
if(unit.getBoolean("is_naval")) {
|
||||||
|
if(unit.getInt("capacity")>0) {
|
||||||
|
units.add(new TransportUnit(
|
||||||
|
unit.getString("id"),
|
||||||
|
unit.getString("name"),
|
||||||
|
unit.getString("description"),
|
||||||
|
unit.getInt("population"),
|
||||||
|
unit.getInt("speed"),
|
||||||
|
unit.getString("category").equals("mythological_ground") || unit.getString("category").equals("mythological_naval"),
|
||||||
|
unit.isNull("god_id")?null:gods.stream().filter(g -> g.getId().equals(unit.getString("god_id"))).findAny().orElse(null),
|
||||||
|
unit.isNull("resources")?null:new Resources(
|
||||||
|
unit.getJSONObject("resources").getInt("wood"),
|
||||||
|
unit.getJSONObject("resources").getInt("stone"),
|
||||||
|
unit.getJSONObject("resources").getInt("iron")),
|
||||||
|
unit.getInt("favor"),
|
||||||
|
unit.getInt("build_time"),
|
||||||
|
unit.isNull("research_dependencies")?Set.of():unit.getJSONArray("research_dependencies").toList().stream().map(k -> Utils.getIdentified(researches, (String)k)).collect(Collectors.toSet()),
|
||||||
|
unit.isNull("building_dependencies")?Map.of():unit.getJSONObject("building_dependencies").keySet().stream()
|
||||||
|
.collect(Collectors.toMap(Function.identity(), b -> unit.getJSONObject("building_dependencies").getInt(b))),
|
||||||
|
unit.getInt("attack"),
|
||||||
|
unit.getInt("defense"),
|
||||||
|
unit.getInt("capacity")
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
units.add(new NavalUnit(
|
||||||
|
unit.getString("id"),
|
||||||
|
unit.getString("name"),
|
||||||
|
unit.getString("description"),
|
||||||
|
unit.getInt("population"),
|
||||||
|
unit.getInt("speed"),
|
||||||
|
unit.getString("category").equals("mythological_ground") || unit.getString("category").equals("mythological_naval"),
|
||||||
|
unit.isNull("god_id")?null:gods.stream().filter(g -> g.getId().equals(unit.getString("god_id"))).findAny().orElse(null),
|
||||||
|
unit.isNull("resources")?null:new Resources(
|
||||||
|
unit.getJSONObject("resources").getInt("wood"),
|
||||||
|
unit.getJSONObject("resources").getInt("stone"),
|
||||||
|
unit.getJSONObject("resources").getInt("iron")),
|
||||||
|
unit.getInt("favor"),
|
||||||
|
unit.getInt("build_time"),
|
||||||
|
unit.isNull("research_dependencies")?Set.of():unit.getJSONArray("research_dependencies").toList().stream().map(k -> Utils.getIdentified(researches,(String)k)).collect(Collectors.toSet()),
|
||||||
|
unit.isNull("building_dependencies")?Map.of():unit.getJSONObject("building_dependencies").keySet().stream()
|
||||||
|
.collect(Collectors.toMap(Function.identity(), b -> unit.getJSONObject("building_dependencies").getInt(b))),
|
||||||
|
unit.getInt("attack"),
|
||||||
|
unit.getInt("defense")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FightType ft = null;
|
||||||
|
switch(unit.getString("attack_type")) {
|
||||||
|
case "pierce": ft = FightType.PIERCE;break;
|
||||||
|
case "hack": ft = FightType.HACK;break;
|
||||||
|
case "distance": ft = FightType.DISTANCE;break;
|
||||||
|
}
|
||||||
|
units.add(new TerrestrialUnit(
|
||||||
|
unit.getString("id"),
|
||||||
|
unit.getString("name"),
|
||||||
|
unit.getString("description"),
|
||||||
|
unit.getInt("population"),
|
||||||
|
unit.getInt("speed"),
|
||||||
|
unit.getString("category").equals("mythological_ground") || unit.getString("category").equals("mythological_naval"),
|
||||||
|
unit.isNull("god_id")?null:gods.stream().filter(g -> g.getId().equals(unit.getString("god_id"))).findAny().orElse(null),
|
||||||
|
unit.isNull("resources")?null:new Resources(
|
||||||
|
unit.getJSONObject("resources").getInt("wood"),
|
||||||
|
unit.getJSONObject("resources").getInt("stone"),
|
||||||
|
unit.getJSONObject("resources").getInt("iron")),
|
||||||
|
unit.getInt("favor"),
|
||||||
|
unit.getInt("build_time"),
|
||||||
|
unit.isNull("research_dependencies")?Set.of():unit.getJSONArray("research_dependencies").toList().stream().map(k -> Utils.getIdentified(researches, (String)k)).collect(Collectors.toSet()),
|
||||||
|
unit.isNull("building_dependencies")?Map.of():unit.getJSONObject("building_dependencies").keySet().stream()
|
||||||
|
.collect(Collectors.toMap(Function.identity(), b -> unit.getJSONObject("building_dependencies").getInt(b))),
|
||||||
|
unit.getInt("attack"),
|
||||||
|
ft,
|
||||||
|
unit.getInt("def_pierce"),
|
||||||
|
unit.getInt("def_hack"),
|
||||||
|
unit.getInt("def_distance"),
|
||||||
|
(unit.has("booty"))?unit.getInt("booty"):0,
|
||||||
|
unit.getJSONArray("special_abilities").toList().stream().filter(o -> o.equals("flying")).findAny().isPresent()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject heroesJ = json.getJSONObject("heroes");
|
||||||
|
Set<Hero> heroes = new HashSet<>();
|
||||||
|
for(String h : heroesJ.keySet()) {
|
||||||
|
JSONObject hero = heroesJ.getJSONObject(h);
|
||||||
|
FightType ft = null;
|
||||||
|
switch(hero.getString("attack_type")) {
|
||||||
|
case "pierce": ft = FightType.PIERCE;break;
|
||||||
|
case "hack": ft = FightType.HACK;break;
|
||||||
|
case "distance": ft = FightType.DISTANCE;break;
|
||||||
|
}
|
||||||
|
JSONObject descargs = hero.getJSONObject("description_args").getJSONObject("1");
|
||||||
|
heroes.add(new Hero(
|
||||||
|
hero.getString("id"),
|
||||||
|
hero.getString("name"),
|
||||||
|
hero.getString("description"),
|
||||||
|
hero.getInt("speed"),
|
||||||
|
hero.getInt("attack"),
|
||||||
|
ft,
|
||||||
|
hero.getInt("def_pierce"),
|
||||||
|
hero.getInt("def_hack"),
|
||||||
|
hero.getInt("def_distance"),
|
||||||
|
hero.getInt("booty"),
|
||||||
|
hero.getString("category").equals("war")?HeroCategory.WAR:HeroCategory.WISDOM,
|
||||||
|
hero.getInt("cost"),
|
||||||
|
hero.getString("short_description"),
|
||||||
|
descargs.getDouble("value"),
|
||||||
|
descargs.getDouble("level_mod")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return new GameConfig(gods, units, heroes, researches, powers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EnumSet<Power.Tag> getPowerTags(JSONObject o) {
|
||||||
|
Set<Power.Tag> out = new HashSet<Power.Tag>();
|
||||||
|
if(o.getBoolean("extendible"))out.add(Power.Tag.EXTENDIBLE);
|
||||||
|
if(o.getBoolean("display_amount"))out.add(Power.Tag.DISPLAY_AMOUNT);
|
||||||
|
if(o.getBoolean("destructive"))out.add(Power.Tag.DESTRUCTIVE);
|
||||||
|
if(o.getBoolean("is_capped"))out.add(Power.Tag.CAPPED);
|
||||||
|
if(o.getBoolean("is_fake_power"))out.add(Power.Tag.FAKE_POWER);
|
||||||
|
if(o.getBoolean("is_onetime_power"))out.add(Power.Tag.ONETIME_POWER);
|
||||||
|
if(o.getBoolean("is_ritual"))out.add(Power.Tag.RITUAL);
|
||||||
|
if(o.getBoolean("is_upgradable"))out.add(Power.Tag.UPGRADABLE);
|
||||||
|
if(o.getBoolean("is_valid_for_happenings"))out.add(Power.Tag.VALID_FOR_HAPPENINGS);
|
||||||
|
if(o.getBoolean("transfer_to_casual_world"))out.add(Power.Tag.TRANSFER_TO_CASUAL_WORLD);
|
||||||
|
if(o.getBoolean("wasteable"))out.add(Power.Tag.WASTEABLE);
|
||||||
|
if(o.getBoolean("needs_level"))out.add(Power.Tag.NEEDS_LEVEL);
|
||||||
|
if(o.getBoolean("passive"))out.add(Power.Tag.PASSIVE);
|
||||||
|
if(o.getBoolean("recreate_on_restart"))out.add(Power.Tag.RECREATE_ON_RESTART);
|
||||||
|
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("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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Power.AreaOfEffect getPowerAOE(String s){
|
||||||
|
switch(s) {
|
||||||
|
case "area_of_effect_build_time": return Power.AreaOfEffect.BUILDTIME;
|
||||||
|
case "area_of_effect_commands": return Power.AreaOfEffect.COMMANDS;
|
||||||
|
case "area_of_effect_favor": return Power.AreaOfEffect.FAVOR;
|
||||||
|
case "area_of_effect_militia": return Power.AreaOfEffect.MILITIA;
|
||||||
|
case "area_of_effect_resources": return Power.AreaOfEffect.RESOURCES;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("I don't know Power AreaOfEffect "+s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Power.Effect getPowerEffect(String s){
|
||||||
|
switch(s) {
|
||||||
|
case "effects_ground": return Power.Effect.GROUND;
|
||||||
|
case "effects_naval": return Power.Effect.NAVAL;
|
||||||
|
case "effects_wall": return Power.Effect.WALL;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("I don't know Power Effect "+s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Power.Group getPowerGroup(String s){
|
||||||
|
switch(s) {
|
||||||
|
case "attack_boost_group": return Power.Group.ATTACK_BOOST;
|
||||||
|
case "attack_ship_attack_boost_group": return Power.Group.ATTACK_SHIP_ATTACK_BOOST;
|
||||||
|
case "battle_point_boost_group": return Power.Group.BATTLE_POINT_BOOST;
|
||||||
|
case "building_boost_group": return Power.Group.BUILDING_BOOST;
|
||||||
|
case "defense_boost_group": return Power.Group.DEFENSE_BOOST;
|
||||||
|
case "favor_boost_group": return Power.Group.FAVOR_BOOST;
|
||||||
|
case "resource_boost_group": return Power.Group.RESOURCE_BOOST;
|
||||||
|
case "unit_boost_group": return Power.Group.UNIT_BOOST;
|
||||||
|
case "": return null;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("I don't know Power Group "+s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Power.Target getPowerTarget(String s){
|
||||||
|
switch(s) {
|
||||||
|
case "target_alliance": return Power.Target.ALLIANCE;
|
||||||
|
case "target_command": return Power.Target.COMMAND;
|
||||||
|
case "target_player": return Power.Target.PLAYER;
|
||||||
|
case "target_support_command": return Power.Target.SUPPORT_COMMAND;
|
||||||
|
case "target_town": return Power.Target.TOWN;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("I don't know Power Target "+s);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.bernard.greposimu.controller;
|
||||||
|
|
||||||
|
public class Randomizer {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,393 @@
|
|||||||
|
package com.bernard.greposimu.controller;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.GrepoSimuApplication;
|
||||||
|
import com.bernard.greposimu.Utils;
|
||||||
|
import com.bernard.greposimu.engine.game.Fight;
|
||||||
|
import com.bernard.greposimu.model.DefContext;
|
||||||
|
import com.bernard.greposimu.model.FightStats;
|
||||||
|
import com.bernard.greposimu.model.OffContext;
|
||||||
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
|
import com.bernard.greposimu.model.game.gods.God;
|
||||||
|
import com.bernard.greposimu.model.game.units.Unit;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class SimulatorController {
|
||||||
|
|
||||||
|
@GetMapping("/simulator")
|
||||||
|
public String simulator(Model model, @RequestParam boolean random) throws IOException {
|
||||||
|
GameConfig gc = GrepoSimuApplication.GREPOLIS_GC;
|
||||||
|
model.addAttribute("heroes", gc.getHeroes());
|
||||||
|
model.addAttribute("defUnits", Fight.relevantDefUnits(gc));
|
||||||
|
model.addAttribute("defCounsellors",DefContext.COUNSELLORS);
|
||||||
|
model.addAttribute("defResearches",DefContext.RESEARCHES);
|
||||||
|
model.addAttribute("defPowers",DefContext.POWERS);
|
||||||
|
model.addAttribute("offUnits", Fight.relevantOffUnits(gc));
|
||||||
|
model.addAttribute("offCounsellors",OffContext.COUNSELLORS);
|
||||||
|
model.addAttribute("offResearches",OffContext.RESEARCHES);
|
||||||
|
model.addAttribute("offPowers",OffContext.POWERS);
|
||||||
|
SimulatorParams params = new SimulatorParams();
|
||||||
|
if(random)
|
||||||
|
params.randomize(new Random(), gc);
|
||||||
|
model.addAttribute("ctx",params);
|
||||||
|
return "simulator";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/simulate")
|
||||||
|
public String simulate(@ModelAttribute SimulatorParams params, Model model) throws IOException {
|
||||||
|
if(params == null)
|
||||||
|
params = new SimulatorParams();
|
||||||
|
GameConfig gc = GrepoSimuApplication.GREPOLIS_GC;
|
||||||
|
DefContext defCtx = params.asDefContext(gc);
|
||||||
|
OffContext offCtx = params.asOffContext(gc);
|
||||||
|
FightStats defStats = Fight.computeDefStats(gc,defCtx);
|
||||||
|
FightStats offStats = Fight.computeOffStats(gc,offCtx);
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||||
|
|
||||||
|
model.addAttribute("content",
|
||||||
|
defStats.toString()+"\n"+
|
||||||
|
offStats.toString()+"\n"+
|
||||||
|
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(defCtx)+"\n"+
|
||||||
|
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(offCtx)
|
||||||
|
);
|
||||||
|
return "debug";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SimulatorParams {
|
||||||
|
|
||||||
|
// unitID -> number of units
|
||||||
|
public Map<String, Integer> defUnits = new HashMap<>();
|
||||||
|
public Map<String, Integer> offUnits = new HashMap<>();
|
||||||
|
|
||||||
|
public String defHero = "";
|
||||||
|
public int defHeroLevel = 0;
|
||||||
|
public String offHero = "";
|
||||||
|
public int offHeroLevel = 0;
|
||||||
|
|
||||||
|
public int wallLevel = 0;
|
||||||
|
public boolean hasTower = false;
|
||||||
|
|
||||||
|
public Set<String> defPowers = new HashSet<>();
|
||||||
|
public Set<String> offPowers = new HashSet<>();
|
||||||
|
public Set<String> defResearches = new HashSet<>();
|
||||||
|
public Set<String> offResearches = new HashSet<>();
|
||||||
|
public Set<String> defCounsellors = new HashSet<>();
|
||||||
|
public Set<String> offCounsellors = new HashSet<>();
|
||||||
|
|
||||||
|
public boolean nightBonus = false;
|
||||||
|
|
||||||
|
int luck, moral;
|
||||||
|
|
||||||
|
int olympicSwordGrepolympiaSummerLevel = 1;
|
||||||
|
int offOlympicSensesGrepolympiaSummerLevel = 1;
|
||||||
|
int aresRageLevel = 1;
|
||||||
|
int aresArmyFurySpent = 0;
|
||||||
|
int bloodlustFurySpent = 0;
|
||||||
|
|
||||||
|
int defOlympicSensesGrepolympiaSummerLevel = 1;
|
||||||
|
int olympicTorchGrepolympiaSummerLevel = 1;
|
||||||
|
int soteriasShrineLevel = 1;
|
||||||
|
|
||||||
|
boolean strategyBreach = false;
|
||||||
|
boolean allianceModifier = false;
|
||||||
|
|
||||||
|
public DefContext asDefContext(GameConfig gc) {
|
||||||
|
Map<Unit,Integer> unitsU = new HashMap<>(defUnits.size());
|
||||||
|
for(String u : defUnits.keySet())
|
||||||
|
unitsU.put(gc.getUnit(u), defUnits.get(u));
|
||||||
|
return new DefContext(
|
||||||
|
unitsU,
|
||||||
|
gc.getHero(defHero),
|
||||||
|
defHeroLevel,
|
||||||
|
wallLevel,
|
||||||
|
hasTower,
|
||||||
|
defPowers,
|
||||||
|
defOlympicSensesGrepolympiaSummerLevel, olympicTorchGrepolympiaSummerLevel, soteriasShrineLevel,
|
||||||
|
defResearches,
|
||||||
|
defCounsellors,
|
||||||
|
nightBonus
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object random() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffContext asOffContext(GameConfig gc) {
|
||||||
|
Map<Unit,Integer> unitsU = new HashMap<>(offUnits.size());
|
||||||
|
for(String u : offUnits.keySet())
|
||||||
|
unitsU.put(gc.getUnit(u), offUnits.get(u));
|
||||||
|
return new OffContext(
|
||||||
|
unitsU,
|
||||||
|
gc.getHero(defHero),
|
||||||
|
defHeroLevel,
|
||||||
|
luck, moral, defPowers,
|
||||||
|
olympicSwordGrepolympiaSummerLevel, offOlympicSensesGrepolympiaSummerLevel, aresRageLevel, aresArmyFurySpent, bloodlustFurySpent, defResearches,
|
||||||
|
defCounsellors, allianceModifier, allianceModifier
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void randomize(Random r,GameConfig gc) {
|
||||||
|
|
||||||
|
offUnits = new HashMap<>();
|
||||||
|
God g = null;
|
||||||
|
if(r.nextDouble()<0.8)
|
||||||
|
g = Utils.randFromSet(r, gc.getGods());
|
||||||
|
for(Unit u : Fight.relevantOffUnits(gc))
|
||||||
|
if(u.getGod() == null || u.getGod().equals(g))
|
||||||
|
if(r.nextDouble() < 0.7)
|
||||||
|
offUnits.put(u.getId(), (int) ((r.nextExponential()*50+10)/Math.max(u.getPopulation(),1)));
|
||||||
|
defUnits = new HashMap<>();
|
||||||
|
g = null;
|
||||||
|
if(r.nextDouble()<0.8)
|
||||||
|
g = Utils.randFromSet(r, gc.getGods());
|
||||||
|
for(Unit u : Fight.relevantDefUnits(gc))
|
||||||
|
if(u.getGod() == null || u.getGod().equals(g))
|
||||||
|
if(r.nextDouble() < 0.7)
|
||||||
|
defUnits.put(u.getId(), (int) ((r.nextExponential()*50+10)/Math.max(u.getPopulation(),1)));
|
||||||
|
|
||||||
|
offHero = null;
|
||||||
|
offHeroLevel = 0;
|
||||||
|
if(r.nextDouble()<.7) {
|
||||||
|
offHero = Utils.randFromSet(r, gc.getHeroes()).getId();
|
||||||
|
offHeroLevel = r.nextInt(1, 21);
|
||||||
|
}
|
||||||
|
defHero = null;
|
||||||
|
defHeroLevel = 0;
|
||||||
|
if(r.nextDouble()<.7) {
|
||||||
|
defHero = Utils.randFromSet(r, gc.getHeroes()).getId();
|
||||||
|
defHeroLevel = r.nextInt(1, 21);
|
||||||
|
}
|
||||||
|
|
||||||
|
wallLevel = r.nextInt(0, 26);
|
||||||
|
hasTower = (wallLevel>20) && (r.nextDouble()<0.2);
|
||||||
|
|
||||||
|
luck = (int) (Math.tanh(r.nextGaussian())*20);
|
||||||
|
moral = 100;
|
||||||
|
if(r.nextDouble()<.7)
|
||||||
|
moral = (int) Math.max(100-(r.nextExponential()*20),0);
|
||||||
|
|
||||||
|
offPowers = new HashSet<>();
|
||||||
|
defPowers = new HashSet<>();
|
||||||
|
for(String p : OffContext.POWERS) {
|
||||||
|
if(r.nextDouble()<0.05)
|
||||||
|
offPowers.add(p);
|
||||||
|
if(r.nextDouble()<0.05)
|
||||||
|
defPowers.add(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
olympicSwordGrepolympiaSummerLevel = r.nextInt(1, 5);
|
||||||
|
offOlympicSensesGrepolympiaSummerLevel = r.nextInt(1, 5);
|
||||||
|
aresRageLevel = r.nextInt(1, 11);
|
||||||
|
aresArmyFurySpent = r.nextInt(1, 5000);
|
||||||
|
bloodlustFurySpent = r.nextInt(1, 5000);
|
||||||
|
defOlympicSensesGrepolympiaSummerLevel = r.nextInt(1, 5);
|
||||||
|
olympicTorchGrepolympiaSummerLevel = r.nextInt(1, 5);
|
||||||
|
soteriasShrineLevel = r.nextInt(1, 11);
|
||||||
|
|
||||||
|
offResearches = new HashSet<>();
|
||||||
|
defResearches = new HashSet<>();
|
||||||
|
for(String p : OffContext.RESEARCHES) {
|
||||||
|
if(r.nextDouble()<0.20)
|
||||||
|
offResearches.add(p);
|
||||||
|
if(r.nextDouble()<0.20)
|
||||||
|
defResearches.add(p);
|
||||||
|
}
|
||||||
|
offCounsellors = new HashSet<>();
|
||||||
|
defCounsellors = new HashSet<>();
|
||||||
|
for(String p : OffContext.COUNSELLORS) {
|
||||||
|
if(r.nextDouble()<0.05)
|
||||||
|
offCounsellors.add(p);
|
||||||
|
if(r.nextDouble()<0.05)
|
||||||
|
defCounsellors.add(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
strategyBreach = (r.nextDouble()<0.02);
|
||||||
|
allianceModifier = (r.nextDouble()<0.001);
|
||||||
|
nightBonus = (r.nextDouble()<0.02);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Map<String, Integer> getDefUnits() {
|
||||||
|
return defUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefUnits(Map<String, Integer> defUnits) {
|
||||||
|
this.defUnits = defUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getOffUnits() {
|
||||||
|
return offUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffUnits(Map<String, Integer> offUnits) {
|
||||||
|
this.offUnits = offUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefHero() {
|
||||||
|
return defHero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefHero(String defHero) {
|
||||||
|
this.defHero = defHero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDefHeroLevel() {
|
||||||
|
return defHeroLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefHeroLevel(int defHeroLevel) {
|
||||||
|
this.defHeroLevel = defHeroLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOffHero() {
|
||||||
|
return offHero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffHero(String offHero) {
|
||||||
|
this.offHero = offHero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOffHeroLevel() {
|
||||||
|
return offHeroLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffHeroLevel(int offHeroLevel) {
|
||||||
|
this.offHeroLevel = offHeroLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWallLevel() {
|
||||||
|
return wallLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWallLevel(int wallLevel) {
|
||||||
|
this.wallLevel = wallLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHasTower() {
|
||||||
|
return hasTower;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasTower(boolean hasTower) {
|
||||||
|
this.hasTower = hasTower;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getDefPowers() {
|
||||||
|
return defPowers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefPowers(Set<String> defPowers) {
|
||||||
|
this.defPowers = defPowers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getOffPowers() {
|
||||||
|
return offPowers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffPowers(Set<String> offPowers) {
|
||||||
|
this.offPowers = offPowers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getDefResearches() {
|
||||||
|
return defResearches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefResearches(Set<String> defResearches) {
|
||||||
|
this.defResearches = defResearches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getOffResearches() {
|
||||||
|
return offResearches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffResearches(Set<String> offResearches) {
|
||||||
|
this.offResearches = offResearches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getDefCounsellors() {
|
||||||
|
return defCounsellors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefCounsellors(Set<String> defCounsellors) {
|
||||||
|
this.defCounsellors = defCounsellors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getOffCounsellors() {
|
||||||
|
return offCounsellors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffCounsellors(Set<String> offCounsellors) {
|
||||||
|
this.offCounsellors = offCounsellors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLuck() {
|
||||||
|
return luck;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLuck(int luck) {
|
||||||
|
this.luck = luck;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMoral() {
|
||||||
|
return moral;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoral(int moral) {
|
||||||
|
this.moral = moral;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStrategyBreach() {
|
||||||
|
return strategyBreach;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStrategyBreach(boolean strategyBreach) {
|
||||||
|
this.strategyBreach = strategyBreach;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllianceModifier() {
|
||||||
|
return allianceModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllianceModifier(boolean allianceModifier) {
|
||||||
|
this.allianceModifier = allianceModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Boolean> getDefPowersAsMap() {
|
||||||
|
return Utils.setToMap(defPowers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Boolean> getDefResearchesAsMap() {
|
||||||
|
return Utils.setToMap(defResearches);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Boolean> getDefCounsellorsAsMap() {
|
||||||
|
return Utils.setToMap(defCounsellors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNightBonus() {
|
||||||
|
return nightBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNightBonus(boolean nightBonus) {
|
||||||
|
this.nightBonus = nightBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
package com.bernard.greposimu.engine;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.ojalgo.optimisation.Expression;
|
|
||||||
import org.ojalgo.optimisation.ExpressionsBasedModel;
|
|
||||||
import org.ojalgo.optimisation.Optimisation;
|
|
||||||
import org.ojalgo.optimisation.Optimisation.Result;
|
|
||||||
import org.ojalgo.optimisation.Variable;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.Dieu;
|
|
||||||
import com.bernard.greposimu.model.Heros;
|
|
||||||
import com.bernard.greposimu.model.OffDefStats;
|
|
||||||
import com.bernard.greposimu.model.Unite;
|
|
||||||
|
|
||||||
public class Optimizer {
|
|
||||||
|
|
||||||
public static UnitesProportions optimize(Contexte c,Set<Unite> uniteList) {
|
|
||||||
// Computing the stats of the unités in this context
|
|
||||||
Map<Unite,OffDefStats> stats = uniteList.stream()
|
|
||||||
.filter(u -> u.getDieu() == null || u.getDieu().equals(c.d))
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
Function.identity(),
|
|
||||||
u -> (OffDefStats)((c.h==null)?u.getStats():c.h.applyToUnit(u, c.level)).div(u.getPopulation())
|
|
||||||
));
|
|
||||||
// Clean list of unités
|
|
||||||
List<Unite> unites = stats.keySet().stream().sorted((u,v) -> u.getNom().compareTo(v.getNom())).toList();
|
|
||||||
|
|
||||||
// Création du modèle
|
|
||||||
ExpressionsBasedModel model = new ExpressionsBasedModel();
|
|
||||||
// Variable à optimiser
|
|
||||||
Variable y = model.addVariable("y").weight(1.0);
|
|
||||||
// Création des variables correspondant aux proportions, elles ne sont pas «optimisées» (weight 0.0) et sont positives
|
|
||||||
List<Variable> varz = new ArrayList<>(unites.size());
|
|
||||||
for(Unite u : unites) {
|
|
||||||
Variable xi = model.addVariable(u.getNom()).weight(0.0);
|
|
||||||
model.addExpression().lower(0.0).set(xi, 1.0); // 0 <= x_i
|
|
||||||
varz.add(xi);
|
|
||||||
}
|
|
||||||
// Les proportions doivent être maximalement 1 (en pratique, 1, parce que croissante)
|
|
||||||
Expression esum = model.addExpression().upper(1.0);
|
|
||||||
// y doit se comparer à chaque somme suivant ce que le scoring précise
|
|
||||||
Expression eAttqCont = model.addExpression().lower(0.0).set(y, -c.scoring.getAttqCont()); // y <= sum(a_1_i * x_i)
|
|
||||||
Expression eAttqBlan = model.addExpression().lower(0.0).set(y, -c.scoring.getAttqBlan()); // y <= sum(a_1_i * x_i)
|
|
||||||
Expression eAttqJet = model.addExpression().lower(0.0).set(y, -c.scoring.getAttqJet() ); // y <= sum(a_1_i * x_i)
|
|
||||||
Expression eAttqNav = model.addExpression().lower(0.0).set(y, -c.scoring.getAttqNav() ); // y <= sum(a_1_i * x_i)
|
|
||||||
Expression eDefCont = model.addExpression().lower(0.0).set(y, -c.scoring.getDefCont() ); // y <= sum(a_1_i * x_i)
|
|
||||||
Expression eDefBlan = model.addExpression().lower(0.0).set(y, -c.scoring.getDefBlan() ); // y <= sum(a_1_i * x_i)
|
|
||||||
Expression eDefJet = model.addExpression().lower(0.0).set(y, -c.scoring.getDefJet() ); // y <= sum(a_1_i * x_i)
|
|
||||||
Expression eDefNav = model.addExpression().lower(0.0).set(y, -c.scoring.getDefNav() ); // y <= sum(a_1_i * x_i)
|
|
||||||
|
|
||||||
for(int i=0;i<varz.size();i++) {
|
|
||||||
esum.set(varz.get(i), 1.0);
|
|
||||||
eAttqCont.set(varz.get(i), stats.get(unites.get(i)).getAttqCont());
|
|
||||||
eAttqBlan.set(varz.get(i), stats.get(unites.get(i)).getAttqBlan());
|
|
||||||
eAttqJet .set(varz.get(i), stats.get(unites.get(i)).getAttqJet());
|
|
||||||
eAttqNav .set(varz.get(i), stats.get(unites.get(i)).getAttqNav());
|
|
||||||
eDefCont .set(varz.get(i), stats.get(unites.get(i)).getDefCont());
|
|
||||||
eDefBlan .set(varz.get(i), stats.get(unites.get(i)).getDefBlan());
|
|
||||||
eDefJet .set(varz.get(i), stats.get(unites.get(i)).getDefJet());
|
|
||||||
eDefNav .set(varz.get(i), stats.get(unites.get(i)).getDefNav());
|
|
||||||
}
|
|
||||||
|
|
||||||
Result r = model.maximise(); // maximize y
|
|
||||||
return new UnitesProportions(unites, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class UnitesProportions {
|
|
||||||
Map<Unite,Double> data;
|
|
||||||
|
|
||||||
public UnitesProportions(List<Unite> unites, Optimisation.Result result) {
|
|
||||||
this.data = new HashMap<>();
|
|
||||||
for(int i=0;i<unites.size();i++) {
|
|
||||||
double val = result.doubleValue(1+i);
|
|
||||||
if(val>=0.0001) {
|
|
||||||
this.data.put(unites.get(i), val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void print(Heros h, int level, int pop) {
|
|
||||||
Map<Unite,Integer> ucounts = new HashMap<>(data.size());
|
|
||||||
for(Unite u : data.keySet())
|
|
||||||
ucounts.put(u, (int) Math.floor((data.get(u) * pop) / u.getPopulation()));
|
|
||||||
int totalpop = ucounts.entrySet().stream().mapToInt(e -> e.getKey().getPopulation() * e.getValue()).sum();
|
|
||||||
OffDefStats t = ucounts.entrySet().stream()
|
|
||||||
.map(e -> h.applyToUnit(e.getKey(), level).times(e.getValue()))
|
|
||||||
.reduce(OffDefStats.zero,(a,b) -> a.plus(b));
|
|
||||||
System.out.println("Population totale de %d".formatted(totalpop));
|
|
||||||
for(Unite u : data.keySet())
|
|
||||||
System.out.println("|-- %d %s (%.1f%% de la population)".formatted(ucounts.get(u),u.getNom(),data.get(u)*100));
|
|
||||||
System.out.println("--- Attaque (%d,%d,%d,%d) Défense (%d,%d,%d,%d)".formatted(
|
|
||||||
(int)t.getAttqCont(),(int)t.getAttqBlan(),(int)t.getAttqJet(),(int)t.getAttqNav(),(int)t.getDefCont(),(int)t.getDefBlan(),(int)t.getDefJet(),(int)t.getDefNav()
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Unite, Double> getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Contexte {
|
|
||||||
public Dieu d;
|
|
||||||
public Heros h;
|
|
||||||
public int level;
|
|
||||||
public OffDefStats scoring;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
package com.bernard.greposimu.engine;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.Dieu;
|
|
||||||
import com.bernard.greposimu.model.Heros;
|
|
||||||
import com.bernard.greposimu.model.OffDefStats;
|
|
||||||
import com.bernard.greposimu.model.Unite;
|
|
||||||
|
|
||||||
public class Registerar {
|
|
||||||
public static List<Unite> unites;
|
|
||||||
public static List<Heros> heros;
|
|
||||||
|
|
||||||
public static Heros getHeros(String pname) {
|
|
||||||
return heros.stream().filter(h -> h.getPname().equals(pname)).findAny().orElse(null);
|
|
||||||
}
|
|
||||||
public static List<Unite> getUnites(Dieu dieu) {
|
|
||||||
return unites.stream().filter(u -> u.getDieu() == null || u.getDieu().equals(dieu)).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addHeros(
|
|
||||||
String nom,
|
|
||||||
String pname,
|
|
||||||
Set<String> appliedToNames,
|
|
||||||
boolean appTerrestre,
|
|
||||||
boolean appNavale,
|
|
||||||
boolean appMythique,
|
|
||||||
double attqContZero,
|
|
||||||
double attqContPlus,
|
|
||||||
double attqBlanZero,
|
|
||||||
double attqBlanPlus,
|
|
||||||
double attqJetZero,
|
|
||||||
double attqJetPlus,
|
|
||||||
double attqNavZero,
|
|
||||||
double attqNavPlus,
|
|
||||||
double defContZero,
|
|
||||||
double defContPlus,
|
|
||||||
double defBlanZero,
|
|
||||||
double defBlanPlus,
|
|
||||||
double defJetZero,
|
|
||||||
double defJetPlus,
|
|
||||||
double defNavZero,
|
|
||||||
double defNavPlus) {
|
|
||||||
heros.add(new Heros(
|
|
||||||
nom, pname, appliedToNames, appTerrestre, appNavale, appMythique,
|
|
||||||
new OffDefStats(attqContZero, attqBlanZero, attqJetZero, attqNavZero, defContZero, defBlanZero, defJetZero, defNavZero),
|
|
||||||
new OffDefStats(attqContPlus, attqBlanPlus, attqJetPlus, attqNavPlus, defContPlus, defBlanPlus, defJetPlus, defNavPlus)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addUnite(String nom, String pname, int population, int speed, int butin, double attqCont, double attqBlan, double attqJet, double attqNav, double defCont, double defBlan,
|
|
||||||
double defJet, double defNav, boolean terrestre, boolean navale,
|
|
||||||
boolean mythique, Dieu dieu) {
|
|
||||||
unites.add(new Unite(
|
|
||||||
nom, pname, population, speed, butin,
|
|
||||||
new OffDefStats(attqCont, attqBlan, attqJet, attqNav, defCont, defBlan, defJet, defNav),
|
|
||||||
terrestre, navale, mythique, dieu
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void regiter() {
|
|
||||||
unites = new ArrayList<Unite>();
|
|
||||||
addUnite("Combattant à l'épée","sword",1,8,16,5.0,0.0,0.0,0.0,14.0,8.0,30.0,0.0,true,false,false,null);
|
|
||||||
addUnite("Frondeur","slinger",1,14,8,0.0,0.0,23.0,0.0,7.0,8.0,2.0,0.0,true,false,false,null);
|
|
||||||
addUnite("Archer","archer",1,12,24,0.0,0.0,8.0,0.0,7.0,25.0,13.0,0.0,true,false,false,null);
|
|
||||||
addUnite("Hoplite","hoplite",1,6,8,0.0,16.0,0.0,0.0,18.0,12.0,7.0,0.0,true,false,false,null);
|
|
||||||
addUnite("Cavalier","rider",3,22,72,60.0,0.0,0.0,0.0,18.0,1.0,24.0,0.0,true,false,false,null);
|
|
||||||
addUnite("Char","chariot",4,18,64,0.0,56.0,0.0,0.0,76.0,16.0,56.0,0.0,true,false,false,null);
|
|
||||||
addUnite("Catapulte","catapult",15,2,400,0.0,0.0,100.0,0.0,30.0,30.0,30.0,0.0,true,false,false,null);
|
|
||||||
addUnite("Envoyé divin","godsent",3,16,5,45.0,0.0,0.0,0.0,40.0,40.0,40.0,0.0,true,false,true,null);
|
|
||||||
addUnite("Centaure","centaur",12,18,200,0.0,0.0,134.0,0.0,195.0,585.0,80.0,0.0,true,false,true,Dieu.ATHENA);
|
|
||||||
addUnite("Cerbère","cerberus",30,4,240,210.0,0.0,0.0,0.0,825.0,300.0,1575.0,0.0,true,false,true,Dieu.HADES);
|
|
||||||
addUnite("Cyclope","zyklop",40,8,320,0.0,0.0,1035.0,0.0,1050.0,10.0,1450.0,0.0,true,false,true,Dieu.POSEIDON);
|
|
||||||
addUnite("Érinye","fury",55,10,440,0.0,0.0,1700.0,0.0,460.0,460.0,595.0,0.0,true,false,true,Dieu.HADES);
|
|
||||||
addUnite("Méduse","medusa",18,6,400,0.0,425.0,0.0,0.0,480.0,345.0,290.0,0.0,true,false,true,Dieu.HERA);
|
|
||||||
addUnite("Minotaure","minotaur",30,10,480,650.0,0.0,0.0,0.0,750.0,330.0,640.0,0.0,true,false,true,Dieu.ZEUS);
|
|
||||||
addUnite("Sanglier","calydonian_boar",20,16,240,0.0,180.0,0.0,0.0,700.0,700.0,100.0,0.0,true,false,true,Dieu.ARTEMIS);
|
|
||||||
addUnite("Satyre","satyr",16,136,335,0.0,385.0,0.0,0.0,55.0,105.0,170.0,0.0,true,false,true,Dieu.APHRODITE);
|
|
||||||
addUnite("Sparte","spartoi",10,16,275,205.0,0.0,0.0,0.0,100.0,100.0,150.0,0.0,true,false,true,Dieu.ARES);
|
|
||||||
addUnite("Harpie","harpy",14,28,340,295.0,0.0,0.0,0.0,105.0,70.0,1.0,0.0,true,false,true,Dieu.HERA);
|
|
||||||
addUnite("Manticore","manticore",45,22,360,0.0,1010.0,0.0,0.0,170.0,225.0,505.0,0.0,true,false,true,Dieu.ZEUS);
|
|
||||||
addUnite("Pégase","pegasus",20,35,160,0.0,100.0,0.0,0.0,750.0,275.0,275.0,0.0,true,false,true,Dieu.ATHENA);
|
|
||||||
addUnite("Griffon","griffin",35,18,350,900.0,0.0,0.0,0.0,320.0,330.0,100.0,0.0,true,false,true,Dieu.ARTEMIS);
|
|
||||||
addUnite("Ladon","ladon",85,40,1000,0.0,0.0,1195.0,0.0,478.0,390.0,420.0,0.0,true,false,true,Dieu.ARES);
|
|
||||||
addUnite("Birème","bireme",8,15,0,0.0,0.0,0.0,24.0,0.0,0.0,0.0,160.0,false,true,false,null);
|
|
||||||
addUnite("Bateau-feu","attack_ship",10,13,0,0.0,0.0,0.0,200.0,0.0,0.0,0.0,60.0,false,true,false,null);
|
|
||||||
addUnite("Trière","trireme",16,15,0,0.0,0.0,0.0,250.0,0.0,0.0,0.0,250.0,false,true,false,null);
|
|
||||||
addUnite("Hydre","sea_monster",50,8,0,0.0,0.0,0.0,1310.0,0.0,0.0,0.0,1400.0,false,false,true,Dieu.POSEIDON);
|
|
||||||
addUnite("Sirène","siren",16,22,0,0.0,0.0,0.0,180.0,0.0,0.0,0.0,170.0,false,false,true,Dieu.APHRODITE);
|
|
||||||
//addUnite("Ladon (max)","ladon",85000,40,1000,0.0,0.0,2988.0,0.0,478.0,390.0,420.0,0.0,true,false,true,Dieu.ARES);
|
|
||||||
|
|
||||||
heros = new ArrayList<Heros>();
|
|
||||||
addHeros("Agamemnon","agamemnon",Set.of("hoplite","archer"),false,false,false,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000);
|
|
||||||
addHeros("Ajax","ajax",Set.of("hoplites"),false,false,false,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000);
|
|
||||||
addHeros("Alexandrios","alexandrios",Set.of("archers"),false,false,false,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000);
|
|
||||||
addHeros("Déimos","deimos",Set.of(),true,true,true,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000);
|
|
||||||
addHeros("Hector","hector",Set.of("sword","slinger"),false,false,false,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000);
|
|
||||||
addHeros("Lysippe","lysippe",Set.of("rider"),false,false,false,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000);
|
|
||||||
addHeros("Léonidas","leonidas",Set.of(),true,true,true,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005);
|
|
||||||
addHeros("Mihalis","mihalis",Set.of(),true,false,false,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.100,0.010,0.100,0.010,0.000,0.000,0.000,0.000);
|
|
||||||
addHeros("Médée","medea",Set.of("slinger"),false,false,false,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000);
|
|
||||||
addHeros("Mélousa","melousa",Set.of("chariot"),false,false,false,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000);
|
|
||||||
addHeros("Pélops","pelops",Set.of("hoplite","chariot"),false,false,false,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000);
|
|
||||||
addHeros("Thémistocle","themistokles",Set.of("godsent","rider"),false,false,false,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000);
|
|
||||||
addHeros("Télémaque","telemachos",Set.of("sword"),false,false,false,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000);
|
|
||||||
addHeros("Urephon","urephon",Set.of(),false,false,true,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005);
|
|
||||||
addHeros("Zuretha","zuretha",Set.of(),false,true,false,0.000,0.000,0.000,0.000,0.000,0.000,0.050,0.005,0.000,0.000,0.000,0.000,0.000,0.000,0.050,0.005);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.bernard.greposimu.engine.game;
|
||||||
|
|
||||||
|
public class Effects {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PC boost per level
|
||||||
|
*/
|
||||||
|
public static final double olympicSensesGrepolympiaSummerBoost(int level) {
|
||||||
|
return 0.1*level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defense boost per level
|
||||||
|
*/
|
||||||
|
public static final double olympicTorchGrepolympiaSummerBoost(int level) {
|
||||||
|
return 0.05*level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defense boost per level
|
||||||
|
*/
|
||||||
|
public static final double soteriasShrineBoost(int level) {
|
||||||
|
return 0.007*level;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,115 +6,260 @@ import java.util.Map;
|
|||||||
import com.bernard.greposimu.model.DefContext;
|
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.GameData;
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
import com.bernard.greposimu.model.game.Power;
|
import com.bernard.greposimu.model.game.units.FightType;
|
||||||
import com.bernard.greposimu.model.game.Research;
|
import com.bernard.greposimu.model.game.units.NavalUnit;
|
||||||
import com.bernard.greposimu.model.game.Unit;
|
import com.bernard.greposimu.model.game.units.TerrestrialUnit;
|
||||||
|
import com.bernard.greposimu.model.game.units.Unit;
|
||||||
|
|
||||||
public class Fight {
|
public class Fight {
|
||||||
|
|
||||||
Game g;
|
public FightResult simulateFight(GameConfig gc, OffContext off, DefContext def) {
|
||||||
|
FightStats offStats = computeOffStats(gc, off);
|
||||||
|
FightStats defStats = computeDefStats(gc, def);
|
||||||
|
|
||||||
|
// Combat Naval
|
||||||
|
if(offStats.getShip() > defStats.getShip()) {
|
||||||
|
// Off wins ship
|
||||||
|
} else {
|
||||||
|
|
||||||
public Fight(Game g) {
|
|
||||||
this.g = g;
|
|
||||||
}
|
}
|
||||||
public FightStats computeDefStats(DefContext def) {
|
//TODO simulateFight
|
||||||
|
throw new UnsupportedOperationException("Simulator not created");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static FightStats computeDefStats(GameConfig gc, DefContext def) {
|
||||||
|
|
||||||
FightStats everyoneStatsBonus = FightStats.zero();
|
FightStats everyoneStatsBonus = FightStats.zero();
|
||||||
Map<String,FightStats> unitsBonuses;
|
Map<Unit,FightStats> unitsBonuses;
|
||||||
FightStats cityBaseStats;
|
FightStats cityBaseStats;
|
||||||
|
|
||||||
// Heroes
|
// Heroes
|
||||||
unitsBonuses = g.heroes.heroFightBonuses(def.hero, def.heroLevel, false);
|
unitsBonuses = Heroes.heroFightBonuses(gc, def.getHero(), def.getHeroLevel(), false);
|
||||||
|
|
||||||
// Tower & wall
|
// Tower & wall
|
||||||
cityBaseStats = Buildings.cityBaseStats(def.wallLevel);
|
if(def.hasTrojanDefense()) {
|
||||||
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, Buildings.wallBonus(def.wallLevel));
|
cityBaseStats = Buildings.cityBaseStats(def.getWallLevel()+1);
|
||||||
if(def.hasTower)
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, Buildings.wallBonus(def.getWallLevel()+1));
|
||||||
|
} else {
|
||||||
|
cityBaseStats = Buildings.cityBaseStats(def.getWallLevel());
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, Buildings.wallBonus(def.getWallLevel()));
|
||||||
|
}
|
||||||
|
if(def.hasTower())
|
||||||
// Add 10% to all units
|
// Add 10% to all units
|
||||||
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.cst(0.1));
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.cst(0.1));
|
||||||
|
|
||||||
// Powers
|
|
||||||
|
|
||||||
//TODO powers
|
|
||||||
|
|
||||||
// Researches
|
// Researches
|
||||||
if(def.counsellors.contains("divine_selection"))
|
if(def.hasDivineSelection())
|
||||||
for(String uid : g.data.units.keySet())
|
for(Unit u : gc.getUnits())
|
||||||
if(g.data.units.get(uid).isMythological())
|
if(u.isMythological())
|
||||||
unitsBonuses.put(uid, FightStats.add(unitsBonuses.getOrDefault(uid, FightStats.zero()), FightStats.cst(0.1)));
|
unitsBonuses.put(u, FightStats.add(unitsBonuses.getOrDefault(u, FightStats.zero()), FightStats.cst(0.1)));
|
||||||
if(def.counsellors.contains("phalanx"))
|
if(def.hasPhalanx())
|
||||||
for(String uid : g.data.units.keySet())
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(0.1));
|
||||||
if(g.data.units.get(uid).isGround())
|
if(def.hasRam())
|
||||||
unitsBonuses.put(uid, FightStats.add(unitsBonuses.getOrDefault(uid, FightStats.zero()), FightStats.cst(0.1)));
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.naval(0.1));
|
||||||
if(def.counsellors.contains("ram"))
|
|
||||||
for(String uid : g.data.units.keySet())
|
|
||||||
if(g.data.units.get(uid).isNaval())
|
|
||||||
unitsBonuses.put(uid, FightStats.add(unitsBonuses.getOrDefault(uid, FightStats.zero()), FightStats.cst(0.1)));
|
|
||||||
|
|
||||||
// Counsellors
|
// Counsellors
|
||||||
if(def.counsellors.contains("priest"))
|
if(def.hasPriest())
|
||||||
for(String uid : g.data.units.keySet())
|
for(Unit u : gc.getUnits())
|
||||||
if(g.data.units.get(uid).isMythological())
|
if(u.isMythological())
|
||||||
unitsBonuses.put(uid, FightStats.add(unitsBonuses.getOrDefault(uid, FightStats.zero()), FightStats.cst(0.2)));
|
unitsBonuses.put(u, FightStats.add(unitsBonuses.getOrDefault(u, FightStats.zero()), FightStats.cst(0.2)));
|
||||||
if(def.counsellors.contains("commander"))
|
if(def.hasCommander())
|
||||||
for(String uid : g.data.units.keySet())
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(0.2));
|
||||||
if(g.data.units.get(uid).isGround())
|
if(def.hasCaptain())
|
||||||
unitsBonuses.put(uid, FightStats.add(unitsBonuses.getOrDefault(uid, FightStats.zero()), FightStats.cst(0.2)));
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.naval(0.2));
|
||||||
if(def.counsellors.contains("captain"))
|
|
||||||
for(String uid : g.data.units.keySet())
|
// Powers
|
||||||
if(g.data.units.get(uid).isNaval())
|
if(def.hasMyrmidionAttack())
|
||||||
unitsBonuses.put(uid, FightStats.add(unitsBonuses.getOrDefault(uid, FightStats.zero()), FightStats.cst(0.2)));
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(-0.1));
|
||||||
|
if(def.hasDefenseBoost())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.05));
|
||||||
|
if(def.hasDefensePenalty())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(-0.1));
|
||||||
|
if(def.hasLongtermDefenseBoost())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.05));
|
||||||
|
if(def.hasRareDefenseBoost())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.05));
|
||||||
|
if(def.hasEpicDefenseBoost())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.1));
|
||||||
|
if(def.getOlympicTorchGrepolympiaSummerLevel()!=0)
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.05*def.getOlympicTorchGrepolympiaSummerLevel()));
|
||||||
|
if(def.getSoteriasShrineLevel()!=0)
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.007*def.getSoteriasShrineLevel()));
|
||||||
|
if(def.hasNarcissism())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(-0.1));
|
||||||
|
|
||||||
// Night Bonus
|
// Night Bonus
|
||||||
if(def.nightBonus)
|
if(def.isNightBonus())
|
||||||
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.cst(1.0));
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.cst(1.0));
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
FightStats total = cityBaseStats.clone();
|
FightStats total = cityBaseStats.clone();
|
||||||
for(Unit u : g.data.units.values()) {
|
for(Unit u : gc.getUnits()) {
|
||||||
// total = total + ucount * ((1+bonus+bonus) * ustats)
|
// total = total + ucount * ((1+bonus+bonus) * ustats)
|
||||||
if(def.units.containsKey(u.id) && def.units.get(u.id) != null)
|
|
||||||
total = FightStats.add(total,
|
total = FightStats.add(total,
|
||||||
FightStats.prod(def.units.get(u.id),
|
FightStats.prod(def.unitCount(u),
|
||||||
FightStats.mul(
|
FightStats.mul(
|
||||||
FightStats.add(FightStats.one(),everyoneStatsBonus,unitsBonuses.getOrDefault(u.id, FightStats.zero()))
|
FightStats.add(FightStats.one(),everyoneStatsBonus,unitsBonuses.getOrDefault(u, FightStats.zero()))
|
||||||
, u.getDefStats())
|
, makeDefStats(u))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeroStat
|
||||||
|
if(def.getHero() != null) {
|
||||||
|
total = FightStats.add(total, new FightStats(
|
||||||
|
def.getHero().getHackDef() * (1.0+0.1*def.getHeroLevel()),
|
||||||
|
def.getHero().getPierceDef() * (1.0+0.1*def.getHeroLevel()),
|
||||||
|
def.getHero().getDistanceDef() * (1.0+0.1*def.getHeroLevel()),
|
||||||
|
0.0
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Power> relevantDefPowers(GameData gd) {
|
public static FightStats makeDefStats(Unit u) {
|
||||||
System.out.println(gd.powers);
|
if(u instanceof TerrestrialUnit) {
|
||||||
return List.of("acumen", "divine_senses", "myrmidion_attack", "trojan_defense", "defense_boost",
|
TerrestrialUnit tu = (TerrestrialUnit)u;
|
||||||
"defense_penalty", "longterm_defense_boost", "assassins_acumen", "rare_defense_boost",
|
return new FightStats(tu.getHackDef(), tu.getPierceDef(), tu.getDistanceDef(), 0.0);
|
||||||
"epic_defense_boost", "olympic_torch.grepolympia_summer", "olympic_senses.grepolympia_summer", "missions_power_4.missions_dionysia",
|
}else if(u instanceof NavalUnit) {
|
||||||
"divine_battle_strategy_rare", "divine_battle_strategy_epic", "naval_battle_strategy_rare",
|
NavalUnit nu = (NavalUnit)u;
|
||||||
"naval_battle_strategy_epic", "land_battle_strategy_rare", "land_battle_strategy_epic",
|
return new FightStats(0.0, 0.0, 0.0, nu.getDefense());
|
||||||
"soterias_shrine.not_cast").stream().map(gd.powers::get).map(p -> (Power)p).toList();
|
|
||||||
}
|
}
|
||||||
public static List<Research> relevantDefResearch(GameData gd) {
|
throw new UnsupportedOperationException("I don't know how to manage units of type "+u.getClass().getName());
|
||||||
return List.of("divine_selection","phalanx","ram")
|
|
||||||
.stream().map(gd.researches::get).toList();
|
|
||||||
}
|
|
||||||
public static List<Unit> relevantDefUnits(GameData data) {
|
|
||||||
return data.units.values().stream().toList();
|
|
||||||
}
|
|
||||||
public static List<String> relevantDefCounsellors(GameData data) {
|
|
||||||
return List.of("priest","commander","captain");
|
|
||||||
}
|
|
||||||
public FightStats computeOffStats(DefContext off) {
|
|
||||||
//TODO computeOffStats
|
|
||||||
throw new UnsupportedOperationException("Simulator not created");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FightResult simulateFight(OffContext off, DefContext def) {
|
public static FightStats computeOffStats(GameConfig gc, OffContext off) {
|
||||||
//TODO simulateFight
|
|
||||||
throw new UnsupportedOperationException("Simulator not created");
|
FightStats everyoneStatsBonus = FightStats.zero();
|
||||||
|
Map<Unit,FightStats> unitsBonuses;
|
||||||
|
|
||||||
|
// Heroes
|
||||||
|
unitsBonuses = Heroes.heroFightBonuses(gc, off.getHero(), off.getHeroLevel(), false);
|
||||||
|
|
||||||
|
// Researches
|
||||||
|
if(off.hasDivineSelection())
|
||||||
|
for(Unit u : gc.getUnits())
|
||||||
|
if(u.isMythological())
|
||||||
|
unitsBonuses.put(u, FightStats.add(unitsBonuses.getOrDefault(u, FightStats.zero()), FightStats.cst(0.1)));
|
||||||
|
if(off.hasPhalanx())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(0.1));
|
||||||
|
if(off.hasRam())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.naval(0.1));
|
||||||
|
|
||||||
|
|
||||||
|
// Counsellors
|
||||||
|
if(off.hasPriest())
|
||||||
|
for(Unit u : gc.getUnits())
|
||||||
|
if(u.isMythological())
|
||||||
|
unitsBonuses.put(u, FightStats.add(unitsBonuses.getOrDefault(u, FightStats.zero()), FightStats.cst(0.2)));
|
||||||
|
if(off.hasCommander())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(0.2));
|
||||||
|
if(off.hasCaptain())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.naval(0.2));
|
||||||
|
|
||||||
|
// Powers
|
||||||
|
if(off.hasMyrmidionAttack())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.1));
|
||||||
|
if(off.hasAttackBoost())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.1));
|
||||||
|
if(off.hasAttackPenalty())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(-0.1));
|
||||||
|
if(off.hasLongtermAttackBoost())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.1));
|
||||||
|
if(off.hasLuxurious_residence())
|
||||||
|
;//XXX Unimplemented
|
||||||
|
if(off.hasAttack_ship_attack_boost_small())
|
||||||
|
unitsBonuses.put(gc.getUnit("attack_ship"), FightStats.add(unitsBonuses.getOrDefault(gc.getUnit("attack_ship"), FightStats.zero()), FightStats.cst(0.1)));
|
||||||
|
if(off.hasAttack_ship_attack_boost_medium())
|
||||||
|
unitsBonuses.put(gc.getUnit("attack_ship"), FightStats.add(unitsBonuses.getOrDefault(gc.getUnit("attack_ship"), FightStats.zero()), FightStats.cst(0.2)));
|
||||||
|
if(off.hasAttack_ship_attack_boost_large())
|
||||||
|
unitsBonuses.put(gc.getUnit("attack_ship"), FightStats.add(unitsBonuses.getOrDefault(gc.getUnit("attack_ship"), FightStats.zero()), FightStats.cst(0.3)));
|
||||||
|
if(off.hasRareAttackBoost())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.1));
|
||||||
|
if(off.hasEpicAttackBoost())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.2));
|
||||||
|
if(off.getOlympicSwordGrepolympiaSummerLevel()!=0)
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.05*off.getOlympicSwordGrepolympiaSummerLevel()));
|
||||||
|
if(off.getAresRageLevel()!=0)
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(+0.01*off.getAresRageLevel()));
|
||||||
|
if(off.getBloodlust()!=0)
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(0.05+0.01*Math.floorDiv(off.getBloodlust(),200)));
|
||||||
|
if(off.hasFairWind())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.naval(0.1));
|
||||||
|
if(off.hasDesire())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(-0.1));
|
||||||
|
if(off.hasStrengthOfHeroes())
|
||||||
|
//XXX check if working
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.terrestre(0.1));
|
||||||
|
if(off.hasEffortOfTheHuntress())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.ofType(FightType.DISTANCE,0.15));
|
||||||
|
|
||||||
|
if(off.hasStrategyBreach())
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.naval(-0.5));
|
||||||
|
|
||||||
|
|
||||||
|
// Units
|
||||||
|
FightStats total = FightStats.zero();
|
||||||
|
for(Unit u : gc.getUnits()) {
|
||||||
|
// total = total + ucount * ((1+bonusA+bonusB) * ustats)
|
||||||
|
total = FightStats.add(total,
|
||||||
|
FightStats.prod(off.unitCount(u),
|
||||||
|
FightStats.mul(
|
||||||
|
FightStats.add(FightStats.one(),everyoneStatsBonus,unitsBonuses.getOrDefault(u, FightStats.zero()))
|
||||||
|
, makeOffStats(u))
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
if(off.getAresArmyFurySpent()!=0)
|
||||||
|
// Ading aresarmy/25 spartiates
|
||||||
|
total = FightStats.add(total,
|
||||||
|
FightStats.prod(Math.floorDiv(off.getAresArmyFurySpent(), 25),
|
||||||
|
FightStats.mul(
|
||||||
|
FightStats.add(FightStats.one(),everyoneStatsBonus,unitsBonuses.getOrDefault(gc.getUnit("spartoi"), FightStats.zero()))
|
||||||
|
, makeOffStats(gc.getUnit("spartoi")))
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// HeroStat
|
||||||
|
if(off.getHero() != null) {
|
||||||
|
total = FightStats.add(total, new FightStats(
|
||||||
|
off.getHero().getHackDef() * (1.0+0.1*off.getHeroLevel()),
|
||||||
|
off.getHero().getPierceDef() * (1.0+0.1*off.getHeroLevel()),
|
||||||
|
off.getHero().getDistanceDef() * (1.0+0.1*off.getHeroLevel()),
|
||||||
|
0.0
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bonuses
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.cst(off.getLuck()/100.0));
|
||||||
|
everyoneStatsBonus = FightStats.add(everyoneStatsBonus, FightStats.cst(-(100.0-off.getMorale())/100.0));
|
||||||
|
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FightStats makeOffStats(Unit u) {
|
||||||
|
if(u instanceof TerrestrialUnit) {
|
||||||
|
TerrestrialUnit tu = (TerrestrialUnit)u;
|
||||||
|
return FightStats.ofType(tu.getAttackType(), tu.getAttack());
|
||||||
|
}else if(u instanceof NavalUnit) {
|
||||||
|
NavalUnit nu = (NavalUnit)u;
|
||||||
|
return new FightStats(0.0, 0.0, 0.0, nu.getAttack());
|
||||||
|
}
|
||||||
|
throw new UnsupportedOperationException("I don't know how to manage units of type "+u.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Unit> relevantDefUnits(GameConfig gc) {
|
||||||
|
return gc.getUnits().stream().toList();
|
||||||
|
}
|
||||||
|
public static List<Unit> relevantOffUnits(GameConfig gc) {
|
||||||
|
return gc.getUnits().stream().toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class FightResult {
|
public static class FightResult {
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
package com.bernard.greposimu.engine.game;
|
package com.bernard.greposimu.engine.game;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.game.GameData;
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
|
|
||||||
public class Game {
|
public class Game {
|
||||||
|
|
||||||
GameData data;
|
GameConfig data;
|
||||||
public Heroes heroes;
|
|
||||||
public Buildings buildings;
|
|
||||||
public Fight fight;
|
|
||||||
|
|
||||||
|
|
||||||
public Game(GameData data) {
|
public Game(GameConfig data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.heroes = new Heroes(this);
|
|
||||||
this.buildings = new Buildings(this);
|
|
||||||
this.fight = new Fight(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,47 +2,33 @@ package com.bernard.greposimu.engine.game;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.bernard.greposimu.model.FightStats;
|
import com.bernard.greposimu.model.FightStats;
|
||||||
import com.bernard.greposimu.model.game.Hero;
|
import com.bernard.greposimu.model.game.GameConfig;
|
||||||
|
import com.bernard.greposimu.model.game.units.Hero;
|
||||||
|
import com.bernard.greposimu.model.game.units.Unit;
|
||||||
|
|
||||||
public class Heroes {
|
public class Heroes {
|
||||||
|
|
||||||
Game g;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Heroes(Game g) {
|
|
||||||
this.g = g;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the bonus applied to each unit
|
* Compute the bonus applied to each unit
|
||||||
* @param hero The uid of the hero
|
* @param hero The hero object to consider
|
||||||
* @param level The level of the hero
|
* @param level The level of the hero
|
||||||
* @param off true for the off stat, false for the def stat
|
* @param off true for the off stat, false for the def stat
|
||||||
* @return For each unit, the bonus that should be applied to it
|
* @return For each unit, the bonus that should be applied to it
|
||||||
*/
|
*/
|
||||||
public Map<String,FightStats> heroFightBonuses(String hero, int level, boolean off){
|
public static Map<Unit, FightStats> heroFightBonuses(GameConfig gc, Hero hero, int level, boolean off){
|
||||||
|
|
||||||
Map<String,FightStats> bonuses = new HashMap<>();
|
|
||||||
|
|
||||||
if(hero == null)
|
if(hero == null)
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
|
|
||||||
double bonus = 0.0;
|
Map<String,FightStats> bonuses = new HashMap<>();
|
||||||
Hero heroD = g.data.heroes.get(hero);
|
|
||||||
if(heroD != null && heroD.description_args != null && heroD.description_args.containsKey("1")) {
|
double bonus = hero.getPowerBaseValue() + level * hero.getPowerValuePerLevel();
|
||||||
Hero.DescriptionArgs args = heroD.description_args.get("1");
|
|
||||||
if(args.unit.equals("%"))
|
|
||||||
bonus = args.value + level * args.level_mod;
|
|
||||||
else
|
|
||||||
throw new UnsupportedOperationException("I don't know about unit "+args.unit);
|
|
||||||
}
|
|
||||||
FightStats appliedBonus = null;
|
FightStats appliedBonus = null;
|
||||||
switch(hero) {
|
switch(hero.getId()) {
|
||||||
case "agamemnon":
|
case "agamemnon":
|
||||||
appliedBonus = FightStats.terrestre(bonus);
|
appliedBonus = FightStats.terrestre(bonus);
|
||||||
bonuses.put("hoplite", appliedBonus);
|
bonuses.put("hoplite", appliedBonus);
|
||||||
@@ -59,7 +45,7 @@ public class Heroes {
|
|||||||
case "deimos":
|
case "deimos":
|
||||||
appliedBonus = FightStats.cst(bonus);
|
appliedBonus = FightStats.cst(bonus);
|
||||||
if(off)
|
if(off)
|
||||||
for(String uid : g.data.units.keySet())bonuses.put(uid,appliedBonus);
|
for(Unit u : gc.getUnits())bonuses.put(u.getId(),appliedBonus);
|
||||||
break;
|
break;
|
||||||
case "hector":
|
case "hector":
|
||||||
appliedBonus = FightStats.terrestre(bonus);
|
appliedBonus = FightStats.terrestre(bonus);
|
||||||
@@ -73,11 +59,11 @@ public class Heroes {
|
|||||||
case "leonidas":
|
case "leonidas":
|
||||||
appliedBonus = FightStats.terrestre(bonus);
|
appliedBonus = FightStats.terrestre(bonus);
|
||||||
if(!off)
|
if(!off)
|
||||||
for(String uid : g.data.units.keySet())bonuses.put(uid,appliedBonus);
|
for(Unit u : gc.getUnits())bonuses.put(u.getId(),appliedBonus);
|
||||||
break;
|
break;
|
||||||
case "mihalis":
|
case "mihalis":
|
||||||
appliedBonus = new FightStats(bonus, bonus, 0.0, 0.0);
|
appliedBonus = new FightStats(bonus, bonus, 0.0, 0.0);
|
||||||
for(String uid : g.data.units.keySet())bonuses.put(uid,appliedBonus);
|
for(Unit u : gc.getUnits())bonuses.put(u.getId(),appliedBonus);
|
||||||
break;
|
break;
|
||||||
case "medea":
|
case "medea":
|
||||||
appliedBonus = FightStats.terrestre(bonus);
|
appliedBonus = FightStats.terrestre(bonus);
|
||||||
@@ -103,17 +89,17 @@ public class Heroes {
|
|||||||
break;
|
break;
|
||||||
case "urephon":
|
case "urephon":
|
||||||
appliedBonus = FightStats.terrestre(bonus);
|
appliedBonus = FightStats.terrestre(bonus);
|
||||||
for(String uid : g.data.units.keySet())if(g.data.units.get(uid).isMythological())bonuses.put(uid,appliedBonus);
|
for(Unit u : gc.getUnits())if(u.isMythological())bonuses.put(u.getId(),appliedBonus);
|
||||||
break;
|
break;
|
||||||
case "zuretha":
|
case "zuretha":
|
||||||
appliedBonus = new FightStats(0.0, 0.0, 0.0, bonus);
|
appliedBonus = new FightStats(0.0, 0.0, 0.0, bonus);
|
||||||
for(String uid : g.data.units.keySet())bonuses.put(uid,appliedBonus);
|
for(Unit u : gc.getUnits())bonuses.put(u.getId(),appliedBonus);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// No buff
|
// No buff
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return bonuses;
|
return bonuses.keySet().stream().collect(Collectors.toMap(k -> gc.getUnit(k), k -> bonuses.get(k)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
package com.bernard.greposimu.engine.json;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
|
||||||
import com.fasterxml.jackson.core.ObjectCodec;
|
|
||||||
import com.fasterxml.jackson.databind.BeanProperty;
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
|
||||||
import com.fasterxml.jackson.databind.JavaType;
|
|
||||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
|
|
||||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
|
||||||
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
|
|
||||||
|
|
||||||
public class MapJsonDeserializer extends StdDeserializer<Map<String,?>> implements ContextualDeserializer{
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -888029778299077908L;
|
|
||||||
private JavaType type;
|
|
||||||
|
|
||||||
public MapJsonDeserializer() {
|
|
||||||
super(Object.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException{
|
|
||||||
MapJsonDeserializer deserializer = new MapJsonDeserializer();
|
|
||||||
if(property != null)
|
|
||||||
deserializer.type = property.getType().containedType(1);
|
|
||||||
else
|
|
||||||
deserializer.type = ctxt.getContextualType();
|
|
||||||
return deserializer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String,?> deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {
|
|
||||||
JsonNode node = parser.getCodec().readTree(parser);
|
|
||||||
if(node.isNull() || (node.isArray() && node.isEmpty()))
|
|
||||||
return new HashMap<>();
|
|
||||||
else if(node.isObject()) {
|
|
||||||
ObjectCodec codec = parser.getCodec();
|
|
||||||
Map<String,Object> output = new HashMap<>();
|
|
||||||
java.util.Iterator<Entry<String, JsonNode>> it = node.fields();
|
|
||||||
while(it.hasNext()) {
|
|
||||||
Entry<String, JsonNode> entry = it.next();
|
|
||||||
output.put(entry.getKey(), entry.getValue().traverse(codec).readValueAs(this.type.getRawClass()));
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
} else
|
|
||||||
throw MismatchedInputException.from(parser, Map.class, "JSON is neither an empty array nor a map");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,118 +1,266 @@
|
|||||||
package com.bernard.greposimu.model;
|
package com.bernard.greposimu.model;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.List;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bernard.greposimu.Utils;
|
import com.bernard.greposimu.model.game.units.Hero;
|
||||||
|
import com.bernard.greposimu.model.game.units.Unit;
|
||||||
|
|
||||||
public class DefContext {
|
public class DefContext {
|
||||||
// unitID -> number of units
|
|
||||||
public Map<String, Integer> units;
|
|
||||||
|
|
||||||
public String hero;
|
// UNITS
|
||||||
public int heroLevel;
|
// Units unrelated to the attacker
|
||||||
|
Map<Unit, Integer> otherUnits;
|
||||||
|
// Units owned by allies of the attacker
|
||||||
|
Map<Unit, Integer> alliedUnits;
|
||||||
|
// Units owned by the attacher
|
||||||
|
Map<Unit, Integer> selfUnits;
|
||||||
|
|
||||||
public int wallLevel;
|
// HEROS
|
||||||
public boolean hasTower;
|
Hero hero = null;
|
||||||
|
int heroLevel = 0;
|
||||||
|
|
||||||
public Set<String> powers;
|
// BUILDINGS
|
||||||
public Set<String> researches;
|
int wallLevel = 0;
|
||||||
|
boolean hasTower=false;
|
||||||
|
|
||||||
public Set<String> counsellors;
|
// RESEARCHES
|
||||||
|
boolean divineSelection= false, phalanx = false, ram=false;
|
||||||
|
|
||||||
public boolean nightBonus;
|
// COUNSELLORS
|
||||||
|
boolean commander= false;
|
||||||
|
boolean priest = false;
|
||||||
|
boolean captain = false;
|
||||||
|
|
||||||
public DefContext() {
|
// EFFECTS
|
||||||
this.units = new HashMap<>();
|
// PC x2
|
||||||
this.hero = null;
|
boolean acumen = false;
|
||||||
this.heroLevel = 0;
|
// PC x4
|
||||||
this.wallLevel = 0;
|
boolean divineSenses= false;
|
||||||
this.hasTower = false;
|
// Attq +10%, Def -10%
|
||||||
this.powers = new HashSet<>();
|
boolean myrmidionAttack= false;
|
||||||
this.researches = new HashSet<>();
|
// Remparts +1, Milice+5/farm (level max 25)
|
||||||
this.counsellors = new HashSet<>();
|
boolean trojanDefense= false;
|
||||||
this.nightBonus = false;
|
// Def +5%
|
||||||
|
boolean defenseBoost= false;
|
||||||
|
// Def -10%
|
||||||
|
boolean defensePenalty= false;
|
||||||
|
// Def +5%
|
||||||
|
boolean longtermDefenseBoost= false;
|
||||||
|
// PC +50%
|
||||||
|
boolean assassinsAcumen= false;
|
||||||
|
// Def +5%
|
||||||
|
boolean rareDefenseBoost= false;
|
||||||
|
// Def +10%
|
||||||
|
boolean epicDefenseBoost= false;
|
||||||
|
// +50% PC
|
||||||
|
boolean missionsPower4= false;
|
||||||
|
// PC+50% (sauf BC, transport)
|
||||||
|
boolean divineBattleStrategyRare= false;
|
||||||
|
// PC+100% (sauf BC, transport)
|
||||||
|
boolean divineBattleStrategyEpic= false;
|
||||||
|
// PC+50% against naval (sauf BC,transports)
|
||||||
|
boolean navalBattleStrategyRare= false;
|
||||||
|
// PC+100% against naval (sauf BC, transport)
|
||||||
|
boolean navalBattleStrategyEpic= false;
|
||||||
|
// PC+50% against terrestres
|
||||||
|
boolean landBattleStrategyRare= false;
|
||||||
|
// PC+100% against terrestre
|
||||||
|
boolean landBattleStrategyEpic= false;
|
||||||
|
// Def -10%
|
||||||
|
boolean narcissism= false;
|
||||||
|
// PC+10%*level
|
||||||
|
int olympicSensesGrepolympiaSummerLevel = 0;
|
||||||
|
// Def +5%*level
|
||||||
|
int olympicTorchGrepolympiaSummerLevel = 0;
|
||||||
|
// Df +0.7%*level
|
||||||
|
int soteriasShrineLevel = 0;
|
||||||
|
|
||||||
|
// BONUSES
|
||||||
|
boolean nightBonus = false;
|
||||||
|
|
||||||
|
public DefContext(Map<Unit, Integer> units, Hero hero, int heroLevel, int wallLevel, boolean hasTower,
|
||||||
|
Set<String> powers, int soteriasShrinePowerLevel, int olympicTorchGrepolympiaSummerLevel, int olympicSensesGrepolympiaSummerLevel,
|
||||||
|
Set<String> researches, Set<String> counsellors, boolean nightBonus) {
|
||||||
|
this(units,Map.of(),Map.of(),hero,heroLevel,wallLevel,hasTower,powers,soteriasShrinePowerLevel,olympicTorchGrepolympiaSummerLevel,olympicSensesGrepolympiaSummerLevel,researches,counsellors,nightBonus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Integer> getUnits() {
|
public DefContext(Map<Unit, Integer> otherUnits, Map<Unit, Integer> alliedUnits, Map<Unit, Integer> selfUnits, Hero hero, int heroLevel, int wallLevel, boolean hasTower,
|
||||||
return units;
|
Set<String> powers, int soteriasShrinePowerLevel, int olympicTorchGrepolympiaSummerLevel, int olympicSensesGrepolympiaSummerLevel, Set<String> researches, Set<String> counsellors, boolean nightBonus) {
|
||||||
|
this.otherUnits = otherUnits;
|
||||||
|
this.alliedUnits = alliedUnits;
|
||||||
|
this.selfUnits = selfUnits;
|
||||||
|
this.hero = hero;
|
||||||
|
this.heroLevel = heroLevel;
|
||||||
|
this.wallLevel = wallLevel;
|
||||||
|
this.hasTower = hasTower;
|
||||||
|
if(powers.contains("acumen"))this.acumen = true;
|
||||||
|
if(powers.contains("divine_senses"))this.divineSenses = true;
|
||||||
|
if(powers.contains("myrmidion_attack"))this.myrmidionAttack = true;
|
||||||
|
if(powers.contains("trojan_defense"))this.trojanDefense = true;
|
||||||
|
if(powers.contains("defense_boost"))this.defenseBoost = true;
|
||||||
|
if(powers.contains("defense_penalty"))this.defensePenalty = true;
|
||||||
|
if(powers.contains("longterm_defense_boost"))this.longtermDefenseBoost = true;
|
||||||
|
if(powers.contains("assassins_acumen"))this.assassinsAcumen = true;
|
||||||
|
if(powers.contains("rare_defense_boost"))this.rareDefenseBoost = true;
|
||||||
|
if(powers.contains("epic_defense_boost"))this.epicDefenseBoost = true;
|
||||||
|
if(powers.contains("olympic_torch"))this.olympicTorchGrepolympiaSummerLevel = olympicTorchGrepolympiaSummerLevel;
|
||||||
|
if(powers.contains("olympic_senses"))this.olympicSensesGrepolympiaSummerLevel = olympicSensesGrepolympiaSummerLevel;
|
||||||
|
if(powers.contains("missions_power_4"))this.missionsPower4 = true;
|
||||||
|
if(powers.contains("divine_battle_strategy_rare"))this.divineBattleStrategyRare = true;
|
||||||
|
if(powers.contains("divine_battle_strategy_epic"))this.divineBattleStrategyEpic = true;
|
||||||
|
if(powers.contains("naval_battle_strategy_rare"))this.navalBattleStrategyRare = true;
|
||||||
|
if(powers.contains("naval_battle_strategy_epic"))this.navalBattleStrategyEpic = true;
|
||||||
|
if(powers.contains("land_battle_strategy_rare"))this.landBattleStrategyRare = true;
|
||||||
|
if(powers.contains("land_battle_strategy_epic"))this.landBattleStrategyEpic = true;
|
||||||
|
if(powers.contains("soterias_shrine"))this.soteriasShrineLevel = soteriasShrinePowerLevel;
|
||||||
|
if(powers.contains("narcissism"))this.narcissism = true;
|
||||||
|
if(researches.contains("divine_selection"))this.divineSelection = true;
|
||||||
|
if(researches.contains("phalanx"))this.phalanx = true;
|
||||||
|
if(researches.contains("ram"))this.ram = true;
|
||||||
|
if(counsellors.contains("commander"))this.commander = true;
|
||||||
|
if(counsellors.contains("priest"))this.priest = true;
|
||||||
|
if(counsellors.contains("captain"))this.captain = true;
|
||||||
|
this.nightBonus = nightBonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHero() {
|
public int unitCount(Unit u) {
|
||||||
|
return
|
||||||
|
Optional.ofNullable(otherUnits.getOrDefault(u,0)).orElse(0) +
|
||||||
|
Optional.ofNullable(alliedUnits.getOrDefault(u,0)).orElse(0) +
|
||||||
|
Optional.ofNullable(selfUnits.getOrDefault(u,0)).orElse(0);
|
||||||
|
}
|
||||||
|
public Hero getHero() {
|
||||||
return hero;
|
return hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeroLevel() {
|
public int getHeroLevel() {
|
||||||
return heroLevel;
|
return heroLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWallLevel() {
|
public int getWallLevel() {
|
||||||
return wallLevel;
|
return wallLevel;
|
||||||
}
|
}
|
||||||
|
public boolean hasTower() {
|
||||||
public boolean isHasTower() {
|
|
||||||
return hasTower;
|
return hasTower;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getPowers() {
|
|
||||||
return powers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getResearches() {
|
|
||||||
return researches;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getCounsellors() {
|
|
||||||
return counsellors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Boolean> getPowersAsMap() {
|
|
||||||
return Utils.setToMap(powers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Boolean> getResearchesAsMap() {
|
|
||||||
return Utils.setToMap(researches);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Boolean> getCounsellorsAsMap() {
|
|
||||||
return Utils.setToMap(counsellors);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNightBonus() {
|
public boolean isNightBonus() {
|
||||||
return nightBonus;
|
return nightBonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasDivineSelection() {
|
||||||
|
return divineSelection;
|
||||||
public void setHero(String hero) {
|
|
||||||
this.hero = hero;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeroLevel(int heroLevel) {
|
public boolean hasPhalanx() {
|
||||||
this.heroLevel = heroLevel;
|
return phalanx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWallLevel(int wallLevel) {
|
public boolean hasRam() {
|
||||||
this.wallLevel = wallLevel;
|
return ram;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHasTower(boolean hasTower) {
|
public boolean hasCommander() {
|
||||||
this.hasTower = hasTower;
|
return commander;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNightBonus(boolean nightBonus) {
|
public boolean hasPriest() {
|
||||||
this.nightBonus = nightBonus;
|
return priest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean hasCaptain() {
|
||||||
public String toString() {
|
return captain;
|
||||||
return "DefContext [units=" + units + ", heros=" + hero + ", herosLevel=" + heroLevel + ", wallLevel="
|
|
||||||
+ wallLevel + ", hasTower=" + hasTower + ", powers=" + powers + ", researches=" + researches
|
|
||||||
+ ", counsellors=" + counsellors + ", nightBonus=" + nightBonus + "]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasAcumen() {
|
||||||
|
return acumen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDivineSenses() {
|
||||||
|
return divineSenses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMyrmidionAttack() {
|
||||||
|
return myrmidionAttack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasTrojanDefense() {
|
||||||
|
return trojanDefense;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDefenseBoost() {
|
||||||
|
return defenseBoost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDefensePenalty() {
|
||||||
|
return defensePenalty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasLongtermDefenseBoost() {
|
||||||
|
return longtermDefenseBoost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAssassinsAcumen() {
|
||||||
|
return assassinsAcumen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasRareDefenseBoost() {
|
||||||
|
return rareDefenseBoost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasEpicDefenseBoost() {
|
||||||
|
return epicDefenseBoost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMhassionsPower4() {
|
||||||
|
return missionsPower4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDivineBattleStrategyRare() {
|
||||||
|
return divineBattleStrategyRare;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDivineBattleStrategyEpic() {
|
||||||
|
return divineBattleStrategyEpic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNavalBattleStrategyRare() {
|
||||||
|
return navalBattleStrategyRare;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNavalBattleStrategyEpic() {
|
||||||
|
return navalBattleStrategyEpic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasLandBattleStrategyRare() {
|
||||||
|
return landBattleStrategyRare;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasLandBattleStrategyEpic() {
|
||||||
|
return landBattleStrategyEpic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOlympicSensesGrepolympiaSummerLevel() {
|
||||||
|
return olympicSensesGrepolympiaSummerLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOlympicTorchGrepolympiaSummerLevel() {
|
||||||
|
return olympicTorchGrepolympiaSummerLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSoteriasShrineLevel() {
|
||||||
|
return soteriasShrineLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNarcissism() {
|
||||||
|
return narcissism;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final List<String> POWERS = List.of("acumen", "divine_senses", "myrmidion_attack", "trojan_defense",
|
||||||
|
"defense_boost", "defense_penalty", "longterm_defense_boost", "assassins_acumen", "rare_defense_boost",
|
||||||
|
"epic_defense_boost", "olympic_torch", "olympic_senses", "missions_power_4", "divine_battle_strategy_rare",
|
||||||
|
"divine_battle_strategy_epic", "naval_battle_strategy_rare", "naval_battle_strategy_epic",
|
||||||
|
"land_battle_strategy_rare", "land_battle_strategy_epic", "soterias_shrine", "narcissism");
|
||||||
|
public static final List<String> RESEARCHES = List.of("divine_selection","phalanx","ram");
|
||||||
|
public static final List<String> COUNSELLORS = List.of("priest","commander","captain");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
package com.bernard.greposimu.model;
|
|
||||||
|
|
||||||
public enum Dieu {
|
|
||||||
ZEUS("Zeus","zeus"),
|
|
||||||
POSEIDON("Poséidon","poseidon"),
|
|
||||||
HERA("Héra","hera"),
|
|
||||||
ATHENA("Athéna","athena"),
|
|
||||||
HADES("Hadès","hades"),
|
|
||||||
ARTEMIS("Artémis","artemis"),
|
|
||||||
APHRODITE("Aphrodite","aphrodite"),
|
|
||||||
ARES("Arès","ares");
|
|
||||||
|
|
||||||
String nom;
|
|
||||||
String pname;
|
|
||||||
|
|
||||||
Dieu(String nom,String pname){
|
|
||||||
this.nom = nom;
|
|
||||||
this.pname = pname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNom() {
|
|
||||||
return nom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPname() {
|
|
||||||
return pname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,8 @@ package com.bernard.greposimu.model;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.units.FightType;
|
||||||
|
|
||||||
public class FightStats implements Cloneable{
|
public class FightStats implements Cloneable{
|
||||||
public double hack;
|
public double hack;
|
||||||
public double pierce;
|
public double pierce;
|
||||||
@@ -15,6 +17,19 @@ public class FightStats implements Cloneable{
|
|||||||
this.ship = ship;
|
this.ship = ship;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final FightStats ofType(FightType type, double value) {
|
||||||
|
switch(type) {
|
||||||
|
case HACK:
|
||||||
|
return new FightStats(value, 0.0, 0.0, 0.0);
|
||||||
|
case PIERCE:
|
||||||
|
return new FightStats(0.0, value, 0.0, 0.0);
|
||||||
|
case DISTANCE:
|
||||||
|
return new FightStats(0.0, 0.0, value, 0.0);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final FightStats zero() {
|
public static final FightStats zero() {
|
||||||
return new FightStats(0, 0, 0, 0);
|
return new FightStats(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
@@ -27,6 +42,10 @@ public class FightStats implements Cloneable{
|
|||||||
return new FightStats(value, value, value, 0.0);
|
return new FightStats(value, value, value, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final FightStats naval(double value) {
|
||||||
|
return new FightStats(0.0, 0.0, 0.0, value);
|
||||||
|
}
|
||||||
|
|
||||||
public static final FightStats cst(double value) {
|
public static final FightStats cst(double value) {
|
||||||
return new FightStats(value, value, value, value);
|
return new FightStats(value, value, value, value);
|
||||||
}
|
}
|
||||||
@@ -51,6 +70,22 @@ public class FightStats implements Cloneable{
|
|||||||
return new FightStats(k * b.hack, k * b.pierce, k * b.distance, k * b.ship);
|
return new FightStats(k * b.hack, k * b.pierce, k * b.distance, k * b.ship);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getHack() {
|
||||||
|
return hack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPierce() {
|
||||||
|
return pierce;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDistance() {
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getShip() {
|
||||||
|
return ship;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FightStats clone() {
|
public FightStats clone() {
|
||||||
return new FightStats(hack, pierce, distance, ship);
|
return new FightStats(hack, pierce, distance, ship);
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
package com.bernard.greposimu.model;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class Heros {
|
|
||||||
String nom;
|
|
||||||
String pname;
|
|
||||||
|
|
||||||
|
|
||||||
Set<String> appliedToNames;
|
|
||||||
boolean appTerrestre,appNavale,appMythique;
|
|
||||||
OffDefStats statsZero;
|
|
||||||
OffDefStats statsPlus;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Heros(String nom, String pname, Set<String> appliedToNames, boolean appTerrestre, boolean appNavale, boolean appMythique,
|
|
||||||
OffDefStats statsZero, OffDefStats statsPlus) {
|
|
||||||
this.nom = nom;
|
|
||||||
this.pname = pname;
|
|
||||||
this.appliedToNames = appliedToNames;
|
|
||||||
this.appTerrestre = appTerrestre;
|
|
||||||
this.appNavale = appNavale;
|
|
||||||
this.appMythique = appMythique;
|
|
||||||
this.statsZero = statsZero;
|
|
||||||
this.statsPlus = statsPlus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public OffDefStats applyToUnit(Unite unite,int level) {
|
|
||||||
if((appTerrestre && unite.terrestre) ||
|
|
||||||
(appNavale && unite.navale) ||
|
|
||||||
(appMythique && unite.mythique) ||
|
|
||||||
appliedToNames.contains(unite.pname)) {
|
|
||||||
return unite.stats.plus(unite.stats.prod(statsZero.plus(statsPlus.times(level))));
|
|
||||||
}
|
|
||||||
return unite.stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getNom() {
|
|
||||||
return nom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPname() {
|
|
||||||
return pname;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Set<String> getAppliedToNames() {
|
|
||||||
return appliedToNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isAppTerrestre() {
|
|
||||||
return appTerrestre;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isAppNavale() {
|
|
||||||
return appNavale;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isAppMythique() {
|
|
||||||
return appMythique;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public OffDefStats getStatsZero() {
|
|
||||||
return statsZero;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public OffDefStats getStatsPlus() {
|
|
||||||
return statsPlus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,288 @@
|
|||||||
package com.bernard.greposimu.model;
|
package com.bernard.greposimu.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.units.Hero;
|
||||||
|
import com.bernard.greposimu.model.game.units.Unit;
|
||||||
|
|
||||||
public class OffContext {
|
public class OffContext {
|
||||||
// unitID -> number of units
|
|
||||||
public Map<String, Integer> units;
|
|
||||||
|
|
||||||
public String heros;
|
Map<Unit, Integer> units;
|
||||||
public int herosLevel;
|
|
||||||
|
|
||||||
public int luck;
|
Hero hero;
|
||||||
public int morale;
|
int heroLevel;
|
||||||
|
|
||||||
public Set<String> powers;
|
int luck;
|
||||||
public Set<String> researches;
|
int moral;
|
||||||
|
|
||||||
public Set<String> counsellors;
|
// RESEARCHES
|
||||||
|
boolean divineSelection= false, phalanx = false, ram=false, combatExperience=false;
|
||||||
|
|
||||||
|
// COUNSELLORS
|
||||||
|
boolean commander= false;
|
||||||
|
boolean priest = false;
|
||||||
|
boolean captain = false;
|
||||||
|
|
||||||
|
// EFFECTS
|
||||||
|
// PC x2
|
||||||
|
boolean acumen = false;
|
||||||
|
// PC x4
|
||||||
|
boolean divineSenses= false;
|
||||||
|
// Attq +10%, Def -10%
|
||||||
|
boolean myrmidionAttack= false;
|
||||||
|
// Attq +10%
|
||||||
|
boolean attackBoost= false;
|
||||||
|
// Attq -10%
|
||||||
|
boolean attackPenalty= false;
|
||||||
|
// Attq +10%
|
||||||
|
boolean longtermAttackBoost = false;
|
||||||
|
//XXX implement this :/
|
||||||
|
boolean luxuriousResidence = false;
|
||||||
|
// BF attq +10%
|
||||||
|
boolean attack_ship_attack_boost_small = false;
|
||||||
|
// BF attq +20%
|
||||||
|
boolean attack_ship_attack_boost_medium = false;
|
||||||
|
// BF attq +30%
|
||||||
|
boolean attack_ship_attack_boost_large = false;
|
||||||
|
// PC +50%
|
||||||
|
boolean assassinsAcumen= false;
|
||||||
|
// Attq +10%
|
||||||
|
boolean rareAttackBoost= false;
|
||||||
|
// Attq +20%
|
||||||
|
boolean epicAttackBoost= false;
|
||||||
|
// Attq +5%*level
|
||||||
|
int olympicSwordGrepolympiaSummerLevel = 0;
|
||||||
|
// PC+10%*level
|
||||||
|
int olympicSensesGrepolympiaSummerLevel = 0;
|
||||||
|
// +50% PC
|
||||||
|
boolean missionsPower4= false;
|
||||||
|
// PC+50% (sauf BC, transport)
|
||||||
|
boolean divineBattleStrategyRare= false;
|
||||||
|
// PC+100% (sauf BC, transport)
|
||||||
|
boolean divineBattleStrategyEpic= false;
|
||||||
|
// PC+50% against naval (sauf BC,transports)
|
||||||
|
boolean navalBattleStrategyRare= false;
|
||||||
|
// PC+100% against naval (sauf BC, transport)
|
||||||
|
boolean navalBattleStrategyEpic= false;
|
||||||
|
// PC+50% against terrestres
|
||||||
|
boolean landBattleStrategyRare= false;
|
||||||
|
// PC+100% against terrestre
|
||||||
|
boolean landBattleStrategyEpic= false;
|
||||||
|
// Attq +1%*level
|
||||||
|
int aresRageLevel = 0;
|
||||||
|
|
||||||
|
// SPELLS
|
||||||
|
// Add one sparte for every 25 fury used
|
||||||
|
int aresArmyFurySpent = 0;
|
||||||
|
// Attq +5% +(1% for each 200 fury spent)
|
||||||
|
// PC + 1% for each 100 fury spent
|
||||||
|
int bloodlustFurySpent = 0;
|
||||||
|
// Attq naval +10%
|
||||||
|
boolean fairWind = false;
|
||||||
|
// Attq -10%
|
||||||
|
boolean desire = false;
|
||||||
|
// Terr + aer +10% attq
|
||||||
|
boolean strengthOfHeroes = false;
|
||||||
|
// Attq distance +15%
|
||||||
|
boolean effortOfTheHuntress = false;
|
||||||
|
|
||||||
|
boolean strategyBreach = false;
|
||||||
|
boolean allianceModifier = false;
|
||||||
|
|
||||||
|
|
||||||
|
public OffContext(Map<Unit, Integer> units, Hero hero, int heroLevel, int luck, int moral,
|
||||||
|
Set<String> powers, int olympicSwordGrepolympiaSummerLevel, int olympicSensesGrepolympiaSummerLevel,
|
||||||
|
int aresRageLevel, int aresArmyFurySpent, int bloodlustFurySpent, Set<String> researches, Set<String> counsellors,
|
||||||
|
boolean strategyBreach, boolean allianceModifier) {
|
||||||
|
this.units = units;
|
||||||
|
this.hero = hero;
|
||||||
|
this.heroLevel = heroLevel;
|
||||||
|
this.luck = luck;
|
||||||
|
this.moral = moral;
|
||||||
|
|
||||||
|
if(powers.contains("acumen"))this.acumen = true;
|
||||||
|
if(powers.contains("divine_senses"))this.divineSenses = true;
|
||||||
|
if(powers.contains("myrmidion_attack"))this.myrmidionAttack = true;
|
||||||
|
if(powers.contains("attack_boost"))this.attackBoost = true;
|
||||||
|
if(powers.contains("attack_penalty"))this.attackPenalty = true;
|
||||||
|
if(powers.contains("longterm_attack_boost"))this.longtermAttackBoost = true;
|
||||||
|
if(powers.contains("attack_ship_attack_boost_small"))this.attack_ship_attack_boost_small = true;
|
||||||
|
if(powers.contains("attack_ship_attack_boost_medium"))this.attack_ship_attack_boost_medium = true;
|
||||||
|
if(powers.contains("attack_ship_attack_boost_large"))this.attack_ship_attack_boost_large = true;
|
||||||
|
if(powers.contains("assassins_acumen"))this.assassinsAcumen = true;
|
||||||
|
if(powers.contains("rare_attack_boost"))this.rareAttackBoost = true;
|
||||||
|
if(powers.contains("epic_attack_boost"))this.epicAttackBoost = true;
|
||||||
|
if(powers.contains("olympic_sword"))this.olympicSwordGrepolympiaSummerLevel = olympicSwordGrepolympiaSummerLevel;
|
||||||
|
if(powers.contains("olympic_senses"))this.olympicSensesGrepolympiaSummerLevel = olympicSensesGrepolympiaSummerLevel;
|
||||||
|
if(powers.contains("missions_power_4"))this.missionsPower4 = true;
|
||||||
|
if(powers.contains("divine_battle_strategy_rare"))this.divineBattleStrategyRare = true;
|
||||||
|
if(powers.contains("divine_battle_strategy_epic"))this.divineBattleStrategyEpic = true;
|
||||||
|
if(powers.contains("naval_battle_strategy_rare"))this.navalBattleStrategyRare = true;
|
||||||
|
if(powers.contains("naval_battle_strategy_epic"))this.navalBattleStrategyEpic = true;
|
||||||
|
if(powers.contains("land_battle_strategy_rare"))this.landBattleStrategyRare = true;
|
||||||
|
if(powers.contains("land_battle_strategy_epic"))this.landBattleStrategyEpic = true;
|
||||||
|
if(powers.contains("ares_rage"))this.aresRageLevel = aresRageLevel;
|
||||||
|
if(powers.contains("ares_army"))this.aresArmyFurySpent = aresArmyFurySpent;
|
||||||
|
if(powers.contains("bloodlust"))this.bloodlustFurySpent = bloodlustFurySpent;
|
||||||
|
if(powers.contains("fair_wind"))this.fairWind = true;
|
||||||
|
if(powers.contains("desire"))this.desire = true;
|
||||||
|
if(powers.contains("effort_of_the_huntress"))this.effortOfTheHuntress = true;
|
||||||
|
if(powers.contains("strength_of_heroes"))this.strengthOfHeroes = true;
|
||||||
|
if(researches.contains("divine_selection"))this.divineSelection = true;
|
||||||
|
if(researches.contains("phalanx"))this.phalanx = true;
|
||||||
|
if(researches.contains("ram"))this.ram = true;
|
||||||
|
if(researches.contains("combat_experience"))this.combatExperience = true;
|
||||||
|
if(counsellors.contains("commander"))this.commander = true;
|
||||||
|
if(counsellors.contains("priest"))this.priest = true;
|
||||||
|
if(counsellors.contains("captain"))this.captain = true;
|
||||||
|
this.strategyBreach = strategyBreach;
|
||||||
|
this.allianceModifier = allianceModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int unitCount(Unit u) {
|
||||||
|
return Optional.ofNullable(units.getOrDefault(u,0)).orElse(0);
|
||||||
|
}
|
||||||
|
public Map<Unit, Integer> getUnits() {
|
||||||
|
return units;
|
||||||
|
}
|
||||||
|
public Hero getHero() {
|
||||||
|
return hero;
|
||||||
|
}
|
||||||
|
public int getHeroLevel() {
|
||||||
|
return heroLevel;
|
||||||
|
}
|
||||||
|
public int getLuck() {
|
||||||
|
return luck;
|
||||||
|
}
|
||||||
|
public int getMorale() {
|
||||||
|
return moral;
|
||||||
|
}
|
||||||
|
public boolean hasDivineSelection() {
|
||||||
|
return divineSelection;
|
||||||
|
}
|
||||||
|
public boolean hasPhalanx() {
|
||||||
|
return phalanx;
|
||||||
|
}
|
||||||
|
public boolean hasRam() {
|
||||||
|
return ram;
|
||||||
|
}
|
||||||
|
public boolean hasCombatExperience() {
|
||||||
|
return combatExperience;
|
||||||
|
}
|
||||||
|
public boolean hasCommander() {
|
||||||
|
return commander;
|
||||||
|
}
|
||||||
|
public boolean hasPriest() {
|
||||||
|
return priest;
|
||||||
|
}
|
||||||
|
public boolean hasCaptain() {
|
||||||
|
return captain;
|
||||||
|
}
|
||||||
|
public boolean hasAcumen() {
|
||||||
|
return acumen;
|
||||||
|
}
|
||||||
|
public boolean hasDivineSenses() {
|
||||||
|
return divineSenses;
|
||||||
|
}
|
||||||
|
public boolean hasMyrmidionAttack() {
|
||||||
|
return myrmidionAttack;
|
||||||
|
}
|
||||||
|
public boolean hasAttackBoost() {
|
||||||
|
return attackBoost;
|
||||||
|
}
|
||||||
|
public boolean hasAttackPenalty() {
|
||||||
|
return attackPenalty;
|
||||||
|
}
|
||||||
|
public boolean hasLongtermAttackBoost() {
|
||||||
|
return longtermAttackBoost;
|
||||||
|
}
|
||||||
|
public boolean hasLuxurious_residence() {
|
||||||
|
return luxuriousResidence;
|
||||||
|
}
|
||||||
|
public boolean hasAttack_ship_attack_boost_small() {
|
||||||
|
return attack_ship_attack_boost_small;
|
||||||
|
}
|
||||||
|
public boolean hasAttack_ship_attack_boost_medium() {
|
||||||
|
return attack_ship_attack_boost_medium;
|
||||||
|
}
|
||||||
|
public boolean hasAttack_ship_attack_boost_large() {
|
||||||
|
return attack_ship_attack_boost_large;
|
||||||
|
}
|
||||||
|
public boolean hasAssassinsAcumen() {
|
||||||
|
return assassinsAcumen;
|
||||||
|
}
|
||||||
|
public boolean hasRareAttackBoost() {
|
||||||
|
return rareAttackBoost;
|
||||||
|
}
|
||||||
|
public boolean hasEpicAttackBoost() {
|
||||||
|
return epicAttackBoost;
|
||||||
|
}
|
||||||
|
public int getOlympicSwordGrepolympiaSummerLevel() {
|
||||||
|
return olympicSwordGrepolympiaSummerLevel;
|
||||||
|
}
|
||||||
|
public int getOlympicSensesGrepolympiaSummerLevel() {
|
||||||
|
return olympicSensesGrepolympiaSummerLevel;
|
||||||
|
}
|
||||||
|
public boolean hasMhassionsPower4() {
|
||||||
|
return missionsPower4;
|
||||||
|
}
|
||||||
|
public boolean hasDivineBattleStrategyRare() {
|
||||||
|
return divineBattleStrategyRare;
|
||||||
|
}
|
||||||
|
public boolean hasDivineBattleStrategyEpic() {
|
||||||
|
return divineBattleStrategyEpic;
|
||||||
|
}
|
||||||
|
public boolean hasNavalBattleStrategyRare() {
|
||||||
|
return navalBattleStrategyRare;
|
||||||
|
}
|
||||||
|
public boolean hasNavalBattleStrategyEpic() {
|
||||||
|
return navalBattleStrategyEpic;
|
||||||
|
}
|
||||||
|
public boolean hasLandBattleStrategyRare() {
|
||||||
|
return landBattleStrategyRare;
|
||||||
|
}
|
||||||
|
public boolean hasLandBattleStrategyEpic() {
|
||||||
|
return landBattleStrategyEpic;
|
||||||
|
}
|
||||||
|
public int getAresRageLevel() {
|
||||||
|
return aresRageLevel;
|
||||||
|
}
|
||||||
|
public int getAresArmyFurySpent() {
|
||||||
|
return aresArmyFurySpent;
|
||||||
|
}
|
||||||
|
public int getBloodlust() {
|
||||||
|
return bloodlustFurySpent;
|
||||||
|
}
|
||||||
|
public boolean hasFairWind() {
|
||||||
|
return fairWind;
|
||||||
|
}
|
||||||
|
public boolean hasDesire() {
|
||||||
|
return desire;
|
||||||
|
}
|
||||||
|
public boolean hasStrengthOfHeroes() {
|
||||||
|
return strengthOfHeroes;
|
||||||
|
}
|
||||||
|
public boolean hasEffortOfTheHuntress() {
|
||||||
|
return effortOfTheHuntress;
|
||||||
|
}
|
||||||
|
public boolean hasStrategyBreach() {
|
||||||
|
return strategyBreach;
|
||||||
|
}
|
||||||
|
public boolean hasAllianceModifier() {
|
||||||
|
return allianceModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final List<String> POWERS = List.of("acumen", "divine_senses", "myrmidion_attack", "attack_boost",
|
||||||
|
"attack_penalty", "longterm_attack_boost", "attack_ship_attack_boost_small",
|
||||||
|
"attack_ship_attack_boost_medium", "attack_ship_attack_boost_large", "assassins_acumen",
|
||||||
|
"rare_attack_boost", "epic_attack_boost", "olympic_sword", "olympic_senses", "missions_power_4",
|
||||||
|
"divine_battle_strategy_rare", "divine_battle_strategy_epic", "naval_battle_strategy_rare",
|
||||||
|
"naval_battle_strategy_epic", "land_battle_strategy_rare", "land_battle_strategy_epic", "ares_rage",
|
||||||
|
"ares_army", "bloodlust", "fair_wind", "desire", "effort_of_the_huntress", "strength_of_heroes");
|
||||||
|
public static final List<String> RESEARCHES = List.of("divine_selection","phalanx","ram","combat_experience");
|
||||||
|
public static final List<String> COUNSELLORS = List.of("priest","commander","captain");
|
||||||
|
|
||||||
public boolean strategy_breach;
|
|
||||||
public boolean alliance_modifier;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,182 +0,0 @@
|
|||||||
package com.bernard.greposimu.model;
|
|
||||||
|
|
||||||
public class OffDefStats {
|
|
||||||
double att_hack;
|
|
||||||
double att_pierce;
|
|
||||||
double att_distance;
|
|
||||||
double ship_attack;
|
|
||||||
double def_hack;
|
|
||||||
double def_pierce;
|
|
||||||
double def_distance;
|
|
||||||
double ship_defense;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public OffDefStats(double attqCont, double attqBlan, double attqJet, double attqNav, double defCont, double defBlan,
|
|
||||||
double defJet, double defNav) {
|
|
||||||
this.att_hack = attqCont;
|
|
||||||
this.att_pierce = attqBlan;
|
|
||||||
this.att_distance = attqJet;
|
|
||||||
this.ship_attack = attqNav;
|
|
||||||
this.def_hack = defCont;
|
|
||||||
this.def_pierce = defBlan;
|
|
||||||
this.def_distance = defJet;
|
|
||||||
this.ship_defense = defNav;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final OffDefStats zero = new OffDefStats(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
||||||
|
|
||||||
public OffDefStats plus(OffDefStats other) {
|
|
||||||
return new OffDefStats(
|
|
||||||
this.att_hack + other.att_hack,
|
|
||||||
this.att_pierce + other.att_pierce,
|
|
||||||
this.att_distance + other.att_distance ,
|
|
||||||
this.ship_attack + other.ship_attack ,
|
|
||||||
this.def_hack + other.def_hack ,
|
|
||||||
this.def_pierce + other.def_pierce ,
|
|
||||||
this.def_distance + other.def_distance ,
|
|
||||||
this.ship_defense + other.ship_defense
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OffDefStats prod(OffDefStats other) {
|
|
||||||
return new OffDefStats(
|
|
||||||
this.att_hack * other.att_hack,
|
|
||||||
this.att_pierce * other.att_pierce,
|
|
||||||
this.att_distance * other.att_distance ,
|
|
||||||
this.ship_attack * other.ship_attack ,
|
|
||||||
this.def_hack * other.def_hack ,
|
|
||||||
this.def_pierce * other.def_pierce ,
|
|
||||||
this.def_distance * other.def_distance ,
|
|
||||||
this.ship_defense * other.ship_defense
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OffDefStats times(int factor) {
|
|
||||||
return new OffDefStats(
|
|
||||||
this.att_hack * factor,
|
|
||||||
this.att_pierce * factor,
|
|
||||||
this.att_distance * factor,
|
|
||||||
this.ship_attack * factor,
|
|
||||||
this.def_hack * factor,
|
|
||||||
this.def_pierce * factor,
|
|
||||||
this.def_distance * factor,
|
|
||||||
this.ship_defense * factor
|
|
||||||
);
|
|
||||||
}
|
|
||||||
public OffDefStats div(int factor) {
|
|
||||||
return new OffDefStats(
|
|
||||||
this.att_hack / factor,
|
|
||||||
this.att_pierce / factor,
|
|
||||||
this.att_distance / factor,
|
|
||||||
this.ship_attack / factor,
|
|
||||||
this.def_hack / factor,
|
|
||||||
this.def_pierce / factor,
|
|
||||||
this.def_distance / factor,
|
|
||||||
this.ship_defense / factor
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAttqCont() {
|
|
||||||
return att_hack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttqCont(double attqCont) {
|
|
||||||
this.att_hack = attqCont;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAttqBlan() {
|
|
||||||
return att_pierce;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttqBlan(double attqBlan) {
|
|
||||||
this.att_pierce = attqBlan;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAttqJet() {
|
|
||||||
return att_distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttqJet(double attqJet) {
|
|
||||||
this.att_distance = attqJet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAttqNav() {
|
|
||||||
return ship_attack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttqNav(double attqNav) {
|
|
||||||
this.ship_attack = attqNav;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDefCont() {
|
|
||||||
return def_hack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefCont(double defCont) {
|
|
||||||
this.def_hack = defCont;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDefBlan() {
|
|
||||||
return def_pierce;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefBlan(double defBlan) {
|
|
||||||
this.def_pierce = defBlan;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDefJet() {
|
|
||||||
return def_distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefJet(double defJet) {
|
|
||||||
this.def_distance = defJet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDefNav() {
|
|
||||||
return ship_defense;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefNav(double defNav) {
|
|
||||||
this.ship_defense = defNav;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAtt_hack() {
|
|
||||||
return att_hack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAtt_pierce() {
|
|
||||||
return att_pierce;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAtt_distance() {
|
|
||||||
return att_distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getShip_attack() {
|
|
||||||
return ship_attack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDef_hack() {
|
|
||||||
return def_hack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDef_pierce() {
|
|
||||||
return def_pierce;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDef_distance() {
|
|
||||||
return def_distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getShip_defense() {
|
|
||||||
return ship_defense;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static OffDefStats getZero() {
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package com.bernard.greposimu.model;
|
|
||||||
|
|
||||||
public class Unite {
|
|
||||||
|
|
||||||
String nom;
|
|
||||||
String pname;
|
|
||||||
|
|
||||||
int population;
|
|
||||||
int speed;
|
|
||||||
|
|
||||||
int butin;
|
|
||||||
OffDefStats stats;
|
|
||||||
|
|
||||||
boolean terrestre,navale,mythique;
|
|
||||||
|
|
||||||
Dieu dieu;
|
|
||||||
|
|
||||||
public Unite(String nom, String pname, int population, int speed, int butin, OffDefStats stats, boolean terrestre, boolean navale,
|
|
||||||
boolean mythique, Dieu dieu) {
|
|
||||||
this.nom = nom;
|
|
||||||
this.pname = pname;
|
|
||||||
this.population = population;
|
|
||||||
this.speed = speed;
|
|
||||||
this.butin = butin;
|
|
||||||
this.stats = stats;
|
|
||||||
this.terrestre = terrestre;
|
|
||||||
this.navale = navale;
|
|
||||||
this.mythique = mythique;
|
|
||||||
this.dieu = dieu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNom() {
|
|
||||||
return nom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPname() {
|
|
||||||
return pname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPopulation() {
|
|
||||||
return population;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSpeed() {
|
|
||||||
return speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getButin() {
|
|
||||||
return butin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OffDefStats getStats() {
|
|
||||||
return stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTerrestre() {
|
|
||||||
return terrestre;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNavale() {
|
|
||||||
return navale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMythique() {
|
|
||||||
return mythique;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dieu getDieu() {
|
|
||||||
return dieu;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Building {
|
|
||||||
public String id;
|
|
||||||
public String name;
|
|
||||||
public String controller;
|
|
||||||
public Object image;
|
|
||||||
public String description;
|
|
||||||
public Object level;
|
|
||||||
public int max_level;
|
|
||||||
public int min_level;
|
|
||||||
public Object requiredBuildings;
|
|
||||||
public String coordinates;
|
|
||||||
public Resources resources;
|
|
||||||
public int pop;
|
|
||||||
public double wood_factor;
|
|
||||||
public double stone_factor;
|
|
||||||
public double iron_factor;
|
|
||||||
public double pop_factor;
|
|
||||||
public Object hide_factor;
|
|
||||||
public int points;
|
|
||||||
public double points_factor;
|
|
||||||
public int build_time;
|
|
||||||
public double build_time_factor;
|
|
||||||
public double build_time_reduction;
|
|
||||||
public Object bolt_protected;
|
|
||||||
public List<Integer> image_levels;
|
|
||||||
public Map<String,Integer> dependencies;
|
|
||||||
public Map<Integer,Integer> fixed_building_times;
|
|
||||||
public Map<Integer, LeveledFactor> level_build_time_factors;
|
|
||||||
public boolean special;
|
|
||||||
public Object resourcesFor;
|
|
||||||
public List<Object> resourcesForLevelFixed;
|
|
||||||
public Map<Integer, Double> resourcesForLevelFactor;
|
|
||||||
public List<Object> resourcesForLevelReduceFactor;
|
|
||||||
public List<Object> offset_value_map;
|
|
||||||
public double catapult_factor;
|
|
||||||
public double catapult_power;
|
|
||||||
public double def_factor_per_level;
|
|
||||||
public double storage_factor;
|
|
||||||
public double storage_pow;
|
|
||||||
public double farm_pow;
|
|
||||||
public double farm_factor;
|
|
||||||
public double thermal_pow;
|
|
||||||
|
|
||||||
public static class LeveledFactor {
|
|
||||||
public int level;
|
|
||||||
public double factor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,307 @@
|
|||||||
|
package com.bernard.greposimu.model.game;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
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.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.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 {
|
||||||
|
|
||||||
|
Set<God> gods;
|
||||||
|
|
||||||
|
// Non-hero units
|
||||||
|
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.units = units;
|
||||||
|
this.heroes = heroes;
|
||||||
|
this.researches = researches;
|
||||||
|
this.powers = powers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<God> getGods() {
|
||||||
|
return gods;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Unit> getUnits() {
|
||||||
|
return Collections.unmodifiableSet(this.units);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unit getUnit(String id) {
|
||||||
|
return Utils.throwingGetIdentified("unit",this.units, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Hero> getHeroes() {
|
||||||
|
return Collections.unmodifiableSet(this.heroes);
|
||||||
|
}
|
||||||
|
public Hero getHero(String id) {
|
||||||
|
return Utils.throwingGetIdentified("hero",this.heroes, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Research> getResearches() {
|
||||||
|
return Collections.unmodifiableSet(this.researches);
|
||||||
|
}
|
||||||
|
public Research getResearch(String id) {
|
||||||
|
return Utils.throwingGetIdentified("research",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,37 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
|
||||||
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
public class GameData {
|
|
||||||
|
|
||||||
public Map<String,Unit> units;
|
|
||||||
|
|
||||||
public Map<String, ? extends JsonPower> powers;
|
|
||||||
|
|
||||||
public Map<String, God> gods;
|
|
||||||
|
|
||||||
public Map<String, Hero> heroes;
|
|
||||||
|
|
||||||
public Map<String, Research> researches;
|
|
||||||
|
|
||||||
public Map<String, Building> buildings;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
DumperOptions options = new DumperOptions();
|
|
||||||
options.setDefaultFlowStyle(FlowStyle.BLOCK);
|
|
||||||
options.setPrettyFlow(true);
|
|
||||||
Yaml yaml = new Yaml(options);
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
yaml.dump(this, writer);
|
|
||||||
return writer.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class God {
|
|
||||||
public String name;
|
|
||||||
public String id;
|
|
||||||
public List<Unit> units;
|
|
||||||
public List<String> powers;
|
|
||||||
public String topic;
|
|
||||||
public String description;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
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,36 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Hero {
|
|
||||||
public String id;
|
|
||||||
public String category;
|
|
||||||
public String name;
|
|
||||||
public String description;
|
|
||||||
public Map<String,DescriptionArgs> description_args;
|
|
||||||
public String short_description;
|
|
||||||
public int default_level;
|
|
||||||
public int cost;
|
|
||||||
public List<Object> award_requirements;
|
|
||||||
public boolean is_naval;
|
|
||||||
public boolean exclusive;
|
|
||||||
public boolean hidden;
|
|
||||||
public String attack_type;
|
|
||||||
public int attack;
|
|
||||||
public int def_hack;
|
|
||||||
public int def_pierce;
|
|
||||||
public int def_distance;
|
|
||||||
public int speed;
|
|
||||||
public int booty;
|
|
||||||
public List<Object> preconditions;
|
|
||||||
public int max_per_attack;
|
|
||||||
public int max_per_support;
|
|
||||||
|
|
||||||
public static class DescriptionArgs {
|
|
||||||
public double value;
|
|
||||||
public double level_mod;
|
|
||||||
public String unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
public class Image {
|
|
||||||
public String mini;
|
|
||||||
public String small;
|
|
||||||
public String medium;
|
|
||||||
public String large;
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class JsonPower {
|
|
||||||
public Object effect;
|
|
||||||
public Object name;
|
|
||||||
public Object description;
|
|
||||||
public int lifetime;
|
|
||||||
public String id;
|
|
||||||
public String short_effect;
|
|
||||||
public int favor;
|
|
||||||
public int fury_percentage_cost;
|
|
||||||
public String god_id;
|
|
||||||
public BigInteger temple_level_sum_dependency;
|
|
||||||
public List<String> targets;
|
|
||||||
public boolean only_own_towns;
|
|
||||||
public boolean boost;
|
|
||||||
public boolean is_fake_power;
|
|
||||||
public List<String> area_of_effect;
|
|
||||||
public boolean destructive;
|
|
||||||
public boolean negative;
|
|
||||||
public boolean extendible;
|
|
||||||
public String power_group;
|
|
||||||
public int power_group_level;
|
|
||||||
public List<String> seeds_to;
|
|
||||||
public Image images;
|
|
||||||
public List<String> effects;
|
|
||||||
public boolean is_valid_for_happenings;
|
|
||||||
public List<String> meta_fields;
|
|
||||||
public Object meta_defaults;
|
|
||||||
public boolean removed_on_target_loss;
|
|
||||||
public boolean needs_level;
|
|
||||||
public boolean requires_god;
|
|
||||||
public boolean ignores_democritus;
|
|
||||||
public boolean display_amount;
|
|
||||||
public boolean wasteable;
|
|
||||||
public boolean is_ritual;
|
|
||||||
public boolean recreate_on_restart;
|
|
||||||
public boolean transfer_to_casual_world;
|
|
||||||
public boolean is_onetime_power;
|
|
||||||
public boolean is_upgradable;
|
|
||||||
public boolean is_capped;
|
|
||||||
public List<String> compatible_powers;
|
|
||||||
public boolean no_lifetime;
|
|
||||||
public boolean passive;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Set<String> getTypes() {
|
|
||||||
Set<String> types = new HashSet<>();
|
|
||||||
if(name instanceof Map) {
|
|
||||||
if(((Map<String,Map<String,String>>)name).containsKey("type"))
|
|
||||||
types.addAll(((Map<String,Map<String,String>>)name).get("type").keySet());
|
|
||||||
else
|
|
||||||
name = ((Map<String,Map<String,String>>)name).get("god").get("athena");
|
|
||||||
}
|
|
||||||
if(description instanceof Map)
|
|
||||||
types.addAll(((Map<String,Map<String,String>>)description).get("type").keySet());
|
|
||||||
if(effect instanceof Map)
|
|
||||||
types.addAll(((Map<String,Map<String,String>>)effect).get("type").keySet());
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "JsonPower [effect=" + effect + ", lifetime=" + lifetime + ", id=" + id + ", name=" + name
|
|
||||||
+ ", description=" + description + ", short_effect=" + short_effect + ", favor=" + favor
|
|
||||||
+ ", fury_percentage_cost=" + fury_percentage_cost + ", god_id=" + god_id
|
|
||||||
+ ", temple_level_sum_dependency=" + temple_level_sum_dependency + ", targets=" + targets
|
|
||||||
+ ", only_own_towns=" + only_own_towns + ", boost=" + boost + ", is_fake_power=" + is_fake_power
|
|
||||||
+ ", area_of_effect=" + area_of_effect + ", destructive=" + destructive + ", negative=" + negative
|
|
||||||
+ ", extendible=" + extendible + ", power_group=" + power_group + ", power_group_level="
|
|
||||||
+ power_group_level + ", seeds_to=" + seeds_to + ", images=" + images + ", effects=" + effects
|
|
||||||
+ ", is_valid_for_happenings=" + is_valid_for_happenings + ", meta_fields=" + meta_fields
|
|
||||||
+ ", meta_defaults=" + meta_defaults + ", removed_on_target_loss=" + removed_on_target_loss
|
|
||||||
+ ", needs_level=" + needs_level + ", requires_god=" + requires_god + ", ignores_democritus="
|
|
||||||
+ ignores_democritus + ", display_amount=" + display_amount + ", wasteable=" + wasteable
|
|
||||||
+ ", is_ritual=" + is_ritual + ", recreate_on_restart=" + recreate_on_restart
|
|
||||||
+ ", transfer_to_casual_world=" + transfer_to_casual_world + ", is_onetime_power=" + is_onetime_power
|
|
||||||
+ ", is_upgradable=" + is_upgradable + ", is_capped=" + is_capped + ", compatible_powers="
|
|
||||||
+ compatible_powers + ", no_lifetime=" + no_lifetime + ", passive=" + passive + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getEffect() {
|
|
||||||
return effect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEffect(Object effect) {
|
|
||||||
this.effect = effect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(Object name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(Object description) {
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Power extends JsonPower {
|
|
||||||
public String effect;
|
|
||||||
public String name;
|
|
||||||
public String description;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Power(JsonPower power, String type) {
|
|
||||||
this.effect = (power.effect instanceof String)?(String)power.effect:((Map<String,Map<String,String>>)power.effect).get("type").get(type);
|
|
||||||
this.lifetime = power.lifetime;
|
|
||||||
this.id = power.id+"."+type;
|
|
||||||
this.name = (power.name instanceof String)?(String)power.name:((Map<String,Map<String,String>>)power.name).get("type").get(type);
|
|
||||||
this.description = (power.description instanceof String)?(String)power.description:((Map<String,Map<String,String>>)power.description).get("type").get(type);
|
|
||||||
this.short_effect = power.short_effect;
|
|
||||||
this.favor = power.favor;
|
|
||||||
this.fury_percentage_cost = power.fury_percentage_cost;
|
|
||||||
this.god_id = power.god_id;
|
|
||||||
this.temple_level_sum_dependency = power.temple_level_sum_dependency;
|
|
||||||
this.targets = power.targets;
|
|
||||||
this.only_own_towns = power.only_own_towns;
|
|
||||||
this.boost = power.boost;
|
|
||||||
this.is_fake_power = power.is_fake_power;
|
|
||||||
this.area_of_effect = power.area_of_effect;
|
|
||||||
this.destructive = power.destructive;
|
|
||||||
this.negative = power.negative;
|
|
||||||
this.extendible = power.extendible;
|
|
||||||
this.power_group = power.power_group;
|
|
||||||
this.power_group_level = power.power_group_level;
|
|
||||||
this.seeds_to = power.seeds_to;
|
|
||||||
this.images = power.images;
|
|
||||||
this.effects = power.effects;
|
|
||||||
this.is_valid_for_happenings = power.is_valid_for_happenings;
|
|
||||||
this.meta_fields = power.meta_fields;
|
|
||||||
this.meta_defaults = power.meta_defaults;
|
|
||||||
this.removed_on_target_loss = power.removed_on_target_loss;
|
|
||||||
this.needs_level = power.needs_level;
|
|
||||||
this.requires_god = power.requires_god;
|
|
||||||
this.ignores_democritus = power.ignores_democritus;
|
|
||||||
this.display_amount = power.display_amount;
|
|
||||||
this.wasteable = power.wasteable;
|
|
||||||
this.is_ritual = power.is_ritual;
|
|
||||||
this.recreate_on_restart = power.recreate_on_restart;
|
|
||||||
this.transfer_to_casual_world = power.transfer_to_casual_world;
|
|
||||||
this.is_onetime_power = power.is_onetime_power;
|
|
||||||
this.is_upgradable = power.is_upgradable;
|
|
||||||
this.is_capped = power.is_capped;
|
|
||||||
this.compatible_powers = power.compatible_powers;
|
|
||||||
this.no_lifetime = power.no_lifetime;
|
|
||||||
this.passive = power.passive;
|
|
||||||
}
|
|
||||||
public Power(JsonPower power) {
|
|
||||||
this.effect = (String) power.effect;
|
|
||||||
this.lifetime = power.lifetime;
|
|
||||||
this.id = power.id;
|
|
||||||
this.name = (String) power.name;
|
|
||||||
this.description = (String) power.description;
|
|
||||||
this.short_effect = power.short_effect;
|
|
||||||
this.favor = power.favor;
|
|
||||||
this.fury_percentage_cost = power.fury_percentage_cost;
|
|
||||||
this.god_id = power.god_id;
|
|
||||||
this.temple_level_sum_dependency = power.temple_level_sum_dependency;
|
|
||||||
this.targets = power.targets;
|
|
||||||
this.only_own_towns = power.only_own_towns;
|
|
||||||
this.boost = power.boost;
|
|
||||||
this.is_fake_power = power.is_fake_power;
|
|
||||||
this.area_of_effect = power.area_of_effect;
|
|
||||||
this.destructive = power.destructive;
|
|
||||||
this.negative = power.negative;
|
|
||||||
this.extendible = power.extendible;
|
|
||||||
this.power_group = power.power_group;
|
|
||||||
this.power_group_level = power.power_group_level;
|
|
||||||
this.seeds_to = power.seeds_to;
|
|
||||||
this.images = power.images;
|
|
||||||
this.effects = power.effects;
|
|
||||||
this.is_valid_for_happenings = power.is_valid_for_happenings;
|
|
||||||
this.meta_fields = power.meta_fields;
|
|
||||||
this.meta_defaults = power.meta_defaults;
|
|
||||||
this.removed_on_target_loss = power.removed_on_target_loss;
|
|
||||||
this.needs_level = power.needs_level;
|
|
||||||
this.requires_god = power.requires_god;
|
|
||||||
this.ignores_democritus = power.ignores_democritus;
|
|
||||||
this.display_amount = power.display_amount;
|
|
||||||
this.wasteable = power.wasteable;
|
|
||||||
this.is_ritual = power.is_ritual;
|
|
||||||
this.recreate_on_restart = power.recreate_on_restart;
|
|
||||||
this.transfer_to_casual_world = power.transfer_to_casual_world;
|
|
||||||
this.is_onetime_power = power.is_onetime_power;
|
|
||||||
this.is_upgradable = power.is_upgradable;
|
|
||||||
this.is_capped = power.is_capped;
|
|
||||||
this.compatible_powers = power.compatible_powers;
|
|
||||||
this.no_lifetime = power.no_lifetime;
|
|
||||||
this.passive = power.passive;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getEffect() {
|
|
||||||
return effect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEffect(String effect) {
|
|
||||||
this.effect = effect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Research {
|
|
||||||
public String id;
|
|
||||||
public String name;
|
|
||||||
public String description;
|
|
||||||
public List<Object> research_dependencies;
|
|
||||||
public Map<String,Integer> building_dependencies;
|
|
||||||
public Resources resources;
|
|
||||||
public int required_time;
|
|
||||||
public int research_points;
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
public class Resources {
|
|
||||||
public int wood;
|
|
||||||
public int stone;
|
|
||||||
public int iron;
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package com.bernard.greposimu.model.game;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.bernard.greposimu.model.FightStats;
|
|
||||||
|
|
||||||
public class Unit {
|
|
||||||
|
|
||||||
public String id;
|
|
||||||
public String name;
|
|
||||||
public String name_plural;
|
|
||||||
public int speed;
|
|
||||||
public int attack;
|
|
||||||
public String description;
|
|
||||||
public Resources resources;
|
|
||||||
public int favor;
|
|
||||||
public int population;
|
|
||||||
public int build_time;
|
|
||||||
public String god_id;
|
|
||||||
public List<String> research_dependencies;
|
|
||||||
public Map<String, Integer> building_dependencies;
|
|
||||||
public boolean is_naval;
|
|
||||||
public int max_per_attack;
|
|
||||||
public int max_per_support;
|
|
||||||
public String unit_function;
|
|
||||||
public String category;
|
|
||||||
public List<Object> special_abilities;
|
|
||||||
public String passive;
|
|
||||||
public boolean is_npc_unit_only;
|
|
||||||
public int def_hack;
|
|
||||||
public int def_pierce;
|
|
||||||
public int def_distance;
|
|
||||||
public int booty;
|
|
||||||
public Object infantry;
|
|
||||||
public boolean flying;
|
|
||||||
public String attack_type;
|
|
||||||
|
|
||||||
// Naval
|
|
||||||
public int defense;
|
|
||||||
public boolean transport;
|
|
||||||
public int capacity;
|
|
||||||
|
|
||||||
public FightStats getDefStats() {
|
|
||||||
return new FightStats(def_hack, def_pierce, def_distance, defense);
|
|
||||||
}
|
|
||||||
public FightStats getAttStats() {
|
|
||||||
switch(attack_type) {
|
|
||||||
case "hack":
|
|
||||||
return new FightStats(attack, 0.0, 0.0, 0.0);
|
|
||||||
case "pierce":
|
|
||||||
return new FightStats(0.0, attack, 0.0, 0.0);
|
|
||||||
case "distance":
|
|
||||||
return new FightStats(0.0, 0.0, attack, 0.0);
|
|
||||||
}
|
|
||||||
if(is_naval)
|
|
||||||
return new FightStats(0.0, 0.0, 0.0, attack);
|
|
||||||
throw new IllegalStateException("This unit has no known attack type, and is not a ship");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMythological() {
|
|
||||||
return category.equals("mythological_ground") || category.equals("mythological_naval");
|
|
||||||
}
|
|
||||||
public boolean isGround() {
|
|
||||||
return category.equals("regular_ground") || category.equals("mythological_ground");
|
|
||||||
}
|
|
||||||
public boolean isNaval() {
|
|
||||||
return category.equals("regular_naval") || category.equals("mythological_naval");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.bernard.greposimu.model.game.gods;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.util.Identified;
|
||||||
|
|
||||||
|
public class God implements Identified,Comparable<God>{
|
||||||
|
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
|
||||||
|
public God(String id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(God o) {
|
||||||
|
return this.getId().compareTo(o.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
God other = (God) obj;
|
||||||
|
return Objects.equals(id, other.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "God [id=" + id + ", name=" + name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.bernard.greposimu.model.game.powers;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.gods.God;
|
||||||
|
|
||||||
|
public class FuryPower extends GodPower {
|
||||||
|
double furyProportionCost;
|
||||||
|
|
||||||
|
public FuryPower(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, God god2, int favorCost, int templeLevelSumDependency,
|
||||||
|
double furyProportionCost) {
|
||||||
|
super(id, targets, seedsTo, shortEffect, powerGroup, powerGroupLevel, metaFields, metaDefaults, lifetime,
|
||||||
|
effects, tags, compatiblePowers, areaOfEffect, name,
|
||||||
|
effect, description, configType, nameM, effectM, descriptionM, god2, favorCost,
|
||||||
|
templeLevelSumDependency);
|
||||||
|
this.furyProportionCost = furyProportionCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getFuryProportionCost() {
|
||||||
|
return furyProportionCost;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.bernard.greposimu.model.game.powers;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.gods.God;
|
||||||
|
|
||||||
|
public class GodPower extends Power {
|
||||||
|
|
||||||
|
God god;
|
||||||
|
int favorCost;
|
||||||
|
|
||||||
|
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,
|
||||||
|
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, God god2, int favorCost, int templeLevelSumDependency) {
|
||||||
|
super(id, targets, seedsTo, shortEffect, powerGroup, powerGroupLevel, metaFields, metaDefaults, lifetime,
|
||||||
|
effects, tags, compatiblePowers, areaOfEffect, name,
|
||||||
|
effect, description, configType, nameM, effectM, descriptionM);
|
||||||
|
god = god2;
|
||||||
|
this.favorCost = favorCost;
|
||||||
|
this.templeLevelSumDependency = templeLevelSumDependency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public God getGod() {
|
||||||
|
return god;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFavorCost() {
|
||||||
|
return favorCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTempleLevelSumDependency() {
|
||||||
|
return templeLevelSumDependency;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
package com.bernard.greposimu.model.game.powers;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.util.Identified;
|
||||||
|
|
||||||
|
public class Power implements Identified {
|
||||||
|
|
||||||
|
|
||||||
|
String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The target it applies to
|
||||||
|
*/
|
||||||
|
EnumSet<Target> targets;
|
||||||
|
/**
|
||||||
|
* The targets it is seeded to. For example, attack boost is targeted to towns, and is seeded to commands.
|
||||||
|
*/
|
||||||
|
EnumSet<Target> seedsTo;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
String shortEffect;
|
||||||
|
Power.Group powerGroup;
|
||||||
|
int powerGroupLevel;
|
||||||
|
|
||||||
|
//name
|
||||||
|
Set<String> metaFields;
|
||||||
|
Map<String,Object> metaDefaults;
|
||||||
|
|
||||||
|
int lifetime;
|
||||||
|
|
||||||
|
EnumSet<Tag> tags;
|
||||||
|
EnumSet<Effect> effects;
|
||||||
|
Set<String> compatiblePowers;
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static enum Tag {
|
||||||
|
EXTENDIBLE,
|
||||||
|
DISPLAY_AMOUNT,
|
||||||
|
DESTRUCTIVE,
|
||||||
|
CAPPED,
|
||||||
|
FAKE_POWER,
|
||||||
|
ONETIME_POWER,
|
||||||
|
RITUAL,
|
||||||
|
UPGRADABLE,
|
||||||
|
VALID_FOR_HAPPENINGS,
|
||||||
|
TRANSFER_TO_CASUAL_WORLD,
|
||||||
|
WASTEABLE,
|
||||||
|
NEEDS_LEVEL,
|
||||||
|
PASSIVE,
|
||||||
|
RECREATE_ON_RESTART,
|
||||||
|
REMOVED_ON_TARGET_LOSS,
|
||||||
|
REQUIRES_GOD,
|
||||||
|
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 {
|
||||||
|
BUILDTIME,COMMANDS,FAVOR,MILITIA,RESOURCES;
|
||||||
|
}
|
||||||
|
public static enum Effect {
|
||||||
|
GROUND,NAVAL,WALL;
|
||||||
|
}
|
||||||
|
public static enum Group {
|
||||||
|
ATTACK_BOOST,ATTACK_SHIP_ATTACK_BOOST,BATTLE_POINT_BOOST,BUILDING_BOOST,DEFENSE_BOOST,FAVOR_BOOST,RESOURCE_BOOST,UNIT_BOOST;
|
||||||
|
}
|
||||||
|
public static enum Target {
|
||||||
|
ALLIANCE,COMMAND,PLAYER,SUPPORT_COMMAND,TOWN;
|
||||||
|
}
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public EnumSet<Target> getTargets() {
|
||||||
|
return targets;
|
||||||
|
}
|
||||||
|
public EnumSet<Target> getSeedsTo() {
|
||||||
|
return seedsTo;
|
||||||
|
}
|
||||||
|
public String getShortEffect() {
|
||||||
|
return shortEffect;
|
||||||
|
}
|
||||||
|
public Power.Group getPowerGroup() {
|
||||||
|
return powerGroup;
|
||||||
|
}
|
||||||
|
public int getPowerGroupLevel() {
|
||||||
|
return powerGroupLevel;
|
||||||
|
}
|
||||||
|
public Set<String> getMetaFields() {
|
||||||
|
return metaFields;
|
||||||
|
}
|
||||||
|
public Map<String, Object> getMetaDefaults() {
|
||||||
|
return metaDefaults;
|
||||||
|
}
|
||||||
|
public int getLifetime() {
|
||||||
|
return lifetime;
|
||||||
|
}
|
||||||
|
public EnumSet<Effect> getEffects() {
|
||||||
|
return effects;
|
||||||
|
}
|
||||||
|
public EnumSet<Tag> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
public Set<String> getCompatiblePowers() {
|
||||||
|
return compatiblePowers;
|
||||||
|
}
|
||||||
|
public EnumSet<AreaOfEffect> getAreaOfEffect() {
|
||||||
|
return areaOfEffect;
|
||||||
|
}
|
||||||
|
public String getName(Map<String,Object> configuration) {
|
||||||
|
return name!=null?name:(nameM.get(configuration.get(configType)));
|
||||||
|
}
|
||||||
|
public String getEffect(Map<String,Object> configuration) {
|
||||||
|
return effect!=null?effect:(effectM.get(configuration.get(configType)));
|
||||||
|
}
|
||||||
|
public String getDescription(Map<String,Object> configuration) {
|
||||||
|
return description!=null?description:(descriptionM.get(configuration.get(configType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.bernard.greposimu.model.game.queues;
|
||||||
|
|
||||||
|
public class QueueItem {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.bernard.greposimu.model.game.researches;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.util.Identified;
|
||||||
|
import com.bernard.greposimu.model.game.util.Resources;
|
||||||
|
|
||||||
|
public class Research implements Identified{
|
||||||
|
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
String description;
|
||||||
|
Set<Research> researchDependencies;
|
||||||
|
Map<String,Integer> buildingDependencies;
|
||||||
|
Resources resources;
|
||||||
|
int requiredTime;
|
||||||
|
int researchPoints;
|
||||||
|
|
||||||
|
public Research(String id, String name, String description, Set<Research> researchDependencies,
|
||||||
|
Map<String, Integer> building_dependencies, Resources resources, int required_time, int research_points) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.researchDependencies = researchDependencies;
|
||||||
|
this.buildingDependencies = building_dependencies;
|
||||||
|
this.resources = resources;
|
||||||
|
this.requiredTime = required_time;
|
||||||
|
this.researchPoints = research_points;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Research> getResearchDependencies() {
|
||||||
|
return researchDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getBuildingDependencies() {
|
||||||
|
return buildingDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Resources getResources() {
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRequiredTime() {
|
||||||
|
return requiredTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResearchpoints() {
|
||||||
|
return researchPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.bernard.greposimu.model.game.units;
|
||||||
|
|
||||||
|
public enum FightType {
|
||||||
|
PIERCE,HACK,DISTANCE;
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package com.bernard.greposimu.model.game.units;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.util.Identified;
|
||||||
|
|
||||||
|
public class Hero extends TerrestrialUnit implements Comparable<Hero>{
|
||||||
|
|
||||||
|
// Zero population
|
||||||
|
// Non mythological
|
||||||
|
// No building cost/time
|
||||||
|
// no research/building dependencies
|
||||||
|
// No flight
|
||||||
|
// Terrestrial
|
||||||
|
public Hero(String id, String name, String description, int speed,
|
||||||
|
int attack, FightType attackType, int pierceDef, int hackDef,
|
||||||
|
int distanceDef, int booty, HeroCategory category, int cost, String shortDescription, double powerBaseValue, double powerValuePerLevel) {
|
||||||
|
super(id, name, description, 0, speed, false, null, null, 0, 0,
|
||||||
|
Set.of(), Map.of(), attack, attackType, pierceDef, hackDef, distanceDef, booty, false);
|
||||||
|
this.category = category;
|
||||||
|
this.cost = cost;
|
||||||
|
this.shortDescription = shortDescription;
|
||||||
|
this.powerBaseValue = powerBaseValue;
|
||||||
|
this.powerValuePerLevel = powerValuePerLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HeroCategory category;
|
||||||
|
int cost;
|
||||||
|
|
||||||
|
String shortDescription;
|
||||||
|
|
||||||
|
double powerBaseValue;
|
||||||
|
double powerValuePerLevel;
|
||||||
|
|
||||||
|
|
||||||
|
public static enum HeroCategory implements Identified{
|
||||||
|
WAR("war"),WISDOM("wisdom");
|
||||||
|
String id;
|
||||||
|
|
||||||
|
HeroCategory(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public HeroCategory getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getCost() {
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getShortDescription() {
|
||||||
|
return shortDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public double getPowerBaseValue() {
|
||||||
|
return powerBaseValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public double getPowerValuePerLevel() {
|
||||||
|
return powerValuePerLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Hero o) {
|
||||||
|
return this.getId().compareTo(o.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Hero other = (Hero) obj;
|
||||||
|
return Objects.equals(id, other.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Hero [category=" + category + ", cost=" + cost + ", shortDescription=" + shortDescription
|
||||||
|
+ ", powerBaseValue=" + powerBaseValue + ", powerValuePerLevel=" + powerValuePerLevel + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.bernard.greposimu.model.game.units;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.gods.God;
|
||||||
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
|
import com.bernard.greposimu.model.game.util.Resources;
|
||||||
|
|
||||||
|
public class NavalUnit extends Unit {
|
||||||
|
|
||||||
|
int attack;
|
||||||
|
int defense;
|
||||||
|
|
||||||
|
public NavalUnit(String id, String name, String description, int population, int speed, boolean mythological, God god,
|
||||||
|
Resources buildCost, int favorCost, int buildTime, Set<Research> research_dependencies,
|
||||||
|
Map<String, Integer> building_dependencies,int attack, int defense) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.population = population;
|
||||||
|
this.speed = speed;
|
||||||
|
this.mythological = mythological;
|
||||||
|
this.god = god;
|
||||||
|
this.buildCost = buildCost;
|
||||||
|
this.favorCost = favorCost;
|
||||||
|
this.buildTime = buildTime;
|
||||||
|
this.research_dependencies = research_dependencies;
|
||||||
|
this.building_dependencies = building_dependencies;
|
||||||
|
this.attack = attack;
|
||||||
|
this.defense = defense;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAttack() {
|
||||||
|
return attack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDefense() {
|
||||||
|
return defense;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGround() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package com.bernard.greposimu.model.game.units;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.gods.God;
|
||||||
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
|
import com.bernard.greposimu.model.game.util.Resources;
|
||||||
|
|
||||||
|
public class TerrestrialUnit extends Unit{
|
||||||
|
|
||||||
|
int attack;
|
||||||
|
FightType attackType;
|
||||||
|
|
||||||
|
int pierceDef;
|
||||||
|
int hackDef;
|
||||||
|
int distanceDef;
|
||||||
|
int booty;
|
||||||
|
|
||||||
|
boolean flight;
|
||||||
|
|
||||||
|
public TerrestrialUnit(String id, String name, String description, int population, int speed, boolean mythological, God god,
|
||||||
|
Resources buildCost, int favorCost, int buildTime, Set<Research> research_dependencies,
|
||||||
|
Map<String, Integer> building_dependencies,int attack, FightType attackType, int pierceDef, int hackDef, int distanceDef, int booty,
|
||||||
|
boolean flight) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.population = population;
|
||||||
|
this.speed = speed;
|
||||||
|
this.mythological = mythological;
|
||||||
|
this.god = god;
|
||||||
|
this.buildCost = buildCost;
|
||||||
|
this.favorCost = favorCost;
|
||||||
|
this.buildTime = buildTime;
|
||||||
|
this.research_dependencies = research_dependencies;
|
||||||
|
this.building_dependencies = building_dependencies;
|
||||||
|
this.attack = attack;
|
||||||
|
this.attackType = attackType;
|
||||||
|
this.pierceDef = pierceDef;
|
||||||
|
this.hackDef = hackDef;
|
||||||
|
this.distanceDef = distanceDef;
|
||||||
|
this.booty = booty;
|
||||||
|
this.flight = flight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAttack() {
|
||||||
|
return attack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FightType getAttackType() {
|
||||||
|
return attackType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPierceDef() {
|
||||||
|
return pierceDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHackDef() {
|
||||||
|
return hackDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDistanceDef() {
|
||||||
|
return distanceDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBooty() {
|
||||||
|
return booty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFlight() {
|
||||||
|
return flight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGround() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.bernard.greposimu.model.game.units;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.gods.God;
|
||||||
|
import com.bernard.greposimu.model.game.researches.Research;
|
||||||
|
import com.bernard.greposimu.model.game.util.Resources;
|
||||||
|
|
||||||
|
public class TransportUnit extends NavalUnit {
|
||||||
|
int capacity;
|
||||||
|
|
||||||
|
public TransportUnit(String id, String name, String description, int population, int speed, boolean mythological,
|
||||||
|
God god, Resources buildCost, int favorCost, int buildTime, Set<Research> research_dependencies,
|
||||||
|
Map<String, Integer> building_dependencies, int attack, int defense, int capacity) {
|
||||||
|
super(id, name, description, population, speed, mythological, god, buildCost, favorCost, buildTime,
|
||||||
|
research_dependencies, building_dependencies, attack, defense);
|
||||||
|
this.capacity = capacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package com.bernard.greposimu.model.game.units;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.bernard.greposimu.model.game.gods.God;
|
||||||
|
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{
|
||||||
|
|
||||||
|
String id;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
String description;
|
||||||
|
int population;
|
||||||
|
int speed;
|
||||||
|
|
||||||
|
boolean mythological;
|
||||||
|
|
||||||
|
God god;
|
||||||
|
Resources buildCost;
|
||||||
|
int favorCost;
|
||||||
|
int buildTime;
|
||||||
|
|
||||||
|
Set<Research> research_dependencies;
|
||||||
|
Map<String, Integer> building_dependencies;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getPopulation() {
|
||||||
|
return population;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isMythological() {
|
||||||
|
return mythological;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public God getGod() {
|
||||||
|
return god;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Resources getBuildCost() {
|
||||||
|
return buildCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getFavorCost() {
|
||||||
|
return favorCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getBuildTime() {
|
||||||
|
return buildTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Set<Research> getResearch_dependencies() {
|
||||||
|
return research_dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Map<String, Integer> getBuilding_dependencies() {
|
||||||
|
return building_dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean isGround();
|
||||||
|
|
||||||
|
public boolean isNaval() {
|
||||||
|
return !this.isGround();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.bernard.greposimu.model.game.util;
|
||||||
|
|
||||||
|
public interface Identified {
|
||||||
|
|
||||||
|
public String getId();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
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+"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.bernard.greposimu.model.game.util;
|
||||||
|
|
||||||
|
public class Timestamp {
|
||||||
|
|
||||||
|
long timestamp;
|
||||||
|
|
||||||
|
public Timestamp(long timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
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,70 @@
|
|||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
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 + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
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 + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
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 + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
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 + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.bernard.greposimu.source;
|
||||||
|
|
||||||
|
public class SourcedMilitiaTimes {
|
||||||
|
long start;
|
||||||
|
long end;
|
||||||
|
|
||||||
|
public long getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
public long getEnd() {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
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 + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
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 + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
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 + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
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,3 +1,4 @@
|
|||||||
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/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
missions_power_4.missions_dionysia.disabled.png
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
missions_power_4.missions_dionysia.hover.png
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
missions_power_4.missions_dionysia.png
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
// ==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,6 +16,7 @@ body {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre th:text="${content}"></pre>
|
<pre th:text="${content}"></pre>
|
||||||
|
<main th:utext="${raw}"></main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@@ -85,23 +85,100 @@ span.fixed50px {
|
|||||||
border: 0px;
|
border: 0px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
.container {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.formcol {
|
||||||
|
flex: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<form action="#" th:object="${defCtx}" method="post" id="simuform" >
|
<form action="#" th:object="${ctx}" method="post" id="simuform" >
|
||||||
|
<div class="columns">
|
||||||
|
<fieldset class="formcol">
|
||||||
|
<legend>Attaque</legend>
|
||||||
<fieldset id="herosFields">
|
<fieldset id="herosFields">
|
||||||
<legend>Héros</legend>
|
<legend>Héros</legend>
|
||||||
<select name="heros" id="heros" th:field="*{hero}">
|
<select name="offHeros" id="offHeros" th:field="*{offHero}">
|
||||||
|
<option value="none">Aucun</option>
|
||||||
|
<option th:each="hero : ${heroes}" th:value="${hero.id}"><span th:text="${hero.name}"/></option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="offHeroLevelSlider">Niveau du héros: (<span id="offHeroLevelSliderInfo" class="fixed50px"></span>)</label>
|
||||||
|
<input type="range" min="1" max="20" value="1" class="slider" id="offHeroLevelSlider" th:field="*{offHeroLevel}">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var offHeroSlider = document.getElementById("offHeroLevelSlider");
|
||||||
|
var offHeroOutput = document.getElementById("offHeroLevelSliderInfo");
|
||||||
|
offHeroOutput.innerHTML = "lvl. "+offHeroSlider.value;
|
||||||
|
// Update the current slider value (each time you drag the slider handle)
|
||||||
|
offHeroSlider.oninput = function() {
|
||||||
|
offHeroOutput.innerHTML = "lvl. "+this.value;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset id="unitesFS">
|
||||||
|
<legend>Unités</legend>
|
||||||
|
<div th:each="unite : ${defUnits}" class="container">
|
||||||
|
<img class="squareImage" th:for="'unite-'+${unite.id}" th:src="@{/images/units/{uname}.png(uname=${unite.id})}"/>
|
||||||
|
<br/>
|
||||||
|
<input type="number" class="squareNumber" th:id="'unite-'+${unite.id}" th:field="*{offUnits[__${unite.id}__]}"/>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Pouvoirs</legend>
|
||||||
|
<div th:each="power : ${offPowers}" class="container">
|
||||||
|
<img class="squareImage" th:for="'power-'+${power}" th:src="@{/images/powers/{pname}.png(pname=${power})}"/>
|
||||||
|
<input type="checkbox" th:id="'power-'+${power}" th:field="*{defPowersAsMap[__${power}__]}" th:value="true"/>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Recherches</legend>
|
||||||
|
<div th:each="research : ${offResearches}" class="container">
|
||||||
|
<img class="squareImage" th:for="'research-'+${research}" th:src="@{/images/researches/{rname}.png(rname=${research})}"/>
|
||||||
|
<input type="checkbox" th:id="'research-'+${research}" th:field="*{defResearchesAsMap[__${research}__]}" th:value="true"/>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Conseillers</legend>
|
||||||
|
<div th:each="counsellor : ${offCounsellors}" class="container">
|
||||||
|
<img class="squareImage" th:for="'counsellor-'+${counsellor}" th:src="@{/images/counsellors/{cname}.png(cname=${counsellor})}"/>
|
||||||
|
<input type="checkbox" th:id="'counsellor-'+${counsellor}" th:field="*{defCounsellorsAsMap[__${counsellor}__]}" th:value="true"/>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Paramètres</legend>
|
||||||
|
|
||||||
|
<label for="moralInput">Moral:</label>
|
||||||
|
<input type="number" min="0" max="100" value="1" id="moralInput" th:field="*{moral}">
|
||||||
|
<label for="luckInput">Chance:</label>
|
||||||
|
<input type="number" min="-20" max="20" value="1" id="luckInput" th:field="*{luck}">
|
||||||
|
<label for="breachInput">Percée:</label>
|
||||||
|
<input type="checkbox" id="breachInput" th:field="*{strategyBreach}">
|
||||||
|
<label for="allianceInput">Alliance:</label>
|
||||||
|
<input type="checkbox" id="allianceInput" th:field="*{allianceModifier}">
|
||||||
|
</fieldset>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="formcol">
|
||||||
|
<legend>Défense</legend>
|
||||||
|
<fieldset id="herosFields">
|
||||||
|
<legend>Héros</legend>
|
||||||
|
<select name="defHeros" id="defHeros" th:field="*{defHero}">
|
||||||
<option value="none">Aucun</option>
|
<option value="none">Aucun</option>
|
||||||
<option th:each="hero : ${heroes}" th:value="${hero.id}"><span th:text="${hero.name}"/></option>
|
<option th:each="hero : ${heroes}" th:value="${hero.id}"><span th:text="${hero.name}"/></option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="heroLevelSlider">Niveau du héros: (<span id="heroLevelSliderInfo" class="fixed50px"></span>)</label>
|
<label for="heroLevelSlider">Niveau du héros: (<span id="heroLevelSliderInfo" class="fixed50px"></span>)</label>
|
||||||
<input type="range" min="1" max="20" value="1" class="slider" id="heroLevelSlider" th:field="*{heroLevel}">
|
<input type="range" min="1" max="20" value="1" class="slider" id="heroLevelSlider" th:field="*{defHeroLevel}">
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var heroSlider = document.getElementById("heroLevelSlider");
|
var heroSlider = document.getElementById("heroLevelSlider");
|
||||||
@@ -113,16 +190,13 @@ span.fixed50px {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset id="unitesFS">
|
||||||
<legend>Unités</legend>
|
<legend>Unités</legend>
|
||||||
<table cellspacing="0" cellpadding="0">
|
<div th:each="unite : ${defUnits}" class="container">
|
||||||
<tr>
|
|
||||||
<td th:each="unite : ${defUnits}" class="squareContainer">
|
|
||||||
<img class="squareImage" th:for="'unite-'+${unite.id}" th:src="@{/images/units/{uname}.png(uname=${unite.id})}"/>
|
<img class="squareImage" th:for="'unite-'+${unite.id}" th:src="@{/images/units/{uname}.png(uname=${unite.id})}"/>
|
||||||
<input type="number" class="squareNumber" th:id="'unite-'+${unite.id}" th:field="*{units[__${unite.id}__]}"/>
|
<br/>
|
||||||
</td>
|
<input type="number" class="squareNumber" th:id="'unite-'+${unite.id}" th:field="*{defUnits[__${unite.id}__]}"/>
|
||||||
</tr>
|
</div>
|
||||||
</table>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Batiments</legend>
|
<legend>Batiments</legend>
|
||||||
@@ -144,43 +218,32 @@ span.fixed50px {
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Pouvoirs</legend>
|
<legend>Pouvoirs</legend>
|
||||||
<table cellspacing="0" cellpadding="0">
|
<div th:each="power : ${defPowers}" class="container">
|
||||||
<tr>
|
<img class="squareImage" th:for="'power-'+${power}" th:src="@{/images/powers/{pname}.png(pname=${power})}"/>
|
||||||
<td th:each="power : ${defPowers}" class="squareContainer">
|
<input type="checkbox" th:id="'power-'+${power}" th:field="*{defPowersAsMap[__${power}__]}" th:value="true"/>
|
||||||
<img class="squareImage" th:for="'power-'+${power.id}" th:src="@{/images/powers/{pname}.png(pname=${power.id})}"/>
|
</div>
|
||||||
<input type="checkbox" th:id="'power-'+${power.id}" th:field="*{powersAsMap[__${power.id}__]}" th:value="true"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Recherches</legend>
|
<legend>Recherches</legend>
|
||||||
<table cellspacing="0" cellpadding="0">
|
<div th:each="research : ${defResearches}" class="container">
|
||||||
<tr>
|
<img class="squareImage" th:for="'research-'+${research}" th:src="@{/images/researches/{rname}.png(rname=${research})}"/>
|
||||||
<td th:each="research : ${defResearches}" class="squareContainer">
|
<input type="checkbox" th:id="'research-'+${research}" th:field="*{defResearchesAsMap[__${research}__]}" th:value="true"/>
|
||||||
<img class="squareImage" th:for="'research-'+${research.id}" th:src="@{/images/researches/{rname}.png(rname=${research.id})}"/>
|
</div>
|
||||||
<input type="checkbox" th:id="'research-'+${research.id}" th:field="*{researchesAsMap[__${research.id}__]}" th:value="true"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Conseillers</legend>
|
<legend>Conseillers</legend>
|
||||||
<table cellspacing="0" cellpadding="0">
|
<div th:each="counsellor : ${defCounsellors}" class="container">
|
||||||
<tr>
|
|
||||||
<td th:each="counsellor : ${defCounsellors}" class="squareContainer">
|
|
||||||
<img class="squareImage" th:for="'counsellor-'+${counsellor}" th:src="@{/images/counsellors/{cname}.png(cname=${counsellor})}"/>
|
<img class="squareImage" th:for="'counsellor-'+${counsellor}" th:src="@{/images/counsellors/{cname}.png(cname=${counsellor})}"/>
|
||||||
<input type="checkbox" th:id="'counsellor-'+${counsellor}" th:field="*{counsellorsAsMap[__${counsellor}__]}" th:value="true"/>
|
<input type="checkbox" th:id="'counsellor-'+${counsellor}" th:field="*{defCounsellorsAsMap[__${counsellor}__]}" th:value="true"/>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Bonus de jeu</legend>
|
<legend>Bonus de jeu</legend>
|
||||||
<label for="nightBonus">Bonus de nuit :</label>
|
<label for="nightBonus">Bonus de nuit :</label>
|
||||||
<input type="checkbox" id="nightBonus" th:field="*{nightBonus}" th:value="true"/><br/>
|
<input type="checkbox" id="nightBonus" th:field="*{nightBonus}" th:value="true"/><br/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
<button type="button" id="compute">Calculer</button>
|
<button type="button" id="compute">Calculer</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,92 @@
|
|||||||
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("Reading game data");
|
// System.out.println(GrepoSimu.makeGameData());
|
||||||
// System.out.println(GrepoSimu.readGameData());
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
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"
|
||||||
Reference in New Issue
Block a user