// 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
      ({int})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
      ({int})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 ;^)
      ({int})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.
      ({int})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 (({int})inv[i]->QueryProp(P_PLAYER_LIGHT)<=0)
          tell_object(inv[i], "Es wird dunkel, als " + ({string})environment()->name(WESSEN) +
            " " + QueryProp(P_NAME) + " erlischt.\n" ) ;
        else tell_object(inv[i], CAP( name( WER, 0 ) ) + " erlischt.\n" ) ;
      if (({int})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 (({int})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" );
}
