Command By Comments: Code (09. April)

Hier geht es um technische Fragen zu Fantasya.
Antworten
Benutzeravatar
nemo
Heerführer
Beiträge: 232
Registriert: Mi 25. Feb 2015, 12:06

Command By Comments: Code (09. April)

Beitrag von nemo » Sa 25. Feb 2017, 13:05

Stand: 09.04.2017
Änderungen: Viele Viele Viele.
Bitte lest
Vollständiger Changelog: http://forum.fantasya-pbem.de/viewtopic ... =193#p1281

???
[Bitte in diesem Thread nicht antworten : Ich gehe davon aus, dass der Platz für weitere Teile gebraucht werden wird und dann würden Antworten den Zusammenhang auseinander reißen]
/???
Dokumentation-Thread:
http://forum.fantasya-pbem.de/viewtopic.php?f=7&t=193
Feedback-Thread:
http://forum.fantasya-pbem.de/viewtopic.php?f=7&t=191

Code: Alles auswählen

import magellan.client.*;
import magellan.client.extern.*;
import magellan.library.*;
import magellan.library.rules.*;
import magellan.plugin.extendedcommands.*;
/*****************************************/

////////{ CbC: Command By Comments /////////
//09.03.2017//

boolean silberverteilung = true;
boolean luxuseinzug = false;

//{ Inhalt:
//{0. Grundfestlegungen 
// 0.1 Konstanten für Meta-Befehle (die Tags)
// 0.2 Priorisierung Baumaterialverteilung von Materiallagern
// 0.3 Tabelle Gebäudeunterhalte
// 0.4 Unbedingte Auslösung von subMetas
// 0.5 Schutz vor +next
//} 1. Wurzelimplementierung (Parteikontainer)

//{ 2. Implementierungen der Metas
//{ 2.1 Getimed
// 2.1.1 +magbest [<x>] [<y>] [,<Kommentar>]
// 2.1.1a +anlernen <Skill> <n> <Skill1> <n1> <Skill2> <n2> ... [- <Folgebefehl>]
// 2.1.1b +segeln <Befehl> [: <Befehl1> : <Befehl2> ...]
// 2.1.2 +next<n> <order> [: <order1>:<order2>...]
// 2.1.2a +route (x, y, z) (befehl) [; (Kommentar)]
// 2.1.3 +rotate<n> <Befehl>
// 2.1.4 +rotaL <Skill> <Skill1> <Skill2> ...
//} 2.1.6 +rotaP <Item> <Item1> <Item2> ...
//{ 2.2 Hart
// 2.2.1 +forst [<percent>] [<AltBef>]
// 2.2.2 +herde <tier> [<percent>] [<AltBef>]
// 2.2.3 +unterhalte [<AltBef>]
// 2.2.4 +silreg [<minSilber>] [<AltBef>]
// 2.2.5 +treibe [<silber>] [<AltBef>]
//} 2.2.6 +killer [<AltBef>]
//{ 2.3 Interaktiv
//} 2.3.1 study-Komplex
//{ 2.4 Weich
// 2.4.1 +rek [<n>] [, <m>]
// 2.4.3 +bewache
//} 2.4.3a +gib
// 2.4.3b Lager- und Reservierung-Metas
//}

//{ 3. Skripte für Metas
//{ 3.1 Getimed
// 3.1.1 +magbest [<x>] [<y>] [,<Kommentar>]
// 3.1.1a +anlernen <Skill> <n> <Skill1> <n1> <Skill2> <n2> ... [- <Folgebefehl>]
// 3.1.1b +segeln <Befehl> [: <Befehl1> : <Befehl2> ...]
// 3.1.2 +next<n> <Befehl>
// 3.1.2a +route (x, y, z) (befehl) [; (Kommentar)]
// 3.1.3 +rotate<n> <Befehl>
// 3.1.4 +rotaL <Skill> <Skill1> <Skill2> ...
//} 3.1.6 +rotaP <Item> <Item1> <Item2> ...
//{ 3.2 Hart
// 3.2.1 +forst [<percent>] [<AltBef>]
// 3.2.2 +herde <tier> [<percent>] [<AltBef>]
// 3.2.3 +unterhalte [<AltBef>]
// 3.2.4 +silreg [<minSilber>] [<AltBef>]
// 3.2.5 +treibe [<silber>] [<AltBef>]
//} 3.2.6 +killer [<AltBef>]
//{ 3.3 Interaktiv
//} 3.3.1 study-Komplex
//{ 3.4 Weich
// 3.4.1 +rek [<n>] [,<m>]
// 3.4.3 +bewache
// 3.4.3a +gib
//} 3.4.3b lager- und Reservierungsmetas
//}
//{ 4. Allgemeine Hilfsfunktionen
// 4.1 setOrderPreserveComments(Unit,String)
//     (ersetzt helper.setOrder(Unit,String), wenn Kommentare erhalten bleiben sollen)
// 4.2 int getResourceAmount(Region,String)
//     (erleichtert das Finden von ...allem)
// 4.3 ArrayList unitsInRegionWithOrder(Region,String)
//     (Listet Einheiten in der Region mit einem bestimmten String im Befehlsblock)
// 4.4 ArrayList unitsInRegionWithOrder(Region,String)
//     (Listet die bekannten Befehle von Einheiten in der Region)
// 4.5 ArrayList splitToArrayList(String,String)
//     (mimiks String.split(String) und erlaubt Zugriff über Index)
// 4.6 ArrayList splitToArrayList(String,String,int)
//     (mimiks String.split(String,int) und erlaubt Zugriff über Index)
// 4.7 int lerntage(Unit,String)
//     (Gibt die Lerntage von Unit für das Talent String aus)
// 4.8 int modifiedLerntage(Unit,String)
//     (Wie 4.7, aber mit Update nach Befehlen)
// 4.9 ArrayList longOrders
// 4.9.a boolean isLongOrder(String);
//}
//}
//}
/**********************************************/

/**********************************************/
////////////// 0. Grundfestlegungen ////////////
/**********************************************/

//{ 0.1 Konstanten für Meta-Befehle (die Tags)
String com = "//";
String com2 = ";";
String me = "// +";
String me2 = ";; +";
String me3 = ",, +";
ArrayList starters = new ArrayList();
starters.add(me);
starters.add(me2);
//}

//{ 0.2 Priorisierung BauMatVertlg /////////
ArrayList mLagerBedient = new ArrayList();
mLagerBedient.add(me+"nkw"); // Waffenbau
mLagerBedient.add(me+"bogner"); // Bogenbau
mLagerBedient.add(me+"ruestung"); // Ruestungsbau
mLagerBedient.add(me+"wagner"); // Wagenbau
mLagerBedient.add(me+"reeder"); // Schiffbau
//}

//{ 0.3 Gebäude-Unterhalte
HashMap buildingMaintenances = new HashMap();
buildingMaintenances.put("Bergwerk", 100);
buildingMaintenances.put("Hafen", 100);
buildingMaintenances.put("Holzfällerhütte", 50);
buildingMaintenances.put("Leuchtturm", 100);
buildingMaintenances.put("Mine", 50);
buildingMaintenances.put("Monument", 100);
buildingMaintenances.put("Sägewerk", 100);
buildingMaintenances.put("Sattlerei", 100);
buildingMaintenances.put("Schiffswerft", 100);
buildingMaintenances.put("Schmiede", 100);
buildingMaintenances.put("Seehafen", 300);
buildingMaintenances.put("Steg", 30);
buildingMaintenances.put("Steinbruch", 100);
buildingMaintenances.put("Steingrube", 50);
buildingMaintenances.put("Steuerturm", 50);
buildingMaintenances.put("Werkstatt", 100);
//}

//{ 0.4 Unbedingte Auslösung von subMetas
ArrayList unconditional = new ArrayList();
unconditional.add("magbest");
unconditional.add("rotaL");
unconditional.add("rotaP");
unconditional.add("rek");
//}

//{ 0.5 Schutz vor +next
ArrayList nextVerschont = new ArrayList();
nextVerschont.add(me+"magbest");
nextVerschont.add(me+"route");
nextVerschont.add(me+"bewache");
nextVerschont.add(me+"segeln");
//}

/******************************************/
////////// Wurzelimplementierung //////////
/*****************************************/

cbc_Alpha(String factionID){
 for(Region region : world.regions().values()){
  implementMetas_cbc_Alpha(region, factionID);
 }// /for(Region
}// /cbc_Alpha(String)

/*****************************************/
//// 2. Implementierung der Metas /////////
/*****************************************/

implementMetas_cbc_Alpha(Region region, String factionID){
 // Metas in der Region suchen und auslösen
 // (erst // +, dann ;; +)
 for(String starter : starters){
  ArrayList thisMeta = new ArrayList();
 //{ 2.1 Getimete Metas
  // 2.1.1 +magbest
  thisMeta = unitsInRegionWithOrder(region, starter+"magbest");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"magbest")){ex=true;}// /if(o
    }// /for(String
    if(ex){magbest(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thismeta
  // /magbest

  // 2.1.1a +anlernen
  thisMeta = unitsInRegionWithOrder(region, starter+"anlernen");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"anlernen")){ex = true;}// /if(o
    }// /for(String
    if (ex){anlernen(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /anlernen

  // 2.1.1b +segeln
  thisMeta = unitsInRegionWithOrder(region, starter+"segeln");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"segeln")){ex = true;}// /if(o
    }// /for(String
    if (ex){segeln(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /segeln

  // 2.1.2 +next
  thisMeta = unitsInRegionWithOrder(region, starter+"next");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if(o.trim().startsWith(starter+"next")){ex = true;}// /if(o
    }// /for(String	
    if(ex){next(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!thisMeta
  // /next

  // 2.1.2a +route
  if (starter.equals(me)){
   thisMeta = unitsInRegionWithOrder(region, me+"route");
   if (!(thisMeta.isEmpty())){
    for (Unit unit : thisMeta){route(unit);}// /for(Unit
   }// /if(!(thisMeta
  }// /if(starter
  // /route

  // 2.1.3 +rotate
  thisMeta = unitsInRegionWithOrder(region, starter+"rotate");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if(o.trim().startsWith(starter+"rotate")){ex = true;}// /if(o
    }// /for(String	
    if(ex){rotate(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /rotate
 
  // 2.1.4 +rotaL
  thisMeta = unitsInRegionWithOrder(region, starter+"rotaL");
  if (!(thisMeta.isEmpty())){
    for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if(o.trim().startsWith(starter+"rotaL")){ex = true;}// /if(o
    }// /for(String	
    if(ex){rotaL(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /rotaL
 
  // 2.1.6 +rotaP
  thisMeta = unitsInRegionWithOrder(region, starter+"rotaP");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"rotaP")){ex=true;}// /if(o
    }// /for(String
    if (ex){rotaP(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /rotaP
//}
 
 //{ 2.2 Harte Metas
  // 2.2.1 ;; +forst n <Altbef>
  thisMeta = unitsInRegionWithOrder(region, starter+"forst");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    ArrayList args = new ArrayList();
    boolean ex = false;
    for(String order : unit.getOrders()){
     if(order.trim().startsWith(starter+"forst")){
      args = splitToArrayList(order.substring(9).trim(), " ", 2);
      ex = true;
     }// /if(order
    }// /for(String)
    if(ex){forst(unit, args);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /forst
 
  // 2.2.2 +herde
  thisMeta = unitsInRegionWithOrder(region, starter+"herde");
  if(!(thisMeta.isEmpty())){
   for(Unit unit: thisMeta){
    boolean ex = false;
    for(String order: unit.getOrders()){
     if(order.trim().startsWith(starter+"herde")){ex = true;}// /if(order
    }// /for(String
    if(ex){monoHerde(unit, starter);}
   }// for(Unit
  thisMeta.clear();
  }// /if(!(thisMeta
  // /herde
 
  // 2.2.3 +unterhalte <AltBef> && ;; +unterhalte <AltBef>
  //(subMetas für den Alternativbefehl)
  thisMeta = unitsInRegionWithOrder(region, starter+"unterhalte");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    String altBef = "LERNE Unterhaltung";
    boolean ex = false;
    for (String order : unit.getOrders()){
     if(order.trim().startsWith(starter+"unterhalte")){
      ex = true;
      if (order.length() > 15){altBef = order.substring(15).trim();}
     }// /id(order
	}// /for(String
    if (ex){unterhalte(unit, altBef);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /unterhalte
 
  // 2.2.4 +silreg <MinSilber> <altBef> & ;; +silreg <altBef>
  //(subMetas für den Alternativbefehl)
  thisMeta = unitsInRegionWithOrder(region, starter+"silreg");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    boolean ex = false;
    for (String order : unit.getOrders()){
     if (order.trim().startsWith(starter+"silreg")){ex = true;}// /if(order
    }// /for(String
    if(ex){silReg(unit, starter);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /silreg
 
  // 2.2.5 +treibe <altBef>
  //(SubMetas für Alternativbefehl)
  thisMeta = unitsInRegionWithOrder(region, starter+"treibe");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    boolean ex = false;
    for (String order : unit.getOrders()){
     if (order.trim().startsWith(starter+"treibe")){ex = true;}// /if(order
 	if(ex){treibe(unit, starter);}// /if(ex
    }// /for(String
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
 
  // 2.2.6 +killer [<AltBef>]
  thisMeta = unitsInRegionWithOrder(region, starter+"killer");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"killer")){ex = true;}// /if(o
    }// /for(String
    if (ex){killer(unit, starter);}// /if(ex
   }// /for(Unit
  }// /if(!(thisMeta
  // /killer
 //}
 
 //{ 2.3 Interaktive Metas
  // 2.3.1 +lerne<p> <skill> [<level> [<AltBef>]]  & +lehre<p> <skill1> [<skill1> <skill2>][, <AltBef>]
  if (starter.equals(me)){studyComplex(region);}
 //}
 
 //{ 2.4 Weiche Metas
 for (Unit unit : region.units()){
 // 2.4.1 +rek [<n>] [, <m>]
  if (unit.getOrders().toString().contains(starter+"rek")){
   boolean ex = false;
   for (String o : unit.getOrders()){
    if (o.startsWith(starter+"rek")){ex=true;}
   }// /for(String
   if (ex){regulator(unit, region, starter);}
  }// /if(unit.getOrders
 }
 // /rek
 for (Unit unit : region.units()){
  if (starter.equals(me)){
   // 2.4.3 +bewache
   autarn(unit);
 // /bewache
  }// /if(starter
 }// /for(Unit
 
   // 2.4.3a +gib
  thisMeta = unitsInRegionWithOrder(region, starter+"gib");
  if (!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    boolean ex = false;
    for(String order : unit.getOrders()){
     if(order.trim().startsWith(starter+"gib")){ex=true;}// /if(order
    }// /for(String
    if(ex){gib(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMEta
  // /gib
}// /for(String starter

//}
 for (Unit unit : region.units()){
  // 2.4.3b +lager und Reservierungen
   if(unit.getOrders().toString().contains(me+"lager") && silberverteilung){lager(unit);}
   if(unit.getOrders().toString().contains(me+"sLag")){sLager(unit);}
   if(unit.getOrders().toString().contains(me+"nLag")){nLager(unit);}
   if(unit.getOrders().toString().contains(me+"fLag")){fLager(unit);}
   if(unit.getOrders().toString().contains(me+"mLag")){mLager(unit);}
   if(unit.getOrders().toString().contains(me+"rLag")){rLager(unit);}
   if(unit.getOrders().toString().contains(me+"tLag")){tLager(unit);}
   if(unit.getOrders().toString().contains("HANDEL") && luxuseinzug){handel(unit);}
   if(unit.getOrders().toString().contains(me+"hLag")){handel(unit);}
  // /lager und Reservierungen
 }
 
  // 2.4.4 +segelnII : Ozean
  thisMeta = unitsInRegionWithOrder(region, starter+"segeln");
  if (region.getType().toString().equals("Ozean") && !(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"segeln")){ex = true;}// /if(o
    }// /for(String
    if (ex){segeln(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /segeln



}// /implementMetas_cbc_Alpha(Region,String)

/*****************************************/
/////////// 3. Skripte für Metas //////////
/*****************************************/
//{ 3.1 Getimte Metas
 // 3.1.1 +magbest [<x>][<y>][, <Kommentar>]
	// x,y € N
	// x>0 => bestätigt; x--
	// x == 0 => ~bestätigt
	// y>0 && x==0 => x=y
magbest(Unit unit, String starter){
// Variabeln:
 int noch = 1;
 int setz = 0;
 String comment = "";
 boolean rewrite = false; // nötig, wenn x != 0
 ArrayList you = new ArrayList();
// Parameter raussuchen:
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"magbest")){
   you = splitToArrayList(o, " ", 5);
   if (you.size() > 2){
    try {
     noch = Integer.parseInt(you.get(2))-1;
     rewrite = true;
     try {
      setz = Integer.parseInt(you.get(3));
     }// /try
     catch(IndexOutOfBoundsException oob){setz = 0;}// /catch(oob
     catch (NumberFormatException nfe2){setz = 0;}// /catch(nfe2 == setz erzwingen
    }// /try
    catch (NumberFormatException nfe){noch = 1;}// /catch(nfe == noch erzwingen
    if (o.contains(",")){comment = o.substring(o.indexOf(",")+1).trim();}// /if(o.contains
   }// /if(you
  }// /if(o
 }// /for(String
// (nicht) bestätigen
 if (noch > 0){unit.setOrdersConfirmed(true);}// /if(noch
 else{ // == if (noch <= 0
  unit.setOrdersConfirmed(false);
  noch = setz; // also wieder hoch, oder auf null
 }// /else <- if(noch>0
// neuschreiben
 if (rewrite){
  you.clear(); // recycling
  // Kommentar einbauen
  if (!(unit.isOrdersConfirmed()) && comment != ""){you.add(comment);}
  // restliche Zeilen einsammeln
  for (String o : unit.getOrders()){
   if (!(o.trim().startsWith(starter+"magbest"))){you.add(o);}// /if(!(o
  }// /for(String
  // clearing
  helper.setOrder(unit, "");
  // neue magbest-Zeile
  String newbest = "";
  if (noch > 0){
   newbest = starter+"magbest "+noch.toString()+" "+setz.toString();
   if (comment != ""){newbest = newbest+" ,"+comment;}
  }// /if(noch
  helper.addOrder(unit, newbest);
  for (String o : you){helper.addOrder(unit, o);}
 }// /if(rewrite
}// /magbest(Unit,String)

 //{ +anlernen
 // 3.1.1a +anlernen <Skill> <n> <Skill1> <n1> <Skill2> <n2> ... [: <Folgebefehl>]
anlernen(Unit unit, String starter){
 // Variabeln:
 String learnOrder = ""; // "LERNE" oder "falschgeschrieben"
 String skills = "";
 String follow = ""; // Folgebefehl
 boolean spell = true;
 HashMap goalsOfSkills = new HashMap();
 // Argumente extrahieren
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"anlernen")){
   skills = o.substring(12).trim();
  }// /if(o
  if (skills.contains("-")){
   follow = skills.substring(skills.indexOf("-")+1).trim();
   skills = skills.substring(0, skills.indexOf("-")).trim();
  }// /if(skills
 }// /for(String
 // Talente an Ziellevel mappen:
 int i = 0;
 while (i < splitToArrayList(skills, " ").size()){
  String skill = splitToArrayList(skills, " ").get(i);
  int lvl = 1;
  try {
   lvl = Integer.parseInt(splitToArrayList(skills, " ").get(i+1));
   i++;
  }// /try
  catch (NumberFormatException nfe){lvl=1;}// /catch(nfe
  catch (IndexOutOfBoundsException oob){lvl=1;}// /catch(oob
  goalsOfSkills.put(skill, lvl);
  i++;
 }// /while(i
 // Schreibweisen und tatsächliche Levels prüfen:
 for (String skill : goalsOfSkills.keySet()){
  if(isImplementedSkill(skill)){
   if (helper.getLevel(unit, skillUmlaute(skill)) < goalsOfSkills.get(skill) && !(learnOrder.contains("LERNE"))){learnOrder = learnOrder+":LERNE "+skill;}// /if(helper
  }// /if(isImplementedSkill
  else {learnOrder = learnOrder+":CbC-Warnung: Talent "+skill+" falsch geschrieben oder nicht implementiert";}// /else <- if(isImplementedSkill
 }// /for(String
 // Schreibarbeit
 if (learnOrder.contains(":")){
  unit.setOrdersConfirmed(true);
  setOrderPreserveComments(unit, "");
  for (String doNow : learnOrder.split(":")){
   helper.addOrder(unit, doNow);
  }// /for(String
  helper.updateUnit(unit);
  if (unit.getOrders().toString().contains("CbC-Warnung")){unit.setOrdersConfirmed(false);}// /if(unit
 }// /if(learnOrder
 else {
  setOrderPreserveComments(unit, "; fertig gelernt");
  for (String doNow : follow.split(":")){
   if (doNow.trim().startsWith(me2)){helper.addOrder(unit, com+" "+doNow.trim().substring(doNow.trim().indexOf(" ")));}// /if(doNOw
   else {helper.addOrder(unit, doNow.trim());}// /else
  }// /for(String
  helper.updateUnit(unit);
 }// /else <- if(learnOrder
}// /anlernen(Unit,String)
 boolean isImplementedSkill(String skill){
 // Kontrolliert bei +lernen, +anlernen, ob <skill> richtig geschrieben wurde
  if (skillList.contains(skillUmlaute(skill))){
   return true;
  }// /if(skillList.contains
  else{
   return false;
  }// /else
}// /boolean isImplementedSkill(String)

 String skillList = "Armbrustschießen Ausdauer ausdauer Bergbau Bogenbau Bogenschießen Burgenbau Handel Hiebwaffen Holzfällen Katapultbedienung Magie Pferdedressur Reiten Rüstungsbau Schiffbau Segeln Speerkampf Spionage Steinbau Steuereintreiben Straßenbau Taktik Tarnung Unterhaltung Waffenbau Wagenbau Wahrnehmung";
 String skillListMitUmlaute = "Armbrustschießen Bogenschießen Holzfällen Rüstungsbau Straßenbau Armbrustschiessen Bogenschiessen Holzfaellen Ruestungsbau Strassenbau";
 String skillListOhneUmlaute = "Armbrustschiessen Bogenschiessen Holzfaellen Ruestungsbau Strassenbau Armbrustschießen Bogenschießen Holzfällen Rüstungsbau Straßenbau";

 String skillUmlaute(String skill){
 // um die Umlautumschreibung des Servers zu umgehen (Ein kleiner Kippschalter)
  if(skillListMitUmlaute.contains(skill)){
   return splitToArrayList(skillListOhneUmlaute, " ").get(splitToArrayList(skillListMitUmlaute, " ").indexOf(skill));}
  if(skillListOhneUmlaute.contains(skill)){
   return splitToArrayList(skillListMitUmlaute, " ").get(splitToArrayList(skillListOhneUmlaute, " ").indexOf(skill));}
  else {return skill;}
 }// /String skillUmlaute(String)
 //} /anlernen

// 3.1.1b // +segeln
segeln(Unit unit, String starter){
 helper.addOrder(unit, unit.getRegion().toString());
 helper.updateUnit(unit);
 String currentOrder = "";
 for (String order : unit.getOrders()){
  if (order.trim().startsWith(starter+"segeln")){
   if (unit.getOrders().toString().contains("Ozean")){currentOrder = "FAULENZE ; segelbedingt";}
   else {currentOrder = order.substring(10).trim();}
  }
 }
 setOrderPreserveComments(unit, currentOrder);
 helper.updateUnit(unit);
}// /segeln(Unit,String)

 // 3.1.2 +next<n> <order> [: <order1>:<order2>...]
 // Setzt bei Auslösung subMetas zu Dauermetas und löscht alle Metas, die nicht in nextVerschont stehen
next(Unit unit){
 ArrayList ordinaries = new ArrayList(); // alles, was nicht mit +next und anfangt und nicht ausgelöscht wird
 ArrayList newNexts = new ArrayList(); // nexts, die nicht diese Runde zuschlagen
 ArrayList doNow = new ArrayList(); // was durch next jetzt ausgelöst wird (verdrängt alles, was kein Kommentar ist
// 1.: die ArrayListen füllen
 for (String o : unit.getOrders()){
  if (!(o.trim().startsWith(me+"next")) ){ordinaries.add(o);}
  else{int wann = Integer.parseInt(splitToArrayList(o, " ").get(1).substring(5))-1;
   if(wann > 0){o=o.substring(o.indexOf(" ")).trim();
    o=o.substring(o.indexOf(" ")).trim();
    newNexts.add(me+"next"+wann.toString()+" "+o);}// /if(wann>0
   else{for(String now : splitToArrayList(o, " ", 3).get(2).split(":")){doNow.add(now.trim());}}
   }// /else <-- if(!(o.startsWith
 }// /for(String o
 helper.setOrder(unit, "");
 helper.updateUnit(unit);
// 2: neue +next einfügen (dann sind die immer oben
 for (String next : newNexts){helper.addOrder(unit, next);}
 helper.updateUnit(unit);
// 3: Rest einfügen; wenn doNow, ungeschützte Metabefehle rausschmeißen
 for(String ord : ordinaries){
  if (doNow.size() > 0){
   if (ord.trim().startsWith(com)){
	if (!(ord.trim().startsWith(me))){helper.addOrder(unit, ord);}
    else {
     boolean take = false;
     for (String prot : nextVerschont){if(ord.trim().startsWith(prot)){take = true;}}
     if (take){helper.addOrder(unit, ord);}
    }// /else
   }// /if(ord
  }// /if(doNow.size>0
  else{helper.addOrder(unit, ord);}// /else <-- if(doNow.size>0
 }// /for(String ord
 helper.updateUnit(unit);
//5: wenn next was auslöst, das durchziehen
 if (doNow.size() > 0){
  for(String dot : doNow){ // somewhat silly, but "do" wont work as variable
   // subMetas umwandeln
   if(dot.trim().startsWith(me2)){
    helper.addOrder(unit, dot);
    helper.addOrder(unit, me+dot.substring(4));
   }// /if(dot.trim
   else {helper.addOrder(unit, dot.trim());}
  }// /for(String dot
 }// /if(doNow.size>0
 helper.updateUnit(unit);
}// /next(Unit,String)

 // 3.1.2a +route (x, y, z) (bewegungsbefehl) [; (Kommentar)]
route(Unit unit){
 HashMap kursZuRegion = new HashMap(); // (String Koordinaten, String Befehle)
 boolean charted = false; // ist die aktuelle Region auf der Liste?
 String doNow = "";
 // Angegebene Regionen und zugehörige Befehle einsammeln
 for (String o : unit.getOrders()){
  if (o.startsWith(me+"route")){
   kursZuRegion.put(o.substring(o.indexOf("(")+1,o.indexOf(")")), o.substring(o.indexOf(")")+1).trim());
  }// /if(o
 }// /for(String
 // Auf Koordinaten prüfen:
 if (kursZuRegion.containsKey(unit.getRegion().getID().toString())){
  charted = true;
  doNow = kursZuRegion.get(unit.getRegion().getID().toString());
 }// /if(kursZuRegion
 // Auf Namen prüfen
 else {
  for (String name : kursZuRegion.keySet()){
   try{
    if (unit.getRegion().getName().startsWith(name)){
     charted = true;
     doNow = kursZuRegion.get(name);
    }// /if(region
   }// /try
   catch (NullPointerException npe){charted = false;}// /catch(npe
  }// /for(String
 }// /else <- if(kursZuregion
 if (charted){
  setOrderPreserveComments(unit, "");
  for (String order : doNow.split(":")){
   helper.addOrder(unit, order);
  }// /for(String
 }// /if(charted
 helper.updateUnit(unit);
}// /route(Unit)

 // 3.1.3 +rotate<n> <order>[ : <order1> : <order2>...]
 // +rotaMax <n> (optional; hilft, einen bestimmten, nicht streng-sequentiellen Rhythmus aufrecht zu erhalten)
