Command By Comments: Code (09. April)

Hier können nach Lust und Laune über alles außerhalb von Fantasya geschrieben werden.

Moderator: Durin

Antworten
Benutzeravatar
nemo
Heerführer
Beiträge: 232
Registriert: Mi 25. Feb 2015, 12:06
Wohnort: Ipska (Nord-Faerun)
Kontaktdaten:

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.
Neues Hilftool für Fantasya+FMagellan: Command By Comments:
http://forum.fantasya-pbem.de/viewtopic.php?f=7&t=192
Seid Ihr das Essen? -- Nein! Wir sind die Jäger! -- Nein! Wir sind die Meerschweinchen!

Benutzeravatar
nemo
Heerführer
Beiträge: 232
Registriert: Mi 25. Feb 2015, 12:06
Wohnort: Ipska (Nord-Faerun)
Kontaktdaten:

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.
Neues Hilftool für Fantasya+FMagellan: Command By Comments:
http://forum.fantasya-pbem.de/viewtopic.php?f=7&t=192
Seid Ihr das Essen? -- Nein! Wir sind die Jäger! -- Nein! Wir sind die Meerschweinchen!

Benutzeravatar
nemo
Heerführer
Beiträge: 232
Registriert: Mi 25. Feb 2015, 12:06
Wohnort: Ipska (Nord-Faerun)
Kontaktdaten:

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
/*****************************************/
Neues Hilftool für Fantasya+FMagellan: Command By Comments:
http://forum.fantasya-pbem.de/viewtopic.php?f=7&t=192
Seid Ihr das Essen? -- Nein! Wir sind die Jäger! -- Nein! Wir sind die Meerschweinchen!

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron