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

//
// 2003-01-20: Nun Zooks Baustelle
//
#pragma strong_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=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])[sinfo[P_WEAPON]->QueryProp(P_WEAPON_TYPE)];
      

  val = sinfo[SI_SKILLABILITY]*(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],
                                   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) && (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=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]) ||
      (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)) )
  {
    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;
}