rotate(Unit unit){
 // vorforhandene Befehle sortieren
 ArrayList rotates = new ArrayList();
 ArrayList comments = new ArrayList();
 int rotaMax = 0;
 for (String order : unit.getOrders()){if (!(order.trim().startsWith(me+"rotate"))){comments.add(order);}
  else{rotates.add(order.substring(10));}
  if (order.trim().startsWith(me+"rotaMax")){rotaMax = Integer.parseInt(splitToArrayList(order, " ").get(2));}
  }// /for(String order
 // vorvorhandene Befehle loswerden
 helper.setOrder(unit, "");
 String zerotate = "";
 for (String rot : rotates){int arg = Integer.parseInt(rot.substring(0, rot.indexOf(" ")));
  if(arg > rotaMax){rotaMax = arg;}
  if (arg - 1 == 0){zerotate = rot.substring(rot.indexOf(" ")).trim();}
  else{helper.addOrder(unit, me+"rotate"+(arg-1).toString()+" "+rot.substring(rot.indexOf(" ")).trim());}
 }// for(rot
 if (zerotate != ""){helper.addOrder(unit, me+"rotate"+rotaMax.toString()+" "+zerotate);} 
 for (String comment : comments){helper.addOrder(unit, comment);}
 if (zerotate != ""){ArrayList doNow = splitToArrayList(zerotate, ":");
  setOrderPreserveComments(unit, doNow.get(0));
  int i = 1;
  while (i<doNow.size()){helper.addOrder(unit, doNow.get(i));
   i++;}
  }// /if(zerotate!=""
}// /rotate(Unit)

 // 3.1.4 +rotaL skill skill2 skill3 skill4 skill1 ...
rotaL(Unit unit, String starter){
 ArrayList newOrders = new ArrayList();
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(com) && !(o.trim().startsWith(starter+"rotaL"))){newOrders.add(o);}
  if (o.trim().startsWith(starter+"rotaL")){o = o.substring(9).trim();
   String skill = o.substring(0, o.indexOf(" ")).trim();
   o = o.substring(o.indexOf(" ")).trim()+" "+skill;
   String newLine = starter+"rotaL "+o;
   newOrders.add(newLine);
   newOrders.add("LERNE "+skill);
  }// /if(o.startsWith starter
 }// /for(String o
 helper.setOrder(unit, "");
 for (String newOrder : newOrders){helper.addOrder(unit, newOrder);}
 helper.updateUnit(unit);
}// /rotaL(Unit)
 
 // 3.1.6 // +rotaP skill skill2 skill3 skill4 skill1 ...
rotaP(Unit unit){
 ArrayList newOrders = new ArrayList();
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(com) && !(o.trim().startsWith(me+"rotaP"))){
   newOrders.add(o);}
  if (o.trim().startsWith(me+"rotaP")){
   o = o.substring(9).trim();
   String skill = o.substring(0, o.indexOf(" ")).trim();
   o = o.substring(o.indexOf(" ")).trim()+" "+skill;
   String newLine = me+"rotaP "+o;
   newOrders.add(newLine);
   newOrders.add("MACHE "+skill);
  }// /if(o.startsWith me
 }// /for(String o
 helper.setOrder(unit, "");
 for (String newOrder : newOrders){
  helper.addOrder(unit, newOrder);
 }// /for String newOrder
 helper.updateUnit(unit);
}// /rotaP(Unit)
//}

//{ 3.2 Harte Metas
 // 3.2.1 +forst| [<perc> <altBef>]
forst(Unit unit, ArrayList args){
 if (helper.getLevel(unit, "Holzfällen") < 1){setOrderPreserveComments(unit, "LERNE Holzfaellen");}
 else{
// Default-Einstellungen
  boolean argZeroIsNumber = false;
  int perc = 0;
  String altBef = "LERNE Holzfaellen";
  int holz = getResourceAmount(unit.getRegion(), "Holz");
  if (args.size() > 0){
   try {perc = Integer.parseInt(args.get(0));
    argZeroIsNumber = true;
   }// /try
   catch (NumberFormatException forstOhneZahl){
    perc = 0;
    argZeroIsNumber = false;
   }// /catch(NumberFormatException
  }// /if(args.size > 0
  int soll = unit.getRegion().getType().getInhabitants() * perc / 1000; // durch 100 weil prozente, dann nochmal durch 10, weil Bäume
  int kann = helper.getLevel(unit, "Holzfällen") * unit.getPersons();
  int diff = 2 * (holz - soll); // wir gehen mal von Sägewerk als Standardszenario aus (lässt sich leichter rechnen als andersrum)
  if (!(unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Sägewerk"))){
   diff = diff / 2;}// und hier korrigieren wir im gegenteiligen Fall
  if (diff <= 0){
   if (argZeroIsNumber){
    if (args.size() > 1){
     altBef = args.get(1);
    }// /if(args.size > 1
   }// /if(argZeroIsNumber
   else{
    if (args.size() > 0){
     altBef = args.get(0);
    }// /if(args.size > 0
    if (args.size() > 1){
     altBef = altBef+" "+args.get(1);
    }// /if(args.size > 1
   }// /else <--if(argZeroIsNumber
   setOrderPreserveComments(unit, altBef);
  }// /if(diff
  else{
   if (diff > kann){
    setOrderPreserveComments(unit, "MACHE Holz");
   }// /if(diff > kann
   else{
    setOrderPreserveComments(unit, "MACHE "+diff.toString()+" Holz");
   }// /else <-- if(diff > kann
  }// /else <--if(diff <= 0
  helper.addOrder(unit, "; Pruefzahl forst: "+soll.toString());
 }// /else <-- if(helper.getLevel
 helper.updateUnit(unit);
}// /forst(Unit,ArrayList)

 // 3.2.2 ;; +herde <tier> <perc> [<altBef>]
monoHerde(Unit unit, String starter){
 // Variabeln
 ArrayList argline = new ArrayList();
 int quali = 1; // TW(Pferdedressur)
 String tier = "Pferd";
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"herde")){argline = splitToArrayList(o.substring(9).trim(), " ", 3);}// /if(o
 }// /for(String
 try {tier = argline.get(0);}// /try
 catch(IndexOutOfBoundsException oob){tier = tier;}// /catch(oob
 if (tier.equals("Elefant") || tier.equals("Mastodon")){
  quali = 2;
 }// /if(tier
 if (helper.getLevel(unit, "Pferdedressur") < quali){
  setOrderPreserveComments(unit, "LERNE Pferdedressur");
 }// /if(helper.getLevel
 else{
// Defaulteinstellungen
  boolean argZeroIsNumber = false;
  String altBef = "LERNE Pferdedressur";
  int perc = 0;
  if (argline.size() > 1){
   try {
    perc = Integer.parseInt(argline.get(1));
    argZeroIsNumber = true;
   }// /try
   catch (NumberFormatException herdeOhneZahl){
    perc = 0;
    argZeroIsNumber = false;
   }// /catch(NumberFormatException
  }// /if(argline.size
  int kann = helper.getLevel(unit, "Pferdedressur") * unit.getPersons() / quali;
  int soll = unit.getRegion().getType().getInhabitants() * perc / 100;
  if (quali == 2){
   soll = soll / 5;
  }// /if(quali
  int t = getResourceAmount(unit.getRegion(), tier);
  int diff = t - soll;
  if (diff <= 0){
   if (argZeroIsNumber){
    if (argline.size() > 2){
     altBef = argline.get(2);
    }// /if(argline.size>2
   }// /if(argZeroIsNumber
   else{
    if (argline.size() > 1){
     altBef = argline.get(1);
     if (argline.size() > 2){
      altBef = altBef+" "+argline.get(2);
     }// /if(argline.size > 2
    }// if(argline.size > 1
   }// /else <-- if(argZeroIsNumber
   setOrderPreserveComments(unit, altBef);
  }// /if(diff <=0
  else{
   if (diff >= kann){
    setOrderPreserveComments(unit, "MACHE "+tier);
   }// /if(diff >= kann
   else{
    setOrderPreserveComments(unit, "MACHE "+diff.toString()+" "+tier);
   }// /else <-- if(diff >= kann
  }// /else <-- if(diff <= 0
  helper.addOrder(unit, "; Pruefzahl herde: "+soll.toString()+" "+tier);
 }// /else<--if(helper.getLevel
 helper.updateUnit(unit);
}// /monoHerde(Unit,String)

 // 3.2.3 +unterhalte <AltBef>
unterhalte(Unit unit, String altBef){
 int soll = unit.getRegion().getType().getInhabitants() * (unit.getRegion().getWage()-10) * 20;
 int kann = 20 * unit.getPersons() * helper.getLevel(unit, "Unterhaltung");
 if (kann <= unit.getRegion().maxEntertain()){setOrderPreserveComments(unit, "UNTERHALTE");}// /if(kann
 else{
  int diff = unit.getRegion().getSilver() - soll;
  if (diff > 0){setOrderPreserveComments(unit, "UNTERHALTE "+diff.toString());}// /if(diff
  else{setOrderPreserveComments(unit, altBef);}
 }// /else <- if(kann
 helper.addOrder(unit, "; unterhaellt automatisch");
 helper.updateUnit(unit);
}// /unterhalte(Unit,String)

 // 3.2.4 +silreg <minSilber> <AltBef>
 // wie +herde oder +forst, aber ohne Prozente und bezogen auf das Altsilber/den Stash
 // wenn <minSilber> ~angegeben, auf das 20fache des regenerativen Maximums
silReg(Unit unit, String starter){
 int soll = unit.getRegion().getType().getInhabitants() * (unit.getRegion().getWage()-10) * 20;
 int kann = unit.getPersons() * 20 * helper.getLevel(unit, "Steuereintreiben");
 String altBef = "LERNE Steuereintreiben";
 for(String o : unit.getOrders()){
  if(o.trim().startsWith(starter+"silreg")){
   try {
    soll = Integer.parseInt(splitToArrayList(o, " ").get(2));
    try {altBef = splitToArrayList(o, " ", 4).get(3);}// /try
    catch(IndexOutOfBoundsException oob){altBef = altBef;}// /catch(oob
   }// /try
   catch(NumberFormatException nfe){
    soll = soll;
    try {altBef = splitToArrayList(o, " ", 3).get(2);}// /try
    catch(IndexOutOfBoundsException oob){altBef = altBef;}// /catch(oob
   }// /catch(nfe
  }// /if(o
 }// /for(String
 int diff = unit.getRegion().getSilver() - soll;
 if (diff <= 0){setOrderPreserveComments(unit, altBef);}// /if(diff <=
 else{
  if (diff >= kann){setOrderPreserveComments(unit, "TREIBE");}// /if(diff>=
  else{setOrderPreserveComments(unit, "TREIBE "+diff.toString());}// /else
 }// /else <- if(diff <=
 helper.updateUnit(unit);
}// /silReg(Unit,String)

 // 3.2.5 +treibe <silber> <altBef>
 // Treibt <silber> Silber, wenn mind so viel im Stash/Altsilber,
 // sonst <altBef> (wenn ~angegeben: LERNE Steuereintreiben)
 // wenn ~<silber> angegeben, wird es auf das regenerative Maximum gesetzt
treibe(Unit unit, String starter){
 int soll = unit.getRegion().getType().getInhabitants() * (unit.getRegion().getWage()-10);
 int kann = unit.getPersons() * 20 * helper.getLevel(unit, "Steuereintreiben");
 String waga = "LERNE Steuereintreiben";
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"treibe")){
   args = splitToArrayList(o, " ", 4);
   boolean haveNumeric = false;
   if (args.size() > 2){
    try {
     soll = Integer.parseInt(args.get(2));
     haveNumeric = true;
    }// /try
    catch (NumberFormatException nfe){waga = args.get(2);}// /catch nfe
    if (haveNumeric){
     if (args.size() > 3){waga = args.get(3);}// /if (args > 3
    }// /if(haveNumeric
    else {
     try {
      waga = args.get(2);
      if (args.size() > 3){waga = waga+" "+args.get(3);}// /if args > 3
     }// /try
     catch (IndexOutOfBoundsException oob){waga = waga;}// /catch oob
    }// /else <- haveNumeric
   }// /if(args > 2
  }// /if(o
 }// /for(String
 int diff = unit.getRegion().getSilver() - soll;
 if (diff <=0){setOrderPreserveComments(unit, waga);}// /if(diff <=
 else{
  if (diff >= kann){setOrderPreserveComments(unit, "TREIBE "+soll.toString());}// /if(diff >=
  else{
   if (diff > kann /2){setOrderPreserveComments(unit, "TREIBE "+diff.toString());}// /if(diff >
   else{setOrderPreserveComments(unit, waga);}// /else
  }// /else <- if(diff >=
 }// /else <- if(diff <=
 helper.updateUnit(unit);
}// /treibe(Unit,String)

 // 3.2.6 +killer [<AltBef>]
killer(Unit unit, String starter){
 // Kann er überhaupt Steuern eintreiben?
 if (helper.getLevel(unit, "Steuereintreiben") < 1){setOrderPreserveComments(unit, "LERNE Steuereintreiben");}
 else{
  String altBef = "LERNE Steuereintreiben"; // Standardeinstellung
  // Alternativbefehl suchen
  for (String o : unit.getOrders()){
   if (o.trim().startsWith(starter+"killer") && splitToArrayList(o, " ").size() > 2){
    altBef = splitToArrayList(o, " ", 3).get(2);
   }// /if(o
  }// /for(String
  // Freie AP und Bauern überprüfen:
  int freeAP = unit.getRegion().getType().getInhabitants() - (getResourceAmount(unit.getRegion(), "Holz")*10 + getResourceAmount(unit.getRegion(), "Elefant")*5 + getResourceAmount(unit.getRegion(), "Mastodon")*5 + getResourceAmount(unit.getRegion(), "Kamel") + getResourceAmount(unit.getRegion(), "Pferd") + getResourceAmount(unit.getRegion(), "Zotte") + getResourceAmount(unit.getRegion(), "Alpaka"));
  if (freeAP > 0 && unit.getRegion().getPeasants() > 0){setOrderPreserveComments(unit, "TREIBE");}// /if(freeAP
  else{setOrderPreserveComments(unit, altBef);}// /else
 }// /else <-if(helper
 helper.updateUnit(unit);
}// /killer(Unit,String)
//}

//{ 3.3 Interaktive Metas
 //{ 3.3.1 Study-Komplex
 // +lerne <Skill> [<level>] [<AltBef>]
 // +lehre <Skill> <AltBef>
studyComplex(Region region){
 String studyReady = "NILLL";
 for(String skill : skillList.split(" ")){
  skill = skillUmlaute(skill);// uL AUS

// betroffene Einheiten einsammeln
  // +lehre und +lerne einsammeln und auf Startposition ("NULLL") stellen:
  ArrayList schueler = unitsInRegionWithOrder(region, me+"lerne "+skill);
  for(Unit unit : schueler){
	  // Gegenprobe von +lernen
   if (!(unit.getOrders().toString().contains(skill+" fertig gelernt"))){setOrderPreserveComments(unit, studyReady);}
  }
  
  ArrayList lehrer = unitsInRegionWithOrder(region, me+"lehre "+skill);
  for(Unit unit : lehrer){setOrderPreserveComments(unit, studyReady);}

  // +lehre sucht +lerne (multiple Schüler))
  for(Unit teacher : lehrer){
   int enumPupils = 0;
   for(Unit student : schueler){
    if(student.getOrders().toString().contains(studyReady) && enumPupils + student.getPersons() <= teacher.getPersons() * 10 && helper.getLevel(student, skillUmlaute(skill)) < helper.getLevel(teacher, skillUmlaute(skill))){
     setOrderPreserveComments(student, "LERNE "+skill+" ; mit Lehrer "+teacher.getID().toString());
     helper.updateUnit(student);
     setTeachOrder(teacher, student.getID().toString());
     helper.updateUnit(teacher);
     enumPupils = enumPupils + student.getPersons();
    }// /if(enumPupils
   }// /for(Unit student
  }// /for(Unit teacher

// +lerne <skill> <lvl> <altBef>
  // +lerne ohne Lehrer bekommen Beschäftigungstherapie
  for(Unit unit : schueler){
   if(unit.getOrders().toString().contains(studyReady)){
    String altBef = "LERNE "+skill+" ; ohne Lehrer"; // default
    for(String order : unit.getOrders()){
     if(order.trim().startsWith(me+"lerne")){
      ArrayList line = splitToArrayList(order, " ", 5);
      if(line.size() > 3){
       try {int a = Integer.parseInt(line.get(3));
        if(line.size() > 4){altBef = line.get(4)+" ; ersatzweise";}
       }// /try
       catch(NumberFormatException testballonSchuelerAltbef){
        altBef = line.get(3);
        if(line.size() > 4){altBef = altBef+" "+line.get(4)+" ; ersatzweise";}
       }// /catch(NFE
      }// /if(line.size>3
     }// /if(order.startsWith
    }// /for(String order
    setOrderPreserveComments(unit, altBef);
    helper.updateUnit(unit);
   }// /if(unit.getOrders()
  }// /for(Unit unit:schueler

// unbeschäftigte Lehrer einsammeln
  schueler.clear();
  for(Unit unit : lehrer){if(unit.getOrders().toString().contains(studyReady) || getNumberOfPupils(unit) < unit.getPersons() * 10){schueler.add(unit);}}
  lehrer = schueler.clone();
  // +lehre lehrt andere +lehre (nur Einheiten mit mehr Personsn; multiple Schüler)
  for(Unit teacher : lehrer){
   int enumSchueler = getNumberOfPupils(teacher);
   for(Unit otherTeacher : schueler){
    if(otherTeacher.getOrders().toString().contains(studyReady) && otherTeacher.getPersons() > teacher.getPersons() && enumSchueler + otherTeacher.getPersons() <= teacher.getPersons() * 10 && helper.getLevel(otherTeacher, skillUmlaute(skill)) < helper.getLevel(teacher, skillUmlaute(skill))){
     enumSchueler = enumSchueler + otherTeacher.getPersons();
     setOrderPreserveComments(otherTeacher, "LERNE "+skill+" ; mit Kollege "+teacher.getID().toString());
     helper.updateUnit(otherTeacher);
     setTeachOrder(teacher, otherTeacher.getID().toString());
     helper.updateUnit(teacher);}}}
  // unbeschäftigte +lehre einsammeln
  schueler.clear();
  for(Unit unit : lehrer){if(unit.getOrders().toString().contains(studyReady)){schueler.add(unit);}}
 // +lehre mit ohne irgendwas bekommt Beschäftigungstherapie
 // +lehre <skill> [<altBef>]
  for(Unit unit : schueler){
   String altBef = "LERNE "+skill+" ; Weiterbildung";
   for(String order : unit.getOrders()){
    if(order.trim().startsWith(me+"lehre "+skill)){
     if(splitToArrayList(order, " ", 4).size() > 3){
      altBef = splitToArrayList(order, " ", 4).get(3)+" ; ersatzweise";
     }// /if
    }// /if(order
   }// for(String
   setOrderPreserveComments(unit, altBef);
  }// /for(Unit
 }// for(String skill
}// /studyComplex(Region)

int getNumberOfPupils(Unit unit){
 int i = 0;
 for(Unit pupil : unit.getPupils()){
 i = i+pupil.getPersons();}
 return i;
}// /int getNumberOfPupils(Unit)

setTeachOrder(Unit unit, String id){
 String teach = "LEHRE";
 for(String order : unit.getOrders()){
  if(order.trim().startsWith(teach)){teach = order;}}
 setOrderPreserveComments(unit, teach+" "+id);
}// /setTeachOrder(Unit,String)
 //} /Study-Komplex
//}

//{ 3.4 Weiche Metas

 //{ 3.4.1 +rek [<n>] [,<m>]
 // n = BauernMax;
 // m = BestätigungsMax
 // +rek n , m
regulator(Unit unit, Region region, String starter){
 // Variabeln:
 int maxBau = getIdeBau(unit);
 int confirm = region.getType().getInhabitants() / 10;
 // suchen nach n und m
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"rek") && splitToArrayList(o, " ").size() > 2){
   if (o.contains(",")){
    maxBau = Integer.parseInt(o.substring(7, o.indexOf(",")).trim());
    confirm = Integer.parseInt(o.substring(o.indexOf(",")).trim());
   }// /if(o.contains
   else{maxBau = Integer.parseInt(splitToArrayList(o, " ").get(2));}
  }// /if(o.startsWith
 }// /for(String
 // Bauernpop untersuchen:
 int diff = region.getPeasants() - maxBau;
 if (diff > 0){
  diff = getLegen(unit, diff);
  int braucht = diff*(unit.getRace().getRecruitmentCosts()+10);
  // Silberlager suchen
   Unit sil = unit; // Platzhalter
   if (regionalUnitOrders(region).contains(me+"sLag")){sil = unitsInRegionWithOrder(region, me+"sLag").get(0);}// if(regionalUnitOrders
   else {
    if (regionalUnitOrders(region).contains(me+"lager")){sil = unitsInRegionWithOrder(region, me+"lager").get(0);}// /if(regionalUnitOrders
   }// /else
   if (sil.getOrders().toString().contains(me+"sLag") || sil.getOrders().toString().contains(me+"lager")){
    helper.addOrder(sil, "GIB "+unit.getID().toString()+" "+braucht.toString()+" Silber ; Rekrutierungskosten");
   }// /if(sil
   // ...oder aus den anderen Einheiten zusammensammeln:
   else{
    int s = 0; // einsammelbares Silber
    HashMap givers = new HashMap(); // in Frage kommende Einheiten und ihre Silberbeträge
    while (s < braucht){
     for (Unit other : region.units()){
      if (other.getFaction() == unit.getFaction() && other != unit && helper.getItemCount(other, "Silber") > 0){
       s = s + helper.getItemCount(other, "Silber");
       givers.put(other, helper.getItemCount(other, "Silber"));
      }// /if(other
     }// /for(Unit
    }// /while(s<braucht
    if (s >= braucht){
     for (Unit u : givers.keySet()){
      helper.addOrder(u, "GIB "+unit.getID().toString()+" "+givers.get(u)+" Silber ; Rekrutierungshilfe");
      helper.updateUnit(u);
     }// /for(Unit
    }// /if(s
   }// /else <- if(sil
   if (helper.getModifiedItemCount(unit, "Silber") >= braucht){
    helper.addOrder(unit, "REKRUTIERE "+diff.toString());
    // Bestätigung untersuchen
    if (unit.getPersons() < confirm){unit.setOrdersConfirmed(true);}// /if(unit
   }// /if(helper
   else{
    unit.setOrdersConfirmed(false);
    helper.addOrder(unit, "Meta-Warnung: Nicht genug Silber vorhanden, um zu rekrutieren");
   }// /else <- if(helper
  }// /if(diff
 helper.updateUnit(unit);
}// /regulator(Unit,Region,String)
int getIdeBau(Unit unit){
 int id = (unit.getRegion().getType().getInhabitants() / 100 * 101)-1;
 if (unit.getRegion().getType().getInhabitants() > 3999){
  id = unit.getRegion().getType().getInhabitants() / 1000 * 1005;
 }// /if(unit
 return id;
}// /int getIdeBau(Unit)

int getLegen(Unit unit, int diff){
 int re = diff;
 if (re > unit.getRegion().getPeasants() / 20){
  re = unit.getRegion().getPeasants() / 20;
 }
 if (re >= 100){
  re = re  / 100;
  return re * 100;
 }
 if (re < 100){
  if (re >= 50){
   re = re / 10;
   return re * 10;
  }
  else{
   return re;
  }
 }
}

 //} /+rek

 // 3.4.3 +bewache
autarn(Unit unit){
// implementiert +bewache
// Einheiten, die Tarnen können, tarnen sich;
// Einheiten mit Parteitarnung nennen die Tarnpartei in einem Kommentar
 if (unit.getOrders().toString().contains(me+"bewache")){
  helper.addOrder(unit, "BEWACHE");
  helper.updateUnit(unit);
 }// /if(unit.getOrders
 else{
  if (unit.getBuilding() == null && !(unit.getOrders().toString().contains("TARNE Einheit ; automatisch"))){
   boolean tarn = false;
   for (skill : unit.getModifiedSkills()){
    if (skill.toString().substring(0, skill.toString().indexOf(" ")).equalsIgnoreCase("Tarnung") && !(splitToArrayList(skill.toString(), " ").get(1).equals("0"))){
     tarn = true;
    }// /if(skill
   }// /for(String
   if(tarn){helper.addOrder(unit, "TARNE Einheit ; automatisch");}// /if(tarn
   helper.updateUnit(unit);
  }// /if(unit
 }// /else
 if (unit.getGuiseFaction() != null){
  helper.addOrder(unit, "; getarnt als: "+unit.getGuiseFaction().toString());
  helper.updateUnit(unit);
 }// /if(unit.getGuiseFaction
}// /autarn(Unit)
//}

 //{ 3.4.3a +gib |<uID> <[<n>] <item> [[<n1>] <item1> [<n2>] <item2>...][;<comment>]//

gib(Unit unit, String starter){
 ArrayList sendOrders = new ArrayList();
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"gib")){
   String id = splitToArrayList(o, " ").get(2);
   if (unit.getRegion().units().toString().contains("("+id+")")){
    String ladeliste = o.substring(o.indexOf(id)+id.length()).trim();
    String comment = "";
    if (ladeliste.contains(";")){
     comment = ladeliste.substring(ladeliste.indexOf(";")).trim();
     ladeliste = ladeliste.substring(0, ladeliste.indexOf(";")).trim();
    }// /if(ladeliste.contains
    
    int i = 0;
    ArrayList liste = splitToArrayList(ladeliste, " ");
    while (i < liste.size()){
     int amount = 0;
     String item = "";
     try {
      amount = Integer.parseInt(liste.get(i));
      i++;
      item = liste.get(i);
      if (helper.getModifiedItemCount(unit, itemUmlaute(item)) > 0){
       if (amount > helper.getModifiedItemCount(unit, itemUmlaute(item))){amount = helper.getModifiedItemCount(unit, itemUmlaute(item));}// /if(amount > item
       sendOrders.add("GIB "+id+" "+amount.toString()+" "+item+" "+comment);
      }// if item > 0
      i++;
     }// /try
     catch (NumberFormatException nfe){
      item = liste.get(i);
      amount = helper.getModifiedItemCount(unit, itemUmlaute(item));
      if (amount > 0){sendOrders.add("GIB "+id+" "+amount.toString()+" "+item+" "+comment);}// /if(amount > 0
      i++;
     }// /catch
    }// /while

	}// /if(unit.getRegion
  }// /if(o.startsWith
 }// /for(String o
 for (String sendOrder : sendOrders){helper.addOrder(unit, sendOrder);}// /for(String sendOrder
 helper.updateUnit(unit);}// /gib(Unit,String)
