// MorgenGrauen MUDlib
//
// player/skills.c -- Spielerskills
//
// $Id: skills.c 8809 2014-05-08 19:52:48Z Zesstra $

//
// 2003-01-20: Nun Zooks Baustelle
//
#pragma strict_types
#pragma save_types
#pragma range_check
#pragma no_clone

inherit "/std/living/skills";

#include <combat.h>
#include <new_skills.h>
#include <properties.h>
#include <break_string.h>
#include <wizlevels.h>

#define NEED_PROTOTYPES
#include <player/base.h>
#include <player/gmcp.h>
#undef NEED_PROTOTYPES

// Dieses Mapping speichert die deaktivierten Skills der einzelnen Gilden
// Diese werden in den Gilden ueber P_GUILD_DEACTIVATED_SKILL gesetzt.
nosave mapping deactivated_skills = ([]);

// Flag fuer den Kompatibilitaetsmodus des Kampfs (Emulation von
// 2s-Alarmzeit). Wenn != 0 speichert das Flag gleichzeitig die Zeit des
// letzten Heartbeats. Auf diese Zeit wird der Startpunkt eines Spellfatigues
// ggf. zurueckdatiert. (max. eine Sekunde)
int spell_fatigue_compat_mode;

// Ein create() fuer das Mapping

protected void create()
{
  mapping act;

  ::create();

  // Wir holen die Gilden aus dem Gildenmaster 
  foreach(string guild:
      ({string *})call_other(GUILDMASTER,"QueryProp",P_VALID_GUILDS))
  {
    if(catch(act=({mapping})call_other("/gilden/"+guild,"QueryProp",
        P_GUILD_DEACTIVATE_SKILLS); publish ))
        log_file("WEAPON_SKILLS", sprintf ("%s: Gilde nicht ladbar: "
              +"TP: %O, TI: %O, PO: %O, Gilde: %s\n", dtime(time()),
              this_player(), this_interactive(), previous_object(), guild));
    else if (act) // wenn act, ins Mapping aufnehmen.
        deactivated_skills+=([guild:act]);
  }
  // keine echte Prop mehr, Save-Modus unnoetig.
  Set(P_NEXT_SPELL_TIME,SAVE,F_MODE_AD);

  Set(P_SKILLSVERSION, SAVE|SECURED, F_MODE_AS);
}

// Das Mapping kann man auch abfragen

public mapping GetDeactivatedSkills()
{
    return copy(deactivated_skills);
}

// Funktion, die sagt ob ein ANY-Skill deaktiviert ist.
public int is_deactivated_skill(string sname,string guild)
{
        if (deactivated_skills[guild])        
                return deactivated_skills[guild][sname];
        return 0;
}


// Funktion fuer die Waffenskills
// traegt die allg. Waffenskills ein. Wird ggf. von FixSkills() gerufen.
// (Das Eintragen bedeutet nicht, dass die aktiv sind! Aber bei Gildenwechsel
// werden sie nicht eingetragen).
private void set_weapon_skills() {

  if (QuerySkillAbility(FIGHT(WT_SWORD))<=0)                
      ModifySkill(FIGHT(WT_SWORD),([SI_SKILLABILITY:0]),150,"ANY");    
  if (QuerySkillAbility(FIGHT(WT_AXE))<=0)                
      ModifySkill(FIGHT(WT_AXE),([SI_SKILLABILITY:0]),150,"ANY");          
  if (QuerySkillAbility(FIGHT(WT_SPEAR))<=0)        
      ModifySkill(FIGHT(WT_SPEAR),([SI_SKILLABILITY:0]),150,"ANY");          
  if (QuerySkillAbility(FIGHT(WT_WHIP))<=0)
      ModifySkill(FIGHT(WT_WHIP),([SI_SKILLABILITY:0]),150,"ANY");
  if (QuerySkillAbility(FIGHT(WT_KNIFE))<=0)                
      ModifySkill(FIGHT(WT_KNIFE),([SI_SKILLABILITY:0]),150,"ANY");          
  if (QuerySkillAbility(FIGHT(WT_CLUB))<=0)                
      ModifySkill(FIGHT(WT_CLUB),([SI_SKILLABILITY:0]),150,"ANY");          
  if (QuerySkillAbility(FIGHT(WT_STAFF))<=0)
      ModifySkill(FIGHT(WT_STAFF),([SI_SKILLABILITY:0]),150,"ANY");
} 

