// MorgenGrauen MUDlib
//
// npc/combat.c -- NPC-spezifische Kampffunktionen
//
// $Id: combat.c 9488 2016-02-19 21:24:04Z Arathorn $
#pragma strong_types
#pragma save_types
#pragma range_check
#pragma no_clone

inherit "std/living/combat";

#include <combat.h>
#include <language.h>
#include <properties.h>
#include <wizlevels.h>
#include <health.h>
#include <new_skills.h>

#define NEED_PROTOTYPES 1
#include <living/life.h>
#undef NEED_PROTOTYPES

#define HB_CHECK 7
#define ME this_object()
#define STATMASTER "/p/service/rochus/guildstat/master"

nosave int heartbeat, beatcount;

private void catch_up_hbs();

protected void create() {
  ::create();
  beatcount=1;
  heartbeat=1;
}

protected void create_super() {
  set_next_reset(-1);
}

// aktuelles Lebewesen, fuer das dieser NPC gerade taetig ist. Default:
// Spieler, bei dem er als Helfer-NPC registriert ist.
public object QueryUser()
{
  mixed helperdata = QueryProp(P_HELPER_NPC);
  if (pointerp(helperdata) && objectp(helperdata[0]))
    return helperdata[0];
  return 0;
}

// ggf. Feinde expiren. Soll das Problem verringern, dass Spieler nach Tagen
// erst die Meldung kriegen, dass der NPC sie nicht mehr jagt, wenn der HB
// reaktivert wird.
void reset() {
  // ggf. die abgeschalteten HBs nachholen.
  if (!heartbeat)
    catch_up_hbs();
  // ggf. P_ENEMY_DAMAGE zuruecksetzen
  ResetEnemyDamage();
}

static void _set_max_hp(int i) {
  Set(P_MAX_HP,i);
  SetProp(P_HP,i);
}

static void _set_max_sp(int i) {
  Set(P_MAX_SP,i);
  SetProp(P_SP,i);
}


// Check-Funktion fuer die P_NO_ATTACK-QueryMethod
static mixed _check_immortality()
{
    int t;

    if ( !(t = Query("time_to_mortality")) || time() > t ){
        // Zeit ist abgelaufen - wieder angreifbar machen
        Set( P_NO_ATTACK, 0, F_QUERY_METHOD );
        heartbeat = 1;
        beatcount = 1;
        set_heart_beat(1);

        return 0;
    }

    // der NPC ist noch unangreifbar
    return break_string( capitalize(name( WER, 1 )) + " versteckt sich hinter "
                         "einem Fehler im Raum-Zeit-Gefuege und entgeht so "
                         "voruebergehend allen Angriffen.", 78 );
}


