// MorgenGrauen MUDlib
//
// container/restrictions.c -- container restrictions
//
// $Id: restrictions.c 9020 2015-01-10 21:49:41Z Zesstra $

// This is a simple container to put objects in. It defines all functions
// which are necessary to describe an object which can be filled with
// other things.
//
// It will support restrictions for volume, weight etc.
//
// The following properties are defined:
// P_MAX_WEIGHT - maximum weight which container can carry
// P_TOTAL_WEIGHT - total weight, with contents.
// P_WEIGHT - the weight of the container without contents
//
// Functions for manipulation of weight
// MayAddWeight(weight) - Can <weight> be inserted?
// AddWeight(weight) - Add an amount of <weight>
//
// IMPORTANT: unit equals 1 gram

#pragma strict_types
#pragma save_types
//#pragma range_check
#pragma no_clone
#pragma pedantic

#define NEED_PROTOTYPES

#include "/sys/thing/properties.h"
#include <properties.h>
#include <defines.h>
#include <thing/description.h>

// local properties prototypes
static int _query_total_weight();


private nosave int LastWeightCalc, contents, LastObjectCount, objcount;
private nosave int last_content_change;


protected void create()
{
    Set( P_WEIGHT_PERCENT, 50 );
    Set( P_TOTAL_WEIGHT, NOSETMETHOD, F_SET_METHOD );
    Set( P_TOTAL_WEIGHT, PROTECTED, F_MODE );
    Set( P_MAX_OBJECTS, 100 );
    Set( P_TOTAL_OBJECTS, NOSETMETHOD, F_SET_METHOD );
    Set( P_TOTAL_OBJECTS, PROTECTED, F_MODE );
    LastWeightCalc = -1;
    LastObjectCount = -1;
}


static int _query_last_content_change()
{
    return last_content_change;
}


// absichtlich public, da es von der simul_efun.c *direkt* aufgerufen
// wird aus Performancegruenden!
public varargs int _set_last_content_change( mixed wert )
{
    // Der uebergebene Wert ist unerheblich. Die Property
    // P_LAST_CONTENT_CHANGE wird so oder so bei jedem SetProp()-
    // Aufruf um eins erhoeht, um der 2s-"Unschaerfe" von time()
    // aus dem Weg zu gehen.
    return ++last_content_change;
}


int query_weight_contents()
{
    object *objs;
    int w, w2, i;

    if ( last_content_change == LastWeightCalc )
        return contents;
    
    w = 0;
    objs = all_inventory(this_object());
    i = sizeof(objs);
    
    while ( i-- ){
        if ( !(w2 = (int)objs[i]->QueryProp(P_TOTAL_WEIGHT)) )
            w2 = (int)objs[i]->QueryProp(P_WEIGHT);
        w += w2;
    }
    
    LastWeightCalc = last_content_change;
    return contents = w;
}


static int _query_total_objects()
{
  if ( last_content_change == LastObjectCount )
      return objcount;

  objcount = sizeof( filter_objects( all_inventory(), "short" ) );
  LastObjectCount = last_content_change;
  return objcount;
}


// diese Funktion sollte von Raeumen natuerlich ueberschrieben werden...
public int MayAddObject( object ob )
{
    if (ob) {
        if ( !ob->short() )
            return 1; // invis-Objekte duerfen immer
        
        if ( ob == ME || environment(ob) == ME)
            return 1; // objekt ist schon drin
    }
    
    return (QueryProp(P_TOTAL_OBJECTS) < QueryProp(P_MAX_OBJECTS));
}


#define ENV environment
#define PO previous_object()

public int MayAddWeight( int w )
{
    int nw, aw;

    // was nix wiegt, passt
    if ( w <= 0 )
        return 0;

    nw = w; // Gewicht im neuen Container
    aw = 0; // Gewicht fuer das env()

    // Von Raum in Behaelter im Spieler: Container sieht volles Gewicht (nw=w),
    // Check im env() (Spieler) mit reduziertem Gewicht.
    if ( ENV() && PO && ENV(PO) != ENV() )
        aw = QueryProp(P_WEIGHT_PERCENT) * w / 100 || 1;

    if ( PO && ENV(PO) && ENV(ENV(PO)) ){
        // Wenn das Objekt ein env() hochbewegt wird, wird das Gewicht im alten
        // Container abgezogen. Weiterer Check im env() ist unnoetig (aw=0).
        if ( ENV(ENV(PO)) == ME )
            nw = w - (int)ENV(PO)->QueryProp(P_WEIGHT_PERCENT) * w / 100;
        // Eine Ebene tiefer bewegen: Test im neuen Container mit unveraendertem
        // Gewicht; Check im env() mit um Gewichtsreduktion verringertem Gewicht
        else if ( present( ME, ENV(PO) ) )
            aw = QueryProp(P_WEIGHT_PERCENT) * w / 100 - w;
        // Auf derselben Ebene verschieben (von Paket in Beutel):
        // Neuer Container sieht volles Gewicht (nw=w), Check im env() mit
        // Differenz aus Gewicht in Container1 und in Container2.
        else if ( ENV(ENV(ENV(PO))) && ENV() == ENV(ENV(PO)) )
            aw = QueryProp(P_WEIGHT_PERCENT) * w / 100
                - ((int)ENV(PO)->QueryProp(P_WEIGHT_PERCENT) * w / 100 || 1);
    }

    if ( query_weight_contents() + nw > QueryProp(P_MAX_WEIGHT) )
        // Container kann Gewicht nicht mehr aufnehmen
        return -1;
    
    if ( aw && ENV()->MayAddWeight(aw) < 0 )
        // Umgebung des Containers kann Gewicht nicht mehr aufnehmen
        return -2;
    
    return 0;
}