// initialisiert die Skills fuer Spieler (momentan: allg. Waffenskills setzen
// und P_SKILLS_VERSION)
protected void InitSkills() {
  mapping ski;
  // schonmal initialisiert?
  if (mappingp(ski=Query(P_NEWSKILLS, F_VALUE)) && sizeof(ski))
    return;

  // allg. Waffenskills aktivieren
  set_weapon_skills();

  // Version setzen
  SetProp(P_SKILLSVERSION, CURRENT_SKILL_VERSION);
  Set(P_SKILLSVERSION, SAVE|SECURED, F_MODE_AS);
}

// Updated Skills aus Version 0 und 1 heraus.
private void FixSkillV1(string skillname, mixed sinfo) {
  // alte Skills auf mappings normieren
  if (intp(sinfo)) {
    sinfo = ([SI_SKILLABILITY: sinfo ]);
  }
  // Eine Reihe von Daten werden geloescht, da die Daten aus der
  // Gilde/Spellbook frisch kommen sollten und sie nicht spieler-individuell
  // sind: SI_CLOSURE (wird onthefly korrekt neu erzeugt), SI_SKILLARG,
  // SI_NUMBER_ENEMIES, SI_NUMBER_FRIENDS, SI_DISTANCE, SI_WIDTH, SI_DEPTH,
  // SI_TESTFLAG, SI_ENEMY, SI_FRIEND.
  // Ausserdem sind alle SP_* im toplevel falsch, die muessen a) in SI_SPELL
  // und sollten b) nicht im Spieler gespeichert werden, sondern von
  // Gilden/Spellbook jeweils frisch kommen.
  // all dieses Zeug landete in alten Spielern im Savefile.
  if (mappingp(sinfo))
    sinfo -= ([SI_CLOSURE, SI_SKILLARG, SI_NUMBER_ENEMIES, SI_NUMBER_FRIENDS,
             SI_DISTANCE, SI_WIDTH, SI_DEPTH, SI_TESTFLAG, SI_ENEMY,
             SI_FRIEND, SP_NAME, SP_SHOW_DAMAGE, SP_REDUCE_ARMOUR,
             SP_PHYSICAL_ATTACK, SP_RECURSIVE, SP_NO_ENEMY,
             SP_NO_ACTIVE_DEFENSE, SP_GLOBAL_ATTACK ]);
  else
  {
    tell_object(this_object(),sprintf(
      "\n**** ACHTUNG - FEHLER ***\n" 
      "Deine Skills enthalten einen defekten Skill %O:\n"
      "Bitte lass dies von einem Erzmagier ueberpruefen.\n",
      skillname));
  }
}