String itemUmlaute(String item){
 if (item.startsWith("Oe")){return "Öl";}
 if(item.contains("ue")){return "Gewürz";}
 return item;
}// /String itemUmpaute(String)
//} /gib

//{ 3.4.3b Lager- und Reservierung-Metas
  //  3.4.3b.1 +lager
  // Allroundlager: Übernimmt alle Lagerjobs, die in der Region sonst nicht vergeben sind
lager(Unit aLager){
 ArrayList ordersInRegion = regionalUnitOrders(aLager.getRegion());
 if (!(ordersInRegion.contains(me+"sLag"))){
  sLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"nLag"))){
  nLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"fLag"))){
  fLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"mLag"))){
  mLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"rLag"))){
  rLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"tLag"))){
  tLager(aLager);
 }
}// /lager(Unit)

  // 3.4.3b.2 +sLag
  // (Silber)
sLager(Unit lager){
// sammelt Silber und gibt allen Unterhalt
 for (Unit unit : lager.getRegion().units()){
  if (unit.getFaction() == lager.getFaction()){
   int futter = unit.getModifiedPersons() * 10;
   if (unit.getOrders().toString().contains("LERNE Taktik")){
    futter = futter + (unit.getPersons() * 100);
   }// /if(unit.getPersons
   if (unit.getBuilding() != null && (unit.getBuilding().getType().toString().equals("Sägewerk") || unit.getBuilding().getType().toString().equals("Bergwerk") || unit.getBuilding().getType().toString().equals("Steinbruch") || unit.getBuilding().getType().toString().equals("Schmiede") || unit.getBuilding().getType().toString().equals("Werkstatt") || unit.getBuilding().getType().toString().equals("Sattlerei") || unit.getBuilding().getType().toString().equals("Schiffswerft"))){
    futter = futter + unit.getPersons() * 5;
   }// /if(unit.getBuilding()
   if (unit.getBuilding() != null && unit == unit.getBuilding().getOwnerUnit() && buildingMaintenances.keySet().contains(unit.getBuilding().getType().toString())){
    futter = futter + buildingMaintenances.get(unit.getBuilding().getType().toString());
   }// /if(unit.getBuilding
   if (unit.getItems().toString().contains("Kriegselefant") || unit.getItems().toString().contains("Kriegsmastodon")){
    int n = helper.getItemCount(unit, "Kriegselefant") + helper.getItemCount(unit, "Kriegsmastodon");
	futter = futter + 5 * n;
   }// /if(unit.getItems
   futter = futter - helper.getModifiedItemCount(unit, "Silber");
   if (futter > 0 && unit != lager){
    helper.addOrder(lager, "GIB "+unit.getID().toString()+" "+futter+" Silber ; Futter");
    helper.updateUnit(lager);
   }// /if(futter
   if (futter < 0 && unit != lager && !(unit.getOrders().toString().contains("REKRUTIERE"))){
    helper.addOrder(unit, "GIB "+lager.getID().toString()+" "+((-1) * futter).toString()+" Silber ; einlagern");
    helper.updateUnit(unit);
   }// /if(futter
  }// /if(unit.getFaction
 }// /for(Unit
  if (lager.getOrders().toString().contains("forlage")){
  lager.setOrdersConfirmed(false);
  helper.updateUnit(lager);
 }
}// /sLager(Unit)

  // 3.4.3b.3 +nLag
  //{ (Nahkampfwaffen)
nLager(Unit nLag){
 for (String waffe : nLagerZieht){
  for (Unit unit : nLag.getRegion().units()){
   if (unit.getFaction() == nLag.getFaction() && unit != nLag && (unit.getOrders().toString().contains(me+"nkw") || (unit.getOrders().toString().contains(com+" #berichte"))) && unit != nLag && helper.getModifiedItemCount(unit, waffe) > 0){
    helper.addOrder(unit, "GIB "+nLag.getID().toString()+" "+helper.getModifiedItemCount(unit, waffe).toString()+" "+waffe+" ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
}
ArrayList nLagerZieht = new ArrayList();
nLagerZieht.add("Schwert");
nLagerZieht.add("Streitaxt");
nLagerZieht.add("Kriegshammer");
nLagerZieht.add("Speer");
nLagerZieht.add("Kriegselefant");
nLagerZieht.add("Kriegsmastodon");
  //} /nLag

  // 3.4.3b.4 +fLag
  //{ (Fernkampfwaffen)
fLager(Unit fLag){
 for (String waffe : fLagerZieht){
  for (Unit unit : fLag.getRegion().units()){
   if (unit.getFaction() == fLag.getFaction() && unit != fLag && (unit.getOrders().toString().contains(me+"bogner") || unit.getOrders().toString().contains(me+"wagner") || (unit.getOrders().toString().contains(com+" #berichte"))) && unit != fLag && helper.getModifiedItemCount(unit, waffe) > 0){
    helper.addOrder(unit, "GIB "+fLag.getID().toString()+" "+helper.getModifiedItemCount(unit, waffe).toString()+" "+waffe+" ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
}
ArrayList fLagerZieht = new ArrayList();
fLagerZieht.add("Bogen");
fLagerZieht.add("Armbrust");
fLagerZieht.add("Katapult");
  //} /fLag

 // 3.4.3b.5 +rLag
 //{ (Rüstungsteile)
rLager(Unit rLag){
 for (String rTeil : rLagerZieht){
  for (Unit unit : rLag.getRegion().units()){
   if (unit.getFaction() == rLag.getFaction() && unit != rLag && (unit.getOrders().toString().contains(me+"ruestung") || unit.getOrders().toString().contains(com+" #berichte")) && unit != rLag && helper.getModifiedItemCount(unit, rTeil) > 0){
    helper.addOrder(unit, "GIB "+rLag.getID().toString()+" "+helper.getModifiedItemCount(unit, rTeil).toString()+" "+rTeil+" ; einlagern");
    helper.updateUnit(unit);
   }
   if (unit.getOrders().toString().contains(me+"nkw") && unit != rLag){
    int epBed = 0;
    if (helper.getLevel(unit, "Waffenbau") > 4){
     epBed = helper.getLevel(unit, "Waffenbau") * unit.getPersons() / 5;
    }
    if (epBed > 0 && helper.getModifiedItemCount(rLag, "Elefantenpanzer") >= epBed){
     helper.addOrder(rLag, "GIB "+unit.getID().toString()+" "+epBed.toString()+" Elefantenpanzer ; Waffenbauer");
     helper.updateUnit(rLag);
    }
   }
  }
 }
}
ArrayList rLagerZieht = new ArrayList();
rLagerZieht.add("Holzschild");
rLagerZieht.add("Eisenschild");
rLagerZieht.add("Kettenhemd");
rLagerZieht.add("Plattenpanzer");
rLagerZieht.add("Elefantenpanzer");
ArrayList rLagerGibt = new ArrayList();
rLagerGibt.add("Elefantenpanzer");
 //} /rLag

 // 3.4.3b.6 +tLag
 //{ (Transport-Items)
tLager(Unit tLag){
 for (Unit unit : tLag.getRegion().units()){
  if (unit.getFaction() == tLag.getFaction() && unit != tLag){ // Standardprüfung zur Vermeidung sinnloser Befehlszeilen
// auf +herde & +wagner & Allroundlager prüfen
   if (unit.getOrders().toString().contains(me+"herde") || unit.getOrders().toString().contains(me+"wagner") || unit.getOrders().toString().contains(com+" #berichte")){
    for (String tier : tLagerZieht){
// auf Items prüfen
     if (helper.getItemCount(unit, tier) > 0){
      helper.addOrder(unit, "GIB "+tLag.getID().toString()+" "+helper.getModifiedItemCount(unit, tier).toString()+" "+tier+" ; einlagern");
      helper.updateUnit(unit);
     }// /if(helper.getItemCount
    }// /for(String tier
   }// /if(unit.getOrders
// Greifeneier prüfen
   if (helper.getItemCount(unit, "Greifenei") > 0){
    helper.addOrder(unit, "GIB "+tLag.getID().toString()+" "+helper.getModifiedItemCount(unit, "Greifenei").toString()+" Greifenei ; einlagern");
    helper.updateUnit(unit);
   }
  }// /if(unit.getFaction
 }// /for(Unit
}// /tLager(Unit)
ArrayList tLagerZieht = new ArrayList();
tLagerZieht.add("Pferd");
tLagerZieht.add("Kamel");
tLagerZieht.add("Elefant");
tLagerZieht.add("Alpaka");
tLagerZieht.add("Zotte");
tLagerZieht.add("Mastodon");
tLagerZieht.add("Wagen");
tLagerZieht.add("Pegasus");
ArrayList tLagerGibt = new ArrayList();
tLagerGibt.add("Elefant");
 //} /tLag

  // 3.4.3b.7 +mLag
  //{ (Baumaterial)
mLager(Unit mLag){
 for (Unit unit : mLag.getRegion().units()){
  for (String mat : mLagerZieht){
   if (unit != mLag && unit.getFaction() == mLag.getFaction() && !(wirdVonMLagBedient(unit)) && helper.getItemCount(unit, mat) > 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+helper.getItemCount(unit, mat).toString()+" "+mat+" ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
 for (Unit unit : mLag.getRegion().units()){
  if (unit != mLag && unit.getFaction() == mLag.getFaction() && wirdVonMLagBedient(unit)){
   int hBed = 0;
   int eBed = 0;
   int sBed = 0;
   if (unit.getOrders().toString().contains(me+"nkw")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Waffenbau") / 2);
    eBed = eBed + (unit.getPersons() * helper.getLevel(unit, "Waffenbau"));
    sBed = sBed + (unit.getPersons() * helper.getLevel(unit, "Waffenbau") / 5);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Schmiede")){
     hBed = hBed / 2;
     eBed = eBed / 2;
     sBed = sBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"bogner")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Bogenbau") / 2);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Schmiede")){
     hBed = hBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"ruestung")){
    eBed = eBed + (unit.getPersons() * helper.getLevel(unit, "Rüstungsbau") * 2);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Sattlerei")){
     eBed = eBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"wagner")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Wagenbau") * 5);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Werkstatt")){
     hBed = hBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"reeder")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Schiffbau") / 2);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Schiffswerft")){
     hBed = hBed / 2;
    }
   }
   hBed = hBed - helper.getModifiedItemCount(unit, "Holz");
   eBed = eBed - helper.getModifiedItemCount(unit, "Eisen");
   sBed = sBed - helper.getModifiedItemCount(unit, "Stein");
   if (hBed > 0 && helper.getItemCount(mLag, "Holz") >= hBed){
    helper.addOrder(mLag, "GIB "+unit.getID().toString()+" "+hBed.toString()+" Holz");
    helper.updateUnit(mLag);
   }
   if (hBed < 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+((-1)*hBed).toString()+" Holz ; einlagern");
    helper.updateUnit(unit);
   }
   if (eBed > 0 && helper.getItemCount(mLag, "Eisen") >= eBed){
    helper.addOrder(mLag, "GIB "+unit.getID().toString()+" "+eBed.toString()+" Eisen");
    helper.updateUnit(mLag);
   }
   if (eBed < 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+((-1)*eBed).toString()+" Eisen ; einlagern");
    helper.updateUnit(unit);
   }
   if (sBed > 0 && helper.getItemCount(mLag, "Stein") >= sBed){
    helper.addOrder(mLag, "GIB "+unit.getID().toString()+" "+sBed.toString()+" Stein");
    helper.updateUnit(mLag);
   }
   if (sBed < 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+((-1)*sBed).toString()+" Stein ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
}
ArrayList mLagerZieht = new ArrayList();
mLagerZieht.add("Holz");
mLagerZieht.add("Eisen");
mLagerZieht.add("Stein");
mLagerZieht.add("Gold");
boolean wirdVonMLagBedient(Unit unit){
 for (String fkt : mLagerBedient){
  if (unit.getOrders().toString().contains(fkt)){
   return true;
  }
 }
 return false;
}
  //} /mLag

  // 3.4.3b.7 Händler: Einsammeln von Luzxusgütern
handel(Unit handler){
 for (Unit unit : handler.getRegion().units()){
  if (unit != handler && unit.getFaction() == handler.getFaction()){
   for (s : handler.getRegion().getPrices().values()){
    String lux = s.toString().substring(0, s.toString().indexOf(":"));
    if (helper.getItemCount(unit, lux) > 0){
     if (helper.getModifiedItemCount(unit, lux) > 0){
      helper.addOrder(unit, "GIB "+handler.getID().toString()+" "+helper.getItemCount(unit, lux).toString()+" "+lux+" ; einlagern");
      helper.updateUnit(unit);
     }
    }
   }
  }
 }
}
 //}

/*****************************************/
/////{ 4. Allgemeine Hilfsskripte /////////
/*****************************************/
// 4.1
setOrderPreserveComments(Unit unit, String order){
// ersetzt helper.setOrder(Unit,String), wenn Kommentare erhalten bleiben sollen
// behällt auch Zeilen, die mit "forlage" anfangen (wg #berichte)
 ArrayList comments = new ArrayList();
 //Einsammeln der Kommentare
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(com) || o.trim().startsWith(";") || o.startsWith("forlage") || o.startsWith("Meta-Warnung")){
   comments.add(o);
  }// /if(o
 }// /for(String
 helper.setOrder(unit, ""); // das set-Element
 for (String c : comments){helper.addOrder(unit, c);}// Wiedergabe von Kommentaren
 helper.addOrder(unit, order); // Befehl wird gegeben
 helper.updateUnit(unit);
}// /setOrderPreserveComments(Unit,String)

// 4.2
int getResourceAmount(Region region, String stuff){
 if (region.resources().toString().contains(stuff)){
  return region.getResource(region.data.getRules().getItemType(StringID.create(stuff))).getAmount();
 }// /if(region
 else{return 0;}
}// /int getResourceAmount(Region,String)

// 4.3
ArrayList unitsInRegionWithOrder(Region region, String order){
 ArrayList arr = new ArrayList();
 for (Unit unit : region.units()){
  if (unit.getOrders().toString().contains(order)){arr.add(unit);}// /if(unit
 }// /for(Unit
 return arr;
}// /ArrayList unitsInRegionWithOrder(Region,String)

// 4.4
ArrayList regionalUnitOrders(Region region){
// Listet alle bekannten Befehle von Einheiten in der Region auf
// und zwar NUR die Befehle
 ArrayList arr = new ArrayList();
 for (Unit unit : region.units()){
  for (String o : unit.getOrders()){arr.add(o);}// /for(String
 }// /for(Unit
 return arr;
}// /ArrayList regionalUnitOrders(Region)

// 4.5
ArrayList splitToArrayList(String s, String trenner){
 arr = new ArrayList();
 for (e : s.split(trenner)){arr.add(e);}
 return arr;
}// /ArrayList splitToArrayList(String,String)

// 4.6
ArrayList splitToArrayList(String s, String trenner, int limit){
 arr = new ArrayList();
 for (e : s.split(trenner, limit)){arr.add(e);}
 return arr;	
}// /ArrayList splitToArrayList(String,String,int)

// 4.7
int lerntage(Unit unit, String skill){
 String n = ""; // bequemlichkeit halber sofort deklariert
                     // In dieser Variablen werden unsere Zieldaten eingefangen werden
 for (String s : unit.getSkills().toString().substring(1, unit.getSkills().toString().length()-1).split(", ")){
  // Die Collection wird zu einem String umgebaut,
  // (In dieser Darstellungsweise beginnt der String mit "[", endet mit "]"
  // und trennt die Elemente der Collection mit ", ")
  // (netto machen wir die Collection also zu einem Array von Strings und
  // untersuchen die Einzelnen Elemente)
  if (s.substring(0, s.indexOf(" ")).equalsIgnoreCase(skill)){
  // Praktischerweise beginnt jedes Element mit Talentname, gefolgt von Space
  // unpraktischerweise hat Magellan nicht alle Talente großgeschrieben in der Datenbank,
  //  daher equalsIgnoreCase(String) statt startsWith(String)
   n = s.substring((s.indexOf("["))+1, s.indexOf("]"));
   // noch praktischererweise sind die Lerntage in den Elementen in eckige Klammern gesetzt
  }
 }
 // Entweder besteht der String n jetzt aus Ziffern-Charakters, oder ist leer.
 try {
  return Integer.parseInt(n);
 }
 catch (NumberFormatException nfe){
 // wenn n leer ist, steht das Talent nicht in der Collection und muss daher null Lerntage haben.
  return 0;
 }
}// /int lerntage(Unit,String)

// 4.8
int modifiedLerntage(Unit unit, String skill){
 String n = "";
 for (String s : unit.getModifiedSkills().toString().substring(1, unit.getSkills().toString().length()-1).split(", ")){
  if (s.substring(0, s.indexOf(" ")).equalsIgnoreCase(skill)){
   n = s.substring((s.indexOf("["))+1, s.indexOf("]"));
  }
 }
 try {
  return Integer.parseInt(n);
 }
 catch (NumberFormatException nfe){
  return 0;
 }
}// /int modifiedLerntage(Unit,String)

//{ 4.9 ArrayList longOrders
ArrayList longOrders = new ArrayList();
longOrders.add("FOLGE");
longOrders.add("NACH");
longOrders.add("ROUTE");
longOrders.add("BEKLAUE");
longOrders.add("HANDEL");
longOrders.add("LEHRE");
longOrders.add("LERNE");
longOrders.add("MACHE");
longOrders.add("TREIBE");
longOrders.add("UNTERHALTE");
longOrders.add("ZERSTOERE");
//}
// 4.9.a
boolean isLongOrder(String order){
 for (String longs : longOrders){
  if (splitToArrayList(order.trim(), " ").get(0).equalsIgnoreCase(longs)){return true;}// /if(order
 }// /for(String
 return false;
}// /boolean isLongOrder(String)

//}
/*****************************************/
//} ENDE CbC
/*****************************************/
Zuletzt geändert von nemo am So 9. Apr 2017, 14:11, insgesamt 12-mal geändert.
I may go pop -- Excuse me!

Benutzeravatar
nemo
Heerführer
Beiträge: 232
Registriert: Mi 25. Feb 2015, 12:06

CbC: 15. März (letzte garantiert-überwiegend-funktionierende und nicht geupdatete Version)

Beitrag von nemo » Di 14. Mär 2017, 18:17

Code: Alles auswählen

import magellan.client.*;
import magellan.client.extern.*;
import magellan.library.*;
import magellan.library.rules.*;
import magellan.plugin.extendedcommands.*;
/*****************************************/

////////{ CbC: Command By Comments /////////
//14.03.2017//

boolean silberverteilung = true;
boolean luxuseinzug = true;

//{ Inhalt:
//{0. Grundfestlegungen 
// 0.1 Konstanten für Meta-Befehle (die Tags)
// 0.2 Priorisierung Baumaterialverteilung von Materiallagern
// 0.3 Tabelle Gebäudeunterhalte
// 0.4 Unbedingte Auslösung von subMetas
// 0.5 Schutz vor +next
//} 1. Wurzelimplementierung (Parteikontainer)

//{ 2. Implementierungen der Metas
//{ 2.1 Getimed
// 2.1.1 +magbest [<x>] [<y>] [,<Kommentar>]
// 2.1.1a +segeln <Befehl> [: <Befehl1> : <Befehl2> ...]
// 2.1.2 +next<n> <order> [: <order1>:<order2>...]
// 2.1.3 +rotate<n> <Befehl>
// 2.1.4 +rotaL <Skill> <Skill1> <Skill2> ...
// 2.1.5 +lernen <Skill> <Level>
// 2.1.5a +anlernen <Skill> <Skill1> <Skill2> ... [: <Folgebefehl>]
//} 2.1.6 +rotaP <Item> <Item1> <Item2> ...
//{ 2.2 Hart
// 2.2.1 +forst [<percent>] [<AltBef>]
// 2.2.2 +herde <tier> [<percent>] [<AltBef>]
// 2.2.3 +unterhalte [<AltBef>]
// 2.2.4 +silreg [<minSilber>] [<AltBef>]
// 2.2.5 +treibe [<silber>] [<AltBef>]
//} 2.2.6 +killer [<AltBef>]
//{ 2.3 Interaktiv
//} 2.3.1 study-Komplex
//{ 2.4 Weich
// 2.4.1 +rek [<n>] [, <m>]
// 2.4.2 Lager- und Reservierung-Metas
// 2.4.3 +bewache
//} 2.4.3a +gib
//}

//{ 3. Skripte für Metas
//{ 3.1 Getimed
// 3.1.1 +magbest [<x>] [<y>] [,<Kommentar>]
// 3.1.1a +segeln <Befehl> [: <Befehl1> : <Befehl2> ...
// 3.1.2 +next<n> <Befehl>
// 3.1.3 +rotate<n> <Befehl>
// 3.1.4 +rotaL <Skill> <Skill1> <Skill2> ...
// 3.1.5 +lernen <Skill> <Level>
// 3.1.5a +anlernen <Skill> <Skill1> <Skill2> ... [: <Folgebefehl>]
//} 3.1.6 +rotaP <Item> <Item1> <Item2> ...
//{ 3.2 Hart
// 3.2.1 +forst [<percent>] [<AltBef>]
// 3.2.2 +herde <tier> [<percent>] [<AltBef>]
// 3.2.3 +unterhalte [<AltBef>]
// 3.2.4 +silreg [<minSilber>] [<AltBef>]
// 3.2.5 +treibe [<silber>] [<AltBef>]
//} 3.2.6 +killer [<AltBef>]
//{ 3.3 Interaktiv
//} 3.3.1 study-Komplex
//{ 3.4 Weich
// 3.4.1 +rek [<n>] [,<m>]
// 3.4.2 lager- und Reservierungsmetas
// 3.4.3 +bewache
//} 3.4.3a +gib
//}
//{ 4. Allgemeine Hilfsfunktionen
// 4.1 setOrderPreserveComments(Unit,String)
//     (ersetzt helper.setOrder(Unit,String), wenn Kommentare erhalten bleiben sollen)
// 4.2 int getResourceAmount(Region,String)
//     (erleichtert das Finden von ...allem)
// 4.3 ArrayList unitsInRegionWithOrder(Region,String)
//     (Listet Einheiten in der Region mit einem bestimmten String im Befehlsblock)
// 4.4 ArrayList unitsInRegionWithOrder(Region,String)
//     (Listet die bekannten Befehle von Einheiten in der Region)
// 4.5 ArrayList splitToArrayList(String,String)
//     (mimiks String.split(String) und erlaubt Zugriff über Index)
// 4.6 ArrayList splitToArrayList(String,String,int)
//     (mimiks String.split(String,int) und erlaubt Zugriff über Index)
// 4.7 int lerntage(Unit,String)
//     (Gibt die Lerntage von Unit für das Talent String aus)
// 4.8 int modifiedLerntage(Unit,String)
//     (Wie 4.7, aber mit Update nach Befehlen)
// 4.9 ArrayList longOrders
// 4.9.a boolean isLongOrder(String);
//}
//}
//}
/**********************************************/

/**********************************************/
////////////// 0. Grundfestlegungen ////////////
/**********************************************/

//{ 0.1 Konstanten für Meta-Befehle (die Tags)
String com = "//";
String com2 = ";";
String me = "// +";
String me2 = ";; +";
String me3 = ",, +";
ArrayList starters = new ArrayList();
starters.add(me);
starters.add(me2);
//}

//{ 0.2 Priorisierung BauMatVertlg /////////
ArrayList mLagerBedient = new ArrayList();
mLagerBedient.add(me+"nkw"); // Waffenbau
mLagerBedient.add(me+"bogner"); // Bogenbau
mLagerBedient.add(me+"ruestung"); // Ruestungsbau
mLagerBedient.add(me+"wagner"); // Wagenbau
mLagerBedient.add(me+"reeder"); // Schiffbau
//}

//{ 0.3 Gebäude-Unterhalte
HashMap buildingMaintenances = new HashMap();
buildingMaintenances.put("Bergwerk", 100);
buildingMaintenances.put("Hafen", 100);
buildingMaintenances.put("Holzfällerhütte", 50);
buildingMaintenances.put("Leuchtturm", 100);
buildingMaintenances.put("Mine", 50);
buildingMaintenances.put("Monument", 100);
buildingMaintenances.put("Sägewerk", 100);
buildingMaintenances.put("Sattlerei", 100);
buildingMaintenances.put("Schiffswerft", 100);
buildingMaintenances.put("Schmiede", 100);
buildingMaintenances.put("Seehafen", 300);
buildingMaintenances.put("Steg", 30);
buildingMaintenances.put("Steinbruch", 100);
buildingMaintenances.put("Steingrube", 50);
buildingMaintenances.put("Steuerturm", 50);
buildingMaintenances.put("Werkstatt", 100);
//}

//{ 0.4 Unbedingte Auslösung von subMetas
ArrayList unconditional = new ArrayList();
unconditional.add("magbest");
unconditional.add("rotaL");
unconditional.add("rotaP");
unconditional.add("rek");
//}

//{ 0.5 Schutz vor +next
ArrayList nextVerschont = new ArrayList();
nextVerschont.add(me+"magbest");
nextVerschont.add(me+"bewache");
nextVerschont.add(me+"segeln");
//}

/******************************************/
////////// Wurzelimplementierung //////////
/*****************************************/

cbc_Alpha(String factionID){
 for(Region region : world.regions().values()){
  implementMetas_cbc_Alpha(region, factionID);
 }// /for(Region
}// /cbc_Alpha(String)

/*****************************************/
//// 2. Implementierung der Metas /////////
/*****************************************/

implementMetas_cbc_Alpha(Region region, String factionID){
 // Metas in der Region suchen und auslösen
 // (erst // +, dann ;; +)
 for(String starter : starters){
  ArrayList thisMeta = new ArrayList();
 //{ 2.1 Getimete Metas
  // 2.1.1 +magbest
  thisMeta = unitsInRegionWithOrder(region, starter+"magbest");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"magbest")){ex=true;}// /if(o
    }// /for(String
    if(ex){magbest(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thismeta
  // /magbest

  // 2.1.1a +segeln
  thisMeta = unitsInRegionWithOrder(region, starter+"segeln");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"segeln")){ex = true;}// /if(o
    }// /for(String
    if (ex){segeln(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /segeln

  // 2.1.2 +next
  thisMeta = unitsInRegionWithOrder(region, starter+"next");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if(o.trim().startsWith(starter+"next")){ex = true;}// /if(o
    }// /for(String	
    if(ex){next(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!thisMeta
  // /next
 
  // 2.1.3 +rotate
  thisMeta = unitsInRegionWithOrder(region, starter+"rotate");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if(o.trim().startsWith(starter+"rotate")){ex = true;}// /if(o
    }// /for(String	
    if(ex){rotate(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /rotate
 
  // 2.1.4 +rotaL
  thisMeta = unitsInRegionWithOrder(region, starter+"rotaL");
  if (!(thisMeta.isEmpty())){
    for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if(o.trim().startsWith(starter+"rotaL")){ex = true;}// /if(o
    }// /for(String	
    if(ex){rotaL(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /rotaL
 
  // 2.1.5 +lernen
  thisMeta = unitsInRegionWithOrder(region, starter+"lernen");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
   String argline = "";
   boolean ex = false;
   for(String order : unit.getOrders()){
    if (order.trim().startsWith(starter+"lernen")){
     ex = true;
     argline = order.substring(10).trim();
    }// /if(order
   }// /for(String
   if(ex){lernen(unit, argline);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /lernen

  // 2.1.5a +anlernen
  thisMeta = unitsInRegionWithOrder(region, starter+"anlernen");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"anlernen")){ex = true;}// /if(o
    }// /for(String
    if (ex){anlernen(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /anlernen

  // 2.1.6 +rotaP
  thisMeta = unitsInRegionWithOrder(region, starter+"rotaP");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"rotaP")){ex=true;}// /if(o
    }// /for(String
    if (ex){rotaP(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /rotaP
//}
 
 //{ 2.2 Harte Metas
  // 2.2.1 ;; +forst n <Altbef>
  thisMeta = unitsInRegionWithOrder(region, starter+"forst");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    ArrayList args = new ArrayList();
    boolean ex = false;
    for(String order : unit.getOrders()){
     if(order.trim().startsWith(starter+"forst")){
      args = splitToArrayList(order.substring(9).trim(), " ", 2);
      ex = true;
     }// /if(order
    }// /for(String)
    if(ex){forst(unit, args);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /forst
 
  // 2.2.2 +herde
  thisMeta = unitsInRegionWithOrder(region, starter+"herde");
  if(!(thisMeta.isEmpty())){
   for(Unit unit: thisMeta){
    boolean ex = false;
    for(String order: unit.getOrders()){
     if(order.trim().startsWith(starter+"herde")){ex = true;}// /if(order
    }// /for(String
    if(ex){monoHerde(unit, starter);}
   }// for(Unit
  thisMeta.clear();
  }// /if(!(thisMeta
  // /herde
 
  // 2.2.3 +unterhalte <AltBef> && ;; +unterhalte <AltBef>
  //(subMetas für den Alternativbefehl)
  thisMeta = unitsInRegionWithOrder(region, starter+"unterhalte");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    String altBef = "LERNE Unterhaltung";
    boolean ex = false;
    for (String order : unit.getOrders()){
     if(order.trim().startsWith(starter+"unterhalte")){
      ex = true;
      if (order.length() > 15){altBef = order.substring(15).trim();}
     }// /id(order
	}// /for(String
    if (ex){unterhalte(unit, altBef);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /unterhalte
 
  // 2.2.4 +silreg <MinSilber> <altBef> & ;; +silreg <altBef>
  //(subMetas für den Alternativbefehl)
  thisMeta = unitsInRegionWithOrder(region, starter+"silreg");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    boolean ex = false;
    for (String order : unit.getOrders()){
     if (order.trim().startsWith(starter+"silreg")){ex = true;}// /if(order
    }// /for(String
    if(ex){silReg(unit, starter);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /silreg
 
  // 2.2.5 +treibe <altBef>
  //(SubMetas für Alternativbefehl)
  thisMeta = unitsInRegionWithOrder(region, starter+"treibe");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    boolean ex = false;
    for (String order : unit.getOrders()){
     if (order.trim().startsWith(starter+"treibe")){ex = true;}// /if(order
 	if(ex){treibe(unit, starter);}// /if(ex
    }// /for(String
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
 
  // 2.2.6 +killer [<AltBef>]
  thisMeta = unitsInRegionWithOrder(region, starter+"killer");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"killer")){ex = true;}// /if(o
    }// /for(String
    if (ex){killer(unit, starter);}// /if(ex
   }// /for(Unit
  }// /if(!(thisMeta
  // /killer
 //}
 
 //{ 2.3 Interaktive Metas
  // 2.3.1 +lerne<p> <skill> [<level> [<AltBef>]]  & +lehre<p> <skill1> [<skill1> <skill2>][, <AltBef>]
  if (starter.equals(me)){studyComplex(region);}
 //}
 
 //{ 2.4 Weiche Metas
 for (Unit unit : region.units()){
 // 2.4.1 +rek [<n>] [, <m>]
  if (unit.getOrders().toString().contains(starter+"rek")){
   boolean ex = false;
   for (String o : unit.getOrders()){
    if (o.startsWith(starter+"rek")){ex=true;}
   }// /for(String
   if (ex){regulator(unit, region, starter);}
  }// /if(unit.getOrders
 // /rek

 // 2.4.2 +lager und Reservierungen
  if (starter.equals(me)){
   if(unit.getOrders().toString().contains(me+"lager") && silberverteilung){lager(unit);}
   if(unit.getOrders().toString().contains(me+"sLag")){sLager(unit);}
   if(unit.getOrders().toString().contains(me+"nLag")){nLager(unit);}
   if(unit.getOrders().toString().contains(me+"fLag")){fLager(unit);}
   if(unit.getOrders().toString().contains(me+"mLag")){mLager(unit);}
   if(unit.getOrders().toString().contains(me+"rLag")){rLager(unit);}
   if(unit.getOrders().toString().contains(me+"tLag")){tLager(unit);}
   if(unit.getOrders().toString().contains("HANDEL") && luxuseinzug){handel(unit);}
 // /lager und Reservierungen

   // 2.4.3 +bewache
   autarn(unit);
 // /bewache
  }// /if(starter
 }// /for(Unit
 
   // 2.4.3a +gib
  thisMeta = unitsInRegionWithOrder(region, starter+"gib");
  if (!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    boolean ex = false;
    for(String order : unit.getOrders()){
     if(order.trim().startsWith(starter+"gib")){ex=true;}// /if(order
    }// /for(String
    if(ex){gib(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMEta
  // /gib
}// /for(String starter
 
//}
  // 2.4.4 +segelnII : Ozean
  thisMeta = unitsInRegionWithOrder(region, starter+"segeln");
  if (region.getType().toString().equals("Ozean") && !(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"segeln")){ex = true;}// /if(o
    }// /for(String
    if (ex){segeln(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /segeln

}// /implementMetas_cbc_Alpha(Region,String)

/*****************************************/
/////////// 3. Skripte für Metas //////////
/*****************************************/
//{ 3.1 Getimte Metas
 // 3.1.1 +magbest [<x>][<y>][, <Kommentar>]
	// x,y € N
	// x>0 => bestätigt; x--
	// x == 0 => ~bestätigt
	// y>0 && x==0 => x=y
magbest(Unit unit){
// Variabeln:
 int noch = 1;
 int setz = 0;
 String comment = "";
 boolean rewrite = false; // nötig, wenn x != 0
 ArrayList you = new ArrayList();
// Parameter raussuchen:
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(me+"magbest")){
   you = splitToArrayList(o, " ", 5);
   if (you.size() > 2){
    try {
     noch = Integer.parseInt(you.get(2))-1;
     rewrite = true;
     try {
      setz = Integer.parseInt(you.get(3));
     }// /try
     catch(IndexOutOfBoundsException oob){setz = 0;}// /catch(oob
     catch (NumberFormatException nfe2){setz = 0;}// /catch(nfe2 == setz erzwingen
    }// /try
    catch (NumberFormatException nfe){noch = 1;}// /catch(nfe == noch erzwingen
    if (o.contains(",")){comment = o.substring(o.indexOf(",")+1).trim();}// /if(o.contains
   }// /if(you
  }// /if(o
 }// /for(String
// (nicht) bestätigen
 if (noch > 0){unit.setOrdersConfirmed(true);}// /if(noch
 else{ // == if (noch <= 0
  unit.setOrdersConfirmed(false);
  noch = setz; // also wieder hoch, oder auf null
 }// /else <- if(noch>0
// neuschreiben
 if (rewrite){
  you.clear(); // recycling
  // Kommentar einbauen
  if (!(unit.isOrdersConfirmed()) && comment != ""){you.add(comment);}
  // restliche Zeilen einsammeln
  for (String o : unit.getOrders()){
   if (!(o.trim().startsWith(me+"magbest"))){you.add(o);}// /if(!(o
  }// /for(String
  // clearing
  helper.setOrder(unit, "");
  // neue magbest-Zeile
  String newbest = "";
  if (noch > 0){
   newbest = me+"magbest "+noch.toString()+" "+setz.toString();
   if (comment != ""){newbest = newbest+" ,"+comment;}
  }// /if(noch
  helper.addOrder(unit, newbest);
  for (String o : you){helper.addOrder(unit, o);}
 }// /if(rewrite
}// /magbest(Unit)

// 3.1.1a // +segeln
segeln(Unit unit, String starter){
 helper.addOrder(unit, unit.getRegion().toString());
 helper.updateUnit(unit);
 String currentOrder = "";
 for (String order : unit.getOrders()){
  if (order.trim().startsWith(starter+"segeln")){
   if (unit.getOrders().toString().contains("Ozean")){currentOrder = "FAULENZE ; segelbedingt";}
   else {currentOrder = order.substring(10).trim();}
  }
 }
 setOrderPreserveComments(unit, currentOrder);
 helper.updateUnit(unit);
}// /segeln(Unit,String)

 // 3.1.2 +next<n> <order> [: <order1>:<order2>...]
 // Setzt bei Auslösung subMetas zu Dauermetas und löscht alle Metas, die nicht in nextVerschont stehen
next(Unit unit){
 ArrayList ordinaries = new ArrayList(); // alles, was nicht mit +next und anfangt und nicht ausgelöscht wird
 ArrayList newNexts = new ArrayList(); // nexts, die nicht diese Runde zuschlagen
 ArrayList doNow = new ArrayList(); // was durch next jetzt ausgelöst wird (verdrängt alles, was kein Kommentar ist
// 1.: die ArrayListen füllen
 for (String o : unit.getOrders()){
  if (!(o.trim().startsWith(me+"next")) ){ordinaries.add(o);}
  else{int wann = Integer.parseInt(splitToArrayList(o, " ").get(1).substring(5))-1;
   if(wann > 0){o=o.substring(o.indexOf(" ")).trim();
    o=o.substring(o.indexOf(" ")).trim();
    newNexts.add(me+"next"+wann.toString()+" "+o);}// /if(wann>0
   else{for(String now : splitToArrayList(o, " ", 3).get(2).split(":")){doNow.add(now.trim());}}
   }// /else <-- if(!(o.startsWith
 }// /for(String o
 helper.setOrder(unit, "");
 helper.updateUnit(unit);
// 2: neue +next einfügen (dann sind die immer oben
 for (String next : newNexts){helper.addOrder(unit, next);}
 helper.updateUnit(unit);
// 3: Rest einfügen; wenn doNow, ungeschützte Metabefehle rausschmeißen
 for(String ord : ordinaries){
  if (doNow.size() > 0){
   if (ord.trim().startsWith(com)){
	if (!(ord.trim().startsWith(me))){helper.addOrder(unit, ord);}
    else {
     boolean take = false;
     for (String prot : nextVerschont){if(ord.trim().startsWith(prot)){take = true;}}
     if (take){helper.addOrder(unit, ord);}
    }// /else
   }// /if(ord
  }// /if(doNow.size>0
  else{helper.addOrder(unit, ord);}// /else <-- if(doNow.size>0
 }// /for(String ord
 helper.updateUnit(unit);
//5: wenn next was auslöst, das durchziehen
 if (doNow.size() > 0){
  for(String dot : doNow){ // somewhat silly, but "do" wont work as variable
   // subMetas umwandeln
   if(dot.trim().startsWith(me2)){
    helper.addOrder(unit, dot);
    helper.addOrder(unit, me+dot.substring(4));
   }// /if(dot.trim
   else {helper.addOrder(unit, dot.trim());}
  }// /for(String dot
 }// /if(doNow.size>0
 helper.updateUnit(unit);
}// /next(Unit,String)

 // 3.1.3 +rotate<n> <order>[ : <order1> : <order2>...]
 // +rotaMax <n> (optional; hilft, einen bestimmten, nicht streng-sequentiellen Rhythmus aufrecht zu erhalten)
rotate(Unit unit){
 // vorforhandene Befehle sortieren
 ArrayList rotates = new ArrayList();
 ArrayList comments = new ArrayList();
 int rotaMax = 0;
 for (String order : unit.getOrders()){if (!(order.trim().startsWith(me+"rotate"))){comments.add(order);}
  else{rotates.add(order.substring(10));}
  if (order.trim().startsWith(me+"rotaMax")){rotaMax = Integer.parseInt(splitToArrayList(order, " ").get(2));}
  }// /for(String order
 // vorvorhandene Befehle loswerden
 helper.setOrder(unit, "");
 String zerotate = "";
 for (String rot : rotates){int arg = Integer.parseInt(rot.substring(0, rot.indexOf(" ")));
  if(arg > rotaMax){rotaMax = arg;}
  if (arg - 1 == 0){zerotate = rot.substring(rot.indexOf(" ")).trim();}
  else{helper.addOrder(unit, me+"rotate"+(arg-1).toString()+" "+rot.substring(rot.indexOf(" ")).trim());}
 }// for(rot
 if (zerotate != ""){helper.addOrder(unit, me+"rotate"+rotaMax.toString()+" "+zerotate);} 
 for (String comment : comments){helper.addOrder(unit, comment);}
 if (zerotate != ""){ArrayList doNow = splitToArrayList(zerotate, ":");
  setOrderPreserveComments(unit, doNow.get(0));
  int i = 1;
  while (i<doNow.size()){helper.addOrder(unit, doNow.get(i));
   i++;}
  }// /if(zerotate!=""
}// /rotate(Unit)

 // 3.1.4 +rotaL skill skill2 skill3 skill4 skill1 ...
rotaL(Unit unit, String starter){
 ArrayList newOrders = new ArrayList();
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(com) && !(o.trim().startsWith(starter+"rotaL"))){newOrders.add(o);}
  if (o.trim().startsWith(starter+"rotaL")){o = o.substring(9).trim();
   String skill = o.substring(0, o.indexOf(" ")).trim();
   o = o.substring(o.indexOf(" ")).trim()+" "+skill;
   String newLine = starter+"rotaL "+o;
   newOrders.add(newLine);
   newOrders.add("LERNE "+skill);
  }// /if(o.startsWith starter
 }// /for(String o
 helper.setOrder(unit, "");
 for (String newOrder : newOrders){helper.addOrder(unit, newOrder);}
 helper.updateUnit(unit);
}// /rotaL(Unit)

 //{ 3.1.5 +lernen <skill> [<lvl>] [<nextOrder>]
lernen(Unit unit, String argline){
// VariabelnDeklaration
 int lvl = 1;
 String nextOrder = "";
 ArrayList args = splitToArrayList(argline, " ", 3);
 String skill = args.get(0);
 if (isImplementedSkill(skill)){// Schreibungsprüfung
  if (args.size() > 1){
   try {
    lvl = Integer.parseInt(args.get(1));
   }// /try
   catch(NumberFormatException lernenOhneNummer){
    lvl = 1;
    nextOrder = args.get(1);
   }// /catch/NumberFormatException
  }// /if(args.size > 1
  // Level-Kontrolle:
  if (helper.getLevel(unit, skill) < lvl){
   unit.setOrdersConfirmed(true);
  }// /if(helper.getLevel
  else{
   unit.setOrdersConfirmed(false);
   setOrderPreserveComments(unit, "; "+skill+" fertig gelernt");
   if (args.size() > 2){
    nextOrder = nextOrder+" "+args.get(2);
   }// /if(args.size > 2
   for(String doNow : nextOrder.split(":")){
    if(doNow.trim().startsWith(me2)){helper.addOrder(unit, me+doNow.substring(me2.length()+1));}
    else {helper.addOrder(unit, doNow.trim());}
   }
   helper.updateUnit(unit);
   // +lerne herausfischen:
  }// /else <-- if(helper.getLevel
 }// /if(isImplementedSkill
 else{
  unit.setOrdersConfirmed(false);
  helper.addOrder(unit, "Meta-Warnung +lernen: Talent falsch geschrieben oder nicht implementiert!");
  helper.updateUnit(unit);
 }// /else <-- if(isImplementedSkill
}// /lernen(Unit,String)

 boolean isImplementedSkill(String skill){
 // Kontrolliert bei +lernen, +anlernen, ob <skill> richtig geschrieben wurde
  if (skillList.contains(skillUmlaute(skill))){
   return true;
  }// /if(skillList.contains
  else{
   return false;
  }// /else
}// /boolean isImplementedSkill(String)

 String skillList = "Armbrustschießen Ausdauer ausdauer Bergbau Bogenbau Bogenschießen Burgenbau Handel Hiebwaffen Holzfällen Katapultbedienung Magie Pferdedressur Reiten Rüstungsbau Schiffbau Segeln Speerkampf Spionage Steinbau Steuereintreiben Straßenbau Taktik Tarnung Unterhaltung Waffenbau Wagenbau Wahrnehmung";
 String skillListMitUmlaute = "Armbrustschießen Bogenschießen Holzfällen Rüstungsbau Straßenbau";
 String skillListOhneUmlaute = "Armbrustschiessen Bogenschiessen Holzfaellen Ruestungsbau Strassenbau";

 String skillUmlaute(String skill){
 // um die Umlautumschreibung des Servers zu umgehen (Ein kleiner Kippschalter)
  if(skillListMitUmlaute.contains(skill)){
   return splitToArrayList(skillListOhneUmlaute, " ").get(splitToArrayList(skillListMitUmlaute, " ").indexOf(skill));}
  if(skillListOhneUmlaute.contains(skill)){
   return splitToArrayList(skillListMitUmlaute, " ").get(splitToArrayList(skillListOhneUmlaute, " ").indexOf(skill));}
  else {return skill;}
 }// /String skillUmlaute(String)
//} /lernen

 // +anlernen
 // 3.1.5a +anlernen <Skill> <Skill1> <Skill2> ... [: <Folgebefehl>]
anlernen(Unit unit, String starter){
 // Variabeln:
 String learnOrder = ""; // "LERNE" oder "falschgeschrieben"
 String skills = "";
 String follow = ""; // Folgebefehl
 boolean spell = true;
 // Argumente extrahieren
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"anlernen")){
   skills = o.substring(12).trim();
  }// /if(o
  if (skills.contains(":")){
   follow = skills.substring(skills.indexOf(":")+1).trim();
   skills = skills.substring(0, skills.indexOf(":")).trim();
  }// /if(skills
 }// /for(String
 for (String skill : skills.split(" ")){
  if(isImplementedSkill(skill)){
   if (helper.getLevel(unit, skillUmlaute(skill)) < 1 && !(learnOrder.contains("LERNE"))){learnOrder = learnOrder+":LERNE "+skill;}// /if(helper
  }// /if(isImplementedSkill
  else {learnOrder = learnOrder+":CbC-Warnung: Talent "+skill+" falsch geschrieben oder nicht implementiert";}// /else <- if(isImplementedSkill
 }// /for(String
 if (learnOrder.contains(":")){
  unit.setOrdersConfirmed(true);
  setOrderPreserveComments(unit, "");
  for (String doNow : learnOrder.split(":")){
   helper.addOrder(unit, doNow);
  }// /for(String
  helper.updateUnit(unit);
  if (unit.getOrders().toString().contains("CbC-Warnung")){unit.setOrdersConfirmed(false);}// /if(unit
 }// /if(learnOrder
 else {
  setOrderPreserveComments(unit, "; fertig gelernt");
  for (String doNow : follow.split(":")){
   if (doNow.trim().startsWith(me2)){helper.addOrder(unit, com+doNow.trim().substring(doNow.trim().indexOf(" ")));}// /if(doNOw
   else {helper.addOrder(unit, doNow.trim());}// /else
  }// /for(String
  helper.updateUnit(unit);
 }// /else <- if(learnOrder
}// /anlernen(Unit,String)
 // 3.1.6 +rotaP skill skill2 skill3 skill4 skill1 ...
