// MorgenGrauen MUDlib
//
// lightsource.c -- standard light source
//
// $Id: lightsource.c 7806 2011-07-11 20:28:17Z Zesstra $

// std/lightsource.c
//
// Original von Miril April '92
// Neufassung von Sir Dezember '92 ( unter Boings Aegide :)
// Version : 1.0
//
// Bugfixes von Sir Juni '93
// Version : 1.2
//
// Wichtige Funktionen, die man in create() aufrufen sollte :
//
// Setzen der Brennstoffmenge :  
// SetProp( P_FUEL, int )       int gibt die Brennzeit in Sekunden an
//
// Setzen der Beschreibung wenn Objekt angezuendet( default : "brennend" ) :
// SetProp( P_LIGHTDESC, string )
//
// Legt fest, ob ein Leuchtobjekt nach seinem Abbrennen destructed wird
// SetProp( P_DO_DESTRUCT, int )
//
// Legt fest, wie hell die Fackel leuchtet.
// SetProp( P_LIGHT, int )
//
// Ansonsten sind die Standardfuktionen wie z.B. SetProp( P_GENDER, MALE ) 
// aufzurufen

#pragma strict_types
#pragma save_types
#pragma no_clone
#pragma range_check

inherit "std/thing" ;

#include <properties.h>
#include <language.h>
#include <defines.h>

#define TRUE  1
#define FALSE 0
#define bool  int

#define DFLT_FUEL       20 // 20 Sekunden
#define DFLT_LIGHTDESC  "brennend"
#define DFLT_LIGHT      2

// So ergibt sich die Moeglichkeit sie wieder auzufuellen
#define CALL_OUT_TIME   100

#undef DEBUG

// TODO: Private waer langfristig nett...
nosave int  fuel, max_fuel;
nosave bool lighted ;
nosave int  call_time ;

void create()
{
  thing::create() ;
  
  SetProp( P_NAME, "Lichtquelle" ) ;
  SetProp( P_SHORT, "Eine Lichtquelle" ) ;
  SetProp( P_LONG, "Du siehst nichts besonderes.\n" ) ;
  SetProp( P_GENDER, FEMALE ) ;
  SetProp( P_FUEL, DFLT_FUEL ) ;
  SetProp( P_LIGHTDESC, DFLT_LIGHTDESC ) ;
  SetProp( P_LIGHT, DFLT_LIGHT );
  SetProp( P_DO_DESTRUCT, TRUE ) ;
  SetProp( P_VALUE, 5 ) ;
  
  AddId( ({ "lichtquelle", "\nlichtquelle" }) ) ;
  AddCmd( ({ "zuende", "zuend" }), "light" );
  AddCmd( ({ "loesche", "loesch" }), "extinguish" );
}

void test_remove()
{  if (QueryProp(P_DO_DESTRUCT)) remove();  }

/*
 * Lichtquelle anzuenden
 */
bool light(string str)
{
  string tmp ;
  object env;

  _notify_fail( "Zuende was an?\n" ) ;

  if( (!str) || (!sscanf( str, "%s an", tmp )) || (!id( tmp )) )
    return FALSE ;
  
  if( environment() != PL ) // Player hat es nicht
  {
    _notify_fail( "Erstmal musst Du " + name( WEN, 0 ) + " haben.\n" ) ;
    return FALSE ;
  }
  
  if( lighted )
  {
    _notify_fail( CAP( name( WER, 1 ) ) + " brennt schon.\n" ) ;
    return FALSE ;
  }

  if( fuel <= 0 )
  {
    _notify_fail( CAP( name( WER, 1 ) ) + " ist abgebrannt.\n" ) ;
    test_remove() ;
    return FALSE ;
  }

  lighted = TRUE ;
  env=this_object();
  while (objectp(env=environment(env)))
      // Ja. Man ruft die _set_xxx()-Funktionen eigentlich nicht direkt auf.
      // Aber das Lichtsystem ist schon *so* rechenintensiv und gerade der
      // P_LAST_CONTENT_CHANGE-Cache wird *so* oft benoetigt, dass es mir
      // da um jedes bisschen Rechenzeit geht.
      // Der Zweck heiligt ja bekanntlich die Mittel. ;-)
      //
      // Tiamak
      env->_set_last_content_change();
  call_time = (fuel < CALL_OUT_TIME)? fuel : CALL_OUT_TIME ;
  call_out( "out_of_fuel", call_time ) ;
  if( ({int})PL->QueryProp(P_PLAYER_LIGHT) == 1 )
    write( "Du kannst wieder etwas sehen.\n" ) ;
  else write( "Ok.\n" ) ;
  say(({string})PL->Name(WER)
      + " zuendet " + name( WEN, 0 ) + " an.\n" ) ;

  return TRUE ;
}

