Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/std/living/skills.c b/std/living/skills.c
new file mode 100644
index 0000000..93c9dcc
--- /dev/null
+++ b/std/living/skills.c
@@ -0,0 +1,595 @@
+// MorgenGrauen MUDlib
+//
+// living/skills.c -- Gilden-, Skill- und Spellfunktionen fuer Lebewesen
+//
+// $Id: skills.c 8755 2014-04-26 13:13:40Z Zesstra $
+#pragma strict_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+inherit "/std/living/std_skills";
+
+#define NEED_PROTOTYPES
+#include <living/skills.h>
+#include <living/skill_attributes.h>
+#include <player/life.h>
+#undef NEED_PROTOTYPES
+
+#include <thing/properties.h>
+#include <properties.h>
+#include <new_skills.h>
+#include <wizlevels.h>
+
+// speichert die Spell-Fatigues (global, Spruchgruppen, Einzelsprueche)
+private mapping spell_fatigues = ([]);
+
+// Prototypen
+private void expire_spell_fatigues();
+
+protected void create()
+{
+  // mainly necessary for players, but there may be some NPC with savefiles.
+  // Additionally, it simplifies expiration of old keys to have it here.
+  call_out(#'expire_spell_fatigues, 4);
+}
+
+
+// Diese - hier scheinbar sinnlose - Funktion wird von /std/player/skills.c dann 
+// ueberladen.
+public int is_deactivated_skill(string sname, string gilde)
+{
+	return 0;
+}
+
+
+
+static string _query_visible_guild()
+{ string res;
+
+  if ( stringp(res=Query(P_VISIBLE_GUILD)) )
+    return res;
+
+  return QueryProp(P_GUILD);
+}
+
+static string _query_visible_subguild_title()
+{ string res;
+
+  if ( stringp(res=Query(P_VISIBLE_SUBGUILD_TITLE)) )
+    return res;
+
+  return QueryProp(P_SUBGUILD_TITLE);
+}
+
+static mixed _query_guild_prepareblock()
+{ mapping res;
+  string  gilde;
+
+  if ( !stringp(gilde=QueryProp(P_GUILD)) )
+    return 0;
+  if ( !mappingp(res=Query(P_GUILD_PREPAREBLOCK)) 
+      || !member(res,gilde) )
+    return 0;
+  return res[gilde];
+}
+
+static mixed _set_guild_prepareblock(mixed arg)
+{ mapping res;
+  string  gilde;
+
+  if ( !stringp(gilde=QueryProp(P_GUILD)) )
+    return 0;
+  if ( !mappingp(res=Query(P_GUILD_PREPAREBLOCK)) )
+    res=([]);
+
+  res[gilde]=arg;
+  Set(P_GUILD_PREPAREBLOCK,res);
+
+  return arg;
+}
+
+
+private nosave int valid_setskills_override;
+// Man sollte eigentlich ja nicht Parameter als globale Variablen
+// uebergeben, aber hier ging es nicht anders
+nomask private int valid_setskills(string gilde)
+{ string fn;
+
+  if ( !query_once_interactive(this_object()) )
+    return 1; // Monster duerfen sich selber Skills setzen :)
+
+  if ( QueryProp(P_TESTPLAYER) || IS_WIZARD(this_object()) )
+      return 1; // Testspieler und Magier sind schutzlose Opfer ;-)
+
+  if ( previous_object() )
+  {
+    if ( previous_object()==this_object()
+        && this_interactive()==this_object() )
+      return 1;
+
+    fn=object_name(previous_object());
+    if ( fn[0..7]=="/gilden/"
+        || fn[0..11]=="/spellbooks/"
+        || fn[0..7]=="/secure/"
+        || fn[0..11]=="/p/zauberer/" )
+      return 1; // Die sollten problemlos aendern duerfen
+
+    if ( file_size("/gilden/access_rights")>0
+       && call_other("/gilden/access_rights",
+                    "access_rights",
+                    getuid(previous_object()),
+                    gilde+".c"))
+      return 1; // Setzendes Objekt kommt vom Gildenprogrammierer
+
+    if ( file_size("/gilden/"+gilde+".c")>0
+        && call_other("/gilden/"+gilde,
+                      "valid_setskills",
+                        explode(fn,"#")[0]) )
+      return 1; // Die Gilde selber kann Ausnahmen zulassen
+  }
+
+  if (valid_setskills_override)
+  {
+    valid_setskills_override=0;
+    return 1; // Fuers Setzen der Closure
+  }
+
+  if ( this_interactive() )
+  {
+    if ( IS_ARCH(this_interactive()) )
+      return 1; // Erzmagier duerfen immer aendern
+
+    if ( call_other("/gilden/access_rights",
+                    "access_rights",
+                    getuid(this_interactive()),
+                    gilde+".c"))
+      return 1;  // Der Gildenprogrammierer selber auch
+  }
+
+  // Fuer die Waffenskills, die sollen sich selbst auch setzen duerfen
+  if (!this_interactive() && this_object()==previous_object())
+	  return 1;
+  
+  
+  log_file("SETSKILLS",sprintf("*****\n%s PO:%O->TO:%O TI:%O\n GUILD:%s VERB_ARGS:'%s'\n",
+            ctime(time())[4..15],
+            previous_object(),
+            this_object(),
+            this_interactive(),
+            gilde,
+            ( this_interactive() ? query_verb() + " " +
+                this_interactive()->_unparsed_args() : "") ));
+
+  return 0;
+}
+
+// Nur interne Verwendung, value wird nicht weiter prueft, muss ok sein.
+// Es wird keine Kopie von value gemacht, wenn es ins Mapping geschrieben
+// wird!
+private mapping internal_set_newskills(mapping value, string gilde) {
+  mapping skills;
+
+  // in der richtigen Gilde setzen.
+  if ( !gilde && !(gilde=QueryProp(P_GUILD)) )
+    gilde="ANY";
+
+  // Query(), hier ist eine Kopie nicht sinnvoll.
+  if ( !mappingp(skills=Query(P_NEWSKILLS,F_VALUE)) ) {
+    skills=([]);
+    Set(P_NEWSKILLS, skills, F_VALUE);
+  }
+
+  // Falls dies hier mal ausgewertet werden sollte, nicht vergessen, dass
+  // einige Funktion hier im File die Prop evtl. via
+  // internal_query_newskills() abrufen und direkt aendern...
+  valid_setskills(gilde); // Sicherheitsueberpruefung
+  
+  // Skills setzen. Set() unnoetig, weil wir das von Query() gelieferte
+  // Mapping aendern und das ja via Referenz bekommen haben.
+  skills[gilde]=value;
+  //Set(P_NEWSKILLS,skills);
+
+  return(value);
+}
+
+// nur zur internen Verwendung, es wird keine Kopie des Skillmappings gemacht!
+private mapping internal_query_newskills(string gilde) {
+  mapping skills;
+
+  // richtige Gilde abfragen.
+  if ( !gilde && !(gilde=QueryProp(P_GUILD)) )
+    gilde="ANY";
+
+  skills=Query(P_NEWSKILLS);
+
+  if (!mappingp(skills) || !mappingp(skills=skills[gilde]) )
+    return ([]);
+
+  return(skills);
+}
+
+// Eigentlich sollte man den _query-Funktionen keine Parameter geben...
+static varargs mapping _query_newskills(string gilde) {
+
+  // sonst Kopie des spellmappings liefern! Kostet zwar, aber verhindert
+  // einige andere Bugs und versehentliche Aenderungen an den Skills!
+  return(deep_copy(internal_query_newskills(gilde)));
+}
+
+// Eigentlich sollte man den _set-Funktionen keine weiteren Parameter geben
+static varargs mapping _set_newskills(mapping value, string gilde) {
+
+  // value auf Mappings normalisieren, ggf. Kopieren
+  if ( !mappingp(value) )
+      value=([]);
+  else
+      //zur Sicherheit, wer weiss, was der setzende noch damit macht...
+      value=deep_copy(value);
+
+  // und setzen...
+  internal_set_newskills(value, gilde);
+
+  // und noch ne Kopie von dem Liefern, was wir gesetzt haben (keine Referenz,
+  // sonst koennte der Aufrufende ja noch im Nachhinein aendern).
+  return(_query_newskills(gilde));
+}
+
+private mapping InternalQuerySkill(string sname, string gilde) {
+  mixed skill, skills;
+  // In is_any wird gespeichert, ob es ein gildenunabhaengier Skill ist,
+  // fuer die is_deactivate_skill-Abfrage.
+  int is_any;
+
+  // Skills komplett abfragen, keine spez. Gilde
+  if (!mappingp(skills=Query(P_NEWSKILLS,F_VALUE)))
+      return 0;
+
+  if (stringp(gilde) && sizeof(gilde)) {
+    //bestimmte Gilde angegeben, gut, dort gucken.
+    if (mappingp(skills[gilde]))
+      skill=skills[gilde][sname]; 
+  }
+  else {
+    gilde=QueryProp(P_GUILD); //reale Gilde holen
+    if (gilde && mappingp(skills[gilde]) && 
+	(skill=skills[gilde][sname])) {
+      // gibt es den Spell in der Gilde des Spielers?
+      // dann hier nix machen...
+    }
+    else if (mappingp(skills["ANY"])) {
+     // Zum Schluss: Gibt es den Skill vielleicht Gildenunabhaengig?
+      skill=skills["ANY"][sname];
+      // wenn man hier reinkommt, dann spaeter mit is_deactivated_skill() 
+      // pruefen!
+      is_any=1;
+    }
+  }
+
+  // wenn kein Skill gefunden, mit 0 direkt raus
+  if (!skill) return 0;
+
+  // Bei gildenunabhaengigen auch im Skillmapping vermerken
+  if ( is_any ) {	
+      skill+=([SI_GUILD:"ANY"]);	
+      // Ist er vielleicht in der Gilde des Spielers deaktiviert? 		
+      // Dies kann nur der Fall sein, wenn es kein Gildenskill ist.		
+      if (is_deactivated_skill(sname,gilde)) {		    
+	  return 0;		
+      }
+  }
+
+  return(skill);
+}
+
+public varargs mapping QuerySkill(string sname, string gilde) {
+ 
+    if (!stringp(sname) || !sizeof(sname))
+	return 0;
+
+    //Kopie zurueckliefern
+    return(deep_copy(InternalQuerySkill(sname,gilde)));
+}
+
+#define SMUL(x,y) ((x<0 && y<0)?(-1*x*y):(x*y))
+public varargs int QuerySkillAbility(string sname, string gilde)
+{ mapping skill;
+  string skill2;
+
+  if ( !(skill=InternalQuerySkill(sname, gilde)) )
+    return 0;
+
+  int val=skill[SI_SKILLABILITY];
+
+  if (skill2=skill[SI_INHERIT])
+  {
+    int val2;
+    val2=QuerySkillAbility(skill2);
+    val=(val*MAX_ABILITY+SMUL(val,val2))/(2*MAX_ABILITY);
+  }
+
+  return val;
+}
+
+protected varargs mixed LimitAbility(mapping sinfo, int diff)
+{ mixed abil;
+  int max,old,d2;
+
+  abil=sinfo[SI_SKILLABILITY];
+
+  if ( !intp(abil) )
+    return sinfo;
+  old=abil;
+
+  // Beim Spieler eingetragene Schwierigkeit gilt vor angegebener.
+  if ( (d2=sinfo[SI_DIFFICULTY]) )
+    diff=d2;
+
+  // diff <-100 soll nicht hemmen und macht keinen Sinn
+  diff=(diff<(-100))?(-100):diff;
+  
+  max=MAX_ABILITY-(diff+100)*(35-QueryProp(P_LEVEL));
+
+// diff|lvl 1:|   3:|	7:| 10:| 13:| 16:| 19:| 22:| 25:| 28:| 31:| 34:|
+// ----+------+-----+-----+----+----+----+----+----+----+----+----+----+
+//  -50|   83%|  84%|  86%| 87%| 89%| 90%| 92%| 93%| 95%| 96%| 98%| 99%|
+//  -10|   69%|  72%|  74%| 77%| 80%| 82%| 85%| 88%| 91%| 93%| 96%| 99%|
+//    0|   66%|  69%|  72%| 75%| 78%| 81%| 84%| 87%| 90%| 93%| 96%| 99%|
+//   10|   62%|  65%|  69%| 72%| 75%| 79%| 82%| 85%| 89%| 92%| 95%| 98%|
+//   20|   59%|  62%|  66%| 70%| 73%| 77%| 80%| 84%| 88%| 91%| 95%| 98%|
+//   30|   55%|  59%|  63%| 67%| 71%| 75%| 79%| 83%| 87%| 90%| 94%| 98%|
+//   40|   52%|  56%|  60%| 65%| 69%| 73%| 77%| 81%| 86%| 90%| 94%| 98%|
+//   50|   49%|  53%|  58%| 62%| 67%| 71%| 76%| 80%| 85%| 89%| 94%| 98%|
+//  100|   32%|  38%|  44%| 50%| 56%| 62%| 68%| 74%| 80%| 86%| 92%| 98%|
+//  150|   15%|  22%|  30%| 37%| 45%| 52%| 60%| 67%| 75%| 82%| 90%| 97%|
+//  200|   -2%|   7%|  16%| 25%| 34%| 43%| 52%| 61%| 70%| 79%| 88%| 97%|
+//  250|  -19%|  -8%|	2%| 12%| 23%| 33%| 44%| 54%| 65%| 75%| 86%| 96%|
+//  300|  -36%| -24%| -12%|  0%| 12%| 24%| 36%| 48%| 60%| 72%| 84%| 96%|
+//  400|  -70%| -55%| -40%|-25%|-10%|  5%| 20%| 35%| 50%| 65%| 80%| 95%|
+//  500| -104%| -86%| -68%|-50%|-32%|-14%|  4%| 22%| 40%| 58%| 76%| 94%|
+//  600| -138%|-117%| -96%|-75%|-54%|-33%|-12%|  9%| 30%| 51%| 72%| 93%|
+
+  if ( abil>max )
+    abil=max;
+  if ( abil>MAX_ABILITY
+    ) abil=MAX_ABILITY;
+  else if ( abil<-MAX_ABILITY )
+    abil=-MAX_ABILITY;
+
+  if ( old && !abil )
+    abil=1;
+  // Faehigkeiten sollen nicht durch die Begrenzung verschwinden
+
+  sinfo[SI_SKILLABILITY]=abil;
+
+  return sinfo;
+}
+
+public varargs void ModifySkill(string sname, mixed val, int diff, string gilde)
+{ 
+  mapping skills;
+  mixed skill;
+
+  if ( !stringp(sname) || !sizeof(sname) )
+    return;
+
+  // internal_query_newskills() macht keine Kopie
+  skills=internal_query_newskills(gilde);
+
+  // Skill ermitteln, wenn nicht existiert, wird er angelegt.
+  if (!skill=skills[sname]) {
+      skill=([]); 
+  }
+  
+  // Zur Sicherheit mal das Mapping kopieren, wer weiss, was der	
+  // Aufrufende dieser Funktion selber spaeter damit noch macht.
+  // ist ok, wenn val kein Mapping ist, dann macht deep_copy nix.
+  val=deep_copy(val);
+
+  // Skill und val vereinigen
+  if ( mappingp(val) )
+    skill+=val;
+  else if (intp(val))
+    skill[SI_SKILLABILITY]=val;
+  else
+    raise_error(sprintf("Bad arg 2 to ModifySkill(): expected 'int', "
+          "got %.10O.\n",val));
+
+  // Lernen entsprechend SI_DIFFICULTY begrenzen.
+  if(diff && !member(skill,SI_DIFFICULTY))
+    skill[SI_DIFFICULTY]=diff;
+  skill=LimitAbility(skill,diff || skill[SI_DIFFICULTY]);
+  
+  // schliesslich im Skillmapping vermerken. Im Normalfall ist der Skill jetzt
+  // schon geaendert, nicht erst nach dem internal_set_newskills().
+  skills[sname]=skill;
+
+  // explizites Abspeichern fast ueberfluessig, weil wir oben eine Referenz
+  // auf das Skillmapping gekriegt haben...
+  // Aber es koennte sein, dass dies der erste Skill fuer diese Gilde ist,
+  // dann ist es noetig. Zum anderen wird internal_set_newskills() nochmal
+  // geloggt.
+  internal_set_newskills(skills,gilde);
+}
+
+public varargs void LearnSkill(string sname, int add, int diff)
+{ mapping skill;
+  string skill2,gilde;
+  int val;
+
+  // Spieler sollen nur lernen, wenn sie interactive sind. Das soll
+  // natuerlich nur fuer Spieler gelten.
+  if (query_once_interactive(this_object()) && !interactive())
+	  return;
+
+  if ( add>MAX_SKILLEARN )
+    add=MAX_SKILLEARN;
+  else if ( add<1 )
+    add=1;
+
+  // Skillmapping ermitteln (hier kommt keine Kopie zurueck)
+  skill=InternalQuerySkill(sname, 0);
+  // wenn kein Skill, dann Abbruch
+  if (!skill) return;
+
+  val=skill[SI_SKILLABILITY];
+  gilde=skill[SI_GUILD];
+ 
+  val+=add;
+
+  ModifySkill(sname,val,diff,gilde);
+  if ( skill2=skill[SI_INHERIT] )
+    LearnSkill(skill2,add/3,diff);
+}
+
+public varargs int UseSpell(string str, string spell)
+{ string gilde,sbook;
+  mapping sinfo;
+  closure cl;
+  
+  if ( !spell && !(spell=query_verb()) )
+    return 0;
+
+  spell=lower_case(spell);
+
+  // QuerySkill() liefert eine Kopie des Skillmappings.
+  // wenn skill unbekannt oder Ability <= 0, ist der Spell nicht nutzbar.
+  if ( !(sinfo=QuerySkill(spell,0))
+        || sinfo[SI_SKILLABILITY] <= 0 )
+    return 0;
+
+  sinfo[SI_SKILLARG]=str; // Argument eintragen
+
+  if ( !closurep(cl=sinfo[SI_CLOSURE]) )
+  {
+    // Wenn ein Spellbook angegeben ist wird der Spell direkt ausgefuehrt
+    if ( stringp(sbook=sinfo[SI_SPELLBOOK]) )
+      cl=symbol_function("UseSpell",SPELLBOOK_DIR+sbook);
+
+    // Wenn der Spieler in einer Gilde ist, so weiss diese, in welchem
+    // Spellbook der Spell zu finden ist...
+    else if ( (gilde=QueryProp(P_GUILD)) && 
+      ( find_object(GUILD_DIR+gilde) || file_size(GUILD_DIR+gilde+".c")>-1))
+      cl=symbol_function("UseSpell",GUILD_DIR+gilde);
+    else
+      cl=function int () {return 0;};
+
+    sinfo[SI_CLOSURE]=cl;
+    valid_setskills_override=1;
+    ModifySkill(spell,([SI_CLOSURE:cl]),0,sinfo[SI_GUILD]);
+    valid_setskills_override=0;
+  }
+  return funcall(cl,this_object(),spell,sinfo);
+}
+
+public varargs mixed UseSkill(string skill, mapping args)
+{ mapping sinfo;
+  string gilde, func,skill2;
+  mixed res;
+  closure cl;
+  
+  if ( !skill ||
+       QueryProp(P_GHOST))
+    return 0;
+
+  skill=capitalize(skill);
+  // QuerySkill() liefert eine Kopie des Skillmappings
+  if ( !(sinfo=QuerySkill(skill,0)) )
+    return 0;
+
+  if (args)
+    sinfo+=args;
+
+  if ( !closurep(cl=sinfo[SI_CLOSURE]) )
+  {
+    if ( !(func=sinfo[SI_SKILLFUNC])    // Keine Funktion angegeben?
+        || !(gilde=QueryProp(P_GUILD))) // Keine Gilde angegeben?
+    {
+      // Dann Standard-Funktion nehmen, wenn es die nicht gibt, den
+      // Ability-Wert zurueckliefern.
+      if (!closurep(cl = symbol_function("StdSkill_"+skill,this_object())))
+        cl=function int (object ob, string sname)
+             {return QuerySkillAbility(sname);} ;
+    }
+    else
+    {
+      // Sonst diese Funktion im Gildenobjekt aufrufen
+      cl=symbol_function(func,GUILD_DIR+gilde);
+    }
+
+    sinfo[SI_CLOSURE]=cl;
+    valid_setskills_override=1;
+    ModifySkill(skill,([SI_CLOSURE:cl]),0,sinfo[SI_GUILD]);
+    valid_setskills_override=0;
+  }
+
+  res=funcall(cl,this_object(),skill,sinfo);
+  if ( (skill2=sinfo[SI_INHERIT]) && mappingp(res) )
+    res=UseSkill(skill2,res); // Fuer Skills, die von anderen abhaengen
+
+  return res;
+}
+
+// ************** Spellfatigues ***************
+
+/*  Prueft die Spellfatigue fuer Spruch(gruppe) <key>.
+ *  <key> darf 0 sein (globale Spruchsperre).
+ *  Liefert 0, wenn keine Sperre und die Ablaufzeit, wenn eine Sperre noch
+ *  gueltig. ist.
+ */
+public varargs int CheckSpellFatigue(string key) {
+  // key==0 is the (default) global spellfatigue.
+  if (spell_fatigues[key] > time())
+    return spell_fatigues[key]; // Ablaufzeit zurueckgeben.
+
+  return 0; // ok, keine Sperre.
+}
+
+/** Speichert eine Spellfatigue von <duration> Sekunden fuer <key>.
+ * <key> darf 0 sein und bezeichnet das globale Spellfatigue.
+ * Rueckgabewert: Ablaufzeit der gesetzten Sperre
+                  -1, wenn noch eine nicht-abgelaufene Sperre auf dem <key> lag.
+                  0, wenn duration 0 ist.
+ */
+public varargs int SetSpellFatigue(int duration, string key) {
+  // aktuelle Sperre abgelaufen?
+  if (CheckSpellFatigue(key))
+    return -1; // alte Sperre noch aktiv.
+
+  duration += time();
+  // 0 is OK for <key>, it is the key for global spell fatigues
+  spell_fatigues[key] = duration;
+  return duration;
+}
+
+/*  Prueft die Spellfatigue fuer Spruch(gruppe) <key>.
+ *  <key> darf fuer diese Funktion 0 (globale Spruchsperre) sein, aber man
+ *  darf das Argument nicht weglassen, damit nicht ein verpeilter Magier
+ *  versehentlich die globale Spruchsperre nullt.
+ */
+public void DeleteSpellFatigue(string key) {
+  // key==0 is the (default) global spellfatigue.
+  m_delete(spell_fatigues, key);
+}
+
+/** Loescht abgelaufene Keys aus dem spell_fatigue mapping.
+ */
+private void expire_spell_fatigues() {
+  foreach(string key, int endtime: spell_fatigues) {
+    if (endtime <= time())
+      m_delete(spell_fatigues, key);
+  }
+}
+
+/** Setmethode fuer P_NEXT_SPELL_TIME.
+  */
+static int _set_next_spell(int fatigue) {
+  return SetSpellFatigue(fatigue - time());
+}
+/** Querymethode fuer P_NEXT_SPELL_TIME.
+  */
+static int _query_next_spell() {
+  return CheckSpellFatigue();
+}
+