rotaP(Unit unit){
 ArrayList newOrders = new ArrayList();
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(com) && !(o.trim().startsWith(me+"rotaP"))){
   newOrders.add(o);}
  if (o.trim().startsWith(me+"rotaP")){o = o.substring(9).trim();
   String skill = o.substring(0, o.indexOf(" ")).trim();
   o = o.substring(o.indexOf(" ")).trim()+" "+skill;
   String newLine = me+"rotaP "+o;
   newOrders.add(newLine);
   newOrders.add("MACHE "+skill);
  }// /if(o.startsWith me
 }// /for(String o
 helper.setOrder(unit, "");
 for (String newOrder : newOrders){
  helper.addOrder(unit, newOrder);
 }// /for String newOrder
 helper.updateUnit(unit);
}// /rotaP(Unit)
//}

//{ 3.2 Harte Metas
 // 3.2.1 +forst| [<perc> <altBef>]
forst(Unit unit, ArrayList args){
 if (helper.getLevel(unit, "Holzfällen") < 1){setOrderPreserveComments(unit, "LERNE Holzfaellen");}
 else{
// Default-Einstellungen
  boolean argZeroIsNumber = false;
  int perc = 0;
  String altBef = "LERNE Holzfaellen";
  int holz = getResourceAmount(unit.getRegion(), "Holz");
  if (args.size() > 0){
   try {perc = Integer.parseInt(args.get(0));
    argZeroIsNumber = true;
   }// /try
   catch (NumberFormatException forstOhneZahl){
    perc = 0;
    argZeroIsNumber = false;
   }// /catch(NumberFormatException
  }// /if(args.size > 0
  int soll = unit.getRegion().getType().getInhabitants() * perc / 1000; // durch 100 weil prozente, dann nochmal durch 10, weil Bäume
  int kann = helper.getLevel(unit, "Holzfällen") * unit.getPersons();
  int diff = 2 * (holz - soll); // wir gehen mal von Sägewerk als Standardszenario aus (lässt sich leichter rechnen als andersrum)
  if (!(unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Sägewerk"))){
   diff = diff / 2;}// und hier korrigieren wir im gegenteiligen Fall
  if (diff <= 0){
   if (argZeroIsNumber){
    if (args.size() > 1){
     altBef = args.get(1);
    }// /if(args.size > 1
   }// /if(argZeroIsNumber
   else{
    if (args.size() > 0){
     altBef = args.get(0);
    }// /if(args.size > 0
    if (args.size() > 1){
     altBef = altBef+" "+args.get(1);
    }// /if(args.size > 1
   }// /else <--if(argZeroIsNumber
   setOrderPreserveComments(unit, altBef);
  }// /if(diff
  else{
   if (diff > kann){
    setOrderPreserveComments(unit, "MACHE Holz");
   }// /if(diff > kann
   else{
    setOrderPreserveComments(unit, "MACHE "+diff.toString()+" Holz");
   }// /else <-- if(diff > kann
  }// /else <--if(diff <= 0
  helper.addOrder(unit, "; Pruefzahl forst: "+soll.toString());
 }// /else <-- if(helper.getLevel
 helper.updateUnit(unit);
}// /forst(Unit,ArrayList)

 // 3.2.2 ;; +herde <tier> <perc> [<altBef>]
monoHerde(Unit unit, String starter){
 // Variabeln
 ArrayList argline = new ArrayList();
 int quali = 1; // TW(Pferdedressur)
 String tier = "Pferd";
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"herde")){argline = splitToArrayList(o.substring(9).trim(), " ", 3);}// /if(o
 }// /for(String
 try {tier = argline.get(0);}// /try
 catch(IndexOutOfBoundsException oob){tier = tier;}// /catch(oob
 if (tier.equals("Elefant") || tier.equals("Mastodon")){
  quali = 2;
 }// /if(tier
 if (helper.getLevel(unit, "Pferdedressur") < quali){
  setOrderPreserveComments(unit, "LERNE Pferdedressur");
 }// /if(helper.getLevel
 else{
// Defaulteinstellungen
  boolean argZeroIsNumber = false;
  String altBef = "LERNE Pferdedressur";
  int perc = 0;
  if (argline.size() > 1){
   try {
    perc = Integer.parseInt(argline.get(1));
    argZeroIsNumber = true;
   }// /try
   catch (NumberFormatException herdeOhneZahl){
    perc = 0;
    argZeroIsNumber = false;
   }// /catch(NumberFormatException
  }// /if(argline.size
  int kann = helper.getLevel(unit, "Pferdedressur") * unit.getPersons() / quali;
  int soll = unit.getRegion().getType().getInhabitants() * perc / 100;
  if (quali == 2){
   soll = soll / 5;
  }// /if(quali
  int t = getResourceAmount(unit.getRegion(), tier);
  int diff = t - soll;
  if (diff <= 0){
   if (argZeroIsNumber){
    if (argline.size() > 2){
     altBef = argline.get(2);
    }// /if(argline.size>2
   }// /if(argZeroIsNumber
   else{
    if (argline.size() > 1){
     altBef = argline.get(1);
     if (argline.size() > 2){
      altBef = altBef+" "+argline.get(2);
     }// /if(argline.size > 2
    }// if(argline.size > 1
   }// /else <-- if(argZeroIsNumber
   setOrderPreserveComments(unit, altBef);
  }// /if(diff <=0
  else{
   if (diff >= kann){
    setOrderPreserveComments(unit, "MACHE "+tier);
   }// /if(diff >= kann
   else{
    setOrderPreserveComments(unit, "MACHE "+diff.toString()+" "+tier);
   }// /else <-- if(diff >= kann
  }// /else <-- if(diff <= 0
  helper.addOrder(unit, "; Pruefzahl herde: "+soll.toString()+" "+tier);
 }// /else<--if(helper.getLevel
 helper.updateUnit(unit);
}// /monoHerde(Unit,String)

 // 3.2.3 +unterhalte <AltBef>
unterhalte(Unit unit, String altBef){
 int soll = unit.getRegion().getType().getInhabitants() * (unit.getRegion().getWage()-10) * 20;
 int kann = 20 * unit.getPersons() * helper.getLevel(unit, "Unterhaltung");
 if (kann <= unit.getRegion().maxEntertain()){setOrderPreserveComments(unit, "UNTERHALTE");}// /if(kann
 else{
  int diff = unit.getRegion().getSilver() - soll;
  if (diff > 0){setOrderPreserveComments(unit, "UNTERHALTE "+diff.toString());}// /if(diff
  else{setOrderPreserveComments(unit, altBef);}
 }// /else <- if(kann
 helper.addOrder(unit, "; unterhaellt automatisch");
 helper.updateUnit(unit);
}// /unterhalte(Unit,String)

 // 3.2.4 +silreg <minSilber> <AltBef>
 // wie +herde oder +forst, aber ohne Prozente und bezogen auf das Altsilber/den Stash
 // wenn <minSilber> ~angegeben, auf das 20fache des regenerativen Maximums
