// MorgenGrauen MUDlib
//
// restriction_checker.c -- Beschraenkungen in Gilden, Spells und Skills
//
// $Id: restriction_checker.c 8754 2014-04-26 13:12:58Z Zesstra $
#pragma strong_types
#pragma save_types
#pragma no_clone
//#pragma range_check
#pragma no_shadow

inherit "/std/util/executer";

#define NEED_PROTOTYPES
#include <thing/properties.h>
#include <properties.h>
#include <new_skills.h>
#include <wizlevels.h>
#include <questmaster.h>

#define DEBUG(x) if (find_player("zesstra")) tell_object(find_player("zesstra"),x)

// erweitert um das <pl> argument und die extra-Argument, die bereits in <fun>
// angegeben wurden. (*grummel*)
protected mixed execute_anything(mixed fun, object pl, varargs mixed args)
{
  //DEBUG(sprintf("ex_any(): Fun: %O, Ob: %O, args: %O\n",fun,pl,args));
  // wenn in fun schon extraargumente stehen, dann pl einfuegen und args
  // dranhaengen.
  if (pointerp(fun) && sizeof(fun) > 2)
  {
    // args kann ({}) sein, wenn keine Extraargumente uebergeben wurden, macht
    // aber nix.
    args = ({pl}) + fun[2..] + args;
    fun = fun[0..1];
    return ::execute_anything(fun, args...);
  }
  // s.o.
  return ::execute_anything(fun, pl, args...);
}

mapping race_modifier(object pl, mapping map_ldfied) {
  mapping rmap,help;

  if (mappingp(map_ldfied) && member(map_ldfied,SM_RACE) && objectp(pl) &&
      mappingp(rmap=map_ldfied[SM_RACE]))
//    if (mappingp(help=rmap[pl->_query_real_race()]))
    if (mappingp(help=rmap[pl->QueryProp(P_REAL_RACE)]))
        return map_ldfied+help;
    else if(member(rmap,"*") && mappingp(help=rmap["*"]))
        return map_ldfied+help;
  return map_ldfied;
}