// wenn der HeartBeat buggt, wird diese Funktion vom Master aufgerufen
public void make_immortal()
{
    // fuer 5 Minuten unangreifbar machen
    Set( P_NO_ATTACK, #'_check_immortality, F_QUERY_METHOD );

    Set( "time_to_mortality", time() + 300, F_VALUE );

    // damit die Spieler keinen Vorteil durch den Bug haben, heilen
    heal_self(10000);

    // da nun der Heartbeat abgeschaltet ist und normalerweise erst
    // reaktiviert wird, sobald jemand nach 5min P_NO_ATTACK abfragt, muss man
    // aber auf Viecher achten, die immer nen Heartbeat haben wollen. In dem
    // fall per call_out selber die Prop abfragen.
    if (QueryProp(P_HB))
      call_out(#'QueryProp, 301, P_NO_ATTACK);
}


// Damit NPCs gegeneinander weiterkaempfen, auch wenn kein Spieler
// in der Naehe ist:
static int _query_hb()
{
    // TODO: return InFight() || Query(P_HB, F_VALUE), sobald InFight()
    // geaendert.
    return (InFight() || Query(P_HB,F_VALUE)) ? 1 : 0;
}


#define SPELL_TOTALRATE 0
#define SPELL_SINFO 1
#define SPELL_TEXT_FOR_ENEMY 2
#define SPELL_TEXT_FOR_OTHERS 3

varargs int AddSpell(int rate, int damage,
  string|<int|string>* TextForEnemy, string|<int|string>* TextForOthers,
  string|string* dam_type, string|closure func, int|mapping sinfo)
{
  mixed *spells;
  int total_rates;
  closure cl;

  if(rate<=0 || damage<0) return 0;

 // Tatsaechlich ist es immer ein nicht-physischer Angriff, wenn spellarg ein
  // int ist, weil wenn spellarg==0 ist der Default nicht-physischer Angriff
  // und bei spellarg!=0 auch. Nur mit einem mapping kann man einen phys.
  // Angriff erzeugen.
  if (intp(sinfo))
    sinfo = ([ SI_SPELL: ([SP_PHYSICAL_ATTACK: 0]) ]);
  else
  {
    // wenn das sinfo-Mapping nicht den Key SI_SPELL enthaelt, gehen wir davon
    // aus, dass es ein alter Aufrufer von AddSpell ist, welcher noch davon
    // ausgeht, dass si_spell an AddSpell() uebergeben werden soll. In diesem
    // Fall bauen wir ein sinfo und nehmen das uebergebene sinfo als SI_SPELL.
    if (!member(sinfo,SI_SPELL))
      sinfo = ([ SI_SPELL: sinfo ]);
  }

  sinfo[SI_SKILLDAMAGE] = damage;

  if(stringp(dam_type))
    dam_type=({dam_type});
  else if(!pointerp(dam_type))
  {
    if(sinfo[SI_SPELL][SP_PHYSICAL_ATTACK])
      dam_type=({DT_BLUDGEON});
    else
      dam_type=({DT_MAGIC});
  }
  foreach(string s : dam_type)
  {
    if(!VALID_DAMAGE_TYPE(s))
    {
      catch(raise_error(
        "AddSpell(): Ungueltiger Schadenstyp: "+s);
        publish);
    }
  }
  sinfo[SI_SKILLDAMAGE_TYPE] = dam_type;

  if(!member(sinfo, SI_MAGIC_TYPE))
    sinfo[SI_MAGIC_TYPE] = ({ MT_ANGRIFF });

  // Falls func ein String ist eine Closure erstellen und diese speichern.
  if(stringp(func))
  {
    if (sizeof(func))
    {
      cl=symbol_function(func,this_object());
      if(!closurep(cl))
      {
        catch(raise_error(
          "AddSpell(): Es konnte keine Closure fuer "+func+" erstellt werden.");
          publish);
      }
    }
  }
  else
  {
    cl=func;
  }
  sinfo[SI_CLOSURE] = cl;

  if(damage==0 && !closurep(cl))
  {
    catch(raise_error(
      "AddSpell(): Bei damage=0 muss eine Funktion eingetragen werden.");
      publish);
    return 0;
  }

  if(!sizeof(TextForEnemy) ||
    (pointerp(TextForEnemy) && !sizeof(TextForEnemy[0])))
  {
    TextForEnemy=0;
  }
  else if(stringp(TextForEnemy))
  {
    TextForEnemy=({TextForEnemy,MT_LOOK});
  }
  else if(pointerp(TextForEnemy) && 
    (!stringp(TextForEnemy[0]) || !intp(TextForEnemy[1])))
  {
    raise_error(
      "AddSpell(): Falsche Datentypen fuer TextForEnemy");
  }

  if(!sizeof(TextForOthers) ||
    (pointerp(TextForOthers) && !sizeof(TextForOthers[0])))
  {
    TextForOthers=0;
  }
  else if(stringp(TextForOthers))
  {
    TextForOthers=({TextForOthers,MT_LOOK});
  }
  else if(pointerp(TextForOthers) && 
    (!stringp(TextForOthers[0]) || !intp(TextForOthers[1])))
  {
    raise_error(
      "AddSpell(): Falsche Datentypen fuer TextForOthers");
  }

  // Falls vorhanden, alte Syntax auf die von replace_personal() anpassen,
  // die im heart_beat() beim Ausgeben der Meldung verwendet wird.
  if ( pointerp(TextForOthers) && strstr(TextForOthers[0], "@", 0) != -1 )
  {
    // Zeichen nach @WER & Co in runde Klammern einschliessen, damit es als
    // Sub-Pattern im Ausgabestring wiederholt werden kann. Ansonsten wuerde
    // es mit ersetzt.
    TextForOthers[0] = regreplace(TextForOthers[0], "@WER([^1-9QU])", "@WER1\\1", 1);
    TextForOthers[0] = regreplace(TextForOthers[0], "@WESSEN([^1-9QU])",
                               "@WESSEN1\\1", 1);
    TextForOthers[0] = regreplace(TextForOthers[0], "@WEM([^1-9QU])", "@WEM1\\1", 1);
    TextForOthers[0] = regreplace(TextForOthers[0], "@WEN([^1-9QU])", "@WEN1\\1", 1);
  }

  total_rates=Query("npc:total_rates", F_VALUE)+rate;
  spells=Query(P_SPELLS);
  if (!pointerp(spells))
    spells=({});
  spells+=({({total_rates, sinfo, TextForEnemy, TextForOthers})});
  Set(P_SPELLS,spells);
  Set("npc:total_rates",total_rates, F_VALUE);
  return 1;
}

int AutoAttack(object ob) {
  mixed m;

  if (!query_once_interactive(ob))
    return 0;
  if (mappingp(m=QueryProp(P_AGGRESSIVE))) {
    mixed *ind,x,z;
    float f;
    int i,n;

    ind=m_indices(m)-({0});n=0;f=0.0;
    for (i=sizeof(ind)-1;i>=0;i--) {
      x=ind[i];
      if ((z=m[x][ob->QueryProp(x)]) || (z=m[x][0])) {
  f=f+(float)z;
  n++;
      }
    }
    if (n)
      m=f/((float)n);
    else
      m=m[0];
  }
  if (((int)(100*(m+ob->QueryProp(P_AGGRESSIVE))))<=random(100))
    return 0;
  if  (IS_LEARNER(ob)
       && (ob->QueryProp(P_INVIS)
     || ob->QueryProp(P_WANTS_TO_LEARN)))
    return 0;
  return 1;
}

void SpellAttack(object enemy) {
}

#if 0
TJ(string s) {
  object o;
  if (o=find_player("jof"))
    tell_object(o,sprintf("%O: %s\n",this_object(),s));
}
#else
#define TJ(x)
#endif

protected void heart_beat() {
  int r,i;
  mixed env,*spells, sinfo;
  object enemy;

  if ( --beatcount < 0 )
      beatcount = 0;
  
  if (!beatcount && !Query(P_HB)) {
    if (!environment()) {
      set_heart_beat(0);
      heartbeat = 0;
      if( clonep(this_object()) ) remove();
      return;
    }
    if (!QueryProp(P_POISON)) {
      // Spieler anwesend?
      env = filter(all_inventory(environment()), #'query_once_interactive);
      if (!sizeof(env)) {
	// Nein, HBs abschalten.
	set_heart_beat(0);
	heartbeat=0;
	TJ("OFF\n");
	beatcount=HB_CHECK;
	Set("npc:beat_off_num",absolute_hb_count());
	return;
      }
    }
  }
  ::heart_beat();
  if (!ME)
      return;
  enemy=SelectEnemy();
  if (QueryProp(P_AGGRESSIVE)
      && (!enemy || environment()!=environment(enemy))
      && !beatcount) {
    beatcount=HB_CHECK;
    env=filter(all_inventory(environment()),#'AutoAttack);
    if (!sizeof(env))
       return;
    i=random(sizeof(env));
    Kill(env[i]);
  }
  else if (!beatcount)
    beatcount=HB_CHECK;
  if (!objectp(enemy) ||QueryProp(P_DISABLE_ATTACK)>0)
    return;
  SpellAttack(enemy);

  if (!pointerp(spells=Query(P_SPELLS))
      || !sizeof(spells)
      || !objectp(enemy=SelectEnemy())
      || environment(enemy)!=environment()
      || (QueryProp(P_DISABLE_ATTACK)>0)
      || random(100)>Query(P_SPELLRATE))
    return;
  // Spell aussuchen, von oben runterlaufen, bis zum ersten Spell, dessen
  // SPELL_TOTALRATE grosser ist als r.
  r=random(Query("npc:total_rates", F_VALUE));
  for (i=sizeof(spells)-1 ; (i>0 && spells[i-1][SPELL_TOTALRATE] > r); i--)
    ;

  <int|string>* akt_spell_mess=spells[i][SPELL_TEXT_FOR_ENEMY];
  // Nur, wenn ueberhaupt eine Meldung gesetzt wurde, muss diese verarbeitet
  // werden.
  if(pointerp(akt_spell_mess))
  {
    enemy->ReceiveMsg(
      akt_spell_mess[0],
      akt_spell_mess[1],
      MA_SPELL);
  }
  akt_spell_mess=spells[i][SPELL_TEXT_FOR_OTHERS];
  if(pointerp(akt_spell_mess))
  {
    send_room(environment(),
      replace_personal(akt_spell_mess[0], ({enemy}), 1),
      akt_spell_mess[1],
      MA_SPELL,
      0,
      ({enemy,this_object()}),
      this_object());
  }

  // Tiefe Kopie, damit wir nach Herzenslust fuer diese Ausfuehrung
  // manipulieren koennen und alle gerufenen Defend und Ruestung etc. nix
  // dauerhaft in SI_SPELL kaputt machen koennen.
  sinfo = deep_copy(spells[i][SPELL_SINFO]);
  sinfo[SI_ENEMY] = enemy;

  if(!sinfo[SP_PHYSICAL_ATTACK] &&
     (enemy->SpellDefend(this_object(),sinfo) >
      random(MAX_ABILITY+QueryProp(P_LEVEL)*50)))
  {
    enemy->ReceiveMsg(
      "Du wehrst den Spruch ab.",
      MT_NOTIFICATION,
      MA_SPELL);
    send_room(environment(),
      enemy->Name(WER,1)+" wehrt den Spruch ab.",
      MT_LOOK,
      MA_SPELL,
      0,
      ({ enemy, this_object()}));
    return ;
  }
  // Bei 0 sparen wir uns das Defend() und rufen nur weiter unter SI_CLOSURE auf.
  if(sinfo[SI_SKILLDAMAGE])
  {
    sinfo[SI_SKILLDAMAGE] = random(sinfo[SI_SKILLDAMAGE]) + 1;
    enemy->Defend(sinfo[SI_SKILLDAMAGE], sinfo[SI_SKILLDAMAGE_TYPE],
                  sinfo[SI_SPELL], this_object());
  }

  // Falls der Gegner (oder wir) im Defend stirbt, hier abbrechen
  if ( !objectp(ME) || !objectp(enemy)
      || enemy->QueryProp(P_GHOST) ) return;

  closure cl = sinfo[SI_CLOSURE];
  if (cl)
  {
    if (closurep(cl))
      catch(funcall(cl, enemy, sinfo[SI_SKILLDAMAGE],
                    sinfo[SI_SKILLDAMAGE_TYPE]);publish);
    else
      raise_error(sprintf("P_SPELL defekt: SPELL_FUNC in Spell %i ist keine "
                          "Closure.\n", i));
  }
}

// Heartbeats nachholen.
private void catch_up_hbs() {
  // gibt es HBs zum nachholen?
  int beat_off_num = Query("npc:beat_off_num");
  if (!beat_off_num)
    return; // nein.
  // wieviele HBs nachholen?
  beat_off_num = absolute_hb_count() - beat_off_num;
  
  if (beat_off_num>0) {
    // Nicht ausgefuehrtes HEILEN nachholen
    int rlock=QueryProp(P_NO_REGENERATION);
    int hp=QueryProp(P_HP);
    int sp=QueryProp(P_SP);
    int alc=QueryProp(P_ALCOHOL);
    if (!(rlock & NO_REG_HP)) {
      hp+=beat_off_num/HEAL_DELAY+alc/ALCOHOL_DELAY;
      SetProp(P_HP,hp);
    }
    if (!(rlock & NO_REG_SP)) {
      sp+=beat_off_num/HEAL_DELAY+alc/ALCOHOL_DELAY;
      SetProp(P_SP,sp);
    }
    alc-=beat_off_num/ALCOHOL_DELAY;
    if ( alc < 0 )
      alc = 0;
    SetProp(P_ALCOHOL,alc);
    int da = QueryProp(P_DISABLE_ATTACK);
    // Paralysen abbauen
    if ( da > 0 ) {
      da -= beat_off_num;
      if ( da < 0 )
	da = 0;
      SetProp( P_DISABLE_ATTACK, da );
    }
    // Hunttimes aktualisieren, Feinde expiren
    update_hunt_times(beat_off_num);
    if (!heartbeat)
      // HBs immer noch abgeschaltet, naechstes Mal HBs seit jetzt nachholen.
      Set("npc:beat_off_num",absolute_hb_count());
    else
      // HB laeuft wieder, nix mehr nachholen, bis zur naechsten Abschaltung.
      Set("npc:beat_off_num",0);
  }
}

public varargs void init(object origin)
{
  // ggf. Heartbeats nachholen und wieder einschalten.
  if (!heartbeat) {
    set_heart_beat(1);
    heartbeat=1;
    catch_up_hbs();
  }

  if (AutoAttack(this_player()))
    Kill(this_player());
}

private nosave closure mod_att_stat;

int Defend(int dam, mixed dam_type, mixed spell, object enemy) {
  if (objectp(enemy=(enemy||this_player()))
      && query_once_interactive(enemy)
      && !IS_LEARNER(enemy)) {
    if (!objectp(get_type_info(mod_att_stat,2))) {
      object ma;
      if (!objectp(ma=find_object(STATMASTER)))
        return ::Defend(dam,dam_type,spell,enemy);
      // Keine Statistik wenn Master nicht geladen ist.
      mod_att_stat=symbol_function("ModifyAttackStat",ma);
    }
    funcall(mod_att_stat,
            enemy->QueryProp(P_GUILD),
            enemy->QueryProp(P_GUILD_LEVEL),
            dam,
            dam_type,
            spell);
  }

  return ::Defend(dam,dam_type,spell,enemy);
}