silReg(Unit unit, String starter){
 int soll = unit.getRegion().getType().getInhabitants() * (unit.getRegion().getWage()-10) * 20;
 int kann = unit.getPersons() * 20 * helper.getLevel(unit, "Steuereintreiben");
 String altBef = "LERNE Steuereintreiben";
 for(String o : unit.getOrders()){
  if(o.trim().startsWith(starter+"silreg")){
   try {
    soll = Integer.parseInt(splitToArrayList(o, " ").get(2));
    try {altBef = splitToArrayList(o, " ", 4).get(3);}// /try
    catch(IndexOutOfBoundsException oob){altBef = altBef;}// /catch(oob
   }// /try
   catch(NumberFormatException nfe){
    soll = soll;
    try {altBef = splitToArrayList(o, " ", 3).get(2);}// /try
    catch(IndexOutOfBoundsException oob){altBef = altBef;}// /catch(oob
   }// /catch(nfe
  }// /if(o
 }// /for(String
 int diff = unit.getRegion().getSilver() - soll;
 if (diff <= 0){setOrderPreserveComments(unit, altBef);}// /if(diff <=
 else{
  if (diff >= kann){setOrderPreserveComments(unit, "TREIBE");}// /if(diff>=
  else{setOrderPreserveComments(unit, "TREIBE "+diff.toString());}// /else
 }// /else <- if(diff <=
 helper.updateUnit(unit);
}// /silReg(Unit,String)

 // 3.2.5 +treibe <silber> <altBef>
 // Treibt <silber> Silber, wenn mind so viel im Stash/Altsilber,
 // sonst <altBef> (wenn ~angegeben: LERNE Steuereintreiben)
 // wenn ~<silber> angegeben, wird es auf das regenerative Maximum gesetzt
treibe(Unit unit, String starter){
 int soll = unit.getRegion().getType().getInhabitants() * (unit.getRegion().getWage()-10);
 int kann = unit.getPersons() * 20 * helper.getLevel(unit, "Steuereintreiben");
 String waga = "LERNE Steuereintreiben";
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"treibe")){
   args = splitToArrayList(o, " ", 4);
   boolean haveNumeric = false;
   if (args.size() > 2){
    try {
     soll = Integer.parseInt(args.get(2));
     haveNumeric = true;
    }// /try
    catch (NumberFormatException nfe){waga = args.get(2);}// /catch nfe
    if (haveNumeric){
     if (args.size() > 3){waga = args.get(3);}// /if (args > 3
    }// /if(haveNumeric
    else {
     try {
      waga = args.get(2);
      if (args.size() > 3){waga = waga+" "+args.get(3);}// /if args > 3
     }// /try
     catch (IndexOutOfBoundsException oob){waga = waga;}// /catch oob
    }// /else <- haveNumeric
   }// /if(args > 2
  }// /if(o
 }// /for(String
 int diff = unit.getRegion().getSilver() - soll;
 if (diff <=0){setOrderPreserveComments(unit, waga);}// /if(diff <=
 else{
  if (diff >= kann){setOrderPreserveComments(unit, "TREIBE "+soll.toString());}// /if(diff >=
  else{
   if (diff > kann /2){setOrderPreserveComments(unit, "TREIBE "+diff.toString());}// /if(diff >
   else{setOrderPreserveComments(unit, waga);}// /else
  }// /else <- if(diff >=
 }// /else <- if(diff <=
 helper.updateUnit(unit);
}// /treibe(Unit,String)

 // 3.2.6 +killer [<AltBef>]
killer(Unit unit, String starter){
 // Kann er überhaupt Steuern eintreiben?
 if (helper.getLevel(unit, "Steuereintreiben") < 1){setOrderPreserveComments(unit, "LERNE Steuereintreiben");}
 else{
  String altBef = "LERNE Steuereintreiben"; // Standardeinstellung
  // Alternativbefehl suchen
  for (String o : unit.getOrders()){
   if (o.trim().startsWith(starter+"killer") && splitToArrayList(o, " ").size() > 2){
    altBef = splitToArrayList(o, " ", 3).get(2);
   }// /if(o
  }// /for(String
  // Freie AP und Bauern überprüfen:
  int freeAP = unit.getRegion().getType().getInhabitants() - (getResourceAmount(unit.getRegion(), "Holz")*10 + getResourceAmount(unit.getRegion(), "Elefant")*5 + getResourceAmount(unit.getRegion(), "Mastodon")*5 + getResourceAmount(unit.getRegion(), "Kamel") + getResourceAmount(unit.getRegion(), "Pferd") + getResourceAmount(unit.getRegion(), "Zotte") + getResourceAmount(unit.getRegion(), "Alpaka"));
  if (freeAP > 0 && unit.getRegion().getPeasants() > 0){setOrderPreserveComments(unit, "TREIBE");}// /if(freeAP
  else{setOrderPreserveComments(unit, altBef);}// /else
 }// /else <-if(helper
 helper.updateUnit(unit);
}// /killer(Unit,String)
//}

//{ 3.3 Interaktive Metas
 //{ 3.3.1 Study-Komplex
 // +lerne <Skill> [<level>] [<AltBef>]
 // +lehre <Skill> <AltBef>
studyComplex(Region region){
 String studyReady = "NILLL";
 for(String skill : skillList.split(" ")){
  skill = skillUmlaute(skill);// uL AUS

// betroffene Einheiten einsammeln
  // +lehre und +lerne einsammeln und auf Startposition ("NULLL") stellen:
  ArrayList schueler = unitsInRegionWithOrder(region, me+"lerne "+skill);
  for(Unit unit : schueler){
	  // Gegenprobe von +lernen
   if (!(unit.getOrders().toString().contains(skill+" fertig gelernt"))){setOrderPreserveComments(unit, studyReady);}
  }
  
  ArrayList lehrer = unitsInRegionWithOrder(region, me+"lehre "+skill);
  for(Unit unit : lehrer){setOrderPreserveComments(unit, studyReady);}

  // +lehre sucht +lerne (multiple Schüler))
  for(Unit teacher : lehrer){
   int enumPupils = 0;
   for(Unit student : schueler){
    if(student.getOrders().toString().contains(studyReady) && enumPupils + student.getPersons() <= teacher.getPersons() * 10 && helper.getLevel(student, skillUmlaute(skill)) < helper.getLevel(teacher, skillUmlaute(skill))){
     setOrderPreserveComments(student, "LERNE "+skill+" ; mit Lehrer "+teacher.getID().toString());
     helper.updateUnit(student);
     setTeachOrder(teacher, student.getID().toString());
     helper.updateUnit(teacher);
     enumPupils = enumPupils + student.getPersons();
    }// /if(enumPupils
   }// /for(Unit student
  }// /for(Unit teacher

// +lerne <skill> <lvl> <altBef>
  // +lerne ohne Lehrer bekommen Beschäftigungstherapie
  for(Unit unit : schueler){
   if(unit.getOrders().toString().contains(studyReady)){
    String altBef = "LERNE "+skill+" ; ohne Lehrer";
    for(String order : unit.getOrders()){
     if(order.trim().startsWith(me+"lerne")){
      ArrayList line = splitToArrayList(order, " ", 5);
      if(line.size() > 3){
       try {int a = Integer.parseInt(line.get(3));
        if(line.size() > 4){altBef = line.get(4)+" ; ersatzweise";}
       }// /try
       catch(NumberFormatException testballonSchuelerAltbef){
        altBef = line.get(3);
        if(line.size() > 4){altBef = altBef+" "+line.get(4)+" ; ersatzweise";}
       }// /catch(NFE
      }// /if(line.size>3
     }// /if(order.startsWith
    }// /for(String order
    setOrderPreserveComments(unit, altBef);
    helper.updateUnit(unit);
   }// /if(unit.getOrders()
  }// /for(Unit unit:schueler

// unbeschäftigte Lehrer einsammeln
  schueler.clear();
  for(Unit unit : lehrer){if(unit.getOrders().toString().contains(studyReady) || getNumberOfPupils(unit) < unit.getPersons() * 10){schueler.add(unit);}}
  lehrer = schueler.clone();
  // +lehre lehrt andere +lehre (nur Einheiten mit mehr Personsn; multiple Schüler)
  for(Unit teacher : lehrer){
   int enumSchueler = getNumberOfPupils(teacher);
   for(Unit otherTeacher : schueler){
    if(otherTeacher.getOrders().toString().contains(studyReady) && otherTeacher.getPersons() > teacher.getPersons() && enumSchueler + otherTeacher.getPersons() <= teacher.getPersons() * 10 && helper.getLevel(otherTeacher, skillUmlaute(skill)) < helper.getLevel(teacher, skillUmlaute(skill))){
     enumSchueler = enumSchueler + otherTeacher.getPersons();
     setOrderPreserveComments(otherTeacher, "LERNE "+skill+" ; mit Kollege "+teacher.getID().toString());
     helper.updateUnit(otherTeacher);
     setTeachOrder(teacher, otherTeacher.getID().toString());
     helper.updateUnit(teacher);}}}
  // unbeschäftigte +lehre einsammeln
  schueler.clear();
  for(Unit unit : lehrer){if(unit.getOrders().toString().contains(studyReady)){schueler.add(unit);}}
 // +lehre mit ohne irgendwas bekommt Beschäftigungstherapie
 // +lehre <skill> [<altBef>]
  for(Unit unit : schueler){
   String altBef = "LERNE "+skill+" ; Weiterbildung";
   for(String order : unit.getOrders()){
    if(order.trim().startsWith(me+"lehre "+skill)){
     if(splitToArrayList(order, " ", 4).size() > 3){
      altBef = splitToArrayList(order, " ", 4).get(3)+" ; ersatzweise";
     }// /if
    }// /if(order
   }// for(String
   setOrderPreserveComments(unit, altBef);
  }// /for(Unit
 }// for(String skill
}// /studyComplex(Region)

int getNumberOfPupils(Unit unit){
 int i = 0;
 for(Unit pupil : unit.getPupils()){
 i = i+pupil.getPersons();}
 return i;
}// /int getNumberOfPupils(Unit)

setTeachOrder(Unit unit, String id){
 String teach = "LEHRE";
 for(String order : unit.getOrders()){
  if(order.trim().startsWith(teach)){teach = order;}}
 setOrderPreserveComments(unit, teach+" "+id);
}// /setTeachOrder(Unit,String)
 //} /Study-Komplex
//}

//{ 3.4 Weiche Metas

 //{ 3.4.1 +rek [<n>] [,<m>]
 // n = BauernMax;
 // m = BestätigungsMax
 // +rek n , m
regulator(Unit unit, Region region, String starter){
 // Variabeln:
 int maxBau = getIdeBau(unit);
 int confirm = region.getType().getInhabitants() / 10;
 // suchen nach n und m
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"rek") && splitToArrayList(o, " ").size() > 2){
   if (o.contains(",")){
    maxBau = Integer.parseInt(o.substring(7, o.indexOf(",")).trim());
    confirm = Integer.parseInt(o.substring(o.indexOf(",")).trim());
   }// /if(o.contains
   else{maxBau = Integer.parseInt(splitToArrayList(o, " ").get(2));}
  }// /if(o.startsWith
 }// /for(String
 // Bauernpop untersuchen:
 int diff = region.getPeasants() - maxBau;
 if (diff > 0){
  diff = getLegen(unit, diff);
  int braucht = diff*(unit.getRace().getRecruitmentCosts()+10);
  // Silberlager suchen
   Unit sil = unit; // Platzhalter
   if (regionalUnitOrders(region).contains(me+"sLag")){sil = unitsInRegionWithOrder(region, me+"sLag").get(0);}// if(regionalUnitOrders
   else {
    if (regionalUnitOrders(region).contains(me+"lager")){sil = unitsInRegionWithOrder(region, me+"lager").get(0);}// /if(regionalUnitOrders
   }// /else
   if (sil.getOrders().toString().contains(me+"sLag") || sil.getOrders().toString().contains(me+"lager")){
    helper.addOrder(sil, "GIB "+unit.getID().toString()+" "+braucht.toString()+" Silber ; Rekrutierungskosten");
   }// /if(sil
   // ...oder aus den anderen Einheiten zusammensammeln:
   else{
    int s = 0; // einsammelbares Silber
    HashMap givers = new HashMap(); // in Frage kommende Einheiten und ihre Silberbeträge
    while (s < braucht){
     for (Unit other : region.units()){
      if (other.getFaction() == unit.getFaction() && other != unit && helper.getItemCount(other, "Silber") > 0){
       s = s + helper.getItemCount(other, "Silber");
       givers.put(other, helper.getItemCount(other, "Silber"));
      }// /if(other
     }// /for(Unit
    }// /while(s<braucht
    if (s >= braucht){
     for (Unit u : givers.keySet()){
      helper.addOrder(u, "GIB "+unit.getID().toString()+" "+givers.get(u)+" Silber ; Rekrutierungshilfe");
      helper.updateUnit(u);
     }// /for(Unit
    }// /if(s
   }// /else <- if(sil
   if (helper.getModifiedItemCount(unit, "Silber") >= braucht){
    helper.addOrder(unit, "REKRUTIERE "+diff.toString());
    // Bestätigung untersuchen
    if (unit.getPersons() < confirm){unit.setOrdersConfirmed(true);}// /if(unit
   }// /if(helper
   else{
    unit.setOrdersConfirmed(false);
    helper.addOrder(unit, "Meta-Warnung: Nicht genug Silber vorhanden, um zu rekrutieren");
   }// /else <- if(helper
  }// /if(diff
 helper.updateUnit(unit);
}// /regulator(Unit,Region,String)
int getIdeBau(Unit unit){
 int id = (unit.getRegion().getType().getInhabitants() / 100 * 101)-1;
 if (unit.getRegion().getType().getInhabitants() > 3999){
  id = unit.getRegion().getType().getInhabitants() / 1000 * 1005;
 }// /if(unit
 return id;
}// /int getIdeBau(Unit)

int getLegen(Unit unit, int diff){
 int re = diff;
 if (re > unit.getRegion().getPeasants() / 20){
  re = unit.getRegion().getPeasants() / 20;
 }
 if (re >= 100){
  re = re  / 100;
  return re * 100;
 }
 if (re < 100){
  if (re >= 50){
   re = re / 10;
   return re * 10;
  }
  else{
   return re;
  }
 }
}

 //} /+rek
 

 //{ 3.4.2 Lager- und Reservierung-Metas
  //  3.4.2.1 +lager
  // Allroundlager: Übernimmt alle Lagerjobs, die in der Region sonst nicht vergeben sind
lager(Unit aLager){
 ArrayList ordersInRegion = regionalUnitOrders(aLager.getRegion());
 if (!(ordersInRegion.contains(me+"sLag"))){
  sLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"nLag"))){
  nLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"fLag"))){
  fLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"mLag"))){
  mLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"rLag"))){
  rLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"tLag"))){
  tLager(aLager);
 }
}// /lager(Unit)

  // 3.4.2.2 +sLag
  // (Silber)
sLager(Unit lager){
// sammelt Silber und gibt allen Unterhalt
 for (Unit unit : lager.getRegion().units()){
  if (unit.getFaction() == lager.getFaction()){
   int futter = unit.getModifiedPersons() * 10;
   if (unit.getOrders().toString().contains("LERNE Taktik")){
    futter = futter + (unit.getPersons() * 100);
   }// /if(unit.getPersons
   if (unit.getBuilding() != null && (unit.getBuilding().getType().toString().equals("Sägewerk") || unit.getBuilding().getType().toString().equals("Bergwerk") || unit.getBuilding().getType().toString().equals("Steinbruch") || unit.getBuilding().getType().toString().equals("Schmiede") || unit.getBuilding().getType().toString().equals("Werkstatt") || unit.getBuilding().getType().toString().equals("Sattlerei") || unit.getBuilding().getType().toString().equals("Schiffswerft"))){
    futter = futter + unit.getPersons() * 5;
   }// /if(unit.getBuilding()
   if (unit.getBuilding() != null && unit == unit.getBuilding().getOwnerUnit() && buildingMaintenances.keySet().contains(unit.getBuilding().getType().toString())){
    futter = futter + buildingMaintenances.get(unit.getBuilding().getType().toString());
   }// /if(unit.getBuilding
   if (unit.getItems().toString().contains("Kriegselefant") || unit.getItems().toString().contains("Kriegsmastodon")){
    int n = helper.getItemCount(unit, "Kriegselefant") + helper.getItemCount(unit, "Kriegsmastodon");
	futter = futter + 5 * n;
   }// /if(unit.getItems
   futter = futter - helper.getModifiedItemCount(unit, "Silber");
   if (futter > 0 && unit != lager){
    helper.addOrder(lager, "GIB "+unit.getID().toString()+" "+futter+" Silber ; Futter");
    helper.updateUnit(lager);
   }// /if(futter
   if (futter < 0 && unit != lager && !(unit.getOrders().toString().contains("REKRUTIERE"))){
    helper.addOrder(unit, "GIB "+lager.getID().toString()+" "+((-1) * futter).toString()+" Silber ; einlagern");
    helper.updateUnit(unit);
   }// /if(futter
  }// /if(unit.getFaction
 }// /for(Unit
  if (lager.getOrders().toString().contains("forlage")){
  lager.setOrdersConfirmed(false);
  helper.updateUnit(lager);
 }
}// /sLager(Unit)

  // 3.4.2.3 +nLag
  //{ (Nahkampfwaffen)
nLager(Unit nLag){
 for (String waffe : nLagerZieht){
  for (Unit unit : nLag.getRegion().units()){
   if (unit.getFaction() == nLag.getFaction() && unit != nLag && (unit.getOrders().toString().contains(me+"nkw") || (unit.getOrders().toString().contains(com+" #berichte"))) && unit != nLag && helper.getModifiedItemCount(unit, waffe) > 0){
    helper.addOrder(unit, "GIB "+nLag.getID().toString()+" "+helper.getModifiedItemCount(unit, waffe).toString()+" "+waffe+" ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
}
ArrayList nLagerZieht = new ArrayList();
nLagerZieht.add("Schwert");
nLagerZieht.add("Streitaxt");
nLagerZieht.add("Kriegshammer");
nLagerZieht.add("Speer");
nLagerZieht.add("Kriegselefant");
nLagerZieht.add("Kriegsmastodon");
  //} /nLag

  // 3.4.2.4 +fLag
  //{ (Fernkampfwaffen)
fLager(Unit fLag){
 for (String waffe : fLagerZieht){
  for (Unit unit : fLag.getRegion().units()){
   if (unit.getFaction() == fLag.getFaction() && unit != fLag && (unit.getOrders().toString().contains(me+"bogner") || unit.getOrders().toString().contains(me+"wagner") || (unit.getOrders().toString().contains(com+" #berichte"))) && unit != fLag && helper.getModifiedItemCount(unit, waffe) > 0){
    helper.addOrder(unit, "GIB "+fLag.getID().toString()+" "+helper.getModifiedItemCount(unit, waffe).toString()+" "+waffe+" ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
}
ArrayList fLagerZieht = new ArrayList();
fLagerZieht.add("Bogen");
fLagerZieht.add("Armbrust");
fLagerZieht.add("Katapult");
  //} /fLag

 // 3.4.2.5 +rLag
 //{ (Rüstungsteile)
rLager(Unit rLag){
 for (String rTeil : rLagerZieht){
  for (Unit unit : rLag.getRegion().units()){
   if (unit.getFaction() == rLag.getFaction() && unit != rLag && (unit.getOrders().toString().contains(me+"ruestung") || unit.getOrders().toString().contains(com+" #berichte")) && unit != rLag && helper.getModifiedItemCount(unit, rTeil) > 0){
    helper.addOrder(unit, "GIB "+rLag.getID().toString()+" "+helper.getModifiedItemCount(unit, rTeil).toString()+" "+rTeil+" ; einlagern");
    helper.updateUnit(unit);
   }
   if (unit.getOrders().toString().contains(me+"nkw") && unit != rLag){
    int epBed = 0;
    if (helper.getLevel(unit, "Waffenbau") > 4){
     epBed = helper.getLevel(unit, "Waffenbau") * unit.getPersons() / 5;
    }
    if (epBed > 0 && helper.getModifiedItemCount(rLag, "Elefantenpanzer") >= epBed){
     helper.addOrder(rLag, "GIB "+unit.getID().toString()+" "+epBed.toString()+" Elefantenpanzer ; Waffenbauer");
     helper.updateUnit(rLag);
    }
   }
  }
 }
}
ArrayList rLagerZieht = new ArrayList();
rLagerZieht.add("Holzschild");
rLagerZieht.add("Eisenschild");
rLagerZieht.add("Kettenhemd");
rLagerZieht.add("Plattenpanzer");
rLagerZieht.add("Elefantenpanzer");
ArrayList rLagerGibt = new ArrayList();
rLagerGibt.add("Elefantenpanzer");
 //} /rLag

 // 3.4.2.6 +tLag
 //{ (Transport-Items)
tLager(Unit tLag){
 for (Unit unit : tLag.getRegion().units()){
  if (unit.getFaction() == tLag.getFaction() && unit != tLag){ // Standardprüfung zur Vermeidung sinnloser Befehlszeilen
// auf +herde & +wagner & Allroundlager prüfen
   if (unit.getOrders().toString().contains(me+"herde") || unit.getOrders().toString().contains(me+"wagner") || unit.getOrders().toString().contains(com+" #berichte")){
    for (String tier : tLagerZieht){
// auf Items prüfen
     if (helper.getItemCount(unit, tier) > 0){
      helper.addOrder(unit, "GIB "+tLag.getID().toString()+" "+helper.getModifiedItemCount(unit, tier).toString()+" "+tier+" ; einlagern");
      helper.updateUnit(unit);
     }// /if(helper.getItemCount
    }// /for(String tier
   }// /if(unit.getOrders
// Greifeneier prüfen
   if (helper.getItemCount(unit, "Greifenei") > 0){
    helper.addOrder(unit, "GIB "+tLag.getID().toString()+" "+helper.getModifiedItemCount(unit, "Greifenei").toString()+" Greifenei ; einlagern");
    helper.updateUnit(unit);
   }
  }// /if(unit.getFaction
 }// /for(Unit
}// /tLager(Unit)
ArrayList tLagerZieht = new ArrayList();
tLagerZieht.add("Pferd");
tLagerZieht.add("Kamel");
tLagerZieht.add("Elefant");
tLagerZieht.add("Alpaka");
tLagerZieht.add("Zotte");
tLagerZieht.add("Mastodon");
tLagerZieht.add("Wagen");
tLagerZieht.add("Pegasus");
ArrayList tLagerGibt = new ArrayList();
tLagerGibt.add("Elefant");
 //} /tLag

  // 3.4.2.7 +mLag
  //{ (Baumaterial)
mLager(Unit mLag){
 for (Unit unit : mLag.getRegion().units()){
  for (String mat : mLagerZieht){
   if (unit != mLag && unit.getFaction() == mLag.getFaction() && !(wirdVonMLagBedient(unit)) && helper.getItemCount(unit, mat) > 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+helper.getItemCount(unit, mat).toString()+" "+mat+" ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
 for (Unit unit : mLag.getRegion().units()){
  if (unit != mLag && unit.getFaction() == mLag.getFaction() && wirdVonMLagBedient(unit)){
   int hBed = 0;
   int eBed = 0;
   int sBed = 0;
   if (unit.getOrders().toString().contains(me+"nkw")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Waffenbau") / 2);
    eBed = eBed + (unit.getPersons() * helper.getLevel(unit, "Waffenbau"));
    sBed = sBed + (unit.getPersons() * helper.getLevel(unit, "Waffenbau") / 5);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Schmiede")){
     hBed = hBed / 2;
     eBed = eBed / 2;
     sBed = sBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"bogner")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Bogenbau") / 2);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Schmiede")){
     hBed = hBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"ruestung")){
    eBed = eBed + (unit.getPersons() * helper.getLevel(unit, "Rüstungsbau") * 2);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Sattlerei")){
     eBed = eBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"wagner")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Wagenbau") * 5);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Werkstatt")){
     hBed = hBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"reeder")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Schiffbau") / 2);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Schiffswerft")){
     hBed = hBed / 2;
    }
   }
   hBed = hBed - helper.getModifiedItemCount(unit, "Holz");
   eBed = eBed - helper.getModifiedItemCount(unit, "Eisen");
   sBed = sBed - - helper.getModifiedItemCount(unit, "Stein");
   if (hBed > 0 && helper.getItemCount(mLag, "Holz") >= hBed){
    helper.addOrder(mLag, "GIB "+unit.getID().toString()+" "+hBed.toString()+" Holz");
    helper.updateUnit(mLag);
   }
   if (hBed < 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+((-1)*hBed).toString()+" Holz ; einlagern");
    helper.updateUnit(unit);
   }
   if (eBed > 0 && helper.getItemCount(mLag, "Eisen") >= eBed){
    helper.addOrder(mLag, "GIB "+unit.getID().toString()+" "+eBed.toString()+" Eisen");
    helper.updateUnit(mLag);
   }
   if (eBed < 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+((-1)*eBed).toString()+" Eisen ; einlagern");
    helper.updateUnit(unit);
   }
   if (sBed > 0 && helper.getItemCount(mLag, "Stein") >= sBed){
    helper.addOrder(mLag, "GIB "+unit.getID().toString()+" "+sBed.toString()+" Stein");
    helper.updateUnit(mLag);
   }
   if (sBed < 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+((-1)*sBed).toString()+" Stein ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
}
ArrayList mLagerZieht = new ArrayList();
mLagerZieht.add("Holz");
mLagerZieht.add("Eisen");
mLagerZieht.add("Stein");
mLagerZieht.add("Gold");
boolean wirdVonMLagBedient(Unit unit){
 for (String fkt : mLagerBedient){
  if (unit.getOrders().toString().contains(fkt)){
   return true;
  }
 }
 return false;
}
  //} /mLag

  // 3.4.2.7 Händler: Einsammeln von Luzxusgütern
handel(Unit handler){
 for (Unit unit : handler.getRegion().units()){
  if (unit != handler && unit.getFaction() == handler.getFaction()){
   for (s : handler.getRegion().getPrices().values()){
    String lux = s.toString().substring(0, s.toString().indexOf(":"));
    if (helper.getItemCount(unit, lux) > 0){
     if (helper.getModifiedItemCount(unit, lux) > 0){
      helper.addOrder(unit, "GIB "+handler.getID().toString()+" "+helper.getItemCount(unit, lux).toString()+" "+lux+" ; einlagern");
      helper.updateUnit(unit);
     }
    }
   }
  }
 }
}
 //}

 // 3.4.3 +bewache
autarn(Unit unit){
// implementiert +bewache
// Einheiten, die Tarnen können, tarnen sich;
// Einheiten mit Parteitarnung nennen die Tarnpartei in einem Kommentar
 if (unit.getOrders().toString().contains(me+"bewache")){
  helper.addOrder(unit, "BEWACHE");
  helper.updateUnit(unit);
 }// /if(unit.getOrders
 else{
  if (unit.getBuilding() == null && !(unit.getOrders().toString().contains("TARNE Einheit ; automatisch"))){
   boolean tarn = false;
   for (skill : unit.getModifiedSkills()){
    if (skill.toString().substring(0, skill.toString().indexOf(" ")).equalsIgnoreCase("Tarnung") && !(splitToArrayList(skill.toString(), " ").get(1).equals("0"))){
     tarn = true;
    }// /if(skill
   }// /for(String
   if(tarn){helper.addOrder(unit, "TARNE Einheit ; automatisch");}// /if(tarn
   helper.updateUnit(unit);
  }// /if(unit
 }// /else
 if (unit.getGuiseFaction() != null){
  helper.addOrder(unit, "; getarnt als: "+unit.getGuiseFaction().toString());
  helper.updateUnit(unit);
 }// /if(unit.getGuiseFaction
}// /autarn(Unit)
//}

 //{ 3.4.3a +gib |<uID> <[<n>] <item> [[<n1>] <item1> [<n2>] <item2>...][;<comment>]//

gib(Unit unit, String starter){
 ArrayList sendOrders = new ArrayList();
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"gib")){
   String id = splitToArrayList(o, " ").get(2);
   if (unit.getRegion().units().toString().contains("("+id+")")){
    String ladeliste = o.substring(o.indexOf(id)+id.length()).trim();
    String comment = "";
    if (ladeliste.contains(";")){
     comment = ladeliste.substring(ladeliste.indexOf(";")).trim();
     ladeliste = ladeliste.substring(0, ladeliste.indexOf(";")).trim();
    }// /if(ladeliste.contains
    
    int i = 0;
    ArrayList liste = splitToArrayList(ladeliste, " ");
    while (i < liste.size()){
     int amount = 0;
     String item = "";
     try {
      amount = Integer.parseInt(liste.get(i));
      i++;
      item = liste.get(i);
      if (helper.getModifiedItemCount(unit, itemUmlaute(item)) > 0){
       if (amount > helper.getModifiedItemCount(unit, itemUmlaute(item))){amount = helper.getModifiedItemCount(unit, itemUmlaute(item));}// /if(amount > item
       sendOrders.add("GIB "+id+" "+amount.toString()+" "+item+" "+comment);
      }// if item > 0
      i++;
     }// /try
     catch (NumberFormatException nfe){
      item = liste.get(i);
      amount = helper.getModifiedItemCount(unit, itemUmlaute(item));
      if (amount > 0){sendOrders.add("GIB "+id+" "+amount.toString()+" "+item+" "+comment);}// /if(amount > 0
      i++;
     }// /catch
    }// /while

	}// /if(unit.getRegion
  }// /if(o.startsWith
 }// /for(String o
 for (String sendOrder : sendOrders){helper.addOrder(unit, sendOrder);}// /for(String sendOrder
 helper.updateUnit(unit);}// /gib(Unit,String)
String itemUmlaute(String item){
 if (item.startsWith("Oe")){return "Öl";}
 if(item.contains("ue")){return "Gewürz";}
 return item;
}// /String itemUmpaute(String)
//} /gib

/*****************************************/
/////{ 4. Allgemeine Hilfsskripte /////////
/*****************************************/
// 4.1
setOrderPreserveComments(Unit unit, String order){
// ersetzt helper.setOrder(Unit,String), wenn Kommentare erhalten bleiben sollen
// behällt auch Zeilen, die mit "forlage" anfangen (wg #berichte)
 ArrayList comments = new ArrayList();
 //Einsammeln der Kommentare
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(com) || o.trim().startsWith(";") || o.startsWith("forlage") || o.startsWith("Meta-Warnung")){
   comments.add(o);
  }// /if(o
 }// /for(String
 helper.setOrder(unit, ""); // das set-Element
 for (String c : comments){helper.addOrder(unit, c);}// Wiedergabe von Kommentaren
 helper.addOrder(unit, order); // Befehl wird gegeben
 helper.updateUnit(unit);
}// /setOrderPreserveComments(Unit,String)