/* Redefine PreventInsert() to prevent inserting of special objects. If
 * a value greater 0 is returned the object ob can't be inserted in the
 * container.
 */
public int PreventInsert( object ob ) { return 0; }
public int PreventLeave( object ob, mixed dest ) { return 0; }
public int PreventInsertLiving( object ob ) { return 0; }
public int PreventLeaveLiving( object ob, mixed dest ) { return 0; }
public void NotifyInsert(object ob, object oldenv) { }
public void NotifyLeave(object ob, object dest) { }

// **** local property methods
static int _query_total_weight() 
{ 
    return QueryProp(P_WEIGHT) +
        (QueryProp(P_WEIGHT_PERCENT) * query_weight_contents() / 100); 
}


// Hilfsfunktion
static int _behalten( object ob, string uid )
{
    return (string)ob->QueryProp(P_KEEP_ON_SELL) == uid;
}


/*
 *
 * get a list of all contained objects matching a complex description
 *
 */

#define POS_INVERS   0x01  /* nur zur funktionsinternen Verwendung */
#define POS_LETZTES  0x02  /* nur zur funktionsinternen Verwendung */

public object *present_objects( string complex_desc )
{
    int i;          // Zaehlervariable
    int meth;       // 0x01 = invers?,  0x02 = letztes?
    object ob;      // einzelnes temporaeres Objekt
    object *obs;    // liste der ausgewaehlten Objekte
    object *erg;    // zum sammeln bis es nachher zurueckgegeben wird...
    string *strlst; // liste aller Gruppen die mit AND verknuepft sind
    object haufen;

    strlst = allocate(2);
    
    if ( sscanf( complex_desc, "%s ausser %s", strlst[0], strlst[1]) == 2 ){
        erg = present_objects( strlst[0] );
        obs = present_objects( strlst[1] );
        return erg-obs;
    }
    
   strlst = explode( complex_desc, " und " );
   erg = ({});
   