bool extinguish(string str)
{
  int ti;
  object env;

  _notify_fail( "Welche Lichtquelle moechtest Du loeschen?\n" ) ;

  if( (!str) || (!id( str )) )
    return FALSE ;
  
  if( !lighted )
  {
    _notify_fail( CAP( name( WER, 1 ) ) + " brennt gar nicht.\n" ) ;
    return FALSE ;
  }

  if( environment() != PL )
  {
    _notify_fail( "Erstmal musst Du " + name( WEN, 0 ) + " haben.\n" ) ;
    return FALSE ;
  }

  if( ( ti = remove_call_out( "out_of_fuel" ) ) == -1 )
    ti = 0 ;

  fuel -= (call_time - ti) ;
  lighted = FALSE ;
  env=this_object();
  while (objectp(env=environment(env)))
      // Ja. Man ruft die _set_xxx()-Funktionen eigentlich nicht direkt auf.
      // Aber das Lichtsystem ist schon *so* rechenintensiv und gerade der
      // P_LAST_CONTENT_CHANGE-Cache wird *so* oft benoetigt, dass es mir
      // da um jedes bisschen Rechenzeit geht.
      // Der Zweck heiligt ja bekanntlich die Mittel. ;-)
      //
      // Tiamak
      env->_set_last_content_change();
  if ( ({int})this_player()->QueryProp(P_PLAYER_LIGHT) == 0 )
  {
    write( "Es wird dunkel.\n" ) ;
    say(({string})PL->Name(WER) + " macht das Licht aus.\n" ) ;
  }
  else
  {
    write( "Ok.\n" ) ;
    say(({string})PL->Name(WER) + " loescht " + name( WEN, 0 )
        + " aus.\n" ) ;
  }

  if( fuel <= 0 ) test_remove() ;
  return TRUE ;
}

bool unlight()
{
  int ti;
  object env;

  if( !lighted )
    return FALSE ;

  if( ( ti = remove_call_out( "out_of_fuel" ) ) == -1 )
    ti = 0 ;

  fuel -= (call_time - ti) ;
  lighted = FALSE ;
  env=this_object();
  while (objectp(env=environment(env)))
      // Kommentar siehe oben ;^)
      env->_set_last_content_change();
  if( fuel <= 0 ) test_remove() ;
  return TRUE ;
}

void out_of_fuel()
{
  int i;
  object *inv, env;
  
  fuel -= call_time ;

  if (fuel>0) {
    call_out( "out_of_fuel", call_time ) ;
    return ;
  }
  lighted=FALSE;
  env=this_object();
  while (objectp(env=environment(env)))
      // Immer noch nicht wirklich sauber. Aber Begruendung siehe oben.
      env->_set_last_content_change();

  if (environment())
  {
    if ( living(environment()) && environment(environment()) )
    {
      inv=(users() & all_inventory(environment(environment())))-({ environment() });
      for (i=sizeof(inv)-1; i>=0; i--) 
        if (inv[i]->QueryProp(P_PLAYER_LIGHT)<=0)
          tell_object(inv[i], "Es wird dunkel, als " + environment()->name(WESSEN) +
            " " + QueryProp(P_NAME) + " erlischt.\n" ) ;
        else tell_object(inv[i], CAP( name( WER, 0 ) ) + " erlischt.\n" ) ;
      if (environment()->QueryProp(P_PLAYER_LIGHT)<=0)
        tell_object(environment(), 
          CAP( name( WER, 1 ) ) + " erlischt, und es wird dunkel.\n" ) ;
      else tell_object(environment(), CAP( name( WER, 1 ) ) + " erlischt.\n" ) ;    
    }
    else
    {
      inv=(users() & all_inventory(environment()));
      for (i=sizeof(inv)-1; i>=0; i--) 
        if (inv[i]->QueryProp(P_PLAYER_LIGHT)<=0)
          tell_object(inv[i], "Es wird dunkel, als " + name(WER,1)
          + " erlischt.\n" ) ;
        else tell_object(inv[i], CAP( name( WER, 0 ) ) + " erlischt.\n" ) ;
    }
  }  
  test_remove() ;
}

// Brennstoff nachfuellen
void AddFuel(int f)
{  fuel += f ;  }

// Property - Funktionen

static void _set_lighted(bool l)
{  lighted = l ;  }

bool _query_lighted()
{  return lighted ;  }

static void _set_fuel(int f)
{
  if (f>max_fuel) max_fuel=f;
  fuel = f ;
}

static int _query_fuel()
{
  int tmp;

  if ((tmp=find_call_out("out_of_fuel"))>=0)
    return fuel-call_time+tmp;
  else return fuel;
}

static string _query_lightdesc()
{
  string|string* l_desc = Query(P_LIGHTDESC);
  if (!pointerp(l_desc))
    return (string)l_desc;
  
  int n = sizeof(l_desc);
  int i = n * _query_fuel() / max_fuel;
  if (i>=n)
    i = n-1;
  return l_desc[i];
}

static int _query_light()
{   return (lighted ? Query(P_LIGHT) : 0);  }

/*
 * short() ueberladen
 */
string short()
{
  string s;
  string desc;

  if(!(s=QueryProp(P_SHORT)))
    return 0;
  return s + ( (lighted)? (" ("+QueryProp( P_LIGHTDESC ) +").\n") : ".\n" );
}