// Updatet und repariert ggf. Skillmappings in Spielern
protected void FixSkills() {

  // nur bei genug rechenzeit loslegen
  if (get_eval_cost() < 750000) {
    call_out(#'FixSkills, 1);
    return;
  }
  // wenn gar keine Skills da (?): InitSkills() rufen.
  mapping allskills = Query(P_NEWSKILLS, F_VALUE);
  if (!mappingp(allskills) || !sizeof(allskills)) {
      InitSkills();
      return;
  }

  // Die Fallthroughs in diesem switch sind voll Absicht!
  switch(QueryProp(P_SKILLSVERSION)) {
    // bei Version 0 und 1 das gleiche tun
    case 0: // von 0 auf 1
    case 1: // von 1 auf 2
      foreach(string gilde, mapping skills: allskills) {
        if (!stringp(gilde)) {
          // sollte nicht vorkommen - tat aber... *seufz*
          m_delete(skills, gilde);
          continue;
        }
        walk_mapping(skills, #'FixSkillV1);
      }
      // allg. Waffenskills aktivieren, einige alte Spieler haben die noch
      // nicht.
      set_weapon_skills();
      // Speicherflag fuer die Versionsprop muss noch gesetzt werden.
      Set(P_SKILLSVERSION, SAVE|SECURED, F_MODE_AS);
      // Version ist jetzt 2.
      SetProp(P_SKILLSVERSION, 2);
      // Fall-through
   case 2:
      // gibt es noch nicht, nichts machen.
      //SetProp(P_SKILLSVERSION, 3);
      // Fall-through, ausser es sind zuwenig Ticks da!
      if (get_eval_cost() < 750000)
        break; 
  }
  // Falls noch nicht auf der aktuellen Version angekommen, neuer callout
  if (QueryProp(P_SKILLSVERSION) < CURRENT_SKILL_VERSION)
      call_out(#'FixSkills, 2);
}

protected void updates_after_restore(int newflag) {
  //Allgemeine Waffenskills aktivieren, wenn noetig
  // Wird nun von InitSkills bzw. FixSkills uebernommen, falls noetig.
  if (newflag) {
    InitSkills();
  }
  else if (QueryProp(P_SKILLSVERSION) < CURRENT_SKILL_VERSION) {
    // Falls noetig, Skills fixen/updaten. *grummel*
    FixSkills();
  }
  // Prop gibt es nicht mehr. SAVE-Status loeschen. 
  Set(P_GUILD_PREVENTS_RACESKILL,SAVE,F_MODE_AD);
}

// Standardisierte Nahkampf-Funktion fuer alle Nahkampf-Waffenarten
protected mapping ShortRangeSkill(object me, string sname, mapping sinfo) 
{ 
  int val, w;
  object enemy;
  
  if (!mappingp(sinfo) || !objectp(sinfo[P_WEAPON]))
    return 0;

  w = ([WT_KNIFE : 8,
        WT_SWORD : 5,
        WT_AXE   : 4,
        WT_SPEAR : 6,
        WT_CLUB  : 1,
        WT_WHIP  : 9,
        WT_STAFF : 7])[({string})sinfo[P_WEAPON]->QueryProp(P_WEAPON_TYPE)];
      

  val = sinfo[SI_SKILLABILITY]*(({int})sinfo[P_WEAPON]->QueryProp(P_WC)*
                                (w*QueryAttribute(A_DEX)+
                                 (10-w)*QueryAttribute(A_STR))/700)
        /MAX_ABILITY;

  if (val > 85) {
    log_file("WEAPON_SKILLS", sprintf("%s: Zu hoher Schaden von: "
    +"TO: %O, TI: %O, PO: %O, val: %d, A_DEX: %d, A_STR: %d, "
                                   +"P_WEAPON: %O, P_WC: %d\n", dtime(time()),
                                   this_object(), this_interactive(),
                                   previous_object(), val,
                                   QueryAttribute(A_DEX),
                                   QueryAttribute(A_STR), sinfo[P_WEAPON],
                                   ({int})sinfo[P_WEAPON]->QueryProp(P_WC)));
    val = 85;
  }

  /*
    Der zusaetzliche Schaden der allgemeinen Waffenskills berechnet
    sich wie folgt: 

    sinfo[SI_SKILLABILITY)* (P_WC * ( X ) / 800) / MAX_ABILITY

    Dabei beruecksichtigt X je nach Waffentyp in unterschiedlicher
    Gewichtung die Werte fuer Geschicklichkeit und Staerke. 

     X == 

       Messer   : 8*A_DEX + 2*A_STR
       Schwert  : 5*A_DEX + 5*A_STR
       Axt      : 4*A_DEX + 6*A_STR 
       Speer    : 6*A_DEX + 4*A_STR
       Keule    : 1*A_DEX + 9*A_STR
       Peitsche : 9*A_DEX + 1*A_STR
  */

  sinfo[SI_SKILLDAMAGE]+=val;


  /* Lernen: Wird immer schwieriger, nur bei jedem 20. Schlag im Schnitt,
   * und nur dann, wenn der Gegner auch XP gibt. 
   * EM-Beschluss: Lernen wird leichter (jeder 5. Schlag, skillabhaengig)
   * und bei jedem 300. Schlag lernt man auch so. Ferner wird noch 
   * ueberprueft, ob der Skill schon maximal ist, wenn man sonst in
   * jedem Falle lernen wurde. 
   */
  if ((random(MAX_ABILITY+1)>sinfo[SI_SKILLABILITY] && !random(5))
       || (!random(300) && sinfo[SI_SKILLABILITY]<MAX_ABILITY))
  {
         enemy=sinfo[SI_ENEMY];
         if (objectp(enemy) && (({int})enemy->QueryProp(P_XP)>0))
         {
           object ausbilder;
        //         log_file("humni/log_wurm","Haut: %s und zwar %s, mit xp %d\n",geteuid(this_object()),to_string(enemy),enemy->QueryProp(P_XP));
            LearnSkill(sname, random(5), 150);
        // Gibt es einen Ausbilder?
        if (QueryProp(P_WEAPON_TEACHER) && 
                        ausbilder=find_player(QueryProp(P_WEAPON_TEACHER)))
          {
            // Ist der Ausbilder anwesend?
            if (present(ausbilder,environment()))
              {
              // Ausbilder und Azubi muessen dieselbe Waffe haben.
              //string wt_aus,wt_azu;
              object waf_aus,waf_azu;

              waf_azu=QueryProp(P_WEAPON);
              waf_aus=({object})call_other(ausbilder,"QueryProp",P_WEAPON);

              //wt_azu=call_other(waf_azu,"QueryProp",P_WEAPON_TYPE);
              //wt_aus=call_other(waf_aus,"QueryProp",P_WEAPON_TYPE);
              //if (wt_azu==wt_aus)
              if (objectp(waf_aus) && objectp(waf_azu) &&
                  ({string})waf_aus->QueryProp(P_WEAPON_TYPE)
                     == ({string})waf_azu->QueryProp(P_WEAPON_TYPE)) 
                {
                // Bonus von bis zu 5 Punkten
                //log_file("humni/log_azubi",
                  // sprintf("Azubi %O und Ausbilder %O : Waffentypen %s und %s, gelernt\n",this_object(),
                    //   ausbilder, wt_azu, wt_aus));
                LearnSkill(sname,random(6),150);
                }
          }
        }
    }
  }

  /* 
     Die Schwierigkeit liegt bei 150, so dass 
     ein Lvl. 1 Spieler maximal 15% Skill 
     usw...
     lernen kann. (Genaue Tabelle in /std/living/skills bei LimitAbility)
  */         

  return sinfo;
}


// Standardisierte Fernkampf-Funktion fuer alle Fernkampf-Waffenarten

// *** noch deaktiviert ***

protected mapping LongRangeSkill(object me, string sname, mapping sinfo, int dam) 
{ int abil,val;

  if (!mappingp(sinfo) || !dam || !objectp(sinfo[P_WEAPON]) ||
      (({int})sinfo[P_WEAPON]->QueryProp(P_SHOOTING_WC))<5)
    return 0;

  abil=sinfo[SI_SKILLABILITY]+sinfo[OFFSET(SI_SKILLABILITY)]; 
  val=dam*abil/MAX_ABILITY;
  val=val/2+random(val/2+1);
  val=(val*QuerySkillAttribute(SA_DAMAGE))/100;
  sinfo[SI_SKILLDAMAGE]+=val;

  if (random(MAX_ABILITY+1)>sinfo[SI_SKILLABILITY] && random(50)==42)
    LearnSkill(sname, 1, 150);

  return sinfo;
}



// Die einzelnen Waffenskills rufen dann nur die Standard-Funktion auf.

protected mapping StdSkill_Fight_axe(object me, string sname, mapping sinfo)
{
  return ShortRangeSkill(me, sname, sinfo);
}

protected mapping StdSkill_Fight_club(object me, string sname, mapping sinfo)
{
  return ShortRangeSkill(me, sname, sinfo);
}

protected mapping StdSkill_Fight_knife(object me, string sname, mapping sinfo)
{
  return ShortRangeSkill(me, sname, sinfo);
}

protected mapping StdSkill_Fight_spear(object me, string sname, mapping sinfo)
{
  return ShortRangeSkill(me, sname, sinfo);
}

protected mapping StdSkill_Fight_sword(object me, string sname, mapping sinfo) 
{
  return ShortRangeSkill(me, sname, sinfo);
}

protected mapping StdSkill_Fight_whip(object me, string sname, mapping sinfo)
{
  return ShortRangeSkill(me, sname, sinfo);
}

protected mapping StdSkill_Fight_staff(object me, string sname, mapping sinfo)
{
  return ShortRangeSkill(me, sname, sinfo);
}




// Die Fernwaffenskills sind Munitionsabhaengig

// *** noch deaktiviert ***

protected mapping StdSkill_Shoot_arrow(object me, string sname, mapping sinfo)
{
  return LongRangeSkill(me, sname, sinfo, 40);
}

protected mapping StdSkill_Shoot_bolt(object me, string sname, mapping sinfo)
{ 
  return LongRangeSkill(me, sname, sinfo, 40);
}

protected mapping StdSkill_Shoot_dart(object me, string sname, mapping sinfo)
{
  return LongRangeSkill(me, sname, sinfo, 20);
}

protected mapping StdSkill_Shoot_stone(object me, string sname, mapping sinfo)
{
  return LongRangeSkill(me, sname, sinfo, 40);
}

protected mixed _query_localcmds() {
    return ({ ({"spruchermuedung","enable_spell_fatigue_compat",0,0}) });
}



// *** Kompatibilitaetsmodus fuer Spellfatigues (Emulation 2s-Alarmzeit) ***

/** Speichert eine Spellfatigue von <duration> Sekunden fuer <key>.
 * Ist hier nur fuer den Spellfatigue-Compat-mode.
 * <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) {

  // 0 sollte nie eine Sperre bewirken, auch nicht im compat mode.
  if (!duration) return 0;

  if (spell_fatigue_compat_mode) {
    // Spell-Fatigues auf HBs synchronisieren (2s-Alarmzeit-Emulation).
    // Aufrunden auf ganzzahlige Vielfache von __HEART_BEAT_INTERVAL__
    if (duration % __HEART_BEAT_INTERVAL__)
        ++duration;

    // Startpunkt des Delay soll Beginn der aktuellen Kampfrunde (HB-Zyklus)
    // sein, ggf. um max. eine Sekunde zurueckdatieren.
    // (spell_fatigue_compat_mode hat die Zeit des letzten HB-Aufrufs)
    // Falls durch irgendein Problem (z.B. sehr hohe Last), der letzte HB
    // laenger als 1s zurueckliegt, funktioniert das natuerlich nicht, aber
    // bei fatigue+=spell_fatigue_compat_mode kann der Spieler zuviel Zeit
    // einsparen.
    if (time() > spell_fatigue_compat_mode)
        --duration;  //1s zurueckdatieren
  }

  return ::SetSpellFatigue(duration, key);
}

/** Befehlsfunktion fuer Spieler um den Spellfatigue-Kompatibilitaetsmodus
 * umzuschalten.
 */
public int enable_spell_fatigue_compat(string cmd) {
  if (QueryProp(P_LAST_COMBAT_TIME) + 600 > time()) {
    write(break_string(
      "Im Kampf oder kurz nach einem Kampf kannst Du nicht zwischen "
      "alter und neuer Spruchermuedung umschalten.\n"
      "Momentan benutzt Du die "
      + (spell_fatigue_compat_mode ? "alte (ungenauere)" : "neue (normale)")
      + " Spruchermuedung.",78,0,BS_LEAVE_MY_LFS));
    return 1;
  }

  if (cmd=="alt") {
    spell_fatigue_compat_mode=time();
    write(break_string(
      "Alte Spruchermuedung wurde eingeschaltet. Alle Ermuedungspausen "
      "zwischen Spruechen werden auf Vielfache von 2s aufgerundet und "
      "beginnen in der Regel am Anfang Deiner Kampfrunde."));
    return 1;
  }
  else if (cmd=="neu" || cmd=="normal") {
    spell_fatigue_compat_mode=0;
    write(break_string(
      "Normale Spruchermuedung wurde eingeschaltet. Alle Ermuedungspausen "
      "zwischen Spruechen werden sekundengenau berechnet."));
    return 1;
  }

  notify_fail(break_string(
      "Moechtest Du die alte oder die neue Spruchermuedung?\n"
      "Momentan benutzt Du die "
      + (spell_fatigue_compat_mode ? "alte (ungenauere)" : "neue (normale)")
      + " Spruchermuedung.",78,0,BS_LEAVE_MY_LFS));
  return 0;
}

/** Speichert die Zeit des letztes Heartbeats.
 */
protected void heart_beat() {
  if (spell_fatigue_compat_mode)
    spell_fatigue_compat_mode = time();
}

static int _set_guild_level(int num)
{ string gilde;
  mapping levels;

  if ( !(gilde=QueryProp(P_GUILD)) )
    return 0;

  if ( !mappingp(levels=Query(P_GUILD_LEVEL)) )
    levels=([]);

  levels[gilde]=num;
  Set(P_GUILD_LEVEL,levels);
  GMCP_Char( ([P_GUILD_LEVEL: num]) );

  return num;
}

static int _query_guild_level()
{ string  gilde;
  mapping levels;

  if ( !(gilde=QueryProp(P_GUILD)) )
    return 0;

  if ( !mappingp(levels=Query(P_GUILD_LEVEL)) )
      return 0;

  return levels[gilde];
}

static string _set_guild_title(string t)
{ string gilde;
  mapping titles;

  if ( !(gilde=QueryProp(P_GUILD)) )
    return 0;

  if ( !mappingp(titles=Query(P_GUILD_TITLE)) )
    titles=([]);

  titles[gilde]=t;
  Set(P_GUILD_TITLE,titles);
  GMCP_Char( ([P_GUILD_TITLE: t]) );
  return t;
}

static string _query_guild_title()
{ string gilde,t;
  object g;
  mapping titles;

  if ( !(gilde=QueryProp(P_GUILD)) )
    return 0;

  if ( !mappingp(titles=Query(P_GUILD_TITLE)) )
    titles=([]);

  t=titles[gilde];
  if ( !t && query_once_interactive(this_object())
      && objectp(g=find_object("/gilden/"+gilde)) )
  {
    ({void})g->adjust_title(this_object());
    SetProp(P_TITLE,0);

    if ( !mappingp(titles=Query(P_GUILD_TITLE)) )
      return 0;

    t=titles[gilde];
  }

  return t;
}


static string _set_guild(string gildenname)
{ object pre;

  if (!objectp(pre=previous_object()))
    return 0;

  if ( pre!=this_object() // Das Lebewesen selber darf die Gilde setzen,
      && object_name(pre)!=GUILDMASTER  // der Gildenmaster auch
      && (!this_player()
          || this_player() != this_interactive()
          || !IS_ARCH(this_player())
         )
      )
    return 0;

  Set(P_GUILD,gildenname);
  GMCP_Char( ([P_GUILD: gildenname]) );
  return gildenname;
}

static string _query_guild()
{ string res;

  if ( !(res=Query(P_GUILD)) && query_once_interactive(this_object()) )
  {
    // Spieler, die keiner Gilde angehoeren, gehoeren zur Abenteurergilde
    if ( !(res=QueryProp(P_DEFAULT_GUILD)) )
      return DEFAULT_GUILD;
    else
      Set(P_GUILD,res);
    return res;
  }

  return res;
}

static string _query_title()
{ string ti;

  if ( stringp(ti=Query(P_TITLE)) )
    return ti;

  return QueryProp(P_GUILD_TITLE);
}

static string _set_title(string t)
{
  Set(P_TITLE, t, F_VALUE);
  GMCP_Char( ([P_TITLE: t]) );
  return t;
}

