// 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;


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...
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()

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 */

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!
 */ 
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 );
}