   for ( i = sizeof(strlst); i--; )
   {
       complex_desc = strlst[i];
       // auf letzte/letztes/letzten pruefen...
       if ( complex_desc[0..5] == "letzte" ){
           switch( complex_desc[6..6] ){
           case " ":
               meth |= POS_LETZTES;
               complex_desc = complex_desc[7..];
               break;
           case "s":
           case "n":
           case "m":
           case "r":
               if ( complex_desc[7..7] != " " )
                   break;
               meth |= POS_LETZTES;
               complex_desc = complex_desc[8..];
               break;
           default:
           }
       }

       // auf verneinung pruefen
       if ( complex_desc[0..5] == "nicht " ){
           meth |= POS_INVERS;
           complex_desc = complex_desc[6..];
       }

       obs=({});
       // nun nach Main-Ids (Gruppen) suchen...
       if ( meth & POS_LETZTES )
       { // geht es nur um den letzten Gegenstand?
           switch( complex_desc ){
           case "waffe":
               obs = filter_objects( all_inventory(), "QueryProp",
                                     P_WEAPON_TYPE );
               break;
               
           case "ruestung":
               obs = filter_objects( all_inventory(), "QueryProp",
                                     P_ARMOUR_TYPE );
               break;
          
           case "kleidung":
               obs = filter_objects( all_inventory(), "IsClothing");
               break;
               
           case "verschiedenem":
           case "verschiedenes":
               obs = all_inventory();
               obs -= filter_objects( obs, "QueryProp", P_WEAPON_TYPE );
               obs -= filter_objects( obs, "QueryProp", P_ARMOUR_TYPE );
               obs -= filter_objects( obs, "IsClothing");
               obs -= filter( obs, #'living/*'*/ );
               break;
        
           case "eigenes":
           case "meins":
               if (objectp(haufen=present("\nhaufen "+
                     this_player()->name(WEM)))) {
                  obs = all_inventory(haufen);
               }
               // kein break;, Fall-through!
           case "behaltenem":
           case "behaltenes":
               obs += filter( all_inventory(), "_behalten", ME,
                                   getuid(this_player() || previous_object()) );

               obs += (QueryProp(P_ARMOURS) || ({}))
                   + ({ QueryProp(P_WEAPON) }) - ({ 0 });
                   break;
                   
           case "gegenstand":
               obs = all_inventory() -
                   filter( all_inventory(), #'living/*'*/ );
               break;
               
           default:
               obs = filter_objects( all_inventory(), "id", complex_desc );
           }

           // unsichtbare objekte entfernen
           obs = filter_objects( obs, "short" );

           // letzten Gegenstand raussuchen
           obs = obs[0..0]; 
       } // if (letzter Gegenstand)
       else
       { // ganze Gruppen und nicht nur das letzte Objekt
           switch ( complex_desc )
           {
           case "allem":
           case "alles":
           case "jeden gegenstand":
           case "jedem gegenstand":
           case "gegenstaende":
           case "alle gegenstaende":
           case "allen gegenstaenden":
               if ( meth & POS_INVERS )
                   continue; // alles nicht = nichts :)
               
               obs = all_inventory() -
                   filter( all_inventory(), #'living/*'*/ );
               break;
               
           case "waffen":
           case "jede waffe":
           case "jeder waffe":
           case "alle waffen":
           case "allen waffen":
               obs = filter_objects( all_inventory(), "QueryProp",
                                     P_WEAPON_TYPE );
               break;
               
           case "ruestungen":
           case "jede ruestung":
           case "jeder ruestung":
           case "alle ruestungen":
           case "allen ruestungen":
               obs = filter_objects( all_inventory(), "QueryProp",
                                     P_ARMOUR_TYPE );
               break;
 
           case "kleidung":
           case "jede kleidung":
           case "jeder kleidung":
           case "alle kleidung":
           case "allen kleidung":
               obs = filter_objects( all_inventory(), "IsClothing");
               break;
              
           case "gegenstand":
               obs = filter_objects( all_inventory() -
                                     filter( all_inventory(),
                                                   #'living/*'*/ ),
                                     "short" )[0..0];
               break;
               
           case "verschiedenem":
           case "verschiedenes":
               obs = all_inventory();
               obs -= filter_objects( obs, "QueryProp", P_WEAPON_TYPE );
               obs -= filter_objects( obs, "QueryProp", P_ARMOUR_TYPE );
               obs -= filter_objects( obs, "IsClothing");
               obs -= filter( obs, #'living/*'*/ );
               break;
       
           case "eigenes":
           case "eigenem":
           case "eigenen":
           case "meins":
           case "alles eigene":
               if (objectp(haufen=present("\nhaufen "+
                       this_player()->name(WEM)))) {
                  obs = all_inventory(haufen);
               }
               // kein break;, Fall-through!
           case "behaltenem":
           case "behaltenen":
           case "behaltenes":
           case "alles behaltene":
               obs += filter( all_inventory(), "_behalten", ME,
                                   getuid(this_player() || previous_object()) );

               obs += (QueryProp(P_ARMOURS) || ({}))
                   + ({ QueryProp(P_WEAPON) }) - ({ 0 });
                   break;
                   
           default:
               if ( complex_desc[0..3] == "jede" ||
                    complex_desc[0..4] == "alle ")
               {
                   if ( complex_desc[4..4] == " " )
                   {
                       obs = filter_objects( all_inventory(), "id",
                                             complex_desc[5..] );
                       break;
                   }
                   else
                   {
                       switch( complex_desc[4..5] )
                       {
                       case "m ":
                       case "r ":
                       case "n ":
                       case "s ":
                           obs = filter_objects( all_inventory(), "id",
                                                 complex_desc[6..] );
                           break;
                           
                       default:
                           obs = 0;
                       }
                       if (obs)
                           break;
                   }
               }

               // Der Normalfall: einzelne ID...
               ob = present( complex_desc, ME );
               // Achtung: dieser Teil setzt das for() fort (continue) und
               // umgeht dabei die Pruefung auf Sichtbarkeit nach dem Ende vom
               // switch(). Aus diesem Grunde muss hier selber geprueft
               // werden.
               if ( meth & POS_INVERS )
               {
                   if ( ob && ob != ME )
                       erg += (filter_objects( all_inventory(), "short" )
                               - ({ ob }) );
                   else
                       erg += filter_objects( all_inventory(), "short" );
               }
               else if ( ob && ob != ME && !ob->QueryProp(P_INVIS) )
                   erg += ({ ob });   //Normalfall: einzelne ID

               continue;

           }  // switch
           // unsichtbare objekte entfernen
           obs = filter_objects( obs, "short" ); 
       } // else

       if ( meth & POS_INVERS )
           erg += ( filter_objects( all_inventory(), "short" ) - obs );
       else
           erg += obs;
   } // for
   return erg;
}

/*
 * returns a list of all found objects inside itself
 * may call same function in objects inside
 *
 * Funktion wird nicht mehr von put_and_get aufgerufen, stattdessen wird
 * direkt present_objects benutzt!
 */ 
public object *locate_objects( string complex_desc, int info ) {
    string was, wo;

    if ( sscanf( complex_desc, "%s in %s", was, wo ) == 2 ){
      object *found_obs = ({});
      foreach(object invob: present_objects(wo)) {
        // || ({}) weil invob ein Objekt ohne locate_objects() sein koennte.
        found_obs += (object *)invob->locate_objects( was, info) || ({});
      }
      return found_obs;
    }
    // kein "in" gefunden
    return present_objects( complex_desc );
}