// 4.2
int getResourceAmount(Region region, String stuff){
 if (region.resources().toString().contains(stuff)){
  return region.getResource(region.data.getRules().getItemType(StringID.create(stuff))).getAmount();
 }// /if(region
 else{return 0;}
}// /int getResourceAmount(Region,String)

// 4.3
ArrayList unitsInRegionWithOrder(Region region, String order){
 ArrayList arr = new ArrayList();
 for (Unit unit : region.units()){
  if (unit.getOrders().toString().contains(order)){arr.add(unit);}// /if(unit
 }// /for(Unit
 return arr;
}// /ArrayList unitsInRegionWithOrder(Region,String)

// 4.4
ArrayList regionalUnitOrders(Region region){
// Listet alle bekannten Befehle von Einheiten in der Region auf
// und zwar NUR die Befehle
 ArrayList arr = new ArrayList();
 for (Unit unit : region.units()){
  for (String o : unit.getOrders()){arr.add(o);}// /for(String
 }// /for(Unit
 return arr;
}// /ArrayList regionalUnitOrders(Region)

// 4.5
ArrayList splitToArrayList(String s, String trenner){
 arr = new ArrayList();
 for (e : s.split(trenner)){arr.add(e);}
 return arr;
}// /ArrayList splitToArrayList(String,String)

// 4.6
ArrayList splitToArrayList(String s, String trenner, int limit){
 arr = new ArrayList();
 for (e : s.split(trenner, limit)){arr.add(e);}
 return arr;	
}// /ArrayList splitToArrayList(String,String,int)

// 4.7
int lerntage(Unit unit, String skill){
 String n = ""; // bequemlichkeit halber sofort deklariert
                     // In dieser Variablen werden unsere Zieldaten eingefangen werden
 for (String s : unit.getSkills().toString().substring(1, unit.getSkills().toString().length()-1).split(", ")){
  // Die Collection wird zu einem String umgebaut,
  // (In dieser Darstellungsweise beginnt der String mit "[", endet mit "]"
  // und trennt die Elemente der Collection mit ", ")
  // (netto machen wir die Collection also zu einem Array von Strings und
  // untersuchen die Einzelnen Elemente)
  if (s.substring(0, s.indexOf(" ")).equalsIgnoreCase(skill)){
  // Praktischerweise beginnt jedes Element mit Talentname, gefolgt von Space
  // unpraktischerweise hat Magellan nicht alle Talente großgeschrieben in der Datenbank,
  //  daher equalsIgnoreCase(String) statt startsWith(String)
   n = s.substring((s.indexOf("["))+1, s.indexOf("]"));
   // noch praktischererweise sind die Lerntage in den Elementen in eckige Klammern gesetzt
  }
 }
 // Entweder besteht der String n jetzt aus Ziffern-Charakters, oder ist leer.
 try {
  return Integer.parseInt(n);
 }
 catch (NumberFormatException nfe){
 // wenn n leer ist, steht das Talent nicht in der Collection und muss daher null Lerntage haben.
  return 0;
 }
}// /int lerntage(Unit,String)

// 4.8
int modifiedLerntage(Unit unit, String skill){
 String n = "";
 for (String s : unit.getModifiedSkills().toString().substring(1, unit.getSkills().toString().length()-1).split(", ")){
  if (s.substring(0, s.indexOf(" ")).equalsIgnoreCase(skill)){
   n = s.substring((s.indexOf("["))+1, s.indexOf("]"));
  }
 }
 try {
  return Integer.parseInt(n);
 }
 catch (NumberFormatException nfe){
  return 0;
 }
}// /int modifiedLerntage(Unit,String)

//{ 4.9 ArrayList longOrders
ArrayList longOrders = new ArrayList();
longOrders.add("FOLGE");
longOrders.add("NACH");
longOrders.add("ROUTE");
longOrders.add("BEKLAUE");
longOrders.add("HANDEL");
longOrders.add("LEHRE");
longOrders.add("LERNE");
longOrders.add("MACHE");
longOrders.add("TREIBE");
longOrders.add("UNTERHALTE");
longOrders.add("ZERSTOERE");
//}
// 4.9.a
boolean isLongOrder(String order){
 for (String longs : longOrders){
  if (splitToArrayList(order.trim(), " ").get(0).equalsIgnoreCase(longs)){return true;}// /if(order
 }// /for(String
 return false;
}// /boolean isLongOrder(String)

//}
/*****************************************/
//} ENDE CbC
/*****************************************/
Zuletzt geändert von nemo am So 9. Apr 2017, 14:07, insgesamt 3-mal geändert.
I may go pop -- Excuse me!

Benutzeravatar
nemo
Heerführer
Beiträge: 232
Registriert: Mi 25. Feb 2015, 12:06

Code vom 19. März

Beitrag von nemo » So 19. Mär 2017, 14:37

Code: Alles auswählen

import magellan.client.*;
import magellan.client.extern.*;
import magellan.library.*;
import magellan.library.rules.*;
import magellan.plugin.extendedcommands.*;
/*****************************************/

////////{ CbC: Command By Comments /////////
//19.03.2017//

boolean silberverteilung = true;
boolean luxuseinzug = true;

//{ Inhalt:
//{0. Grundfestlegungen
// 0.1 Konstanten für Meta-Befehle (die Tags)
// 0.2 Priorisierung Baumaterialverteilung von Materiallagern
// 0.3 Tabelle Gebäudeunterhalte
// 0.4 Unbedingte Auslösung von subMetas
// 0.5 Schutz vor +next
//} 1. Wurzelimplementierung (Parteikontainer)

//{ 2. Implementierungen der Metas
//{ 2.1 Getimed
// 2.1.1 +magbest [<x>] [<y>] [,<Kommentar>]
// 2.1.1a +segeln <Befehl> [: <Befehl1> : <Befehl2> ...]
// 2.1.2 +next<n> <order> [: <order1>:<order2>...]
// 2.1.2a +route (x, y, z) (befehl) [; (Kommentar)]
// 2.1.3 +rotate<n> <Befehl>
// 2.1.4 +rotaL <Skill> <Skill1> <Skill2> ...
// 2.1.5 +lernen <Skill> <Level>
// 2.1.5a +anlernen <Skill> <Skill1> <Skill2> ... [: <Folgebefehl>]
//} 2.1.6 +rotaP <Item> <Item1> <Item2> ...
//{ 2.2 Hart
// 2.2.1 +forst [<percent>] [<AltBef>]
// 2.2.2 +herde <tier> [<percent>] [<AltBef>]
// 2.2.3 +unterhalte [<AltBef>]
// 2.2.4 +silreg [<minSilber>] [<AltBef>]
// 2.2.5 +treibe [<silber>] [<AltBef>]
//} 2.2.6 +killer [<AltBef>]
//{ 2.3 Interaktiv
//} 2.3.1 study-Komplex
//{ 2.4 Weich
// 2.4.1 +rek [<n>] [, <m>]
// 2.4.2 Lager- und Reservierung-Metas
// 2.4.3 +bewache
//} 2.4.3a +gib
//}

//{ 3. Skripte für Metas
//{ 3.1 Getimed
// 3.1.1 +magbest [<x>] [<y>] [,<Kommentar>]
// 3.1.1a +segeln <Befehl> [: <Befehl1> : <Befehl2> ...
// 3.1.2 +next<n> <Befehl>
// 3.1.2a +route (x, y, z) (befehl) [; (Kommentar)]
// 3.1.3 +rotate<n> <Befehl>
// 3.1.4 +rotaL <Skill> <Skill1> <Skill2> ...
// 3.1.5 +lernen <Skill> <Level>
// 3.1.5a +anlernen <Skill> <Skill1> <Skill2> ... [: <Folgebefehl>]
//} 3.1.6 +rotaP <Item> <Item1> <Item2> ...
//{ 3.2 Hart
// 3.2.1 +forst [<percent>] [<AltBef>]
// 3.2.2 +herde <tier> [<percent>] [<AltBef>]
// 3.2.3 +unterhalte [<AltBef>]
// 3.2.4 +silreg [<minSilber>] [<AltBef>]
// 3.2.5 +treibe [<silber>] [<AltBef>]
//} 3.2.6 +killer [<AltBef>]
//{ 3.3 Interaktiv
//} 3.3.1 study-Komplex
//{ 3.4 Weich
// 3.4.1 +rek [<n>] [,<m>]
// 3.4.2 lager- und Reservierungsmetas
// 3.4.3 +bewache
//} 3.4.3a +gib
//}
//{ 4. Allgemeine Hilfsfunktionen
// 4.1 setOrderPreserveComments(Unit,String)
//     (ersetzt helper.setOrder(Unit,String), wenn Kommentare erhalten bleiben sollen)
// 4.2 int getResourceAmount(Region,String)
//     (erleichtert das Finden von ...allem)
// 4.3 ArrayList unitsInRegionWithOrder(Region,String)
//     (Listet Einheiten in der Region mit einem bestimmten String im Befehlsblock)
// 4.4 ArrayList unitsInRegionWithOrder(Region,String)
//     (Listet die bekannten Befehle von Einheiten in der Region)
// 4.5 ArrayList splitToArrayList(String,String)
//     (mimiks String.split(String) und erlaubt Zugriff über Index)
// 4.6 ArrayList splitToArrayList(String,String,int)
//     (mimiks String.split(String,int) und erlaubt Zugriff über Index)
// 4.7 int lerntage(Unit,String)
//     (Gibt die Lerntage von Unit für das Talent String aus)
// 4.8 int modifiedLerntage(Unit,String)
//     (Wie 4.7, aber mit Update nach Befehlen)
// 4.9 ArrayList longOrders
// 4.9.a boolean isLongOrder(String);
//}
//}
//}
/**********************************************/

/**********************************************/
////////////// 0. Grundfestlegungen ////////////
/**********************************************/

//{ 0.1 Konstanten für Meta-Befehle (die Tags)
String com = "//";
String com2 = ";";
String me = "// +";
String me2 = ";; +";
String me3 = ",, +";
ArrayList starters = new ArrayList();
starters.add(me);
starters.add(me2);
//}

//{ 0.2 Priorisierung BauMatVertlg /////////
ArrayList mLagerBedient = new ArrayList();
mLagerBedient.add(me+"nkw"); // Waffenbau
mLagerBedient.add(me+"bogner"); // Bogenbau
mLagerBedient.add(me+"ruestung"); // Ruestungsbau
mLagerBedient.add(me+"wagner"); // Wagenbau
mLagerBedient.add(me+"reeder"); // Schiffbau
//}

//{ 0.3 Gebäude-Unterhalte
HashMap buildingMaintenances = new HashMap();
buildingMaintenances.put("Bergwerk", 100);
buildingMaintenances.put("Hafen", 100);
buildingMaintenances.put("Holzfällerhütte", 50);
buildingMaintenances.put("Leuchtturm", 100);
buildingMaintenances.put("Mine", 50);
buildingMaintenances.put("Monument", 100);
buildingMaintenances.put("Sägewerk", 100);
buildingMaintenances.put("Sattlerei", 100);
buildingMaintenances.put("Schiffswerft", 100);
buildingMaintenances.put("Schmiede", 100);
buildingMaintenances.put("Seehafen", 300);
buildingMaintenances.put("Steg", 30);
buildingMaintenances.put("Steinbruch", 100);
buildingMaintenances.put("Steingrube", 50);
buildingMaintenances.put("Steuerturm", 50);
buildingMaintenances.put("Werkstatt", 100);
//}

//{ 0.4 Unbedingte Auslösung von subMetas
ArrayList unconditional = new ArrayList();
unconditional.add("magbest");
unconditional.add("rotaL");
unconditional.add("rotaP");
unconditional.add("rek");
//}

//{ 0.5 Schutz vor +next
ArrayList nextVerschont = new ArrayList();
nextVerschont.add(me+"magbest");
nextVerschont.add(me+"route");
nextVerschont.add(me+"bewache");
nextVerschont.add(me+"segeln");
//}

/******************************************/
////////// Wurzelimplementierung //////////
/*****************************************/

cbc_Alpha(String factionID){
 for(Region region : world.regions().values()){
  implementMetas_cbc_Alpha(region, factionID);
 }// /for(Region
}// /cbc_Alpha(String)

/*****************************************/
//// 2. Implementierung der Metas /////////
/*****************************************/

implementMetas_cbc_Alpha(Region region, String factionID){
 // Metas in der Region suchen und auslösen
 // (erst // +, dann ;; +)
 for(String starter : starters){
  ArrayList thisMeta = new ArrayList();
 //{ 2.1 Getimete Metas
  // 2.1.1 +magbest
  thisMeta = unitsInRegionWithOrder(region, starter+"magbest");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"magbest")){ex=true;}// /if(o
    }// /for(String
    if(ex){magbest(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thismeta
  // /magbest

  // 2.1.1a +segeln
  thisMeta = unitsInRegionWithOrder(region, starter+"segeln");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"segeln")){ex = true;}// /if(o
    }// /for(String
    if (ex){segeln(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /segeln

  // 2.1.2 +next
  thisMeta = unitsInRegionWithOrder(region, starter+"next");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if(o.trim().startsWith(starter+"next")){ex = true;}// /if(o
    }// /for(String   
    if(ex){next(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!thisMeta
  // /next

  // 2.1.2a +route
  if (starter.equals(me)){
   thisMeta = unitsInRegionWithOrder(region, me+"route");
   if (!(thisMeta.isEmpty())){
    for (Unit unit : thisMeta){route(unit);}// /for(Unit
   }// /if(!(thisMeta
  }// /if(starter
  // /route

  // 2.1.3 +rotate
  thisMeta = unitsInRegionWithOrder(region, starter+"rotate");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if(o.trim().startsWith(starter+"rotate")){ex = true;}// /if(o
    }// /for(String   
    if(ex){rotate(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /rotate
 
  // 2.1.4 +rotaL
  thisMeta = unitsInRegionWithOrder(region, starter+"rotaL");
  if (!(thisMeta.isEmpty())){
    for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if(o.trim().startsWith(starter+"rotaL")){ex = true;}// /if(o
    }// /for(String   
    if(ex){rotaL(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /rotaL
 
  // 2.1.5 +lernen
  thisMeta = unitsInRegionWithOrder(region, starter+"lernen");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
   String argline = "";
   boolean ex = false;
   for(String order : unit.getOrders()){
    if (order.trim().startsWith(starter+"lernen")){
     ex = true;
     argline = order.substring(10).trim();
    }// /if(order
   }// /for(String
   if(ex){lernen(unit, argline);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /lernen

  // 2.1.5a +anlernen
  thisMeta = unitsInRegionWithOrder(region, starter+"anlernen");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"anlernen")){ex = true;}// /if(o
    }// /for(String
    if (ex){anlernen(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /anlernen

  // 2.1.6 +rotaP
  thisMeta = unitsInRegionWithOrder(region, starter+"rotaP");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"rotaP")){ex=true;}// /if(o
    }// /for(String
    if (ex){rotaP(unit);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /rotaP
//}
 
 //{ 2.2 Harte Metas
  // 2.2.1 ;; +forst n <Altbef>
  thisMeta = unitsInRegionWithOrder(region, starter+"forst");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    ArrayList args = new ArrayList();
    boolean ex = false;
    for(String order : unit.getOrders()){
     if(order.trim().startsWith(starter+"forst")){
      args = splitToArrayList(order.substring(9).trim(), " ", 2);
      ex = true;
     }// /if(order
    }// /for(String)
    if(ex){forst(unit, args);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /forst
 
  // 2.2.2 +herde
  thisMeta = unitsInRegionWithOrder(region, starter+"herde");
  if(!(thisMeta.isEmpty())){
   for(Unit unit: thisMeta){
    boolean ex = false;
    for(String order: unit.getOrders()){
     if(order.trim().startsWith(starter+"herde")){ex = true;}// /if(order
    }// /for(String
    if(ex){monoHerde(unit, starter);}
   }// for(Unit
  thisMeta.clear();
  }// /if(!(thisMeta
  // /herde
 
  // 2.2.3 +unterhalte <AltBef> && ;; +unterhalte <AltBef>
  //(subMetas für den Alternativbefehl)
  thisMeta = unitsInRegionWithOrder(region, starter+"unterhalte");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    String altBef = "LERNE Unterhaltung";
    boolean ex = false;
    for (String order : unit.getOrders()){
     if(order.trim().startsWith(starter+"unterhalte")){
      ex = true;
      if (order.length() > 15){altBef = order.substring(15).trim();}
     }// /id(order
   }// /for(String
    if (ex){unterhalte(unit, altBef);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /unterhalte
 
  // 2.2.4 +silreg <MinSilber> <altBef> & ;; +silreg <altBef>
  //(subMetas für den Alternativbefehl)
  thisMeta = unitsInRegionWithOrder(region, starter+"silreg");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    boolean ex = false;
    for (String order : unit.getOrders()){
     if (order.trim().startsWith(starter+"silreg")){ex = true;}// /if(order
    }// /for(String
    if(ex){silReg(unit, starter);}
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /silreg
 
  // 2.2.5 +treibe <altBef>
  //(SubMetas für Alternativbefehl)
  thisMeta = unitsInRegionWithOrder(region, starter+"treibe");
  if(!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    boolean ex = false;
    for (String order : unit.getOrders()){
     if (order.trim().startsWith(starter+"treibe")){ex = true;}// /if(order
    if(ex){treibe(unit, starter);}// /if(ex
    }// /for(String
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
 
  // 2.2.6 +killer [<AltBef>]
  thisMeta = unitsInRegionWithOrder(region, starter+"killer");
  if (!(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"killer")){ex = true;}// /if(o
    }// /for(String
    if (ex){killer(unit, starter);}// /if(ex
   }// /for(Unit
  }// /if(!(thisMeta
  // /killer
 //}
 
 //{ 2.3 Interaktive Metas
  // 2.3.1 +lerne<p> <skill> [<level> [<AltBef>]]  & +lehre<p> <skill1> [<skill1> <skill2>][, <AltBef>]
  if (starter.equals(me)){studyComplex(region);}
 //}
 
 //{ 2.4 Weiche Metas
 for (Unit unit : region.units()){
 // 2.4.1 +rek [<n>] [, <m>]
  if (unit.getOrders().toString().contains(starter+"rek")){
   boolean ex = false;
   for (String o : unit.getOrders()){
    if (o.startsWith(starter+"rek")){ex=true;}
   }// /for(String
   if (ex){regulator(unit, region, starter);}
  }// /if(unit.getOrders
 // /rek

 // 2.4.2 +lager und Reservierungen
  if (starter.equals(me)){
   if(unit.getOrders().toString().contains(me+"lager") && silberverteilung){lager(unit);}
   if(unit.getOrders().toString().contains(me+"sLag")){sLager(unit);}
   if(unit.getOrders().toString().contains(me+"nLag")){nLager(unit);}
   if(unit.getOrders().toString().contains(me+"fLag")){fLager(unit);}
   if(unit.getOrders().toString().contains(me+"mLag")){mLager(unit);}
   if(unit.getOrders().toString().contains(me+"rLag")){rLager(unit);}
   if(unit.getOrders().toString().contains(me+"tLag")){tLager(unit);}
   if(unit.getOrders().toString().contains("HANDEL") && luxuseinzug){handel(unit);}
 // /lager und Reservierungen

   // 2.4.3 +bewache
   autarn(unit);
 // /bewache
  }// /if(starter
 }// /for(Unit
 
   // 2.4.3a +gib
  thisMeta = unitsInRegionWithOrder(region, starter+"gib");
  if (!(thisMeta.isEmpty())){
   for(Unit unit : thisMeta){
    boolean ex = false;
    for(String order : unit.getOrders()){
     if(order.trim().startsWith(starter+"gib")){ex=true;}// /if(order
    }// /for(String
    if(ex){gib(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMEta
  // /gib
}// /for(String starter
 
//}
  // 2.4.4 +segelnII : Ozean
  thisMeta = unitsInRegionWithOrder(region, starter+"segeln");
  if (region.getType().toString().equals("Ozean") && !(thisMeta.isEmpty())){
   for (Unit unit : thisMeta){
    boolean ex = false;
    for (String o : unit.getOrders()){
     if (o.trim().startsWith(starter+"segeln")){ex = true;}// /if(o
    }// /for(String
    if (ex){segeln(unit, starter);}// /if(ex
   }// /for(Unit
   thisMeta.clear();
  }// /if(!(thisMeta
  // /segeln

}// /implementMetas_cbc_Alpha(Region,String)

/*****************************************/
/////////// 3. Skripte für Metas //////////
/*****************************************/
//{ 3.1 Getimte Metas
 // 3.1.1 +magbest [<x>][<y>][, <Kommentar>]
   // x,y € N
   // x>0 => bestätigt; x--
   // x == 0 => ~bestätigt
   // y>0 && x==0 => x=y
magbest(Unit unit){
// Variabeln:
 int noch = 1;
 int setz = 0;
 String comment = "";
 boolean rewrite = false; // nötig, wenn x != 0
 ArrayList you = new ArrayList();
// Parameter raussuchen:
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(me+"magbest")){
   you = splitToArrayList(o, " ", 5);
   if (you.size() > 2){
    try {
     noch = Integer.parseInt(you.get(2))-1;
     rewrite = true;
     try {
      setz = Integer.parseInt(you.get(3));
     }// /try
     catch(IndexOutOfBoundsException oob){setz = 0;}// /catch(oob
     catch (NumberFormatException nfe2){setz = 0;}// /catch(nfe2 == setz erzwingen
    }// /try
    catch (NumberFormatException nfe){noch = 1;}// /catch(nfe == noch erzwingen
    if (o.contains(",")){comment = o.substring(o.indexOf(",")+1).trim();}// /if(o.contains
   }// /if(you
  }// /if(o
 }// /for(String
// (nicht) bestätigen
 if (noch > 0){unit.setOrdersConfirmed(true);}// /if(noch
 else{ // == if (noch <= 0
  unit.setOrdersConfirmed(false);
  noch = setz; // also wieder hoch, oder auf null
 }// /else <- if(noch>0
// neuschreiben
 if (rewrite){
  you.clear(); // recycling
  // Kommentar einbauen
  if (!(unit.isOrdersConfirmed()) && comment != ""){you.add(comment);}
  // restliche Zeilen einsammeln
  for (String o : unit.getOrders()){
   if (!(o.trim().startsWith(me+"magbest"))){you.add(o);}// /if(!(o
  }// /for(String
  // clearing
  helper.setOrder(unit, "");
  // neue magbest-Zeile
  String newbest = "";
  if (noch > 0){
   newbest = me+"magbest "+noch.toString()+" "+setz.toString();
   if (comment != ""){newbest = newbest+" ,"+comment;}
  }// /if(noch
  helper.addOrder(unit, newbest);
  for (String o : you){helper.addOrder(unit, o);}
 }// /if(rewrite
}// /magbest(Unit)

// 3.1.1a // +segeln
segeln(Unit unit, String starter){
 helper.addOrder(unit, unit.getRegion().toString());
 helper.updateUnit(unit);
 String currentOrder = "";
 for (String order : unit.getOrders()){
  if (order.trim().startsWith(starter+"segeln")){
   if (unit.getOrders().toString().contains("Ozean")){currentOrder = "FAULENZE ; segelbedingt";}
   else {currentOrder = order.substring(10).trim();}
  }
 }
 setOrderPreserveComments(unit, currentOrder);
 helper.updateUnit(unit);
}// /segeln(Unit,String)

 // 3.1.2 +next<n> <order> [: <order1>:<order2>...]
 // Setzt bei Auslösung subMetas zu Dauermetas und löscht alle Metas, die nicht in nextVerschont stehen
next(Unit unit){
 ArrayList ordinaries = new ArrayList(); // alles, was nicht mit +next und anfangt und nicht ausgelöscht wird
 ArrayList newNexts = new ArrayList(); // nexts, die nicht diese Runde zuschlagen
 ArrayList doNow = new ArrayList(); // was durch next jetzt ausgelöst wird (verdrängt alles, was kein Kommentar ist
// 1.: die ArrayListen füllen
 for (String o : unit.getOrders()){
  if (!(o.trim().startsWith(me+"next")) ){ordinaries.add(o);}
  else{int wann = Integer.parseInt(splitToArrayList(o, " ").get(1).substring(5))-1;
   if(wann > 0){o=o.substring(o.indexOf(" ")).trim();
    o=o.substring(o.indexOf(" ")).trim();
    newNexts.add(me+"next"+wann.toString()+" "+o);}// /if(wann>0
   else{for(String now : splitToArrayList(o, " ", 3).get(2).split(":")){doNow.add(now.trim());}}
   }// /else <-- if(!(o.startsWith
 }// /for(String o
 helper.setOrder(unit, "");
 helper.updateUnit(unit);
// 2: neue +next einfügen (dann sind die immer oben
 for (String next : newNexts){helper.addOrder(unit, next);}
 helper.updateUnit(unit);
// 3: Rest einfügen; wenn doNow, ungeschützte Metabefehle rausschmeißen
 for(String ord : ordinaries){
  if (doNow.size() > 0){
   if (ord.trim().startsWith(com)){
   if (!(ord.trim().startsWith(me))){helper.addOrder(unit, ord);}
    else {
     boolean take = false;
     for (String prot : nextVerschont){if(ord.trim().startsWith(prot)){take = true;}}
     if (take){helper.addOrder(unit, ord);}
    }// /else
   }// /if(ord
  }// /if(doNow.size>0
  else{helper.addOrder(unit, ord);}// /else <-- if(doNow.size>0
 }// /for(String ord
 helper.updateUnit(unit);
//5: wenn next was auslöst, das durchziehen
 if (doNow.size() > 0){
  for(String dot : doNow){ // somewhat silly, but "do" wont work as variable
   // subMetas umwandeln
   if(dot.trim().startsWith(me2)){
    helper.addOrder(unit, dot);
    helper.addOrder(unit, me+dot.substring(4));
   }// /if(dot.trim
   else {helper.addOrder(unit, dot.trim());}
  }// /for(String dot
 }// /if(doNow.size>0
 helper.updateUnit(unit);
}// /next(Unit,String)

 // 3.1.2a +route (x, y, z) (bewegungsbefehl) [; (Kommentar)]
route(Unit unit){
 HashMap kursZuRegion = new HashMap();
 for (String o : unit.getOrders()){
  if (o.startsWith(me+"route")){
   kursZuRegion.put(o.substring(o.indexOf("(")+1,o.indexOf(")")), o.substring(o.indexOf(")")+1).trim());
  }// /if(o
 }// /for(String
 if (kursZuRegion.containsKey(unit.getRegion().getID().toString())){
  setOrderPreserveComments(unit, kursZuRegion.get(unit.getRegion().getID().toString()));
 }// /if(kursZuRegion
}// /route(Unit)

 // 3.1.3 +rotate<n> <order>[ : <order1> : <order2>...]
 // +rotaMax <n> (optional; hilft, einen bestimmten, nicht streng-sequentiellen Rhythmus aufrecht zu erhalten)
rotate(Unit unit){
 // vorforhandene Befehle sortieren
 ArrayList rotates = new ArrayList();
 ArrayList comments = new ArrayList();
 int rotaMax = 0;
 for (String order : unit.getOrders()){if (!(order.trim().startsWith(me+"rotate"))){comments.add(order);}
  else{rotates.add(order.substring(10));}
  if (order.trim().startsWith(me+"rotaMax")){rotaMax = Integer.parseInt(splitToArrayList(order, " ").get(2));}
  }// /for(String order
 // vorvorhandene Befehle loswerden
 helper.setOrder(unit, "");
 String zerotate = "";
 for (String rot : rotates){int arg = Integer.parseInt(rot.substring(0, rot.indexOf(" ")));
  if(arg > rotaMax){rotaMax = arg;}
  if (arg - 1 == 0){zerotate = rot.substring(rot.indexOf(" ")).trim();}
  else{helper.addOrder(unit, me+"rotate"+(arg-1).toString()+" "+rot.substring(rot.indexOf(" ")).trim());}
 }// for(rot
 if (zerotate != ""){helper.addOrder(unit, me+"rotate"+rotaMax.toString()+" "+zerotate);}
 for (String comment : comments){helper.addOrder(unit, comment);}
 if (zerotate != ""){ArrayList doNow = splitToArrayList(zerotate, ":");
  setOrderPreserveComments(unit, doNow.get(0));
  int i = 1;
  while (i<doNow.size()){helper.addOrder(unit, doNow.get(i));
   i++;}
  }// /if(zerotate!=""
}// /rotate(Unit)

 // 3.1.4 +rotaL skill skill2 skill3 skill4 skill1 ...
rotaL(Unit unit, String starter){
 ArrayList newOrders = new ArrayList();
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(com) && !(o.trim().startsWith(starter+"rotaL"))){newOrders.add(o);}
  if (o.trim().startsWith(starter+"rotaL")){o = o.substring(9).trim();
   String skill = o.substring(0, o.indexOf(" ")).trim();
   o = o.substring(o.indexOf(" ")).trim()+" "+skill;
   String newLine = starter+"rotaL "+o;
   newOrders.add(newLine);
   newOrders.add("LERNE "+skill);
  }// /if(o.startsWith starter
 }// /for(String o
 helper.setOrder(unit, "");
 for (String newOrder : newOrders){helper.addOrder(unit, newOrder);}
 helper.updateUnit(unit);
}// /rotaL(Unit)

 //{ 3.1.5 +lernen <skill> [<lvl>] [<nextOrder>]
lernen(Unit unit, String argline){
// VariabelnDeklaration
 int lvl = 1;
 String nextOrder = "";
 ArrayList args = splitToArrayList(argline, " ", 3);
 String skill = args.get(0);
 if (isImplementedSkill(skill)){// Schreibungsprüfung
  if (args.size() > 1){
   try {
    lvl = Integer.parseInt(args.get(1));
   }// /try
   catch(NumberFormatException lernenOhneNummer){
    lvl = 1;
    nextOrder = args.get(1);
   }// /catch/NumberFormatException
  }// /if(args.size > 1
  // Level-Kontrolle:
  if (helper.getLevel(unit, skill) < lvl){
   unit.setOrdersConfirmed(true);
  }// /if(helper.getLevel
  else{
   unit.setOrdersConfirmed(false);
   setOrderPreserveComments(unit, "; "+skill+" fertig gelernt");
   if (args.size() > 2){
    nextOrder = nextOrder+" "+args.get(2);
   }// /if(args.size > 2
   for(String doNow : nextOrder.split(":")){
    if(doNow.trim().startsWith(me2)){helper.addOrder(unit, me+doNow.substring(me2.length()+1));}
    else {helper.addOrder(unit, doNow.trim());}
   }
   helper.updateUnit(unit);
   // +lerne herausfischen:
  }// /else <-- if(helper.getLevel
 }// /if(isImplementedSkill
 else{
  unit.setOrdersConfirmed(false);
  helper.addOrder(unit, "Meta-Warnung +lernen: Talent falsch geschrieben oder nicht implementiert!");
  helper.updateUnit(unit);
 }// /else <-- if(isImplementedSkill
}// /lernen(Unit,String)

 boolean isImplementedSkill(String skill){
 // Kontrolliert bei +lernen, +anlernen, ob <skill> richtig geschrieben wurde
  if (skillList.contains(skillUmlaute(skill))){
   return true;
  }// /if(skillList.contains
  else{
   return false;
  }// /else
}// /boolean isImplementedSkill(String)

 String skillList = "Armbrustschießen Ausdauer ausdauer Bergbau Bogenbau Bogenschießen Burgenbau Handel Hiebwaffen Holzfällen Katapultbedienung Magie Pferdedressur Reiten Rüstungsbau Schiffbau Segeln Speerkampf Spionage Steinbau Steuereintreiben Straßenbau Taktik Tarnung Unterhaltung Waffenbau Wagenbau Wahrnehmung";
 String skillListMitUmlaute = "Armbrustschießen Bogenschießen Holzfällen Rüstungsbau Straßenbau";
 String skillListOhneUmlaute = "Armbrustschiessen Bogenschiessen Holzfaellen Ruestungsbau Strassenbau";

 String skillUmlaute(String skill){
 // um die Umlautumschreibung des Servers zu umgehen (Ein kleiner Kippschalter)
  if(skillListMitUmlaute.contains(skill)){
   return splitToArrayList(skillListOhneUmlaute, " ").get(splitToArrayList(skillListMitUmlaute, " ").indexOf(skill));}
  if(skillListOhneUmlaute.contains(skill)){
   return splitToArrayList(skillListMitUmlaute, " ").get(splitToArrayList(skillListOhneUmlaute, " ").indexOf(skill));}
  else {return skill;}
 }// /String skillUmlaute(String)
//} /lernen

 // +anlernen
 // 3.1.5a +anlernen <Skill> <Skill1> <Skill2> ... [: <Folgebefehl>]
anlernen(Unit unit, String starter){
 // Variabeln:
 String learnOrder = ""; // "LERNE" oder "falschgeschrieben"
 String skills = "";
 String follow = ""; // Folgebefehl
 boolean spell = true;
 // Argumente extrahieren
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"anlernen")){
   skills = o.substring(12).trim();
  }// /if(o
  if (skills.contains(":")){
   follow = skills.substring(skills.indexOf(":")+1).trim();
   skills = skills.substring(0, skills.indexOf(":")).trim();
  }// /if(skills
 }// /for(String
 for (String skill : skills.split(" ")){
  if(isImplementedSkill(skill)){
   if (helper.getLevel(unit, skillUmlaute(skill)) < 1 && !(learnOrder.contains("LERNE"))){learnOrder = learnOrder+":LERNE "+skill;}// /if(helper
  }// /if(isImplementedSkill
  else {learnOrder = learnOrder+":CbC-Warnung: Talent "+skill+" falsch geschrieben oder nicht implementiert";}// /else <- if(isImplementedSkill
 }// /for(String
 if (learnOrder.contains(":")){
  unit.setOrdersConfirmed(true);
  setOrderPreserveComments(unit, "");
  for (String doNow : learnOrder.split(":")){
   helper.addOrder(unit, doNow);
  }// /for(String
  helper.updateUnit(unit);
  if (unit.getOrders().toString().contains("CbC-Warnung")){unit.setOrdersConfirmed(false);}// /if(unit
 }// /if(learnOrder
 else {
  setOrderPreserveComments(unit, "; fertig gelernt");
  for (String doNow : follow.split(":")){
   if (doNow.trim().startsWith(me2)){helper.addOrder(unit, com+doNow.trim().substring(doNow.trim().indexOf(" ")));}// /if(doNOw
   else {helper.addOrder(unit, doNow.trim());}// /else
  }// /for(String
  helper.updateUnit(unit);
 }// /else <- if(learnOrder
}// /anlernen(Unit,String)
 // 3.1.6 +rotaP skill skill2 skill3 skill4 skill1 ...