string
check_restrictions(object pl, mapping restr) {
  /* Folgende Einschraenkungen koennen geprueft werden:
   * - Mindestwerte bei allen Attributen und Properties Level, QP, XP
   * - bestimmte Rassen koennen ausgeschlossen werden bzw. erlaubt werden
   *   (SR_EXCLUDE_RACE ist ein Array von ausgeschlossenen Rassen,
   *    SR_INCLUDE_RACE eines mit eingeschlossenen)
   * - SR_RACE kann ein Mapping sein, dass Rassen ein eigenes
   *   Restriction-mapping zuordnet. "*" steht fuer alle anderen Rassen.
   */
  closure cl,cl2;
  string race, guild;

  if (!mappingp(restr) || !sizeof(restr)) return 0; // Keine Einschraenkungen
  if (!objectp(pl)) return "";
  if (pl->QueryDisguise())
    return "Zieh erst mal den Tarnhelm aus.\n";

  restr=race_modifier(&pl,&restr);

  cl=symbol_function("QueryProp",pl);
  cl2=symbol_function("QueryAttribute",pl);

  foreach(string to_check, mixed condition: restr)
  {
    switch(to_check)
    {
      case P_LEVEL:
        if (funcall(cl,P_LEVEL) < condition)
          return "Deine Stufe reicht dafuer nicht aus.\n";
        break;
      case P_GUILD_LEVEL:
        if (funcall(cl,P_GUILD_LEVEL) < condition)
          return "Deine Gildenstufe reicht dafuer nicht aus.\n";
        break;
      case SR_SEER: // das macht nun wahrlich nur bei interactives sinn!!!
        if (condition && query_once_interactive(pl) && !IS_SEER(pl))
          return "Du musst dazu erst Seher werden.\n";
        break;
      case P_XP:
        if (funcall(cl,P_XP) < condition)
          return "Du hast nicht genuegend Erfahrung dafuer.\n";
        break;
      case P_QP:
        if (funcall(cl,P_QP) < condition)
          return "Du hast nicht genuegend Aufgaben geloest.\n";
        break;
      case P_ALCOHOL:
        if (funcall(cl,P_ALCOHOL) >= condition)
          return "Du bist zu besoffen.\n";
        break;
      case P_DRINK:
        if (funcall(cl,P_DRINK) >= condition)
          return "Du hast zuviel getrunken.\n";
        break;
      case P_FOOD:
        if (funcall(cl,P_FOOD) >= condition)
          return "Du hast zuviel gegessen.\n";
        break;
      case P_DEAF:
        if (funcall(cl,P_DEAF))
          return "Du kannst nichts hoeren.\n";
        break;
      case P_BLIND:
        if (funcall(cl,P_BLIND))
          return "Du kannst nichts sehen.\n";
        break;
      case P_FROG:
        if (funcall(cl,P_FROG))
          return "Als Frosch kannst Du das leider nicht.\n";
        break;
      case A_INT:
        if (funcall(cl2,A_INT) < condition)
          return "Deine Intelligenz reicht dafuer nicht aus.\n";
        break;
      case A_DEX:
        if (funcall(cl2,A_DEX) < condition)
          return "Deine Geschicklichkeit reicht dafuer nicht aus.\n";
        break;
      case A_CON:
        if (funcall(cl2,A_CON) < condition)
          return "Deine Ausdauer reicht dafuer nicht aus.\n";
        break;
      case A_STR:
        if (funcall(cl2,A_STR) < condition)
          return "Deine Staerke reicht dafuer nicht aus.\n";
        break;
      case SR_BAD:
        if (funcall(cl,P_ALIGN) < condition)
          return "Du bist zu boese.\n";
        break;
      case SR_GOOD:
        if (funcall(cl,P_ALIGN) > condition)
          return "Du bist nicht boese genug.\n";
        break;
      case SR_MIN_SIZE:
        if (funcall(cl,P_SIZE) < condition)
          return "Du bist dafuer zu klein.\n";
        break;
      case SR_MAX_SIZE:
        if (funcall(cl,P_SIZE) > condition)
          return "Du bist dafuer zu gross.\n";
        break;
      case SR_FREE_HANDS:
        if (condition > (funcall(cl,P_MAX_HANDS)-funcall(cl,P_USED_HANDS)))
          return "Du hast nicht genug freie Haende dafuer.\n";
        break;
      case SR_EXCLUDE_RACE:
        if (IS_LEARNER(pl))
          race=funcall(cl,P_RACE);
        else
          race=funcall(cl,P_REAL_RACE); //race=pl->_query_real_race();
        if ( pointerp(condition) && member(condition,race)>=0 )
          return ("Als "+race+" kannst Du das nicht.\n");
        break;
     case SR_INCLUDE_RACE:
        if (IS_LEARNER(pl))
          race=funcall(cl,P_RACE);
        else
          race=funcall(cl,P_REAL_RACE); //race=pl->_query_real_race();
        if (pointerp(condition) && member(condition,race)<0)
          return ("Als "+race+" kannst Du das nicht.\n");
        break;
     case SR_EXCLUDE_GUILD:
        guild=funcall(cl,P_GUILD);
        if (pointerp(condition) && member(condition,guild)>=0)
          return ("Mit Deiner Gildenzugehoerigkeit kannst Du das nicht.\n");
        break;
      case SR_INCLUDE_GUILD:
        guild=funcall(cl,P_GUILD);
        if (pointerp(condition) && member(condition,guild)<0)
          return ("Mit Deiner Gildenzugehoerigkeit kannst Du das nicht.\n");
        break;
     case SR_FUN:
        // In aller Regel sollte die Funktion dann nicht in diesem Objekt
        // gerufen werden, sondern in dem, was uns ruft.
        if(stringp(condition) && extern_call())
        {
          condition=({previous_object(),condition});
        }
        string res=execute_anything(condition, pl);
        if (stringp(res))
          return res;
        break;
     case SR_PROP:
        foreach ( string propname, mixed value, string msg: condition ) {
          if ( funcall(cl, propname) != value )
            return ( stringp(msg) && sizeof(msg) ? msg :
              "Koennte es sein, dass Du vergessen hast, etwas zu "
              "erledigen?\n");
        }
        break;
     case SR_QUEST:
        if (pointerp(condition))
        {
          // geloeste Quests aus der Liste der Bedingungen entfernen
          condition -= filter(condition, "QueryQuest", pl);
          if ( sizeof(condition) )
            return ("Du musst zuerst das Abenteuer '"+condition[0]+
              "' loesen.\n");
        }
        break;
     case SR_MINIQUEST:
        if (pointerp(condition))
        {
          closure unsolved_MQs = function int (mixed mq_num)
            { return !(QM)->HasMiniQuest(pl, mq_num); };
          if ( sizeof(filter(condition, unsolved_MQs)) )
            return "Du hast eine benoetigte Miniquest noch nicht geloest.\n";
            // Der Name der MQ wird absichtlich nicht explizit ausgegeben.
        }
        break;
    } // switch
  } // foreach
  return 0;
}

