Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/std/inpc/.readme b/std/inpc/.readme
new file mode 100644
index 0000000..06c1f14
--- /dev/null
+++ b/std/inpc/.readme
@@ -0,0 +1,11 @@
+
+INPC: Intelligenter NPC
+*** IN ENTWICKLUNG - BENUTZUNG AUF EIGENE GEFAHR ***
+
+nobank:   Moneyhandler+Behandlung von Bankzweities
+walking:  Laufmonster, automatische Routensuche
+boozing:  Optimale Saeuferei
+select:   Auswahl guter Objekte (beste Waffe/Ruestung...)
+eval.c:   Gegner einschaetzen
+items.c:  Waffen, Ruestungen einfach einfuegen, automatisch im Reset zuecken
+
diff --git a/std/inpc/boozing.c b/std/inpc/boozing.c
new file mode 100644
index 0000000..4f24f52
--- /dev/null
+++ b/std/inpc/boozing.c
@@ -0,0 +1,62 @@
+// MorgenGrauen MUDlib
+//
+// inpc/boozing.c -- Intelligentes Saufen
+//
+// $Id: boozing.c 8396 2013-02-18 21:56:37Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+#include <thing.h>
+#include <living.h>
+#include <inpc.h>
+#include <container/moneyhandler.h>
+#include <properties.h>
+
+#define DRINK_IDS 1
+#define DRINK_COST 2
+#define DRINK_HEAL 3
+#define DRINK_ALC 4
+#define DRINK_SAT 5
+
+int Drink() {
+  mixed drinks;
+  object env;
+  int i,max,mon,hdiff;
+ 
+  if ((mon=QueryMoney())<=0
+      || !(env=environment())
+      || !pointerp(drinks=env->query_drink())
+      || (hdiff=QueryProp(P_MAX_HP)-QueryProp(P_HP))<=0)
+    return 0;
+  max=-1;
+  for (i=sizeof(drinks)-1;i>=0;i--) {
+    if (drinks[i][DRINK_COST]>mon
+        || ((drinks[i][DRINK_ALC]>0) &&
+	    ((drinks[i][DRINK_ALC]+QueryProp(P_ALCOHOL))
+	     > (100-QueryProp(P_I_HATE_ALCOHOL))))
+        || drinks[i][DRINK_SAT]+QueryProp(P_DRINK)>100
+        || drinks[i][DRINK_HEAL]<=0)
+      continue;
+    if (max<0
+        || (drinks[i][DRINK_HEAL]>drinks[max][DRINK_HEAL] &&
+            drinks[max][DRINK_HEAL]<hdiff)
+        || (drinks[i][DRINK_HEAL]>=hdiff &&
+            drinks[i][DRINK_COST]<drinks[max][DRINK_COST]))
+      max=i;
+  }
+  if (max<0) return 0;
+  command("bestell "+drinks[max][DRINK_IDS][0]);
+  return 1;
+}
+
+void DrinkLoop() {
+  while (remove_call_out("DrinkLoop")>=0);
+  if (!Drink())
+    return;
+  call_out("DrinkLoop",0);
+}
+
diff --git a/std/inpc/eval.c b/std/inpc/eval.c
new file mode 100644
index 0000000..f755576
--- /dev/null
+++ b/std/inpc/eval.c
@@ -0,0 +1,189 @@
+// MorgenGrauen MUDlib
+//
+// inpc/eval.c -- Einschaetzen von Gegnern
+//
+// $Id: eval.c 6371 2007-07-17 22:46:50Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+#include <thing/properties.h>
+#include <living.h>
+#undef NEED_PROTOTYPES
+#include <properties.h>
+#include <thing.h>
+#include <inpc.h>
+
+varargs void SetEvalFactor(mixed what, int fac, int off) {
+  mapping offs,facs;
+
+  if (!mappingp(facs=QueryProp(P_EVAL_FACTORS))) facs=([]);
+  if (!mappingp(offs=QueryProp(P_EVAL_OFFSETS))) offs=([]);
+  facs[what]=fac;
+  offs[what]=off;
+  SetProp(P_EVAL_FACTORS,facs);
+  SetProp(P_EVAL_OFFSETS,offs);
+}
+
+void SetDefaultEvalFactors() {
+  SetEvalFactor(P_HP,150,-60);
+  SetEvalFactor(P_TOTAL_WC,250,0);
+  SetEvalFactor(P_TOTAL_AC,1000,-50);
+  SetEvalFactor("abenteurer_pfeil",3,0);
+  SetEvalFactor("abenteurer_feuerball",8,0);
+}
+
+varargs int
+modify_eval(object ob, mixed what, mapping fac, mapping off, int val) {
+  if (!val) val=QueryProp(what);
+  val-=off[what];
+  if (val<0) val=0;
+  val=(val*fac[what])/10000;
+  if (val>200) val=200;
+  return val;
+}
+
+varargs int eval_enemy(object enemy, mapping fac, mapping off) {
+  int res;
+  string gilde;
+  
+  if (!objectp(enemy)) return 0;
+  if (!mappingp(fac)) fac=QueryProp(P_EVAL_FACTORS);
+  if (!mappingp(fac)) fac=([]);
+  if (!mappingp(off)) off=QueryProp(P_EVAL_OFFSETS);
+  if (!mappingp(off)) off=([]);
+
+  res=0;
+  res+=modify_eval(enemy,P_TOTAL_WC,fac,off);
+  res+=modify_eval(enemy,P_TOTAL_AC,fac,off);
+  res+=modify_eval(enemy,P_HP,fac,off);
+  if (stringp(gilde=enemy->QueryProp(P_GUILD)))
+    res+=call_other(this_object(),"eval_guild_"+gilde,enemy,fac,off,gilde);
+  if (res<0) res=0;
+  if (res>1000) res=1000;
+  return res;
+}
+
+varargs mixed *eval_enemies(mapping fac, mapping off, object *here) {
+  int i,sz;
+  mixed *res;
+
+  res=({});
+  if (!here)
+    here=PresentEnemies();
+  if (!pointerp(here) || !(sz=sizeof(here)))
+    return res;
+  if (!mappingp(fac)) fac=QueryProp(P_EVAL_FACTORS);
+  if (!mappingp(fac)) fac=([]);
+  if (!mappingp(off)) off=QueryProp(P_EVAL_OFFSETS);
+  if (!mappingp(off)) off=([]);
+
+  for (i=sz-1;i>=0;i--)
+    res+=({({here[i],eval_enemy(here[i],fac,off)})});
+  return res;
+}
+
+varargs int sum_eval_enemies(mapping fac, mapping off, object *here) {
+  int res,i;
+  mixed *evals,x,y;
+
+  res=0;
+  if (!pointerp(evals=eval_enemies(fac,off,here)))
+    return res;
+  for (i=sizeof(evals)-1;i>=0;i--)
+    if (pointerp(x=evals[i]) && sizeof(x)>=2 && intp(y=x[1]))
+      res+=y;
+  return res;
+}
+
+varargs object *minimize_prop_filt(object *here, mixed prop) {
+  object *obs,ob;
+  int i,mhp,hp,sz;
+  
+  obs=0;
+  if (!pointerp(here))
+    here=PresentEnemies();
+  if (!prop)
+    prop=P_HP;
+  for (i=sizeof(here)-1;i>=0;i--) {
+    if (objectp(ob=here[i])) {
+      hp=ob->QueryProp(prop);
+      if (!pointerp(obs) || hp<mhp) {
+	obs=({ob});
+	mhp=hp;
+      } else if (hp==mhp) {
+	obs+=({ob});
+      }
+    }
+  }
+  if (!pointerp(obs))
+    obs=({});
+  return obs;
+}
+
+varargs object *maximize_prop_filt(object *here, mixed prop) {
+  object *obs,ob;
+  int i,mwc,wc,sz;
+  
+  obs=0;
+  if (!pointerp(here))
+    here=PresentEnemies();
+  if (!prop)
+    prop=P_TOTAL_WC;
+  for (i=sizeof(here)-1;i>=0;i--) {
+    if (objectp(ob=here[i])) {
+      wc=ob->QueryProp(prop);
+      if (!pointerp(obs) || wc<mwc) {
+	obs=({ob});
+	mwc=wc;
+      } else if (wc==mwc) {
+	obs+=({ob});
+      }
+    }
+  }
+  if (!pointerp(obs))
+    obs=({});
+  return obs;
+}
+
+varargs object *player_filt(object *here) {
+  object *obs,ob;
+  int i;
+  
+  obs=({});
+  if (!pointerp(here))
+    here=PresentEnemies();
+  for (i=sizeof(here)-1;i>=0;i--)
+    if (objectp(ob=here[i]) && query_once_interactive(ob))
+      obs+=({ob});
+  return obs;
+}
+
+varargs object select_enemy_min_prop(object *here, mixed prop) {
+  object *obs;
+  int sz;
+
+  if (pointerp(obs=minimize_prop_filt(here,prop)) && (sz=sizeof(obs)))
+    return obs[random(sz)];
+  return 0;
+}
+
+varargs object select_enemy_max_prop(object *here, mixed prop) {
+  object *obs;
+  int sz;
+
+  if (pointerp(obs=maximize_prop_filt(here,prop)) && (sz=sizeof(obs)))
+    return obs[random(sz)];
+  return 0;
+}
+
+varargs object select_player_min_prop(object *here, mixed prop) {
+  return select_enemy_min_prop(player_filt(here),prop);
+}
+
+varargs object select_player_max_prop(object *here, mixed prop) {
+  return select_enemy_max_prop(player_filt(here),prop);
+}
diff --git a/std/inpc/items.c b/std/inpc/items.c
new file mode 100644
index 0000000..fafdd04
--- /dev/null
+++ b/std/inpc/items.c
@@ -0,0 +1,78 @@
+// MorgenGrauen MUDlib
+//
+// inpc/items.c -- Die richtige Ausruestung tragen
+//
+// $Id: items.c 6571 2007-10-21 14:41:10Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+
+#include <thing.h>
+#include <inpc.h>
+#include <properties.h>
+#include <moving.h>
+
+protected void create() {
+  SetProp(P_ITEMS,({0}));
+}
+
+protected void create_super() {
+  set_next_reset(-1);
+}
+
+void AddWeapon(string nm, string path) {
+  object ob;
+  mixed *it;
+  
+  if (!path || !nm) return;
+  if (ob=clone_object(path)) {
+    ob->move(this_object(),M_NOCHECK);
+    command("zuecke "+nm);
+  }
+  it=QueryProp(P_ITEMS);
+  if (!pointerp(it) || !sizeof(it)) it=({0});
+  it[0]=({ob,path,nm});
+  SetProp(P_ITEMS,it);
+}
+
+void AddArmour(string nm, string path) {
+  object ob;
+  mixed *it;
+  
+  if (!path || !nm) return;
+  if (ob=clone_object(path)) {
+    ob->move(this_object(),M_NOCHECK);
+    command("zieh "+nm+" an");
+  }
+  it=QueryProp(P_ITEMS);
+  if (!pointerp(it) || !sizeof(it)) it=({0});
+  it+=({ob,path,nm});
+  SetProp(P_ITEMS,it);
+}
+
+void reset() {
+  mixed *it,x;
+  int i;
+  object ob;
+  
+  if (!pointerp(it=QueryProp(P_ITEMS))) return;
+  for (i=sizeof(it)-1;i>=0;i--) {
+    x=it[i];
+    if (!pointerp(x) || sizeof(x)<3) continue;
+    if (!objectp(x[0])) {
+      if (ob=clone_object(x[1]))
+	ob->move(this_object(),M_NOCHECK);
+      x[0]=ob;
+    }
+    if (objectp(x[0])) {
+      if (i)
+	command("zieh "+x[2]+" an");
+      else
+	command("zuecke "+x[2]);
+    }
+  }
+}
diff --git a/std/inpc/nobank.c b/std/inpc/nobank.c
new file mode 100644
index 0000000..6f04aef
--- /dev/null
+++ b/std/inpc/nobank.c
@@ -0,0 +1,100 @@
+// MorgenGrauen MUDlib
+//
+// inpc/nobank.c -- Nieder mit Bankzweities!
+//
+// $Id: nobank.c 8966 2014-11-19 21:41:12Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+inherit "/std/living/moneyhandler";
+
+#include <properties.h>
+#include <attributes.h>
+#include <money.h>
+#define ME this_object()
+
+int DeepQueryMoney(object ob) {
+  int res,i;
+  object *obs;
+  
+  if (!ob) return 0;
+  res=0;obs=deep_inventory(ob);
+  for (i=sizeof(obs)-1;i>=0;i--)
+    if ((ob=obs[i]) && load_name(ob)==GELD)
+      res+=ob->QueryProp(P_AMOUNT);
+  return res;
+}
+
+int is_bank(object ob) {
+  int *stats,geld;
+  
+  if (!ob || !query_once_interactive(ob)) return 0;
+  stats=({ob->QueryAttribute(A_STR),
+	  ob->QueryAttribute(A_INT),
+	  ob->QueryAttribute(A_DEX),
+	  ob->QueryAttribute(A_CON),
+	  0});
+  stats[4]=stats[1]+stats[2]+stats[3];
+  geld=DeepQueryMoney(ob);
+  
+  if (stats[0]>=10
+      && stats[4]<stats[0]
+      && geld>5000
+      && ob->QueryProp(P_XP)<300000
+      && ob->QueryProp(P_QP)<300)
+    return geld;
+  return 0;
+}
+
+int DeepTransferMoney(object pl, int amount) {
+  object *obs,ob;
+  int act,trans,i;
+  
+  if (!pl || amount<=0)
+    return 0;
+  if (pl->QueryMoney()>=amount) {
+    pl->AddMoney(-1*amount);
+    trans=amount;
+  } else {
+    obs=deep_inventory(pl);trans=0;
+    for (i=sizeof(obs)-1;i>=0;i--) {
+      if ((ob=obs[i]) && load_name(ob)==GELD) {
+	act=ob->QueryProp(P_AMOUNT);
+	if (act<=0) continue;
+	if (act>=amount) { // mehr Geld als benoetigt?
+	  ob->SetProp(P_AMOUNT,act-amount); // abziehen
+	  trans+=amount; 
+	  amount=0; // nichts mehr benoetigt
+	  break;    // also auch ende
+	}
+	amount-=act;
+	trans+=act;
+	ob->remove(); // abziehen was da ist
+      }
+    }
+  }
+  log_file("stolen_money",
+	   sprintf("%s %O: %O (%O)\n",ctime(time())[4..15],pl,trans,ME));
+  AddMoney(trans);
+  return trans;
+}
+
+varargs int TestAndTransfer(object ob, int trans, string msg) {
+  int geld,abzug;
+
+  if ((geld=is_bank(ob))<=0) return 0;
+  if (trans<0)
+    abzug=(geld*trans)/-100; // Prozentsatz
+  else
+    abzug=trans;             // fester Abzug
+  if (abzug>geld) abzug=geld;
+  if (abzug<=0) return 0;
+  abzug=DeepTransferMoney(ob,abzug);
+  if (abzug<=0) return 0;  
+  if (msg && ob)
+    tell_object(ob,sprintf(msg,abzug));
+  return abzug;
+}
diff --git a/std/inpc/select.c b/std/inpc/select.c
new file mode 100644
index 0000000..d73ebed
--- /dev/null
+++ b/std/inpc/select.c
@@ -0,0 +1,337 @@
+// MorgenGrauen MUDlib
+//
+// inpc/select.c -- Beste Ausruestung suchen
+//
+// $Id: select.c 6998 2008-08-24 17:17:46Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+
+#include <thing.h>
+#include <living.h>
+#include <inpc.h>
+#include <properties.h>
+#include <combat.h>
+#include <language.h>
+
+#define ME this_object()
+
+mapping scan_objects(mixed src) {
+  // Ermittelt zu jedem Typ (Waffe, Ruestungstyp...) alle Objekte diesen Typs
+  // Gesucht wird: - Im Inventory, falls Objekt angegeben
+  //               - Im Array, falls Array angegeben
+  object *obs;
+  mapping res;
+  mixed x;
+  int i,cost,cost_limit;
+
+  if (mappingp(src))
+    return src;
+  res=([]);
+  if (objectp(src))
+    src=all_inventory(src);
+  if (!pointerp(src))
+    src=({src});
+  
+  cost_limit = get_eval_cost()/3;
+  foreach(object ob: src)
+  {
+    if ( (cost=get_eval_cost()) < cost_limit )
+    {
+      log_file("rochus/raeuber_eval",
+        ctime()+"select::scan_objects(). Rest "+to_string(cost)+
+        ", i="+to_string(i)+", Size "+to_string(sizeof(src))+".\n");
+      return res;
+      break;
+    }
+    if (!objectp(ob))
+      continue;
+    if (x=ob->QueryProp(P_ARMOUR_TYPE))
+      ;
+    else if (ob->QueryProp(P_WEAPON_TYPE))
+      x=OT_WEAPON;
+    else if (ob->QueryProp(P_COMBATCMDS))
+      x=OT_COMBAT_OBJECT;
+    else
+      x=OT_MISC;
+    if (!pointerp(obs=res[x]))
+      obs=({});
+    obs+=({ob});
+    res[x]=obs;
+  }
+  return res;
+}
+
+mixed *find_object_by_type(mixed from, mixed typ) {
+  // Findet all Objekte eines Typs, z.B. alle Waffen im Monster
+  // <from> kann auch ein Mapping sein, das schon die mit scan_objects
+  // erstellt Klassifikation enthaelt, damit diese nicht mehrfach
+  // erstellt werden muss.
+  mixed res;
+
+  if (!mappingp(from))
+    from=scan_objects(from);
+  if (!mappingp(from) ||
+      !pointerp(res=from[typ]))
+    return ({});
+  return res;
+}
+
+int eval_weapon(object ob) {
+  return ob->QueryProp(P_WC);
+}
+
+object find_best_weapon(mixed from) {
+  // Findet die beste Waffe
+  int i,wc,bwc,cost,cost_limit;
+  object *res,bob;
+
+  if (!pointerp(res=find_object_by_type(from, OT_WEAPON)))
+    return 0;
+  bwc=-1;bob=0;
+  
+  cost_limit = get_eval_cost()/3;
+  for (i=sizeof(res);i--;)
+  foreach(object ob: res)
+  {
+    if (!objectp(ob)) continue;
+    wc=eval_weapon(ob);
+    if (wc>bwc)
+    {
+      bob=ob;
+      bwc=wc;
+    }
+    
+    if ( (cost=get_eval_cost()) < cost_limit )
+    {
+      log_file("rochus/raeuber_eval",
+        "Break in select::find_best_weapon(). Rest-Ticks "+to_string(cost)+
+        ", i = "+to_string(i)+", Size "+to_string(sizeof(res))+".\n");
+      return bob; // zurueckgeben, was bisher drinsteht.
+      break;
+    } 
+  }
+  return bob;
+}
+
+varargs int wield_best_weapon(mixed from) {
+  // Zueckt die beste Waffe.
+  // Sollte mit command("zuecke_beste_waffe") aufgerufen werden,
+  // damit this_player() richtig gesetzt wird.
+  object ob,old;
+
+  // Einige NPC moegen keine Waffen. Zum Beispiel Karate-Gilden-NPC
+  // Durch Setzen von INPC_DONT_WIELD_WEAPONS kann man das Zuecken verhindern
+  if(QueryProp(INPC_DONT_WIELD_WEAPONS)) return 0;
+
+  if (!from)
+    from=ME;
+  
+  if (!objectp(ob=find_best_weapon(from)))
+    return 0;
+  if (objectp(old=QueryProp(P_WEAPON)) && old!=ob) {
+    old->RemoveId(INPC_BEST_WEAPON_ID);
+    old->DoUnwield();
+  }
+  if (!ob->id(INPC_BEST_WEAPON_ID))
+    ob->AddId(INPC_BEST_WEAPON_ID);
+
+  return ob->DoWield();
+}
+
+int eval_armour(object ob) {
+  return ob->QueryProp(P_AC);
+}
+
+object find_best_armour(mixed from, mixed typ) {
+  // Findet die beste Ruestung eines Typs
+  int i,ac,bac;
+  object *res,bob;
+  
+  if (!pointerp(res=find_object_by_type(from, typ)))
+    return 0;
+  bac=-1;
+  bob=0;
+  foreach(object ob: res)
+  {
+    if (!objectp(ob)) continue;
+    ac=eval_armour(ob);
+    if (ac>bac) 
+    {
+      bob=ob;
+      bac=ac;
+    }
+  }
+  return bob;
+}
+
+object *find_best_armours(mixed from) {
+  // Findet die besten Ruestungen, die gleichzeitig getragen werden koennen
+  mapping ol;
+  object *res,ob;
+  mixed *types;
+  int i;
+  
+  if (!mappingp(ol=scan_objects(from)))
+    return ({});
+  if (!pointerp(res=ol[AT_MISC]))
+    res=({});
+  types=m_indices(ol);
+  foreach(object typ: types)
+  { 
+    if (VALID_ARMOUR_CLASS[typ]) // anderer Armour-Typ ausser AT_MISC?
+    {
+      ob=find_best_armour(from,typ);
+      if (objectp(ob))
+	res+=({ob});
+    }
+  }
+  return res;
+}
+
+varargs int wear_best_armours(mixed from) {
+  // Die besten Ruestungen werden angezogen
+  // Sollte mit command("trage_beste_ruestungen") aufgerufen werden,
+  // damit this_player() richtig gesetzt wird.
+  object *na,*oa,*diff;
+  int i,cost,cost_limit;
+  
+  if (!from)
+    from=ME;
+  if (!pointerp(na=find_best_armours(from)))
+    return 0;
+  if (!pointerp(oa=QueryProp(P_ARMOURS)))
+    oa=({});
+  diff=oa-na;
+  cost_limit = get_eval_cost()/3;
+  foreach(object di: diff)
+  {
+    di->RemoveId(INPC_BEST_SHIELD_ID);
+    di->DoUnwear();
+    if ( (cost=get_eval_cost()) < cost_limit )
+    {
+      log_file("rochus/raeuber_eval",
+        ctime()+"Break 1 in select::wear_best_armours(). Rest "+
+	to_string(cost)+", i="+to_string(i)+", Size "+
+	to_string(sizeof(diff))+".\n");
+      return 1; // zurueckgeben, was bisher drinsteht.
+      break;
+    }
+  }
+  diff=na-oa;
+  cost_limit = get_eval_cost()/3;
+  foreach(object di: diff)
+  {
+    if ( di->QueryProp(P_ARMOUR_TYPE)==AT_SHIELD
+         && !di->id(INPC_BEST_SHIELD_ID))
+     di->AddId(INPC_BEST_SHIELD_ID);
+     di->do_wear("alles");
+     if ( (cost=get_eval_cost()) < cost_limit )
+     {
+       log_file("rochus/raeuber_eval",
+         ctime()+"Break 2 in select::wear_best_armours(). Rest "+
+	 to_string(cost)+", i="+to_string(i)+", Size "+
+	 to_string(sizeof(diff))+".\n");
+      return 1; // zurueckgeben, was bisher drinsteht.
+      break;
+    }
+  }
+  return 1;
+}
+
+int eval_combat_object(object ob, mapping vals, object enemy) {
+  return 0;
+}
+
+varargs string
+find_best_combat_command(mixed from, object enemy, mapping pref) {
+  // Sucht den guenstigsten Befehl zur Benutzung einer Sonderwaffe heraus
+  object *obs;
+  mixed *ind,y,vul;
+  mapping x;
+  string best;
+  int i,j,max,val,mhp;
+  
+  if (!from)
+    from=ME;
+  if (!enemy)
+    enemy=SelectEnemy();
+  if (!mappingp(pref)) // bevorzugte Eigenschaften
+    pref=([C_MIN:5,
+	   C_AVG:10,
+	   C_MAX:2,
+	   C_HEAL:10
+	   ]);
+  best=0;max=-1;
+  if (!pointerp(obs=find_object_by_type(from,OT_COMBAT_OBJECT)))
+    return best;
+  mhp=QueryProp(P_MAX_HP)-QueryProp(P_HP);
+  if (objectp(enemy))
+    vul=enemy->QueryProp(P_RESISTANCE_STRENGTHS);
+  if (mhp<0) mhp=0;
+  foreach(object ob: obs)
+  {
+    if (!objectp(ob)) 
+      continue;
+    if (!mappingp(x=ob->QueryProp(P_COMBATCMDS)))
+      continue;
+    ind=m_indices(x);
+    for (j=sizeof(ind)-1;j>=0;j--)
+    {
+      if (!stringp(ind[j])) continue;
+      y=x[ind[j]];
+      if (mappingp(y)) 
+      {
+	if (val=y[C_HEAL]) 
+	{
+	  if (val>mhp) val=mhp; // Nur MOEGLICHE Heilung beruecksichtigen
+	  val*=pref[C_HEAL];
+	} 
+	else 
+	{
+	  val=y[C_MIN]*pref[C_MIN]
+	    + y[C_AVG]*pref[C_AVG]
+	    + y[C_MAX]*pref[C_MAX];
+	  // auskommentiert, da eval_resistance() bisher nicht implementiert
+	  // ist. Zesstra, 06.08.2007
+	  //if (y[C_DTYPES] && vul) // Vulnerability des Gegners bedenken...
+	  //  val=(int)(((float)val)*(1.0+eval_resistance(y[C_DTYPES],vul)));
+	}
+      } 
+      else 
+      {
+	val=1;
+      }
+      val+=eval_combat_object(obs[i],y,enemy);
+      if (val<max) continue;
+      max=val;
+      if (mappingp(y) && y[C_HEAL]>0)
+        best=sprintf(ind[j],name(RAW)); // Heilung auf sich selbst
+      else if (objectp(enemy))
+        best=sprintf(ind[j],enemy->name(RAW)); // Schaden auf Gegner
+    }
+  }
+
+  return best;
+}
+
+varargs int use_best_combat_command(mixed enemy, mixed from, mapping pref) {
+  // Fuehrt moeglichst guten Kampfeinsatz mit einer Sonderwaffe aus
+  string str;
+    
+  if (stringp(enemy) && environment())
+    enemy=present(enemy,environment());
+  if (str=find_best_combat_command(from,enemy,pref))
+    return command(str);
+  return 0;
+}
+
+void add_select_commands() {
+  add_action("wield_best_weapon","zuecke_beste_waffe");
+  add_action("wear_best_armours","trage_beste_ruestungen");
+  add_action("use_best_combat_command","benutze_beste_sonderwaffe");
+}
diff --git a/std/inpc/walking.c b/std/inpc/walking.c
new file mode 100644
index 0000000..f24aae6
--- /dev/null
+++ b/std/inpc/walking.c
@@ -0,0 +1,130 @@
+// MorgenGrauen MUDlib
+//
+// inpc/walking.c -- Intelligent herumlaufen
+//
+// $Id: walking.c 8755 2014-04-26 13:13:40Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+#include <thing/properties.h>
+#include <thing.h>
+#undef NEED_PROTOTYPES
+
+#include <inpc.h>
+#include <properties.h>
+#include <moving.h>
+
+#define ME this_object()
+#define ENV environment()
+
+int _set_inpc_walk_delay(int del) {
+  if (del && del<5) del=5;
+  return Set(P_INPC_WALK_DELAYS,del);
+}
+
+mixed _query_inpc_home() {
+  mixed res;
+
+  res=Query(P_INPC_HOME);
+  if (!res) return "/room/void";
+  return res;
+}
+
+int area_check(string fn) {
+  mixed area;
+  string *words;
+  int i;
+
+  if (!(area=QueryProp(P_INPC_WALK_AREA)))
+    return 1; // Keine Beschraenkung im Gebiet?
+  if (mappingp(area)) {
+    if (area[fn])
+      return 1; // Explizit erlaubter Raum
+    words=old_explode(fn,"/");
+    for (i=sizeof(words)-2;i>=0;i--)
+      if (area[implode(words[0..i],"/")])
+	return 1; // Erlaubtes Gebiet
+    return 0; // Nicht erlaubtes Gebiet
+  }
+  if (pointerp(area)) {
+    for (i=sizeof(area)-1;i>=0;i--)
+      if (fn[0..(sizeof(area[i])-1)]==area[i])
+	return 1; // Erlaubtes Gebiet
+    return 0; // Nicht erlaubtes Gebiet
+  }
+  return 1;
+}
+
+int may_enter_room(mixed room) {
+  int flags;
+  string fn;
+  object ob;
+  
+  if (objectp(room)) {
+    fn=object_name(room);
+    ob=room;
+  } else if (stringp(room)) {
+    fn=room;
+    ob=find_object(room);
+  } else
+    return 1; // Dann sollte move schon nen Fehler machen
+  if (fn=="/room/void") // Void darf IMMER betreten werden
+    return 1;
+  flags=QueryProp(P_INPC_WALK_FLAGS);
+  if (!(flags & WF_MAY_LOAD)
+      && !objectp(ob))
+    return 0; // Darf nicht in nicht geladene Raeume folgen.
+  if (!(flags & WF_MAY_WALK_BACK)
+      && ob==QueryProp(P_INPC_LAST_ENVIRONMENT))
+    return 0; // Darf nicht in den vorherigen Raum
+  return area_check(fn);
+}
+
+int walk_random() {
+  string *ex,*ex2;
+  object env;
+  int i,r,flags;
+  
+  if (!objectp(env=ENV))
+    return 0;
+  ex=m_indices(ENV->QueryProp(P_EXITS));
+  flags=QueryProp(P_CAN_FLAGS);
+  if (flags & WF_MAY_USE_SPECIAL)
+    ex+=m_indices(ENV->QueryProp(P_SPECIAL_EXITS));
+  ex2=ex[0..];
+  while (i=sizeof(ex)) {
+    r=random(i);
+    command(ex[r]);
+    if (ENV!=env)
+      return 1;
+    ex-=({ex[r]});
+  }
+  if (!(flags & WF_MAY_WALK_BACK)) {
+    SetProp(P_INPC_LAST_ENVIRONMENT,0);//Dirty Hack, um Sackgassen zu verlassen
+    ex=ex2;
+    while (i=sizeof(ex)) {
+      r=random(i);
+      command(ex[r]);
+      if (ENV!=env)
+	return 1;
+      ex-=({ex[r]});
+    }
+  }
+  return move(QueryProp(P_INPC_HOME),M_TPORT);
+}
+
+int walk_route() {
+}
+
+int walk_to() {
+}
+
+int walk_follow() {
+}
+
+int walk_flee() {
+}