rotaP(Unit unit){
 ArrayList newOrders = new ArrayList();
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(com) && !(o.trim().startsWith(me+"rotaP"))){
   newOrders.add(o);}
  if (o.trim().startsWith(me+"rotaP")){o = o.substring(9).trim();
   String skill = o.substring(0, o.indexOf(" ")).trim();
   o = o.substring(o.indexOf(" ")).trim()+" "+skill;
   String newLine = me+"rotaP "+o;
   newOrders.add(newLine);
   newOrders.add("MACHE "+skill);
  }// /if(o.startsWith me
 }// /for(String o
 helper.setOrder(unit, "");
 for (String newOrder : newOrders){
  helper.addOrder(unit, newOrder);
 }// /for String newOrder
 helper.updateUnit(unit);
}// /rotaP(Unit)
//}

//{ 3.2 Harte Metas
 // 3.2.1 +forst| [<perc> <altBef>]
forst(Unit unit, ArrayList args){
 if (helper.getLevel(unit, "Holzfällen") < 1){setOrderPreserveComments(unit, "LERNE Holzfaellen");}
 else{
// Default-Einstellungen
  boolean argZeroIsNumber = false;
  int perc = 0;
  String altBef = "LERNE Holzfaellen";
  int holz = getResourceAmount(unit.getRegion(), "Holz");
  if (args.size() > 0){
   try {perc = Integer.parseInt(args.get(0));
    argZeroIsNumber = true;
   }// /try
   catch (NumberFormatException forstOhneZahl){
    perc = 0;
    argZeroIsNumber = false;
   }// /catch(NumberFormatException
  }// /if(args.size > 0
  int soll = unit.getRegion().getType().getInhabitants() * perc / 1000; // durch 100 weil prozente, dann nochmal durch 10, weil Bäume
  int kann = helper.getLevel(unit, "Holzfällen") * unit.getPersons();
  int diff = 2 * (holz - soll); // wir gehen mal von Sägewerk als Standardszenario aus (lässt sich leichter rechnen als andersrum)
  if (!(unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Sägewerk"))){
   diff = diff / 2;}// und hier korrigieren wir im gegenteiligen Fall
  if (diff <= 0){
   if (argZeroIsNumber){
    if (args.size() > 1){
     altBef = args.get(1);
    }// /if(args.size > 1
   }// /if(argZeroIsNumber
   else{
    if (args.size() > 0){
     altBef = args.get(0);
    }// /if(args.size > 0
    if (args.size() > 1){
     altBef = altBef+" "+args.get(1);
    }// /if(args.size > 1
   }// /else <--if(argZeroIsNumber
   setOrderPreserveComments(unit, altBef);
  }// /if(diff
  else{
   if (diff > kann){
    setOrderPreserveComments(unit, "MACHE Holz");
   }// /if(diff > kann
   else{
    setOrderPreserveComments(unit, "MACHE "+diff.toString()+" Holz");
   }// /else <-- if(diff > kann
  }// /else <--if(diff <= 0
  helper.addOrder(unit, "; Pruefzahl forst: "+soll.toString());
 }// /else <-- if(helper.getLevel
 helper.updateUnit(unit);
}// /forst(Unit,ArrayList)

 // 3.2.2 ;; +herde <tier> <perc> [<altBef>]
monoHerde(Unit unit, String starter){
 // Variabeln
 ArrayList argline = new ArrayList();
 int quali = 1; // TW(Pferdedressur)
 String tier = "Pferd";
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"herde")){argline = splitToArrayList(o.substring(9).trim(), " ", 3);}// /if(o
 }// /for(String
 try {tier = argline.get(0);}// /try
 catch(IndexOutOfBoundsException oob){tier = tier;}// /catch(oob
 if (tier.equals("Elefant") || tier.equals("Mastodon")){
  quali = 2;
 }// /if(tier
 if (helper.getLevel(unit, "Pferdedressur") < quali){
  setOrderPreserveComments(unit, "LERNE Pferdedressur");
 }// /if(helper.getLevel
 else{
// Defaulteinstellungen
  boolean argZeroIsNumber = false;
  String altBef = "LERNE Pferdedressur";
  int perc = 0;
  if (argline.size() > 1){
   try {
    perc = Integer.parseInt(argline.get(1));
    argZeroIsNumber = true;
   }// /try
   catch (NumberFormatException herdeOhneZahl){
    perc = 0;
    argZeroIsNumber = false;
   }// /catch(NumberFormatException
  }// /if(argline.size
  int kann = helper.getLevel(unit, "Pferdedressur") * unit.getPersons() / quali;
  int soll = unit.getRegion().getType().getInhabitants() * perc / 100;
  if (quali == 2){
   soll = soll / 5;
  }// /if(quali
  int t = getResourceAmount(unit.getRegion(), tier);
  int diff = t - soll;
  if (diff <= 0){
   if (argZeroIsNumber){
    if (argline.size() > 2){
     altBef = argline.get(2);
    }// /if(argline.size>2
   }// /if(argZeroIsNumber
   else{
    if (argline.size() > 1){
     altBef = argline.get(1);
     if (argline.size() > 2){
      altBef = altBef+" "+argline.get(2);
     }// /if(argline.size > 2
    }// if(argline.size > 1
   }// /else <-- if(argZeroIsNumber
   setOrderPreserveComments(unit, altBef);
  }// /if(diff <=0
  else{
   if (diff >= kann){
    setOrderPreserveComments(unit, "MACHE "+tier);
   }// /if(diff >= kann
   else{
    setOrderPreserveComments(unit, "MACHE "+diff.toString()+" "+tier);
   }// /else <-- if(diff >= kann
  }// /else <-- if(diff <= 0
  helper.addOrder(unit, "; Pruefzahl herde: "+soll.toString()+" "+tier);
 }// /else<--if(helper.getLevel
 helper.updateUnit(unit);
}// /monoHerde(Unit,String)

 // 3.2.3 +unterhalte <AltBef>
unterhalte(Unit unit, String altBef){
 int soll = unit.getRegion().getType().getInhabitants() * (unit.getRegion().getWage()-10) * 20;
 int kann = 20 * unit.getPersons() * helper.getLevel(unit, "Unterhaltung");
 if (kann <= unit.getRegion().maxEntertain()){setOrderPreserveComments(unit, "UNTERHALTE");}// /if(kann
 else{
  int diff = unit.getRegion().getSilver() - soll;
  if (diff > 0){setOrderPreserveComments(unit, "UNTERHALTE "+diff.toString());}// /if(diff
  else{setOrderPreserveComments(unit, altBef);}
 }// /else <- if(kann
 helper.addOrder(unit, "; unterhaellt automatisch");
 helper.updateUnit(unit);
}// /unterhalte(Unit,String)

 // 3.2.4 +silreg <minSilber> <AltBef>
 // wie +herde oder +forst, aber ohne Prozente und bezogen auf das Altsilber/den Stash
 // wenn <minSilber> ~angegeben, auf das 20fache des regenerativen Maximums
silReg(Unit unit, String starter){
 int soll = unit.getRegion().getType().getInhabitants() * (unit.getRegion().getWage()-10) * 20;
 int kann = unit.getPersons() * 20 * helper.getLevel(unit, "Steuereintreiben");
 String altBef = "LERNE Steuereintreiben";
 for(String o : unit.getOrders()){
  if(o.trim().startsWith(starter+"silreg")){
   try {
    soll = Integer.parseInt(splitToArrayList(o, " ").get(2));
    try {altBef = splitToArrayList(o, " ", 4).get(3);}// /try
    catch(IndexOutOfBoundsException oob){altBef = altBef;}// /catch(oob
   }// /try
   catch(NumberFormatException nfe){
    soll = soll;
    try {altBef = splitToArrayList(o, " ", 3).get(2);}// /try
    catch(IndexOutOfBoundsException oob){altBef = altBef;}// /catch(oob
   }// /catch(nfe
  }// /if(o
 }// /for(String
 int diff = unit.getRegion().getSilver() - soll;
 if (diff <= 0){setOrderPreserveComments(unit, altBef);}// /if(diff <=
 else{
  if (diff >= kann){setOrderPreserveComments(unit, "TREIBE");}// /if(diff>=
  else{setOrderPreserveComments(unit, "TREIBE "+diff.toString());}// /else
 }// /else <- if(diff <=
 helper.updateUnit(unit);
}// /silReg(Unit,String)

 // 3.2.5 +treibe <silber> <altBef>
 // Treibt <silber> Silber, wenn mind so viel im Stash/Altsilber,
 // sonst <altBef> (wenn ~angegeben: LERNE Steuereintreiben)
 // wenn ~<silber> angegeben, wird es auf das regenerative Maximum gesetzt
treibe(Unit unit, String starter){
 int soll = unit.getRegion().getType().getInhabitants() * (unit.getRegion().getWage()-10);
 int kann = unit.getPersons() * 20 * helper.getLevel(unit, "Steuereintreiben");
 String waga = "LERNE Steuereintreiben";
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"treibe")){
   args = splitToArrayList(o, " ", 4);
   boolean haveNumeric = false;
   if (args.size() > 2){
    try {
     soll = Integer.parseInt(args.get(2));
     haveNumeric = true;
    }// /try
    catch (NumberFormatException nfe){waga = args.get(2);}// /catch nfe
    if (haveNumeric){
     if (args.size() > 3){waga = args.get(3);}// /if (args > 3
    }// /if(haveNumeric
    else {
     try {
      waga = args.get(2);
      if (args.size() > 3){waga = waga+" "+args.get(3);}// /if args > 3
     }// /try
     catch (IndexOutOfBoundsException oob){waga = waga;}// /catch oob
    }// /else <- haveNumeric
   }// /if(args > 2
  }// /if(o
 }// /for(String
 int diff = unit.getRegion().getSilver() - soll;
 if (diff <=0){setOrderPreserveComments(unit, waga);}// /if(diff <=
 else{
  if (diff >= kann){setOrderPreserveComments(unit, "TREIBE "+soll.toString());}// /if(diff >=
  else{
   if (diff > kann /2){setOrderPreserveComments(unit, "TREIBE "+diff.toString());}// /if(diff >
   else{setOrderPreserveComments(unit, waga);}// /else
  }// /else <- if(diff >=
 }// /else <- if(diff <=
 helper.updateUnit(unit);
}// /treibe(Unit,String)

 // 3.2.6 +killer [<AltBef>]
killer(Unit unit, String starter){
 // Kann er überhaupt Steuern eintreiben?
 if (helper.getLevel(unit, "Steuereintreiben") < 1){setOrderPreserveComments(unit, "LERNE Steuereintreiben");}
 else{
  String altBef = "LERNE Steuereintreiben"; // Standardeinstellung
  // Alternativbefehl suchen
  for (String o : unit.getOrders()){
   if (o.trim().startsWith(starter+"killer") && splitToArrayList(o, " ").size() > 2){
    altBef = splitToArrayList(o, " ", 3).get(2);
   }// /if(o
  }// /for(String
  // Freie AP und Bauern überprüfen:
  int freeAP = unit.getRegion().getType().getInhabitants() - (getResourceAmount(unit.getRegion(), "Holz")*10 + getResourceAmount(unit.getRegion(), "Elefant")*5 + getResourceAmount(unit.getRegion(), "Mastodon")*5 + getResourceAmount(unit.getRegion(), "Kamel") + getResourceAmount(unit.getRegion(), "Pferd") + getResourceAmount(unit.getRegion(), "Zotte") + getResourceAmount(unit.getRegion(), "Alpaka"));
  if (freeAP > 0 && unit.getRegion().getPeasants() > 0){setOrderPreserveComments(unit, "TREIBE");}// /if(freeAP
  else{setOrderPreserveComments(unit, altBef);}// /else
 }// /else <-if(helper
 helper.updateUnit(unit);
}// /killer(Unit,String)
//}

//{ 3.3 Interaktive Metas
 //{ 3.3.1 Study-Komplex
 // +lerne <Skill> [<level>] [<AltBef>]
 // +lehre <Skill> <AltBef>
studyComplex(Region region){
 String studyReady = "NILLL";
 for(String skill : skillList.split(" ")){
  skill = skillUmlaute(skill);// uL AUS

// betroffene Einheiten einsammeln
  // +lehre und +lerne einsammeln und auf Startposition ("NULLL") stellen:
  ArrayList schueler = unitsInRegionWithOrder(region, me+"lerne "+skill);
  for(Unit unit : schueler){
     // Gegenprobe von +lernen
   if (!(unit.getOrders().toString().contains(skill+" fertig gelernt"))){setOrderPreserveComments(unit, studyReady);}
  }
 
  ArrayList lehrer = unitsInRegionWithOrder(region, me+"lehre "+skill);
  for(Unit unit : lehrer){setOrderPreserveComments(unit, studyReady);}

  // +lehre sucht +lerne (multiple Schüler))
  for(Unit teacher : lehrer){
   int enumPupils = 0;
   for(Unit student : schueler){
    if(student.getOrders().toString().contains(studyReady) && enumPupils + student.getPersons() <= teacher.getPersons() * 10 && helper.getLevel(student, skillUmlaute(skill)) < helper.getLevel(teacher, skillUmlaute(skill))){
     setOrderPreserveComments(student, "LERNE "+skill+" ; mit Lehrer "+teacher.getID().toString());
     helper.updateUnit(student);
     setTeachOrder(teacher, student.getID().toString());
     helper.updateUnit(teacher);
     enumPupils = enumPupils + student.getPersons();
    }// /if(enumPupils
   }// /for(Unit student
  }// /for(Unit teacher

// +lerne <skill> <lvl> <altBef>
  // +lerne ohne Lehrer bekommen Beschäftigungstherapie
  for(Unit unit : schueler){
   if(unit.getOrders().toString().contains(studyReady)){
    String altBef = "LERNE "+skill+" ; ohne Lehrer"; // default
    for(String order : unit.getOrders()){
     if(order.trim().startsWith(me+"lerne")){
      ArrayList line = splitToArrayList(order, " ", 5);
      if(line.size() > 3){
       try {int a = Integer.parseInt(line.get(3));
        if(line.size() > 4){altBef = line.get(4)+" ; ersatzweise";}
       }// /try
       catch(NumberFormatException testballonSchuelerAltbef){
        altBef = line.get(3);
        if(line.size() > 4){altBef = altBef+" "+line.get(4)+" ; ersatzweise";}
       }// /catch(NFE
      }// /if(line.size>3
     }// /if(order.startsWith
    }// /for(String order
    setOrderPreserveComments(unit, altBef);
    helper.updateUnit(unit);
   }// /if(unit.getOrders()
  }// /for(Unit unit:schueler

// unbeschäftigte Lehrer einsammeln
  schueler.clear();
  for(Unit unit : lehrer){if(unit.getOrders().toString().contains(studyReady) || getNumberOfPupils(unit) < unit.getPersons() * 10){schueler.add(unit);}}
  lehrer = schueler.clone();
  // +lehre lehrt andere +lehre (nur Einheiten mit mehr Personsn; multiple Schüler)
  for(Unit teacher : lehrer){
   int enumSchueler = getNumberOfPupils(teacher);
   for(Unit otherTeacher : schueler){
    if(otherTeacher.getOrders().toString().contains(studyReady) && otherTeacher.getPersons() > teacher.getPersons() && enumSchueler + otherTeacher.getPersons() <= teacher.getPersons() * 10 && helper.getLevel(otherTeacher, skillUmlaute(skill)) < helper.getLevel(teacher, skillUmlaute(skill))){
     enumSchueler = enumSchueler + otherTeacher.getPersons();
     setOrderPreserveComments(otherTeacher, "LERNE "+skill+" ; mit Kollege "+teacher.getID().toString());
     helper.updateUnit(otherTeacher);
     setTeachOrder(teacher, otherTeacher.getID().toString());
     helper.updateUnit(teacher);}}}
  // unbeschäftigte +lehre einsammeln
  schueler.clear();
  for(Unit unit : lehrer){if(unit.getOrders().toString().contains(studyReady)){schueler.add(unit);}}
 // +lehre mit ohne irgendwas bekommt Beschäftigungstherapie
 // +lehre <skill> [<altBef>]
  for(Unit unit : schueler){
   String altBef = "LERNE "+skill+" ; Weiterbildung";
   for(String order : unit.getOrders()){
    if(order.trim().startsWith(me+"lehre "+skill)){
     if(splitToArrayList(order, " ", 4).size() > 3){
      altBef = splitToArrayList(order, " ", 4).get(3)+" ; ersatzweise";
     }// /if
    }// /if(order
   }// for(String
   setOrderPreserveComments(unit, altBef);
  }// /for(Unit
 }// for(String skill
}// /studyComplex(Region)