varargs mixed
GetData(string dname, mapping map_ldfied, object pl) {
  mixed dat,res;

  if (!dname || !mappingp(map_ldfied)) return 0;
  if (closurep(dat=map_ldfied[dname]) && (res=funcall(dat,pl,map_ldfied)))
        return res;
  return dat;

}

varargs int
GetValue(string vname, mapping map_ldfied, object pl) {
  mixed dat,res;

  // printf("GetValue(%O): %O\n",vname,map_ldfied);
  if (!vname || !map_ldfied) return 0;
  if ((dat=map_ldfied[vname]) && (res=execute_anything(dat,pl,map_ldfied)))
        return res;
  // printf("Value: %O\n",dat);
  return intp(dat) ? dat : 0;
}

varargs int
GetFactor(string fname, mapping map_ldfied, object pl) {
  mixed res;

  // printf("GetFactor(%O):\n",fname);
  if (!fname  || !(res=GetValue(FACTOR(fname),map_ldfied,pl)))
        return 100;
  if (res<10) res=10;
  else if (res>1000) res=1000;
  // printf("Factor: %O\n",res);
  return res;
}

varargs int
GetOffset(string oname, mapping map_ldfied, object pl) {
  mixed res;

  // printf("GetOffset(%O):\n",oname);
  if (!oname  || !(res=GetValue(OFFSET(oname),map_ldfied,pl)))
        return 0;
  if (res<-10000) res=-10000;
  else if (res>10000) res=10000;
  // printf("Offset: %O\n",res);
  return res;
}

varargs int
GetFValue(string vname, mapping map_ldfied, object pl) {
  return (GetValue(vname,map_ldfied,pl)*GetFactor(vname,map_ldfied,pl))/100;
}

varargs int
GetValueO(string vname, mapping map_ldfied, object pl) {
  return GetValue(vname,map_ldfied,pl)+GetOffset(vname,map_ldfied,pl);
}

varargs int
GetFValueO(string vname, mapping map_ldfied, object pl) {
  return ((GetValue(vname,map_ldfied,pl)*GetFactor(vname,map_ldfied,pl))/100
                  + GetOffset(vname,map_ldfied,pl));
}

varargs int
GetRandFValueO(string vname, mapping map_ldfied, object pl) {
  return (random(GetValue(vname,map_ldfied,pl)*GetFactor(vname,map_ldfied,pl))/100
          + GetOffset(vname,map_ldfied,pl));
}

mapping AddSkillMappings(mapping oldmap, mapping newmap) {
  mapping res,t1,t2;
  mixed *inx,ind;
  int i;

  if (!mappingp(oldmap)) return newmap;
  if (!mappingp(newmap)) return oldmap;
  inx=({SI_SKILLRESTR_LEARN,SI_SKILLRESTR_USE,SM_RACE});
  res=oldmap+newmap;
  for (i=sizeof(inx);i--;) {
        ind=inx[i];
        t1=oldmap[ind];
        t2=newmap[ind];
        if (t1) {
          if (t2)
                res[ind]=t1+t2;
          else
                res[ind]=t1;
        } else {
          if (t2)
                res[ind]=t2;
        }
  }
  return res;
}