int getNumberOfPupils(Unit unit){
 int i = 0;
 for(Unit pupil : unit.getPupils()){
 i = i+pupil.getPersons();}
 return i;
}// /int getNumberOfPupils(Unit)

setTeachOrder(Unit unit, String id){
 String teach = "LEHRE";
 for(String order : unit.getOrders()){
  if(order.trim().startsWith(teach)){teach = order;}}
 setOrderPreserveComments(unit, teach+" "+id);
}// /setTeachOrder(Unit,String)
 //} /Study-Komplex
//}

//{ 3.4 Weiche Metas

 //{ 3.4.1 +rek [<n>] [,<m>]
 // n = BauernMax;
 // m = BestätigungsMax
 // +rek n , m
regulator(Unit unit, Region region, String starter){
 // Variabeln:
 int maxBau = getIdeBau(unit);
 int confirm = region.getType().getInhabitants() / 10;
 // suchen nach n und m
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"rek") && splitToArrayList(o, " ").size() > 2){
   if (o.contains(",")){
    maxBau = Integer.parseInt(o.substring(7, o.indexOf(",")).trim());
    confirm = Integer.parseInt(o.substring(o.indexOf(",")).trim());
   }// /if(o.contains
   else{maxBau = Integer.parseInt(splitToArrayList(o, " ").get(2));}
  }// /if(o.startsWith
 }// /for(String
 // Bauernpop untersuchen:
 int diff = region.getPeasants() - maxBau;
 if (diff > 0){
  diff = getLegen(unit, diff);
  int braucht = diff*(unit.getRace().getRecruitmentCosts()+10);
  // Silberlager suchen
   Unit sil = unit; // Platzhalter
   if (regionalUnitOrders(region).contains(me+"sLag")){sil = unitsInRegionWithOrder(region, me+"sLag").get(0);}// if(regionalUnitOrders
   else {
    if (regionalUnitOrders(region).contains(me+"lager")){sil = unitsInRegionWithOrder(region, me+"lager").get(0);}// /if(regionalUnitOrders
   }// /else
   if (sil.getOrders().toString().contains(me+"sLag") || sil.getOrders().toString().contains(me+"lager")){
    helper.addOrder(sil, "GIB "+unit.getID().toString()+" "+braucht.toString()+" Silber ; Rekrutierungskosten");
   }// /if(sil
   // ...oder aus den anderen Einheiten zusammensammeln:
   else{
    int s = 0; // einsammelbares Silber
    HashMap givers = new HashMap(); // in Frage kommende Einheiten und ihre Silberbeträge
    while (s < braucht){
     for (Unit other : region.units()){
      if (other.getFaction() == unit.getFaction() && other != unit && helper.getItemCount(other, "Silber") > 0){
       s = s + helper.getItemCount(other, "Silber");
       givers.put(other, helper.getItemCount(other, "Silber"));
      }// /if(other
     }// /for(Unit
    }// /while(s<braucht
    if (s >= braucht){
     for (Unit u : givers.keySet()){
      helper.addOrder(u, "GIB "+unit.getID().toString()+" "+givers.get(u)+" Silber ; Rekrutierungshilfe");
      helper.updateUnit(u);
     }// /for(Unit
    }// /if(s
   }// /else <- if(sil
   if (helper.getModifiedItemCount(unit, "Silber") >= braucht){
    helper.addOrder(unit, "REKRUTIERE "+diff.toString());
    // Bestätigung untersuchen
    if (unit.getPersons() < confirm){unit.setOrdersConfirmed(true);}// /if(unit
   }// /if(helper
   else{
    unit.setOrdersConfirmed(false);
    helper.addOrder(unit, "Meta-Warnung: Nicht genug Silber vorhanden, um zu rekrutieren");
   }// /else <- if(helper
  }// /if(diff
 helper.updateUnit(unit);
}// /regulator(Unit,Region,String)
int getIdeBau(Unit unit){
 int id = (unit.getRegion().getType().getInhabitants() / 100 * 101)-1;
 if (unit.getRegion().getType().getInhabitants() > 3999){
  id = unit.getRegion().getType().getInhabitants() / 1000 * 1005;
 }// /if(unit
 return id;
}// /int getIdeBau(Unit)

int getLegen(Unit unit, int diff){
 int re = diff;
 if (re > unit.getRegion().getPeasants() / 20){
  re = unit.getRegion().getPeasants() / 20;
 }
 if (re >= 100){
  re = re  / 100;
  return re * 100;
 }
 if (re < 100){
  if (re >= 50){
   re = re / 10;
   return re * 10;
  }
  else{
   return re;
  }
 }
}

 //} /+rek
 

 //{ 3.4.2 Lager- und Reservierung-Metas
  //  3.4.2.1 +lager
  // Allroundlager: Übernimmt alle Lagerjobs, die in der Region sonst nicht vergeben sind
lager(Unit aLager){
 ArrayList ordersInRegion = regionalUnitOrders(aLager.getRegion());
 if (!(ordersInRegion.contains(me+"sLag"))){
  sLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"nLag"))){
  nLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"fLag"))){
  fLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"mLag"))){
  mLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"rLag"))){
  rLager(aLager);
 }
 if (!(ordersInRegion.contains(me+"tLag"))){
  tLager(aLager);
 }
}// /lager(Unit)

  // 3.4.2.2 +sLag
  // (Silber)
sLager(Unit lager){
// sammelt Silber und gibt allen Unterhalt
 for (Unit unit : lager.getRegion().units()){
  if (unit.getFaction() == lager.getFaction()){
   int futter = unit.getModifiedPersons() * 10;
   if (unit.getOrders().toString().contains("LERNE Taktik")){
    futter = futter + (unit.getPersons() * 100);
   }// /if(unit.getPersons
   if (unit.getBuilding() != null && (unit.getBuilding().getType().toString().equals("Sägewerk") || unit.getBuilding().getType().toString().equals("Bergwerk") || unit.getBuilding().getType().toString().equals("Steinbruch") || unit.getBuilding().getType().toString().equals("Schmiede") || unit.getBuilding().getType().toString().equals("Werkstatt") || unit.getBuilding().getType().toString().equals("Sattlerei") || unit.getBuilding().getType().toString().equals("Schiffswerft"))){
    futter = futter + unit.getPersons() * 5;
   }// /if(unit.getBuilding()
   if (unit.getBuilding() != null && unit == unit.getBuilding().getOwnerUnit() && buildingMaintenances.keySet().contains(unit.getBuilding().getType().toString())){
    futter = futter + buildingMaintenances.get(unit.getBuilding().getType().toString());
   }// /if(unit.getBuilding
   if (unit.getItems().toString().contains("Kriegselefant") || unit.getItems().toString().contains("Kriegsmastodon")){
    int n = helper.getItemCount(unit, "Kriegselefant") + helper.getItemCount(unit, "Kriegsmastodon");
   futter = futter + 5 * n;
   }// /if(unit.getItems
   futter = futter - helper.getModifiedItemCount(unit, "Silber");
   if (futter > 0 && unit != lager){
    helper.addOrder(lager, "GIB "+unit.getID().toString()+" "+futter+" Silber ; Futter");
    helper.updateUnit(lager);
   }// /if(futter
   if (futter < 0 && unit != lager && !(unit.getOrders().toString().contains("REKRUTIERE"))){
    helper.addOrder(unit, "GIB "+lager.getID().toString()+" "+((-1) * futter).toString()+" Silber ; einlagern");
    helper.updateUnit(unit);
   }// /if(futter
  }// /if(unit.getFaction
 }// /for(Unit
  if (lager.getOrders().toString().contains("forlage")){
  lager.setOrdersConfirmed(false);
  helper.updateUnit(lager);
 }
}// /sLager(Unit)

  // 3.4.2.3 +nLag
  //{ (Nahkampfwaffen)
nLager(Unit nLag){
 for (String waffe : nLagerZieht){
  for (Unit unit : nLag.getRegion().units()){
   if (unit.getFaction() == nLag.getFaction() && unit != nLag && (unit.getOrders().toString().contains(me+"nkw") || (unit.getOrders().toString().contains(com+" #berichte"))) && unit != nLag && helper.getModifiedItemCount(unit, waffe) > 0){
    helper.addOrder(unit, "GIB "+nLag.getID().toString()+" "+helper.getModifiedItemCount(unit, waffe).toString()+" "+waffe+" ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
}
ArrayList nLagerZieht = new ArrayList();
nLagerZieht.add("Schwert");
nLagerZieht.add("Streitaxt");
nLagerZieht.add("Kriegshammer");
nLagerZieht.add("Speer");
nLagerZieht.add("Kriegselefant");
nLagerZieht.add("Kriegsmastodon");
  //} /nLag

  // 3.4.2.4 +fLag
  //{ (Fernkampfwaffen)
fLager(Unit fLag){
 for (String waffe : fLagerZieht){
  for (Unit unit : fLag.getRegion().units()){
   if (unit.getFaction() == fLag.getFaction() && unit != fLag && (unit.getOrders().toString().contains(me+"bogner") || unit.getOrders().toString().contains(me+"wagner") || (unit.getOrders().toString().contains(com+" #berichte"))) && unit != fLag && helper.getModifiedItemCount(unit, waffe) > 0){
    helper.addOrder(unit, "GIB "+fLag.getID().toString()+" "+helper.getModifiedItemCount(unit, waffe).toString()+" "+waffe+" ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
}
ArrayList fLagerZieht = new ArrayList();
fLagerZieht.add("Bogen");
fLagerZieht.add("Armbrust");
fLagerZieht.add("Katapult");
  //} /fLag

 // 3.4.2.5 +rLag
 //{ (Rüstungsteile)
rLager(Unit rLag){
 for (String rTeil : rLagerZieht){
  for (Unit unit : rLag.getRegion().units()){
   if (unit.getFaction() == rLag.getFaction() && unit != rLag && (unit.getOrders().toString().contains(me+"ruestung") || unit.getOrders().toString().contains(com+" #berichte")) && unit != rLag && helper.getModifiedItemCount(unit, rTeil) > 0){
    helper.addOrder(unit, "GIB "+rLag.getID().toString()+" "+helper.getModifiedItemCount(unit, rTeil).toString()+" "+rTeil+" ; einlagern");
    helper.updateUnit(unit);
   }
   if (unit.getOrders().toString().contains(me+"nkw") && unit != rLag){
    int epBed = 0;
    if (helper.getLevel(unit, "Waffenbau") > 4){
     epBed = helper.getLevel(unit, "Waffenbau") * unit.getPersons() / 5;
    }
    if (epBed > 0 && helper.getModifiedItemCount(rLag, "Elefantenpanzer") >= epBed){
     helper.addOrder(rLag, "GIB "+unit.getID().toString()+" "+epBed.toString()+" Elefantenpanzer ; Waffenbauer");
     helper.updateUnit(rLag);
    }
   }
  }
 }
}
ArrayList rLagerZieht = new ArrayList();
rLagerZieht.add("Holzschild");
rLagerZieht.add("Eisenschild");
rLagerZieht.add("Kettenhemd");
rLagerZieht.add("Plattenpanzer");
rLagerZieht.add("Elefantenpanzer");
ArrayList rLagerGibt = new ArrayList();
rLagerGibt.add("Elefantenpanzer");
 //} /rLag

 // 3.4.2.6 +tLag
 //{ (Transport-Items)
tLager(Unit tLag){
 for (Unit unit : tLag.getRegion().units()){
  if (unit.getFaction() == tLag.getFaction() && unit != tLag){ // Standardprüfung zur Vermeidung sinnloser Befehlszeilen
// auf +herde & +wagner & Allroundlager prüfen
   if (unit.getOrders().toString().contains(me+"herde") || unit.getOrders().toString().contains(me+"wagner") || unit.getOrders().toString().contains(com+" #berichte")){
    for (String tier : tLagerZieht){
// auf Items prüfen
     if (helper.getItemCount(unit, tier) > 0){
      helper.addOrder(unit, "GIB "+tLag.getID().toString()+" "+helper.getModifiedItemCount(unit, tier).toString()+" "+tier+" ; einlagern");
      helper.updateUnit(unit);
     }// /if(helper.getItemCount
    }// /for(String tier
   }// /if(unit.getOrders
// Greifeneier prüfen
   if (helper.getItemCount(unit, "Greifenei") > 0){
    helper.addOrder(unit, "GIB "+tLag.getID().toString()+" "+helper.getModifiedItemCount(unit, "Greifenei").toString()+" Greifenei ; einlagern");
    helper.updateUnit(unit);
   }
  }// /if(unit.getFaction
 }// /for(Unit
}// /tLager(Unit)
ArrayList tLagerZieht = new ArrayList();
tLagerZieht.add("Pferd");
tLagerZieht.add("Kamel");
tLagerZieht.add("Elefant");
tLagerZieht.add("Alpaka");
tLagerZieht.add("Zotte");
tLagerZieht.add("Mastodon");
tLagerZieht.add("Wagen");
tLagerZieht.add("Pegasus");
ArrayList tLagerGibt = new ArrayList();
tLagerGibt.add("Elefant");
 //} /tLag

  // 3.4.2.7 +mLag
  //{ (Baumaterial)
mLager(Unit mLag){
 for (Unit unit : mLag.getRegion().units()){
  for (String mat : mLagerZieht){
   if (unit != mLag && unit.getFaction() == mLag.getFaction() && !(wirdVonMLagBedient(unit)) && helper.getItemCount(unit, mat) > 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+helper.getItemCount(unit, mat).toString()+" "+mat+" ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
 for (Unit unit : mLag.getRegion().units()){
  if (unit != mLag && unit.getFaction() == mLag.getFaction() && wirdVonMLagBedient(unit)){
   int hBed = 0;
   int eBed = 0;
   int sBed = 0;
   if (unit.getOrders().toString().contains(me+"nkw")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Waffenbau") / 2);
    eBed = eBed + (unit.getPersons() * helper.getLevel(unit, "Waffenbau"));
    sBed = sBed + (unit.getPersons() * helper.getLevel(unit, "Waffenbau") / 5);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Schmiede")){
     hBed = hBed / 2;
     eBed = eBed / 2;
     sBed = sBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"bogner")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Bogenbau") / 2);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Schmiede")){
     hBed = hBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"ruestung")){
    eBed = eBed + (unit.getPersons() * helper.getLevel(unit, "Rüstungsbau") * 2);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Sattlerei")){
     eBed = eBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"wagner")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Wagenbau") * 5);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Werkstatt")){
     hBed = hBed / 2;
    }
   }
   if (unit.getOrders().toString().contains(me+"reeder")){
    hBed = hBed + (unit.getPersons() * helper.getLevel(unit, "Schiffbau") / 2);
    if (unit.getBuilding() != null && unit.getBuilding().getType().toString().equals("Schiffswerft")){
     hBed = hBed / 2;
    }
   }
   hBed = hBed - helper.getModifiedItemCount(unit, "Holz");
   eBed = eBed - helper.getModifiedItemCount(unit, "Eisen");
   sBed = sBed - - helper.getModifiedItemCount(unit, "Stein");
   if (hBed > 0 && helper.getItemCount(mLag, "Holz") >= hBed){
    helper.addOrder(mLag, "GIB "+unit.getID().toString()+" "+hBed.toString()+" Holz");
    helper.updateUnit(mLag);
   }
   if (hBed < 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+((-1)*hBed).toString()+" Holz ; einlagern");
    helper.updateUnit(unit);
   }
   if (eBed > 0 && helper.getItemCount(mLag, "Eisen") >= eBed){
    helper.addOrder(mLag, "GIB "+unit.getID().toString()+" "+eBed.toString()+" Eisen");
    helper.updateUnit(mLag);
   }
   if (eBed < 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+((-1)*eBed).toString()+" Eisen ; einlagern");
    helper.updateUnit(unit);
   }
   if (sBed > 0 && helper.getItemCount(mLag, "Stein") >= sBed){
    helper.addOrder(mLag, "GIB "+unit.getID().toString()+" "+sBed.toString()+" Stein");
    helper.updateUnit(mLag);
   }
   if (sBed < 0){
    helper.addOrder(unit, "GIB "+mLag.getID().toString()+" "+((-1)*sBed).toString()+" Stein ; einlagern");
    helper.updateUnit(unit);
   }
  }
 }
}
ArrayList mLagerZieht = new ArrayList();
mLagerZieht.add("Holz");
mLagerZieht.add("Eisen");
mLagerZieht.add("Stein");
mLagerZieht.add("Gold");
boolean wirdVonMLagBedient(Unit unit){
 for (String fkt : mLagerBedient){
  if (unit.getOrders().toString().contains(fkt)){
   return true;
  }
 }
 return false;
}
  //} /mLag

  // 3.4.2.7 Händler: Einsammeln von Luzxusgütern
handel(Unit handler){
 for (Unit unit : handler.getRegion().units()){
  if (unit != handler && unit.getFaction() == handler.getFaction()){
   for (s : handler.getRegion().getPrices().values()){
    String lux = s.toString().substring(0, s.toString().indexOf(":"));
    if (helper.getItemCount(unit, lux) > 0){
     if (helper.getModifiedItemCount(unit, lux) > 0){
      helper.addOrder(unit, "GIB "+handler.getID().toString()+" "+helper.getItemCount(unit, lux).toString()+" "+lux+" ; einlagern");
      helper.updateUnit(unit);
     }
    }
   }
  }
 }
}
 //}

 // 3.4.3 +bewache
autarn(Unit unit){
// implementiert +bewache
// Einheiten, die Tarnen können, tarnen sich;
// Einheiten mit Parteitarnung nennen die Tarnpartei in einem Kommentar
 if (unit.getOrders().toString().contains(me+"bewache")){
  helper.addOrder(unit, "BEWACHE");
  helper.updateUnit(unit);
 }// /if(unit.getOrders
 else{
  if (unit.getBuilding() == null && !(unit.getOrders().toString().contains("TARNE Einheit ; automatisch"))){
   boolean tarn = false;
   for (skill : unit.getModifiedSkills()){
    if (skill.toString().substring(0, skill.toString().indexOf(" ")).equalsIgnoreCase("Tarnung") && !(splitToArrayList(skill.toString(), " ").get(1).equals("0"))){
     tarn = true;
    }// /if(skill
   }// /for(String
   if(tarn){helper.addOrder(unit, "TARNE Einheit ; automatisch");}// /if(tarn
   helper.updateUnit(unit);
  }// /if(unit
 }// /else
 if (unit.getGuiseFaction() != null){
  helper.addOrder(unit, "; getarnt als: "+unit.getGuiseFaction().toString());
  helper.updateUnit(unit);
 }// /if(unit.getGuiseFaction
}// /autarn(Unit)
//}

 //{ 3.4.3a +gib |<uID> <[<n>] <item> [[<n1>] <item1> [<n2>] <item2>...][;<comment>]//

gib(Unit unit, String starter){
 ArrayList sendOrders = new ArrayList();
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(starter+"gib")){
   String id = splitToArrayList(o, " ").get(2);
   if (unit.getRegion().units().toString().contains("("+id+")")){
    String ladeliste = o.substring(o.indexOf(id)+id.length()).trim();
    String comment = "";
    if (ladeliste.contains(";")){
     comment = ladeliste.substring(ladeliste.indexOf(";")).trim();
     ladeliste = ladeliste.substring(0, ladeliste.indexOf(";")).trim();
    }// /if(ladeliste.contains
   
    int i = 0;
    ArrayList liste = splitToArrayList(ladeliste, " ");
    while (i < liste.size()){
     int amount = 0;
     String item = "";
     try {
      amount = Integer.parseInt(liste.get(i));
      i++;
      item = liste.get(i);
      if (helper.getModifiedItemCount(unit, itemUmlaute(item)) > 0){
       if (amount > helper.getModifiedItemCount(unit, itemUmlaute(item))){amount = helper.getModifiedItemCount(unit, itemUmlaute(item));}// /if(amount > item
       sendOrders.add("GIB "+id+" "+amount.toString()+" "+item+" "+comment);
      }// if item > 0
      i++;
     }// /try
     catch (NumberFormatException nfe){
      item = liste.get(i);
      amount = helper.getModifiedItemCount(unit, itemUmlaute(item));
      if (amount > 0){sendOrders.add("GIB "+id+" "+amount.toString()+" "+item+" "+comment);}// /if(amount > 0
      i++;
     }// /catch
    }// /while

   }// /if(unit.getRegion
  }// /if(o.startsWith
 }// /for(String o
 for (String sendOrder : sendOrders){helper.addOrder(unit, sendOrder);}// /for(String sendOrder
 helper.updateUnit(unit);}// /gib(Unit,String)
String itemUmlaute(String item){
 if (item.startsWith("Oe")){return "Öl";}
 if(item.contains("ue")){return "Gewürz";}
 return item;
}// /String itemUmpaute(String)
//} /gib

/*****************************************/
/////{ 4. Allgemeine Hilfsskripte /////////
/*****************************************/
// 4.1
setOrderPreserveComments(Unit unit, String order){
// ersetzt helper.setOrder(Unit,String), wenn Kommentare erhalten bleiben sollen
// behällt auch Zeilen, die mit "forlage" anfangen (wg #berichte)
 ArrayList comments = new ArrayList();
 //Einsammeln der Kommentare
 for (String o : unit.getOrders()){
  if (o.trim().startsWith(com) || o.trim().startsWith(";") || o.startsWith("forlage") || o.startsWith("Meta-Warnung")){
   comments.add(o);
  }// /if(o
 }// /for(String
 helper.setOrder(unit, ""); // das set-Element
 for (String c : comments){helper.addOrder(unit, c);}// Wiedergabe von Kommentaren
 helper.addOrder(unit, order); // Befehl wird gegeben
 helper.updateUnit(unit);
}// /setOrderPreserveComments(Unit,String)

// 4.2
int getResourceAmount(Region region, String stuff){
 if (region.resources().toString().contains(stuff)){
  return region.getResource(region.data.getRules().getItemType(StringID.create(stuff))).getAmount();
 }// /if(region
 else{return 0;}
}// /int getResourceAmount(Region,String)

// 4.3
ArrayList unitsInRegionWithOrder(Region region, String order){
 ArrayList arr = new ArrayList();
 for (Unit unit : region.units()){
  if (unit.getOrders().toString().contains(order)){arr.add(unit);}// /if(unit
 }// /for(Unit
 return arr;
}// /ArrayList unitsInRegionWithOrder(Region,String)

// 4.4
ArrayList regionalUnitOrders(Region region){
// Listet alle bekannten Befehle von Einheiten in der Region auf
// und zwar NUR die Befehle
 ArrayList arr = new ArrayList();
 for (Unit unit : region.units()){
  for (String o : unit.getOrders()){arr.add(o);}// /for(String
 }// /for(Unit
 return arr;
}// /ArrayList regionalUnitOrders(Region)

// 4.5
ArrayList splitToArrayList(String s, String trenner){
 arr = new ArrayList();
 for (e : s.split(trenner)){arr.add(e);}
 return arr;
}// /ArrayList splitToArrayList(String,String)

// 4.6
ArrayList splitToArrayList(String s, String trenner, int limit){
 arr = new ArrayList();
 for (e : s.split(trenner, limit)){arr.add(e);}
 return arr;   
}// /ArrayList splitToArrayList(String,String,int)

// 4.7
int lerntage(Unit unit, String skill){
 String n = ""; // bequemlichkeit halber sofort deklariert
                     // In dieser Variablen werden unsere Zieldaten eingefangen werden
 for (String s : unit.getSkills().toString().substring(1, unit.getSkills().toString().length()-1).split(", ")){
  // Die Collection wird zu einem String umgebaut,
  // (In dieser Darstellungsweise beginnt der String mit "[", endet mit "]"
  // und trennt die Elemente der Collection mit ", ")
  // (netto machen wir die Collection also zu einem Array von Strings und
  // untersuchen die Einzelnen Elemente)
  if (s.substring(0, s.indexOf(" ")).equalsIgnoreCase(skill)){
  // Praktischerweise beginnt jedes Element mit Talentname, gefolgt von Space
  // unpraktischerweise hat Magellan nicht alle Talente großgeschrieben in der Datenbank,
  //  daher equalsIgnoreCase(String) statt startsWith(String)
   n = s.substring((s.indexOf("["))+1, s.indexOf("]"));
   // noch praktischererweise sind die Lerntage in den Elementen in eckige Klammern gesetzt
  }
 }
 // Entweder besteht der String n jetzt aus Ziffern-Charakters, oder ist leer.
 try {
  return Integer.parseInt(n);
 }
 catch (NumberFormatException nfe){
 // wenn n leer ist, steht das Talent nicht in der Collection und muss daher null Lerntage haben.
  return 0;
 }
}// /int lerntage(Unit,String)

// 4.8
int modifiedLerntage(Unit unit, String skill){
 String n = "";
 for (String s : unit.getModifiedSkills().toString().substring(1, unit.getSkills().toString().length()-1).split(", ")){
  if (s.substring(0, s.indexOf(" ")).equalsIgnoreCase(skill)){
   n = s.substring((s.indexOf("["))+1, s.indexOf("]"));
  }
 }
 try {
  return Integer.parseInt(n);
 }
 catch (NumberFormatException nfe){
  return 0;
 }
}// /int modifiedLerntage(Unit,String)

//{ 4.9 ArrayList longOrders
ArrayList longOrders = new ArrayList();
longOrders.add("FOLGE");
longOrders.add("NACH");
longOrders.add("ROUTE");
longOrders.add("BEKLAUE");
longOrders.add("HANDEL");
longOrders.add("LEHRE");
longOrders.add("LERNE");
longOrders.add("MACHE");
longOrders.add("TREIBE");
longOrders.add("UNTERHALTE");
longOrders.add("ZERSTOERE");
//}
// 4.9.a
boolean isLongOrder(String order){
 for (String longs : longOrders){
  if (splitToArrayList(order.trim(), " ").get(0).equalsIgnoreCase(longs)){return true;}// /if(order
 }// /for(String
 return false;
}// /boolean isLongOrder(String)

//}
/*****************************************/
//} ENDE CbC
/*****************************************/
I may go pop -- Excuse me!

Benutzeravatar
nemo
Heerführer
Beiträge: 232
Registriert: Mi 25. Feb 2015, 12:06

Discontinuing CbC

Beitrag von nemo » Do 29. Mär 2018, 03:44

Wo ich gerade sehe, dass das letzte Upate über ein Jahr her ist, vermutlich keine große Überraschung, aber ums einfach mal amtlich zu machen: Braucht erstmal niemand auf neue Updates warten. Bin erstmal komplett raus aus Fantasya. Wie ich mich kenne, wird es aber weiter gehen, wenn ich zurück komme. Bis dahin alles Gute
nemo
I may go pop -- Excuse me!

Benutzeravatar
Kombinat
Oberst
Beiträge: 140
Registriert: Mo 26. Jan 2015, 21:48

Re: Command By Comments: Code (09. April)

Beitrag von Kombinat » Fr 30. Mär 2018, 15:36

Hey,

schonmal dank für alles was du da gemacht hast. ich nutze es immernoch und läuft 1a :)

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste