Posted to tcl by hypnotoad at Tue Dec 09 22:18:29 GMT 2014view pretty

/*
** This file is machine generated. Changes will
** be overwritten on the next run of cstruct.tcl
*/
#include "sim.h"


void compartment_export_nmalloc(Tcl_Interp *interp) { 
#if IRM_MEM_DEBUG
  Tcl_LinkVar(interp, "module_malloc(cstruct_compartment)", (char*)&nMalloc,
        TCL_LINK_INT | TCL_LINK_READ_ONLY);
#endif
}


/* Structure Compartment */

const struct IrmParamNameMap Compartment_paramNameMap[] = {
  { "accessible", CSTRUCT_COMPARTMENT_ACCESSIBLE, PTYPE_INT },
  { "agent_suppression", CSTRUCT_COMPARTMENT_AGENT_SUPPRESSION, PTYPE_INT },
  { "airlock_open", CSTRUCT_COMPARTMENT_AIRLOCK_OPEN, PTYPE_INT },
  { "chrr", CSTRUCT_COMPARTMENT_CHRR, PTYPE_FLOAT },
  { "collapse", CSTRUCT_COMPARTMENT_COLLAPSE, PTYPE_FLOAT },
  { "cten", CSTRUCT_COMPARTMENT_CTEN, PTYPE_INT },
  { "ctrans", CSTRUCT_COMPARTMENT_CTRANS, PTYPE_INT },
  { "cvis", CSTRUCT_COMPARTMENT_CVIS, PTYPE_FLOAT },
  { "fire_size", CSTRUCT_COMPARTMENT_FIRE_SIZE, PTYPE_FLOAT },
  { "flooding", CSTRUCT_COMPARTMENT_FLOODING, PTYPE_FLOAT },
  { "has_abandon", CSTRUCT_COMPARTMENT_HAS_ABANDON, PTYPE_INT },
  { "has_debris", CSTRUCT_COMPARTMENT_HAS_DEBRIS, PTYPE_INT },
  { "has_exception", CSTRUCT_COMPARTMENT_HAS_EXCEPTION, PTYPE_INT },
  { "has_fire", CSTRUCT_COMPARTMENT_HAS_FIRE, PTYPE_INT },
  { "has_flood", CSTRUCT_COMPARTMENT_HAS_FLOOD, PTYPE_INT },
  { "has_hot", CSTRUCT_COMPARTMENT_HAS_HOT, PTYPE_INT },
  { "has_investigation", CSTRUCT_COMPARTMENT_HAS_INVESTIGATION, PTYPE_INT },
  { "has_pda", CSTRUCT_COMPARTMENT_HAS_PDA, PTYPE_INT },
  { "has_smoke", CSTRUCT_COMPARTMENT_HAS_SMOKE, PTYPE_INT },
  { "has_steam", CSTRUCT_COMPARTMENT_HAS_STEAM, PTYPE_INT },
  { "has_suppression", CSTRUCT_COMPARTMENT_HAS_SUPPRESSION, PTYPE_INT },
  { "inescapable", CSTRUCT_COMPARTMENT_INESCAPABLE, PTYPE_INT },
  { "is_airlock", CSTRUCT_COMPARTMENT_IS_AIRLOCK, PTYPE_INT },
  { "is_passage", CSTRUCT_COMPARTMENT_IS_PASSAGE, PTYPE_INT },
  { "is_void", CSTRUCT_COMPARTMENT_IS_VOID, PTYPE_INT },
  { "is_weather", CSTRUCT_COMPARTMENT_IS_WEATHER, PTYPE_INT },
  { "soot", CSTRUCT_COMPARTMENT_SOOT, PTYPE_FLOAT },
  { "suppression_junction", CSTRUCT_COMPARTMENT_SUPPRESSION_JUNCTION, PTYPE_INT },
  { "temperature", CSTRUCT_COMPARTMENT_TEMPERATURE, PTYPE_FLOAT },
};
const struct IrmParamNameMap Compartment_canonicalNameMap[] = {
  { "accessible", CSTRUCT_COMPARTMENT_ACCESSIBLE, PTYPE_INT },
  { "agent_suppression", CSTRUCT_COMPARTMENT_AGENT_SUPPRESSION, PTYPE_INT },
  { "airlock_open", CSTRUCT_COMPARTMENT_AIRLOCK_OPEN, PTYPE_INT },
  { "chrr", CSTRUCT_COMPARTMENT_CHRR, PTYPE_FLOAT },
  { "collapse", CSTRUCT_COMPARTMENT_COLLAPSE, PTYPE_FLOAT },
  { "cten", CSTRUCT_COMPARTMENT_CTEN, PTYPE_INT },
  { "ctrans", CSTRUCT_COMPARTMENT_CTRANS, PTYPE_INT },
  { "cvis", CSTRUCT_COMPARTMENT_CVIS, PTYPE_FLOAT },
  { "exception", CSTRUCT_COMPARTMENT_HAS_EXCEPTION, PTYPE_INT },
  { "fire_size", CSTRUCT_COMPARTMENT_FIRE_SIZE, PTYPE_FLOAT },
  { "flooding", CSTRUCT_COMPARTMENT_FLOODING, PTYPE_FLOAT },
  { "has_abandon", CSTRUCT_COMPARTMENT_HAS_ABANDON, PTYPE_INT },
  { "has_debris", CSTRUCT_COMPARTMENT_HAS_DEBRIS, PTYPE_INT },
  { "has_exception", CSTRUCT_COMPARTMENT_HAS_EXCEPTION, PTYPE_INT },
  { "has_fire", CSTRUCT_COMPARTMENT_HAS_FIRE, PTYPE_INT },
  { "has_flood", CSTRUCT_COMPARTMENT_HAS_FLOOD, PTYPE_INT },
  { "has_hot", CSTRUCT_COMPARTMENT_HAS_HOT, PTYPE_INT },
  { "has_investigation", CSTRUCT_COMPARTMENT_HAS_INVESTIGATION, PTYPE_INT },
  { "has_pda", CSTRUCT_COMPARTMENT_HAS_PDA, PTYPE_INT },
  { "has_smoke", CSTRUCT_COMPARTMENT_HAS_SMOKE, PTYPE_INT },
  { "has_steam", CSTRUCT_COMPARTMENT_HAS_STEAM, PTYPE_INT },
  { "has_suppression", CSTRUCT_COMPARTMENT_HAS_SUPPRESSION, PTYPE_INT },
  { "inescapable", CSTRUCT_COMPARTMENT_INESCAPABLE, PTYPE_INT },
  { "is_airlock", CSTRUCT_COMPARTMENT_IS_AIRLOCK, PTYPE_INT },
  { "is_passage", CSTRUCT_COMPARTMENT_IS_PASSAGE, PTYPE_INT },
  { "is_void", CSTRUCT_COMPARTMENT_IS_VOID, PTYPE_INT },
  { "is_weather", CSTRUCT_COMPARTMENT_IS_WEATHER, PTYPE_INT },
  { "soot", CSTRUCT_COMPARTMENT_SOOT, PTYPE_FLOAT },
  { "suppression_junction", CSTRUCT_COMPARTMENT_SUPPRESSION_JUNCTION, PTYPE_INT },
  { "temperature", CSTRUCT_COMPARTMENT_TEMPERATURE, PTYPE_FLOAT },
};


/*
** Code for managing compartments in the simulator.  This information
** is used to compute crew escape.
*/

/*
** Routines from simnode.c that we need access to
*/
int SimLink_CalculateThermalEndurance(Roid id,double rTemp,double rFire);

/*
** All compartments indexed by Compartment.id
*/

static  inline int ifHigher(int oldvalue,int newvalue) {
   if(newvalue>oldvalue) {
      return newvalue;
   }
   return oldvalue;
}

static void CompartmentComputeAccessible(Compartment *p) {
  int lastAccess = p->public_accessible;
  p->public_accessible=0;
  /* If a compartment is not passable, it accessible = 3 */  
  /*
  ** RULE: compartment-has_pda-0001
  ** A [cstruct compartment] in state [cstruct compartment field has_pda]=1 is
  ** considered to be on fire and it's decking destroyed. This is intended to model
  ** a strike from a missile or other explosive.
  **
  ** RULE: compartment-has_pda-0002
  ** A [cstruct compartment] in state [cstruct compartment field has_pda]=2 is
  ** is in the area that would be affected by a shock event, and while likely to
  ** contain damaged equipment, will not impede crew movement
  */
  if (p->public_has_pda==1) {
    p->public_accessible=ifHigher(p->public_accessible,CurrentSim->public_crew_trans_pda);
  }
  if (p->public_has_flood) {
    p->public_accessible=ifHigher(p->public_accessible,CurrentSim->public_crew_trans_flood);
  }
  if (p->public_has_abandon) {
    p->public_accessible=ifHigher(p->public_accessible,CurrentSim->public_crew_trans_abandon);
  }
  if (p->public_has_smoke) {
    p->public_accessible=ifHigher(p->public_accessible,CurrentSim->public_crew_trans_smoke);
  }
  if (p->public_has_fire) {
     p->public_accessible=ifHigher(p->public_accessible,CurrentSim->public_crew_trans_fire);
  } else if (p->public_has_hot==2) {
     p->public_accessible=ifHigher(p->public_accessible,2); 
  } else if (p->public_has_hot==3) {
     p->public_accessible=ifHigher(p->public_accessible,3); 
  }
  
  /* If FSSMIX is running use its scores for cten and ctrans */
  if(p->public_cten || p->public_ctrans) {
    if(p->public_ctrans > 1) {
      p->public_accessible=ifHigher(p->public_accessible,1);
    }
    if (p->public_cten > 1) {
      p->public_accessible=ifHigher(p->public_accessible,p->public_cten);
    }
  }
  if(lastAccess != p->public_accessible) {
    p->changed=1;
  }
}

/*
** Functions provided by the template
*/
Compartment *Compartment_ById(Roid id, int createFlag) {
  /*
  ** Return a pointer to a Compartment with the given ID.  Return NULL
  ** if there is no such portal.  Create a new one if the createFlag
  ** is true and the portal does not previously exist.
  */
  Tcl_HashEntry *pEntry;
  int isNew;
  Compartment *p;

  pEntry=Tcl_FindHashEntry(&CurrentSim->CompartmentIdSet,(char *)id);
  if(pEntry) {
    return (Compartment*)Tcl_GetHashValue(pEntry);
  }
  if(!createFlag) {
    return NULL;
  }

  pEntry = Tcl_CreateHashEntry(&CurrentSim->CompartmentIdSet,(char *)id, &isNew);
  p = (Compartment *)local_Alloc( sizeof(*p) );
  p->id = id;
  p->public_cvis = 2000.0;
  if(!CurrentSim->GlobalSim) {
    p->pType=Entity_ById('c',p->id,1);
  } else {
    p->pType=Entity_ById('c',p->id,0);
  }
  Tcl_SetHashValue(pEntry,(ClientData)p);
  Compartment_StructAlloc(p);
  Compartment_Index(CurrentSim,p);
  return p;
}

Compartment *Compartment_ByName(char *idstring, int createFlag) {    
    Roid i=-1;
    i=Irm_RoidFromString(idstring,'c');
    
    if(i<0) {
      return NULL;
    }
    return Compartment_ById(i,createFlag);
  }

Tcl_HashEntry *Compartment_First(Simulator *sim,Tcl_HashSearch *search) {
    /*
    ** Return the first compartment in a list of them all
    */
    return Tcl_FirstHashEntry(&CurrentSim->CompartmentIdSet,search);
  }

Tcl_Obj *Compartment_GroupToTclObj(Compartment *pNode) {
    Roid groupid;
    if(!pNode) {
      return Tcl_NewBooleanObj(0);
    }
    groupid=Compartment_StructGetGroup(pNode);
    if(!groupid) {
      return Tcl_NewBooleanObj(0);
    }
    return Tcl_NewWideIntObj(groupid);
  }

Tcl_Obj *Compartment_Identify(Compartment *pNode) {
    if(!pNode) {
      return Tcl_NewWideIntObj(0);
    }
    return Tcl_NewWideIntObj(pNode->id);  
  }

Compartment *Compartment_Index_First(Simulator *sim) {
    return sim->Compartment_IndexAll;
  }

Tcl_Obj *Compartment_PublicId(Compartment *pNode) {
    char idstring[64];
    if(!pNode) {
      return Tcl_NewWideIntObj(0);
    }
    if(pNode->pType) {
      if(pNode->pType->name) {
        return Irm_NewStringObj(pNode->pType->name);
      }
    }
    sprintf(idstring,"c%d",pNode->id);
    return Irm_NewStringObj(idstring);  
  }

Tcl_Obj *Compartment_StructDictGet(Compartment *p,Tcl_Obj* key,int nulltype) {
    return Entity_ExportField(p->pType,NULL,Tcl_GetString(key),nulltype);
  }

Tcl_Obj *Compartment_StructGet(
  Compartment *pNode,
  int field
) {
  switch (field) {
    case CSTRUCT_COMPARTMENT_ACCESSIBLE: return Tcl_NewIntObj(pNode->public_accessible);
    case CSTRUCT_COMPARTMENT_HAS_EXCEPTION: return Tcl_NewIntObj(pNode->public_has_exception);
    case CSTRUCT_COMPARTMENT_IS_PASSAGE: return Tcl_NewIntObj(pNode->public_is_passage);
    case CSTRUCT_COMPARTMENT_COLLAPSE: {
        return IRM_NewFuzzyObj(pNode->public_collapse);
      }
      
    case CSTRUCT_COMPARTMENT_IS_VOID: return Tcl_NewIntObj(pNode->public_is_void);
    case CSTRUCT_COMPARTMENT_CHRR: {
        return IRM_NewFuzzyObj(pNode->public_chrr);
      }
      
    case CSTRUCT_COMPARTMENT_FLOODING: {
        return IRM_NewFuzzyObj(pNode->public_flooding);
      }
      
    case CSTRUCT_COMPARTMENT_CVIS: {
        return IRM_NewFuzzyObj(pNode->public_cvis);
      }
      
    case CSTRUCT_COMPARTMENT_INESCAPABLE: return Tcl_NewIntObj(pNode->public_inescapable);
    case CSTRUCT_COMPARTMENT_IS_WEATHER: return Tcl_NewIntObj(pNode->public_is_weather);
    case CSTRUCT_COMPARTMENT_IS_AIRLOCK: return Tcl_NewIntObj(pNode->public_is_airlock);
    case CSTRUCT_COMPARTMENT_CTEN: return Tcl_NewIntObj(pNode->public_cten);
    case CSTRUCT_COMPARTMENT_HAS_SUPPRESSION: return Tcl_NewIntObj(pNode->public_has_suppression);
    case CSTRUCT_COMPARTMENT_HAS_INVESTIGATION: return Tcl_NewIntObj(pNode->public_has_investigation);
    case CSTRUCT_COMPARTMENT_SOOT: {
        return IRM_NewFuzzyObj(pNode->public_soot);
      }
      
    case CSTRUCT_COMPARTMENT_SUPPRESSION_JUNCTION: return Tcl_NewIntObj(pNode->public_suppression_junction);
    case CSTRUCT_COMPARTMENT_HAS_ABANDON: return Tcl_NewIntObj(pNode->public_has_abandon);
    case CSTRUCT_COMPARTMENT_CTRANS: return Tcl_NewIntObj(pNode->public_ctrans);
    case CSTRUCT_COMPARTMENT_AGENT_SUPPRESSION: return Tcl_NewIntObj(pNode->public_agent_suppression);
    case CSTRUCT_COMPARTMENT_HAS_FIRE: return Tcl_NewIntObj(pNode->public_has_fire);
    case CSTRUCT_COMPARTMENT_HAS_DEBRIS: return Tcl_NewIntObj(pNode->public_has_debris);
    case CSTRUCT_COMPARTMENT_HAS_PDA: return Tcl_NewIntObj(pNode->public_has_pda);
    case CSTRUCT_COMPARTMENT_HAS_STEAM: return Tcl_NewIntObj(pNode->public_has_steam);
    case CSTRUCT_COMPARTMENT_HAS_HOT: return Tcl_NewIntObj(pNode->public_has_hot);
    case CSTRUCT_COMPARTMENT_AIRLOCK_OPEN: return Tcl_NewIntObj(pNode->public_airlock_open);
    case CSTRUCT_COMPARTMENT_TEMPERATURE: {
        return IRM_NewFuzzyObj(pNode->public_temperature);
      }
      
    case CSTRUCT_COMPARTMENT_FIRE_SIZE: {
        return IRM_NewFuzzyObj(pNode->public_fire_size);
      }
      
    case CSTRUCT_COMPARTMENT_HAS_FLOOD: return Tcl_NewIntObj(pNode->public_has_flood);
    case CSTRUCT_COMPARTMENT_HAS_SMOKE: return Tcl_NewIntObj(pNode->public_has_smoke);
  }

return NULL;
}

Entity *Compartment_StructGetType(Compartment *p) {
  if(p->pType) {
    return Entity_StructGetType(p->pType);
  }
  return NULL;
  }

Tcl_Obj *Compartment_StructToDict(Tcl_Interp *interp,Compartment *p,int virtual) {
    Tcl_Obj *pResult=NULL;
    int i;
    if (virtual) {
      pResult=Entity_GetDict(p->pType,NULL);
    }
    if(!pResult) {
      pResult=Tcl_NewObj();
    }
    /* Finaly, Add the Tcl Data */
    for(i=0;i<CSTRUCT_COMPARTMENT_Count;i++) {
      Tcl_Obj *newElement=Compartment_StructGet(p,i);
      Irm_DictObjPut(interp,pResult,Compartment_paramNameMap[i].zName,newElement);
    }
    if(virtual) {
      Compartment_StructAddLocation(interp,p,pResult);
    }
    return pResult;
  }

Tcl_Obj *Compartment_TypeToTclObj(Compartment *pNode) {
    Entity *pType;
    if(!pNode) {
      return Tcl_NewBooleanObj(0);
    }
    pType=Compartment_StructGetType(pNode);
    if(!pType) {
      return Tcl_NewBooleanObj(0);
    }
    return Tcl_NewWideIntObj(pType->id);
  }

void Compartment_ApplySettings(Compartment *p) {
  int exception=0;
  double tempC;
  p->changed=0;
  
  if (p->public_is_void) {
    p->public_accessible=3;
    p->public_has_exception=exception;
    return;
  }
  if(p->public_fire_size > 0.0 && p->public_has_fire < 1) {
    int fueltype=TypeSpec_GetInt(p->pType,"fssim_fuel_type");
    if(fueltype<0) {
      p->public_has_fire=0;
    } else if (fueltype>0) {
      p->public_has_fire=2;
    } else {
      p->public_has_fire=1;
    }
  }
  if(p->public_flooding > 0.2) {
    p->public_has_flood=1;
  }
  if(p->public_cvis <  CurrentSim->public_crew_detect_smoke) {
    p->public_has_smoke=1;
  } else {
    p->public_has_smoke=0;
  }
  tempC=p->public_temperature-273.15;
  if(tempC > CurrentSim->public_crew_detect_hot_3) {
    p->public_has_hot=3;
    exception=1;
  } else if (tempC > CurrentSim->public_crew_detect_hot_2) {
    p->public_has_hot=2;
    exception=1;
  } else if (tempC > CurrentSim->public_crew_detect_hot_1) {
    p->public_has_hot=1;
    exception=1;
  } else {
    p->public_has_hot=0;
  }
  
  CompartmentComputeAccessible(p);

  if(p->public_accessible != p->delta->public_accessible) {
    p->changed=1;
  }
  if(p->public_temperature != p->delta->public_temperature) {
    p->changed=1;
  }
  if(p->public_fire_size != p->delta->public_fire_size) {
    p->changed=1;
  }
  if(p->public_cvis != p->delta->public_cvis) {
    p->changed=1;
  }
  if(p->changed) {
    exception=1;
  }
  if(!p->public_is_void && p->public_accessible) {
    exception=1;
  }
  if(p->public_inescapable) exception=1;
  if(p->public_has_pda) exception=1;
  if(p->public_has_flood) exception=1;
  if(p->public_has_fire) exception=1;
  if(p->public_has_smoke) exception=1;
  if(p->public_has_abandon) exception=1;
  if(p->public_has_investigation) exception=1;
  if(p->public_has_steam) exception=1;

  if(p->public_cten > 0) exception=1;
  if(p->public_ctrans > 0) exception=1;
  if(p->public_chrr > 0.0 ) exception=1;
  
  if(p->public_has_suppression) exception=1;
  p->public_has_exception=exception;
}

int Compartment_Compare(Compartment *a,Compartment *b) {
    if(!a && !b) {
      return 0;
    }
    if(!b) {
      return 1;
    }
    if(!a) {
      return -1;
    }
    if(b->id>a->id) {
      return -1;
    }
    if(a->id>b->id) {
      return 1;
    }
    return 0;
  }

int Compartment_FromTclObj(Tcl_Interp *interp, Tcl_Obj *pObj, Compartment **ppCompartment) {
    /*
    ** Find a Compartment given a Tcl_Obj that contains the Compartment ID.
    ** Leave an error message in interp and return TCL_ERROR if anything
    ** goes wrong.
    */
    Roid i=-1;
    i=Irm_RoidFromString(Tcl_GetString(pObj),'c');
    
    if(i<0) {
      if(interp) {
        Tcl_AppendResult(interp, "no such Compartment: ",
          Tcl_GetStringFromObj(pObj, 0),  0);
      }
    }
    *ppCompartment = Compartment_ById(i, 0);
    if( *ppCompartment==0 ){
      if(interp) {
        Tcl_AppendResult(interp, "no such Compartment: ",
        Tcl_GetStringFromObj(pObj, 0),  0);
      }
      return TCL_ERROR;
    }
    return TCL_OK;
  }

void Compartment_Index(Simulator *sim,Compartment *p) {
    Compartment *i,*iPrev;
    p->pNextAll=NULL;
    /*
    ** Index the node
    */
    if(!sim->Compartment_IndexAll) {
      /*
      ** Perform a head insertion if the list is empty
      */
      p->pNextAll=sim->Compartment_IndexAll;
      sim->Compartment_IndexAll=p;
      return;
    }
    if(Compartment_Compare(p,sim->Compartment_IndexAll)<0) {
      /*
      ** Perform a head insertion if this node
      ** is less than the head node
      */
      p->pNextAll=sim->Compartment_IndexAll;
      sim->Compartment_IndexAll=p;
      return;
    }
    iPrev=sim->Compartment_IndexAll;
    for(i=iPrev;i;i=i->pNextAll) {
      if(Compartment_Compare(i,p)>0) {
        p->pNextAll=i;
        iPrev->pNextAll=p;
        return;
      }
      iPrev=i;
    }
    /*
    ** If we have gotten this far, do a tail
    ** insertion
    */
    iPrev->pNextAll=p;
  }

void Compartment_Index_Rebuild(Simulator *sim) {
    Tcl_HashSearch search;
    Tcl_HashEntry *i;
    CurrentSim->Compartment_IndexAll=NULL;
    for(i=Compartment_First(CurrentSim,&search); i ; i = Tcl_NextHashEntry(&search)) {
      Compartment *p = (Compartment *)Tcl_GetHashValue(i);
      p->pNextAll=NULL;
    }
    for(i=Compartment_First(CurrentSim,&search); i ; i = Tcl_NextHashEntry(&search)) {
      Compartment *p = (Compartment *)Tcl_GetHashValue(i);
      Compartment_Index(CurrentSim,p);
    }
  }

void Compartment_Module_Advance(Simulator *ActiveSim,int clocktime) {
  Tcl_HashSearch search;
  Tcl_HashEntry *i;

  for(i=Compartment_First(ActiveSim,&search); i ; i = Tcl_NextHashEntry(&search)) {
    Compartment *p = (Compartment *)Tcl_GetHashValue(i);
    memcpy(p->delta,p,sizeof(*p));
  }
  }

void Compartment_Module_Free(Simulator *sim) {
  /*
  ** Reset the compartment map
  */
  Tcl_HashSearch searchPtr;
  Tcl_HashEntry *i;

  if(!sim->module_compartment) return;
  
  for(i=Compartment_First(sim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
    Compartment *p = (Compartment*)Tcl_GetHashValue(i);
    if(p->kidlist) {
       local_Free((char *)p->kidlist);
    }
    Compartment_StructFree(p);
    local_Free((char *)p);
  }
  for(i=Portal_First(sim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
    Portal *p = (Portal*)Tcl_GetHashValue(i);
    Portal_StructFree(p);
    local_Free((char *)p);
  }
  Tcl_DeleteHashTable(&sim->PortalIdSet);
  Tcl_DeleteHashTable(&sim->CompartmentIdSet);
  sim->Compartment_IndexAll=NULL;
  sim->module_compartment=0;
}

void Compartment_Module_Init(Simulator *sim) {
  Compartment *external;

  if(sim->module_compartment) return;

  Tcl_InitHashTable(&sim->CompartmentIdSet, TCL_ONE_WORD_KEYS);
  /* Build an entry for external */
  Tcl_InitHashTable(&sim->PortalIdSet, TCL_ONE_WORD_KEYS);
  sim->NextHoleId=SYNTHETIC_START;
  sim->pSubcompt = 0;
  sim->Compartment_IndexAll=NULL;
  external=Compartment_ById(-1,1);
  external->public_is_weather=1;
  sim->module_compartment=0;
}

void Compartment_Module_Rewind(Simulator *sim) {
  Tcl_HashSearch searchPtr;
  Tcl_HashEntry *i;
  Compartment *pCompt;

  for(i=Portal_First(sim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
    Portal *p = (Portal*)Tcl_GetHashValue(i);
    Portal_Repair(p,1);
  }
  Compartment_Index_Rebuild(sim);

  for(pCompt=sim->Compartment_IndexAll; pCompt ; pCompt=pCompt->pNextAll) {
    Compartment_Repair(pCompt,1);
  }
}

void Compartment_Node_GetLink(Tcl_Obj *pResult,Compartment *pNode,char *linktype) {
  if(linktype==NULL) {
    if(pNode->pType->pType) {
      Tcl_ListObjAppendElement(NULL, pResult, Irm_NewStringObj("type"));
      Tcl_ListObjAppendElement(NULL, pResult, Entity_Identify(pNode->pType->pType));      
    }
    if(pNode->pType->gType) {
      Tcl_ListObjAppendElement(NULL, pResult, Irm_NewStringObj("group"));
      Tcl_ListObjAppendElement(NULL, pResult, Entity_Identify(pNode->pType->gType));      
    }
  }
}

int Compartment_nodeeval(Tcl_Interp *interp,Compartment *p,Tcl_Obj *body,int writeback) {
    Tcl_Obj *id;
    //Tcl_Obj *pValueDict;
    int i;
    Tcl_Obj **varv;
    int varc,result;
    
    
    Compartment_StructWith(interp,p,1);
    /*
    if (Tcl_ListObjGetElements(interp, pValueDict, &varc, &varv) != TCL_OK) {
        return TCL_ERROR;
    }
    for(i=0;i<varc;i+=2) {
      //Tcl_IncrRefCount(varv[i+1]);
      Tcl_ObjSetVar2(interp, varv[i], (Tcl_Obj *)NULL, varv[i+1], 0);
    }
    */
    id=Compartment_Identify(p);
    Tcl_ObjSetVar2(interp,Irm_NewStringObj("id"),NULL,id,0);
    Tcl_ObjSetVar2(interp,Irm_NewStringObj("typeid"),NULL,Compartment_TypeToTclObj(p),0);
    Tcl_ObjSetVar2(interp,Irm_NewStringObj("groupid"),NULL,Compartment_GroupToTclObj(p),0);
    /*Tcl_ObjSetVar2(interp,Irm_NewStringObj("config_dict"),NULL,Tcl_DuplicateObj(pValueDict),0);*/
  
    result=Tcl_EvalObjEx(interp, body, 0);

    if(result!=TCL_OK) {
      #ifdef NEVER
      if(pValueDict) {
        Tcl_DecrRefCount(pValueDict);
      }
      #endif
      return result;
    }
    #ifdef NEVER
    if(writeback){
      /*
      ** Read values back into the dict
      ** For now, we limit writeback to state variables
      ** And we don't care about garbage values
      */
      for(i=0;i<varc;i+=2) {
        Tcl_Obj *newValue;
        int offset;
        int type;
        newValue=Tcl_ObjGetVar2(interp,varv[i],(Tcl_Obj*)NULL,0);
        if(newValue==varv[i+1]) {
           /* Undocumented, unsanctioned, but it works in practice
           ** If the pointer hasn't changed, neither has the value
           */
           continue;
        }
        if(!newValue) {
          /* Variable must have been unset... move along */
          continue;
        }
        if( Compartment_StructValueOffset(0, varv[i], &offset, &type) == TCL_OK ) {
            Compartment_StructSet(interp,p,offset,newValue);
        } else {
          Compartment_SpecDictPut(p,varv[i],newValue);
        }
      }
      Compartment_ApplySettings(p);
    }
    if(pValueDict) {
      Tcl_DecrRefCount(pValueDict);
    }
    #endif
    return TCL_OK;
  }

void Compartment_Repair(Compartment *p, int revert) {
  p->public_airlock_open=0;
  p->public_chrr=0.0;
  p->public_collapse=0.0;
  p->public_ctrans=0;
  p->public_cten=0;
  p->public_cvis=2000;
  p->public_fire_size=0.0;
  p->public_flooding=0.0;
  p->public_has_abandon=0;
  p->public_has_fire=0;
  p->public_has_flood=0;
  p->public_has_hot=0;
  p->public_has_investigation=0;
  p->public_has_pda=0;
  p->public_inescapable=0;
  p->public_has_smoke=0;
  p->public_has_suppression=0;
  p->public_has_steam=0;
  p->public_soot=0.0;
  p->public_suppression_junction=0;
  p->public_temperature=300.0;
  CompartmentComputeAccessible(p);
}

void Compartment_Rewind(Compartment *p, int revert) {
  }

void Compartment_SpecDictClear(Compartment *p,Tcl_Obj *key,Tcl_Obj *value) {
    if(p->pType) {
      Irm_DictFree(p->pType->infoDict);
      p->pType->infoDict=NULL;
    }
  }

void Compartment_SpecDictPut(Compartment *p,Tcl_Obj *key,Tcl_Obj *value) {
    if(p->pType) {
      Irm_DictPut(&p->pType->infoDict,Tcl_GetString(key),value);
    }
  }


/*
** Add a key/value list describing the location of this object
*/
IRM_INLINE void Compartment_StructAddLocation(
  Tcl_Interp *interp,Compartment *pNode, Tcl_Obj *pValueDict
) {
  /* Default empty implementation from generic template */
}

void Compartment_StructAlloc(Compartment *p) {
  if (!p->delta) {
    p->delta=(Compartment *) local_Alloc(sizeof(*p));
    memcpy(p->delta,p,sizeof(*p));
  } 
}

int Compartment_StructChanged(Compartment *pNode,int field, int embargo, int force) {

    if(field < 0) return 0;
    if(field > CSTRUCT_COMPARTMENT_Count)
      return 0;
    if(!pNode->delta) force=1;
    /* No Photo, no comment */
  
  switch (field) {
    case CSTRUCT_COMPARTMENT_ACCESSIBLE:

          if (force || pNode->public_accessible != pNode->delta->public_accessible) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_IS_PASSAGE:

          if (force || pNode->public_is_passage != pNode->delta->public_is_passage) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_COLLAPSE:
          if(force) {
            return !IRM_Real_Is_Zero(pNode->public_collapse);
          } else {
            if(pNode->public_collapse != pNode->delta->public_collapse) {
              return 1;
            }
            return 0;
          }
          
    case CSTRUCT_COMPARTMENT_IS_VOID:

          if (force || pNode->public_is_void != pNode->delta->public_is_void) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_CHRR:
          if(force) {
            return !IRM_Real_Is_Zero(pNode->public_chrr);
          } else {
            if(pNode->public_chrr != pNode->delta->public_chrr) {
              return 1;
            }
            return 0;
          }
          
    case CSTRUCT_COMPARTMENT_FLOODING:
          if(force) {
            return !IRM_Real_Is_Zero(pNode->public_flooding);
          } else {
            if(pNode->public_flooding != pNode->delta->public_flooding) {
              return 1;
            }
            return 0;
          }
          
    case CSTRUCT_COMPARTMENT_CVIS:
          if(force) {
            return !IRM_Real_Is_Zero(pNode->public_cvis);
          } else {
            if(pNode->public_cvis != pNode->delta->public_cvis) {
              return 1;
            }
            return 0;
          }
          
    case CSTRUCT_COMPARTMENT_INESCAPABLE:

          if (force || pNode->public_inescapable != pNode->delta->public_inescapable) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_IS_WEATHER:

          if (force || pNode->public_is_weather != pNode->delta->public_is_weather) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_IS_AIRLOCK:

          if (force || pNode->public_is_airlock != pNode->delta->public_is_airlock) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_CTEN:

          if (force || pNode->public_cten != pNode->delta->public_cten) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_HAS_SUPPRESSION:

          if (force || pNode->public_has_suppression != pNode->delta->public_has_suppression) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_HAS_INVESTIGATION:

          if (force || pNode->public_has_investigation != pNode->delta->public_has_investigation) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_SOOT:
          if(force) {
            return !IRM_Real_Is_Zero(pNode->public_soot);
          } else {
            if(pNode->public_soot != pNode->delta->public_soot) {
              return 1;
            }
            return 0;
          }
          
    case CSTRUCT_COMPARTMENT_SUPPRESSION_JUNCTION:

          if (force || pNode->public_suppression_junction != pNode->delta->public_suppression_junction) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_HAS_ABANDON:

          if (force || pNode->public_has_abandon != pNode->delta->public_has_abandon) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_CTRANS:

          if (force || pNode->public_ctrans != pNode->delta->public_ctrans) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_AGENT_SUPPRESSION:

          if (force || pNode->public_agent_suppression != pNode->delta->public_agent_suppression) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_HAS_FIRE:

          if (force || pNode->public_has_fire != pNode->delta->public_has_fire) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_HAS_DEBRIS:

          if (force || pNode->public_has_debris != pNode->delta->public_has_debris) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_HAS_PDA:

          if (force || pNode->public_has_pda != pNode->delta->public_has_pda) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_HAS_STEAM:

          if (force || pNode->public_has_steam != pNode->delta->public_has_steam) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_HAS_HOT:

          if (force || pNode->public_has_hot != pNode->delta->public_has_hot) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_AIRLOCK_OPEN:

          if (force || pNode->public_airlock_open != pNode->delta->public_airlock_open) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_TEMPERATURE:
          if(force) {
            return !IRM_Real_Is_Zero(pNode->public_temperature);
          } else {
            if(pNode->public_temperature != pNode->delta->public_temperature) {
              return 1;
            }
            return 0;
          }
          
    case CSTRUCT_COMPARTMENT_FIRE_SIZE:
          if(force) {
            return !IRM_Real_Is_Zero(pNode->public_fire_size);
          } else {
            if(pNode->public_fire_size != pNode->delta->public_fire_size) {
              return 1;
            }
            return 0;
          }
          
    case CSTRUCT_COMPARTMENT_HAS_FLOOD:

          if (force || pNode->public_has_flood != pNode->delta->public_has_flood) {
            return 1;
          }
          return 0;
          
    case CSTRUCT_COMPARTMENT_HAS_SMOKE:

          if (force || pNode->public_has_smoke != pNode->delta->public_has_smoke) {
            return 1;
          }
          return 0;
          
  }
  return 0;
}

void Compartment_StructFree(Compartment *p) {
  if (p->delta) {
    IRM_Free((char *)p->delta);
    p->delta=NULL;
  }
}


/*
** Free memory the was allocated internally by the data
** structure
*/
IRM_INLINE void Compartment_StructFree_Private(
  Compartment *p
) {

}

Roid Compartment_StructGetGroup(Compartment *p) {
  if(p->pType) {
    return Entity_StructGetGroup(p->pType);
  }
  return 0;
  }

void Compartment_StructLocation(Irm_Location *lstruct,Compartment *p) {
  CrewRoute_ComptCenter(p->id,0,lstruct);
}

int Compartment_StructSet(
  Tcl_Interp *interp,
  Compartment *pNode,
  int field,
  Tcl_Obj *value
) {
 
  if(field < 0 ) {
    return TCL_ERROR;
  }

  switch (field) {
    case CSTRUCT_COMPARTMENT_ACCESSIBLE: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_accessible=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_HAS_EXCEPTION: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_exception=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_IS_PASSAGE: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_is_passage=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_COLLAPSE: {
        double floatValue;
        if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
        pNode->public_collapse=(IrmReal)floatValue;
        return TCL_OK;
        }
    case CSTRUCT_COMPARTMENT_IS_VOID: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_is_void=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_CHRR: {
        double floatValue;
        if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
        pNode->public_chrr=(IrmReal)floatValue;
        return TCL_OK;
        }
    case CSTRUCT_COMPARTMENT_FLOODING: {
        double floatValue;
        if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
        pNode->public_flooding=(IrmReal)floatValue;
        return TCL_OK;
        }
    case CSTRUCT_COMPARTMENT_CVIS: {
        double floatValue;
        if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
        pNode->public_cvis=(IrmReal)floatValue;
        return TCL_OK;
        }
    case CSTRUCT_COMPARTMENT_INESCAPABLE: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_inescapable=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_IS_WEATHER: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_is_weather=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_IS_AIRLOCK: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_is_airlock=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_CTEN: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_cten=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_HAS_SUPPRESSION: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_suppression=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_HAS_INVESTIGATION: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_investigation=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_SOOT: {
        double floatValue;
        if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
        pNode->public_soot=(IrmReal)floatValue;
        return TCL_OK;
        }
     case CSTRUCT_COMPARTMENT_SUPPRESSION_JUNCTION: {
            Tcl_WideInt wideValue;
            if(Tcl_GetWideIntFromObj(interp,value,&wideValue)) return TCL_ERROR;
            pNode->public_suppression_junction=(Roid)wideValue;
            return TCL_OK;
        }
    case CSTRUCT_COMPARTMENT_HAS_ABANDON: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_abandon=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_CTRANS: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_ctrans=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_AGENT_SUPPRESSION: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_agent_suppression=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_HAS_FIRE: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_fire=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_HAS_DEBRIS: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_debris=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_HAS_PDA: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_pda=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_HAS_STEAM: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_steam=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_HAS_HOT: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_hot=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_AIRLOCK_OPEN: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_airlock_open=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_TEMPERATURE: {
        double floatValue;
        if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
        pNode->public_temperature=(IrmReal)floatValue;
        return TCL_OK;
        }
    case CSTRUCT_COMPARTMENT_FIRE_SIZE: {
        double floatValue;
        if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
        pNode->public_fire_size=(IrmReal)floatValue;
        return TCL_OK;
        }
    case CSTRUCT_COMPARTMENT_HAS_FLOOD: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_flood=intValue;
          return TCL_OK;
          }
    case CSTRUCT_COMPARTMENT_HAS_SMOKE: {
          int intValue;
          double floatValue;
          if(Tcl_GetIntFromObj(interp,value,&intValue)) {
            Tcl_ResetResult(interp);
            if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
            intValue=(int)floatValue;
          }
          pNode->public_has_smoke=intValue;
          return TCL_OK;
          }
  }
  return TCL_OK;
}

void Compartment_StructSetGroup(Compartment *p,Roid groupid) {
  Entity_StructSetGroup(p->pType,groupid);  
  }

void Compartment_StructSetType(Compartment *p,Entity *pType) {
  if(!p->pType) {
    return;
  }
  Entity_StructSetType(p->pType,pType);
  }

IRM_INLINE int Compartment_StructValueOffset(
  Tcl_Interp *interp,
  Tcl_Obj *pObj,
  int *pIndex,
  int *pType
) {
  /*
  ** Given the name of one of the arState[] values in the Compartment structure,
  ** return the index of the particular arState[].  Return TCL_OK.
  **
  ** Leave an error message in interp and return TCL_ERROR if
  ** anything goes wrong.
  */

  int lo, hi, mid, c, max, i;
  int nName;
  const char *zName;
  const struct IrmParamNameMap *aParam = Compartment_canonicalNameMap;

  lo = 0;
  hi = max = CSTRUCT_COMPARTMENT_AliasCount - 1;
  zName = Tcl_GetStringFromObj(pObj, &nName);
  mid = (lo+hi)/2;
  if(nName>32) {
    nName=32;
  }
  while( lo<=hi ){
    mid = (lo+hi)/2;
    c = strncmp(zName, aParam[mid].zName, nName);
    if( c<0 ){
      hi = mid-1;
    }else if( c>0 ){
      lo = mid+1;
    }else if( 
      (mid>0 && strncmp(zName, aParam[mid-1].zName, nName)==0) ||
      (mid<max && strncmp(zName, aParam[mid+1].zName, nName)==0)
    ){
      i = mid;
      while( i>0 && strncmp(zName, aParam[i-1].zName, nName)==0 ){
        i--;
      }
      if( strlen(aParam[i].zName)==nName ){
        *pIndex = aParam[i].iCode;
        *pType = aParam[i].pType;
        return TCL_OK;
      }
      if(interp) {
        Tcl_AppendResult(interp, "ambiguous parameter:", 0);
        do{
          Tcl_AppendResult(interp, " ", aParam[i++].zName, 0);
        }while( i<=max && strncmp(zName, aParam[i].zName, nName)==0 );
      }
      return TCL_ERROR;
    }else{
      *pIndex = aParam[mid].iCode;
      *pType = aParam[mid].pType;
      return TCL_OK;
    }
  }
  if(interp) {
    Tcl_AppendResult(interp, "unknown parameter \"", zName,
            "\" - nearby choices:", 0);
    for(i=mid-3; i<mid+3; i++){
      if( i<0 || i>max ) continue;
      Tcl_AppendResult(interp, " ", aParam[i].zName, 0);
    }
  }
  return TCL_ERROR;
}

void Compartment_StructWith(Tcl_Interp *interp,Compartment *p,int virtual) {
    int i;
    if (virtual) {
      Entity_With(interp,p->pType,NULL);
    }
    /* Finaly, Add the Tcl Data */
    for(i=0;i<CSTRUCT_COMPARTMENT_Count;i++) {
      Tcl_Obj *newElement=Compartment_StructGet(p,i);
      Tcl_ObjSetVar2(interp,Irm_NewStringObj(Compartment_paramNameMap[i].zName),NULL,newElement,0);
    }
    if(virtual) {
      Compartment_StructWithLocation(interp,p);
    }
  }

IRM_INLINE void Compartment_StructWithLocation(
  Tcl_Interp *interp,Compartment *pNode
) {
  /* Default empty implementation from generic template */
}

static int Compartment_method_add (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Roid id;
  Compartment *p;
  Entity *pType=NULL;
  
  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID ?typeid?");
    return TCL_ERROR;
  }
  if( Tcl_GetIntFromObj(interp, objv[1], &id) ) return TCL_ERROR;
  if( id<=0 ){
    Tcl_AppendResult(interp, "compartment ID must be 1 or greater", 0);
    return TCL_ERROR;
  }
  p=Compartment_ById(id,1);
  if(objc==3) {
    if( SimType_FromTclObj(interp, objv[2], &pType) ) return TCL_ERROR;
    Compartment_StructSetType(p,pType);
  }
  Compartment_Repair(p,1);
  return TCL_OK;
}

static int Compartment_method_cid (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;  
  if( objc!=2 ) {
    Tcl_WrongNumArgs(interp, 1, objv, "ID");
    return TCL_ERROR; 
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) {
    Tcl_ResetResult(interp);
    Tcl_SetObjResult(interp, Tcl_NewIntObj(0));  
    return TCL_OK;
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(p->id));
  return TCL_OK;  
}

static int Compartment_method_condition (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Tcl_Obj *pResult;
  if( objc!=2 ) {
    Tcl_WrongNumArgs(interp, 1, objv, "ID");
    return TCL_ERROR; 
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  pResult=Tcl_NewObj();
  CompartmentComputeAccessible(p);

  Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(p->public_accessible));
  if(p->public_is_void) {
    Tcl_ListObjAppendElement(interp, pResult, Irm_NewStringObj("void"));
  }
  if(p->public_has_pda) {
    Tcl_ListObjAppendElement(interp, pResult, Irm_NewStringObj("pda"));
  }
  if(p->public_has_flood) {
    Tcl_ListObjAppendElement(interp, pResult, Irm_NewStringObj("flood"));
  }
  if(p->public_has_fire>0 && p->public_has_fire<8 ) {
    Tcl_ListObjAppendElement(interp, pResult, Irm_NewStringObj("fire"));
  }
  if(p->public_has_smoke) {
    Tcl_ListObjAppendElement(interp, pResult, Irm_NewStringObj("smoke"));
  }
  if(p->public_has_abandon) {
    Tcl_ListObjAppendElement(interp, pResult, Irm_NewStringObj("abandon"));
  }
  if(p->public_cten > 1) {
    Tcl_ListObjAppendElement(interp, pResult, Irm_NewStringObj("cten"));
  }
  if(p->public_ctrans > 1) {
    Tcl_ListObjAppendElement(interp, pResult, Irm_NewStringObj("ctrans"));
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;
}

static int Compartment_method_count (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Tcl_HashSearch search;
  Tcl_HashEntry *i;
  int count=0;
  for(i=Compartment_First(CurrentSim,&search); i ; i = Tcl_NextHashEntry(&search)) {
    count++;
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(count));
  return TCL_OK;
}

static int Compartment_method_exists (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Tcl_Obj *pResult;
  char name[64];
  
  if( objc!=2 && objc!=3 && objc!=4 ) {
    Tcl_WrongNumArgs(interp, 1, objv, "ID ?idvar? ?namevar?");
    return TCL_ERROR; 
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) {
    Tcl_ResetResult(interp);
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
    return TCL_OK;
  }
  sprintf(name,"c%d",p->id);
  pResult=Tcl_NewStringObj(name,-1);
  if(objc>2) {
    Tcl_ObjSetVar2(interp, objv[2], NULL, Tcl_NewIntObj(p->id), 0);
  }
  if(objc==4) {
    Tcl_ObjSetVar2(interp, objv[3], NULL, pResult, 0);
  }
  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
  return TCL_OK;  
}

static int Compartment_method_flooding (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  double rFlow = 0.0;
  int comptid_valid = 0;
  Roid comptid=-1;
  Roid min_comptid;
  SimNode *pNode;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "COMPTID");
    return TCL_ERROR;
  }
  if( Tcl_GetIntFromObj(interp, objv[1], &min_comptid) ) return TCL_ERROR;
  for(pNode=SimNode_Index_First(CurrentSim); pNode; pNode=pNode->pNextAll) {
    if( pNode->public_compartment<min_comptid ||
            (comptid_valid && pNode->public_compartment>comptid) ) continue;
    if( pNode->public_compartment!=comptid ){
      comptid = pNode->public_compartment;
      comptid_valid = 1;
      rFlow = 0.0;
    }
    rFlow += pNode->public_water_to_deck;
    rFlow += pNode->public_fuel_to_deck;
  }
  if( comptid_valid && rFlow != 0.0){
    Tcl_Obj *pResult = Tcl_NewObj();
    Tcl_ListObjAppendElement(0, pResult, Tcl_NewWideIntObj(comptid));
    Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(rFlow));
    Tcl_SetObjResult(interp, pResult);
  }
  return TCL_OK;
}

static int Compartment_method_for (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Tcl_HashSearch *searchPtr;
  Tcl_HashEntry *i;
  int searchresult=TCL_OK;

  Tcl_Obj *keyvar;
  Tcl_Obj *infovar=NULL;
  Tcl_Obj *body;

  if( objc != 3 && objc != 4){
    Tcl_WrongNumArgs(interp, 1, objv, "keyvar ?valvar? body");
    return TCL_ERROR;
  }

  keyvar=objv[1];
  if (objc == 4) {
    infovar=objv[2];
    body=objv[3];
  } else {
    body=objv[3];
  }
  Tcl_IncrRefCount(keyvar);
  Tcl_IncrRefCount(body);
  if(infovar) {
    Tcl_IncrRefCount(infovar);
  }
  searchresult=TCL_OK;
  searchPtr=(Tcl_HashSearch *)local_Alloc(sizeof(Tcl_HashSearch));
  for(i=Compartment_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
    Compartment *p = (Compartment *)Tcl_GetHashValue(i);
    Tcl_ObjSetVar2(interp, keyvar, (Tcl_Obj *)NULL, Compartment_Identify(p), 0);
    if(infovar) {
      Tcl_ObjSetVar2(interp, infovar, (Tcl_Obj *)NULL, Compartment_StructToDict(interp,p,1), 0);
    }
    searchresult=Tcl_EvalObjEx(interp,body,0);
    if (searchresult !=TCL_OK && searchresult!=TCL_CONTINUE) {
      break;
    }
  }
  Tcl_DecrRefCount(keyvar);
  if(infovar) {
    Tcl_DecrRefCount(infovar);
  }
  Tcl_DecrRefCount(body);
  Tcl_Free((char *)searchPtr);
  return searchresult;
}

static int Compartment_method_foreach (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Tcl_HashSearch *searchPtr;
  Tcl_HashEntry *i;
  int searchresult=TCL_OK;
  Tcl_Obj *body;

  if( objc != 2){
    Tcl_WrongNumArgs(interp, 1, objv, "body");
    return TCL_ERROR;
  }
  body=objv[1];
  searchPtr=(Tcl_HashSearch *)local_Alloc(sizeof(Tcl_HashSearch));
  for(i=Compartment_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
    Compartment *p = (Compartment *)Tcl_GetHashValue(i);
    searchresult=Compartment_nodeeval(interp,p,body,0);
    if (searchresult !=TCL_OK && searchresult!=TCL_CONTINUE) {
      Tcl_Free((char *)searchPtr);
      return searchresult;
    }
  }
  Tcl_Free((char *)searchPtr);
  return TCL_OK;
}

static int Compartment_method_groupid (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Roid groupid=0;
  if( objc!=2 && objc != 3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID ?groupid?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) {
    Tcl_ResetResult(interp);
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
    return TCL_OK;
  }
  if(objc==3) {
    if(Tcl_GetIntFromObj(interp,objv[2],&groupid)) {
      return TCL_ERROR;
    }
    Compartment_StructSetGroup(p,groupid);
  }
  groupid=Compartment_StructGetGroup(p);
  if(groupid>0) {
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(groupid));
  } else {
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
  }
  return TCL_OK;
}

static int Compartment_method_kidlist (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  
  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID ?LISTOFKIDS?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  /* Ensure we have a list of integers */

  if(objc==2 && p->kidlist) {
    Tcl_Obj *pResult=Tcl_NewObj();
    int i;
    for(i=1;i<=p->kidlist[0];i++) {
      Tcl_ListObjAppendList(interp,pResult,Tcl_NewIntObj(p->kidlist[i]));
    }
    Tcl_SetObjResult(interp, pResult);
    return TCL_OK;
  }
  if(objc==3) {
    int i,n;
    Tcl_Obj *element;
    if(Tcl_ListObjLength(interp,objv[2],&n)) return TCL_ERROR;
    if(n==0) {
      /* If zero, empty our list */
      if(p->kidlist) {
        local_Free((char *)p->kidlist);
        p->kidlist=NULL;
      }
      return TCL_OK;
    }
    if(p->kidlist) {
      p->kidlist=(Roid *)Tcl_Realloc((char *)p->kidlist,sizeof(Roid)*(n+1));
    } else {   
      p->kidlist=(Roid *)local_Alloc(sizeof(Roid)*(n+1));
    }
    p->kidlist[0]=n;
    for(i=0;i<n;i++) {
      int j=i+1;
      int value;
      if(Tcl_ListObjIndex(interp, objv[2], i, &element)) return TCL_ERROR;
      if(Tcl_GetIntFromObj(interp,element,&value)) return TCL_ERROR;
      p->kidlist[j]=(Roid)value;
    }
    Tcl_SetObjResult(interp, Tcl_NewIntObj(n));
  }
  return TCL_OK;  
}

static int Compartment_method_list (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Tcl_Obj *pResult = Tcl_NewObj();
  Tcl_HashSearch search;
  Tcl_HashEntry *i;
  for(i=Compartment_First(CurrentSim,&search); i ; i = Tcl_NextHashEntry(&search)) {
    Compartment *p = (Compartment *)Tcl_GetHashValue(i);
    Tcl_ListObjAppendElement(interp, pResult, Compartment_Identify(p));
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;
}

static int Compartment_method_list_changed (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
Tcl_HashSearch searchPtr;
  Tcl_HashEntry *i;
  Tcl_Obj *pResult=Tcl_NewObj();
  
  for(i=Compartment_First(CurrentSim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
    Compartment *p = (Compartment*)Tcl_GetHashValue(i);
    if(p->changed) {
      Tcl_ListObjAppendElement(interp, pResult, Compartment_Identify(p));
    }
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;
}

static int Compartment_method_list_crew (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Roid comptid;
  Tcl_HashSearch searchPtr;
  Tcl_HashEntry *i;
  int exception=0;
  Tcl_Obj *pResult=Tcl_NewObj();

  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "COMPTID ?only_exceptional?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) {
    return TCL_ERROR;
  }
  comptid=p->id;
  if(objc==3) {
    if( Tcl_GetIntFromObj(interp, objv[2], &exception) ) return TCL_ERROR;
  }
  for(i=Crew_First(CurrentSim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
    Crew *pNode = (Crew*)Tcl_GetHashValue(i);
    if( pNode->public_compartment != comptid && pNode->public_compartment_entering != comptid) continue;
    if( exception && !pNode->public_has_exception ) {
      continue;
    }
    Tcl_ListObjAppendElement(interp, pResult, Tcl_NewWideIntObj(pNode->id));
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;
}

static int Compartment_method_list_detectors (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Roid comptid;
  Compartment *p;
  SimNode *pNode;
  Tcl_Obj *pResult=Tcl_NewObj();
  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "COMPTID");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) {
    return TCL_ERROR;
  }
  comptid=p->id;
  for(pNode=SimNode_Index_First(CurrentSim); pNode; pNode=pNode->pNextAll) {
    if( !pNode->isDetector || pNode->public_compartment != comptid ) continue;
    Tcl_ListObjAppendElement(interp, pResult, Tcl_NewWideIntObj(pNode->id));
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;  
}

static int Compartment_method_list_eqpt (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  int exception=0;
  Roid comptid;
  Compartment *p;
  SimNode *pNode;
  
  Tcl_Obj *pResult=Tcl_NewObj();
  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "COMPTID ?only_exceptional?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) {
    return TCL_ERROR;
  }
  comptid=p->id;
  if(objc==3) {
    if( Tcl_GetIntFromObj(interp, objv[1], &exception) ) return TCL_ERROR;
  }
  for(pNode=SimNode_Index_First(CurrentSim); pNode; pNode=pNode->pNextAll) {
    if( pNode->public_compartment != comptid ) continue;
    if( exception && !pNode->public_has_exception ) continue;
    Tcl_ListObjAppendElement(interp, pResult, Tcl_NewWideIntObj(pNode->id));
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;  
}

static int Compartment_method_list_exception (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
Tcl_HashSearch searchPtr;
  Tcl_HashEntry *i;
  Tcl_Obj *pResult=Tcl_NewObj();
  
  for(i=Compartment_First(CurrentSim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
    Compartment *p = (Compartment*)Tcl_GetHashValue(i);
    if(p->public_has_exception || p->public_accessible!=p->delta->public_accessible) {
      Tcl_ListObjAppendElement(interp, pResult, Compartment_Identify(p));
    }
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;
}

static int Compartment_method_list_portal (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *pCompt,*pComptTo=NULL;
  int from, to=0;
  Tcl_Obj *pResult=Tcl_NewObj();
  Tcl_HashSearch searchPtr;
  Tcl_HashEntry *i;
  
  if( objc !=2 && objc !=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "CID ?CID2?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &pCompt) ) return TCL_ERROR;
  from=pCompt->id;
  if( objc==3 ) {
    if( Compartment_FromTclObj(interp, objv[2], &pComptTo) ) return TCL_ERROR;
    to=pComptTo->id;
  }

  for(i=Portal_First(CurrentSim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
    Portal *p = (Portal*)Tcl_GetHashValue(i);
    if(p->public_fromid==p->public_toid) continue;
    if( p->public_fromid!=from && p->public_toid!=from ) continue;
    if(objc==3) {
      if( p->public_fromid!=to && p->public_toid!=to ) continue;
      Tcl_ListObjAppendElement(interp, pResult, Portal_Identify(p));
    } else {
      Tcl_ListObjAppendElement(interp, pResult, Portal_Identify(p));
      if(p->public_fromid==from) {
        Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(p->public_toid));
      } else {
        Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(p->public_fromid));
      }
    }
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;
}

static int Compartment_method_list_sorted (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
    Tcl_Obj *pResult = Tcl_NewObj();
    Compartment *p;
  
    if(!CurrentSim->Compartment_IndexAll) {
      Compartment_Index_Rebuild(CurrentSim);
    }
    for(p=CurrentSim->Compartment_IndexAll;p;p=p->pNextAll) {
      Tcl_ListObjAppendElement(interp, pResult, Compartment_Identify(p));
    }
    Tcl_SetObjResult(interp, pResult);
    return TCL_OK;
  
}

static int Compartment_method_list_weather (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
Tcl_HashSearch searchPtr;
  Tcl_HashEntry *i;
  Tcl_Obj *pResult=Tcl_NewObj();
  
  for(i=Compartment_First(CurrentSim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
    Compartment *p = (Compartment*)Tcl_GetHashValue(i);
    if(p->public_is_weather) {
      Tcl_ListObjAppendElement(interp, pResult, Compartment_Identify(p));
    }
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;
}

static int Compartment_method_nodedelta (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Tcl_Obj *pResult;
  int i;
  int embargo=(CurrentSim->SimCurrentTime % 10);
  
  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID ?field?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  if(objc==3) {
    /* Test if a specific field has changed */
    int offset=-1,err,type;
    int changevalue=0;
    err=Compartment_StructValueOffset(interp, objv[2], &offset,&type);
    if(err  == TCL_OK ) {
      if(Compartment_StructChanged(p,offset,embargo,0)) {
        changevalue=1;
      }
    }
    pResult=Tcl_NewBooleanObj(changevalue);
  } else {
    pResult=Tcl_NewDictObj();
    for(i=0;i<CSTRUCT_COMPARTMENT_Count;i++) {
      if(!Compartment_StructChanged(p,i,embargo,0)) continue;
      Tcl_Obj *newElement=Compartment_StructGet(p,i);
      Irm_DictObjPut(interp,pResult,Compartment_paramNameMap[i].zName,newElement);
    }
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;
}

static int Compartment_method_nodeget (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  if( objc!=2 && objc != 3){
    Tcl_WrongNumArgs(interp, 1, objv, "ID ?field?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;

  if(objc==3) {
    Tcl_Obj *result;
    int offset=-1,err,type;
    err=Compartment_StructValueOffset(interp, objv[2], &offset,&type);
    if(err  == TCL_OK ) {
      result=Compartment_StructGet(p,offset);
      Tcl_SetObjResult(interp,result);
      return TCL_OK;
    }
    /* Pull the value from extended dict */
    result=Compartment_StructDictGet(p,objv[2],IRM_NULL_EMPTY);
    Tcl_SetObjResult(interp,result);
  } else {
    Tcl_SetObjResult(interp,Compartment_StructToDict(interp,p,1));
  }
  return TCL_OK;
}

static int Compartment_method_nodeprior (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
    Compartment *p;
    Tcl_Obj *pResult;
    int i;
    
    if( objc!=2 && objc!=3 ){
      Tcl_WrongNumArgs(interp, 1, objv, "ID ?field?");
      return TCL_ERROR;
    }
    if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;

    if(objc==3) {
      /* Test if a specific field has changed */
      int offset=-1,err,type;
      err=Compartment_StructValueOffset(interp, objv[2], &offset,&type);
      if(err  == TCL_OK ) {
        pResult=Compartment_StructGet(p,offset);
      } else {
        pResult=Tcl_NewObj();
      }
    } else {
      pResult=Tcl_NewDictObj();
      for(i=0;i<CSTRUCT_COMPARTMENT_Count;i++) {
        Tcl_Obj *newElement=Compartment_StructGet(p,i);
        Irm_DictObjPut(interp,pResult,Compartment_paramNameMap[i].zName,newElement);
      }
    }
    Tcl_SetObjResult(interp, pResult);
    return TCL_OK;
  
}

static int Compartment_method_nodeput (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Tcl_DictSearch search;
  Tcl_Obj *key, *value, *objPtr;
  int done;
  int offset,type,err=TCL_OK;

  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID infoDict");
    return TCL_ERROR;
  }
  
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  objPtr=objv[2];
  if (Tcl_DictObjFirst(interp, objPtr, &search,
      &key, &value, &done) != TCL_OK) {
      return TCL_ERROR;
  }
  for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
   if( Compartment_StructValueOffset(interp, key, &offset, &type) == TCL_OK ) {
     err=Compartment_StructSet(interp,p,offset,value);
     if(err != TCL_OK) {
         break;
     }
   } else {
     Compartment_SpecDictPut(p,key,value);
     Tcl_SetObjResult(interp, value);
   }
  }
  Tcl_DictObjDone(&search);
  if(err==TCL_OK) {
    Compartment_ApplySettings(p);
  }
  return err; 
}

static int Compartment_method_nodewith (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;  
  if( objc != 3){
    Tcl_WrongNumArgs(interp, 1, objv, "ID body");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  return Compartment_nodeeval(interp,p,objv[2],1);
}

static int Compartment_method_passage (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  if( objc!=2 ) {
    Tcl_WrongNumArgs(interp, 1, objv, "ID");
    return TCL_ERROR; 
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) {
    /* Treat non-existent comptid as a non passage */
    Tcl_ResetResult(interp);
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
    return TCL_OK;
  }
  if(p->public_is_weather) {
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
  } else {
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(p->public_is_passage));
  }
  return TCL_OK; 
}

static int Compartment_method_redraw (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  if( objc!=2 ) {
    Tcl_WrongNumArgs(interp, 1, objv, "ID");
    return TCL_ERROR; 
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(p->redraw));
  p->redraw=0;
  return TCL_OK;  
}

static int Compartment_method_repair (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
    
  if( objc != 2 ){    
    Tcl_WrongNumArgs(interp, 1, objv, "ID");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  Compartment_Repair(p,1);
  return TCL_OK;
}

static int Compartment_method_reset (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment_Module_Free(CurrentSim);
  Compartment_Module_Init(CurrentSim);
  Tcl_ResetResult(interp);
  return TCL_OK;
}

static int Compartment_method_setting (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  int offset,type,rcode;
  /* If given a new value, act like a stylized set */
  Compartment *p;
  
  if( objc!=3 && objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID FIELD ?VALUE?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;

  if(objc == 4) {
    if( Compartment_StructValueOffset(interp, objv[2], &offset, &type) != TCL_OK ) {
      return TCL_ERROR;
    }
    rcode=Compartment_StructSet(interp,p,offset,objv[3]);
    if(rcode==TCL_OK) {
      Compartment_ApplySettings(p);
    }
    return rcode;
  } else {
    Tcl_Obj *result;
    int offset=-1,err,type;
    err=Compartment_StructValueOffset(interp, objv[2], &offset,&type);
    if(err  == TCL_OK ) {
      result=Compartment_StructGet(p,offset);
      Tcl_SetObjResult(interp,result);
      return TCL_OK;
    }
    /* Pull the value from extended dict */
    result=Compartment_StructDictGet(p,objv[2],IRM_NULL_ZERO);
    Tcl_SetObjResult(interp,result);
    return TCL_OK;
  }
}

static int Compartment_method_spec_get (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Tcl_Obj *pResult=NULL;
  if( objc!=2 && objc != 3){
    Tcl_WrongNumArgs(interp, 1, objv, "ID ?field?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;

  if(objc==3) {
    /* Pull the value from extended dict */
    pResult=Compartment_StructDictGet(p,objv[2],IRM_NULL_EMPTY);
  } else {
    pResult=Entity_GetDict(p->pType,NULL);
  }
  if(pResult) {
    Tcl_SetObjResult(interp,pResult);
  }
  return TCL_OK;
}

static int Compartment_method_spec_put (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Tcl_DictSearch search;
  Tcl_Obj *key, *value, *objPtr;
  int done;

  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID infoDict");
    return TCL_ERROR;
  }
  
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  objPtr=objv[2];
  if (Tcl_DictObjFirst(interp, objPtr, &search,
      &key, &value, &done) != TCL_OK) {
      return TCL_ERROR;
  }
  for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
   Compartment_SpecDictPut(p,key,value);
   Tcl_SetObjResult(interp, value);
  }
  Tcl_DictObjDone(&search);
  return TCL_OK; 
}

static int Compartment_method_spec_replace (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Tcl_DictSearch search;
  Tcl_Obj *key, *value, *objPtr;
  int done;

  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID infoDict");
    return TCL_ERROR;
  }
  
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  objPtr=objv[2];
  if (Tcl_DictObjFirst(interp, objPtr, &search,
      &key, &value, &done) != TCL_OK) {
      return TCL_ERROR;
  }
  for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
   Compartment_SpecDictPut(p,key,value);
   Tcl_SetObjResult(interp, value);
  }
  Tcl_DictObjDone(&search);
  return TCL_OK; 
}

static int Compartment_method_step (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Tcl_Obj *pResult = Tcl_NewObj();
  Tcl_HashSearch searchPtr;
  Tcl_HashEntry *i;

  for(i=Compartment_First(CurrentSim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
    Compartment *p = (Compartment*)Tcl_GetHashValue(i);
    double tempC;
    int ki;
    
    Compartment_ApplySettings(p);
    if(p->public_is_weather) continue;   
    //if(!p->public_has_exception) continue;   

    /*
    ** The compartment stores temperature in K
    ** convert to C
    */
    tempC=p->public_temperature-273.15;
  
    if(CurrentSim->public_fire_damage_conduit && p->kidlist) {
      for(ki=1;ki <= p->kidlist[0];ki++) {
        if(SimLink_CalculateThermalEndurance((Roid)p->kidlist[ki],tempC,p->public_fire_size)) {
          Tcl_ListObjAppendList(interp,pResult,Irm_NewStringObj("conduit_rupture"));
          Tcl_ListObjAppendList(interp,pResult,Tcl_NewIntObj((int)p->id));
          Tcl_ListObjAppendList(interp,pResult,Tcl_NewIntObj(p->kidlist[ki]));
        }
      }
    }
    /*
    ** Notify equipment of the cabin temperature
    ** in the surrounding compartment
    */
    SimNode *pNode;
    Roid comptid=p->id;
    
    for(pNode=SimNode_Index_First(CurrentSim); pNode; pNode=pNode->pNextAll) {
      if( pNode->public_compartment==0 || pNode->public_compartment!=comptid ) {
        continue;
      }
      /*
      ** Kick off the coil calculations
      */
      SimNode_ComputeThermalEndurance(pNode,tempC,p->public_fire_size,p->public_cvis);
    }
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;
}

static int Compartment_method_struct_get (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  if( objc!=2 && objc != 3){
    Tcl_WrongNumArgs(interp, 1, objv, "ID ?field?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;

  if(objc==3) {
    Tcl_Obj *result;
    int offset=-1,err,type;
    err=Compartment_StructValueOffset(interp, objv[2], &offset,&type);
    if(err  == TCL_OK ) {
      result=Compartment_StructGet(p,offset);
      Tcl_SetObjResult(interp,result);
      return TCL_OK;
    }
    return TCL_ERROR;
  } else {
    Tcl_SetObjResult(interp,Compartment_StructToDict(interp,p,0));
  }
  return TCL_OK;
}

static int Compartment_method_struct_put (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Tcl_DictSearch search;
  int done;
  int offset,type,err=TCL_OK;

  if( objc!=3 && objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID infoDict");
    return TCL_ERROR;
  }
  
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  if(objc==4) {
    if( Compartment_StructValueOffset(interp, objv[2], &offset, &type) == TCL_OK ) {
       err=Compartment_StructSet(interp,p,offset,objv[3]);
       if(err != TCL_OK) {
          return TCL_ERROR;
       }
    } else {
      return TCL_ERROR;
    }
  } else {
    Tcl_Obj *key, *value;
    Tcl_Obj *objPtr=objv[2];
    if (Tcl_DictObjFirst(interp, objPtr, &search,
        &key, &value, &done) != TCL_OK) {
        return TCL_ERROR;
    }
    for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
     if( Compartment_StructValueOffset(interp, key, &offset, &type) == TCL_OK ) {
       err=Compartment_StructSet(interp,p,offset,value);
       if(err != TCL_OK) {
           break;
       }
     } else {
      return TCL_ERROR;
     }
    }
    Tcl_DictObjDone(&search);
  }
  if(err==TCL_OK) {
    Compartment_ApplySettings(p);
  }
  return err; 
}

static int Compartment_method_suppressors (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Roid comptid=0;
  SimNode *pNode;

  Tcl_Obj *pResult=Tcl_NewObj();
  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "COMPTID");
    return TCL_ERROR;
  }
  if(objc==2) {
    if( Tcl_GetIntFromObj(interp, objv[1], &comptid) ) return TCL_ERROR;
  }
  for(pNode=SimNode_Index_First(CurrentSim); pNode; pNode=pNode->pNextAll) {
    int stype=TypeSpec_GetInt(pNode->pType,SPEC_SUPPRESSOR_STYPE);
    int lastop=0,op=0;
    if (stype==9||stype==8) {
      stype=10;
    }
    if( !pNode->isSuppressor ) continue;
    if(objc==2) {
      if(pNode->public_compartment != comptid ) continue;
      Tcl_ListObjAppendElement(interp, pResult, Tcl_NewWideIntObj(pNode->id));
    } else {
      Tcl_ListObjAppendElement(interp, pResult, Tcl_NewWideIntObj(pNode->id));
      Tcl_ListObjAppendElement(interp, pResult, Tcl_NewWideIntObj(pNode->public_compartment));
    }
    Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(stype));
    if((pNode->delta->public_operational==1) && (pNode->delta->public_onoff == 1)) {
      lastop=1;
    }
    if((pNode->public_operational==1) && (pNode->public_onoff == 1)) {
      op=1;
    }    
    Tcl_ListObjAppendElement(interp, pResult, Tcl_NewBooleanObj(op==lastop));    
    Tcl_ListObjAppendElement(interp, pResult, Tcl_NewBooleanObj(op));
  }
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;  
}

static int Compartment_method_type (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Entity *pType;
  if( objc != 2 && objc != 3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "NODEID field");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  pType=Compartment_StructGetType(p);
  if(!pType) {
    if(objc==2) {
      Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
    }
    return TCL_OK;
  }
  if(objc==2) {
    Tcl_SetObjResult(interp, SimType_Identify(pType));    
  }
  if(objc==3) {
    Tcl_Obj *pResult;
    pResult=Entity_ExportField(pType,NULL,Tcl_GetString(objv[2]),IRM_NULL_EMPTY);
    Tcl_SetObjResult(interp,pResult);
  }
  return TCL_OK;
}

static int Compartment_method_typeid (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  Entity *pType;
  if( objc!=2 && objc != 3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID ?typeid?");
    return TCL_ERROR;
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) return TCL_ERROR;
  if(objc==3) {
    if( SimType_FromTclObj(interp, objv[2], &pType) ) {
      /* Translate a ZERO length list to null */
      int len;
      if(Tcl_ListObjLength(NULL,objv[2],&len)) {
        return TCL_ERROR;
      }
      if(len) {
        int intval;
        if(Tcl_GetIntFromObj(NULL,objv[2],&intval)==TCL_ERROR) {
          return TCL_ERROR;
        }
        if(intval>0) {
          return TCL_ERROR;
        }
      }
      Tcl_ResetResult(interp);
      pType=NULL;
    }
    Compartment_StructSetType(p,pType);
    /* Reset the group pointer so it's recalculated */
    Compartment_StructSetGroup(p,-1);
  }
  pType=Compartment_StructGetType(p);
  if(pType) {
    Tcl_SetObjResult(interp, SimType_Identify(pType));
  } else {
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
  }
  return TCL_OK;
}

static int Compartment_method_weather (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Compartment *p;
  if( objc!=2 ) {
    Tcl_WrongNumArgs(interp, 1, objv, "ID");
    return TCL_ERROR; 
  }
  if( Compartment_FromTclObj(interp, objv[1], &p) ) {
    /* Treat non-existent comptid as weather */
    Tcl_ResetResult(interp);
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
    return TCL_OK;
  }
  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(p->public_is_weather));
  return TCL_OK; 
}

static int Compartment_method_witheach (
  ClientData *simulator,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
) {

  CurrentSim=(Simulator *)simulator;

  local_interp=interp;
  Tcl_HashSearch *searchPtr;
  Tcl_HashEntry *i;
  int searchresult=TCL_OK;
  Tcl_Obj *body;

  if( objc != 2){
    Tcl_WrongNumArgs(interp, 1, objv, "body");
    return TCL_ERROR;
  }
  body=objv[1];
  searchPtr=(Tcl_HashSearch *)local_Alloc(sizeof(Tcl_HashSearch));
  for(i=Compartment_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
    Compartment *p = (Compartment *)Tcl_GetHashValue(i);
    searchresult=Compartment_nodeeval(interp,p,body,1);
    if (searchresult !=TCL_OK && searchresult!=TCL_CONTINUE) {
      Tcl_Free((char *)searchPtr);
      return searchresult;
    }
  }
  Tcl_Free((char *)searchPtr);
  return TCL_OK;
}

int compartment_Ensemble(Tcl_Interp *interp,Simulator *simPtr,Tcl_Namespace *nsPtr) {

  char zAppend[256];
  char yAppend[256]; 
  Tcl_Namespace *modPtr;


  /*
  ** Implement compartment
  */


  modPtr=Tcl_FindNamespace(interp,"compartment",nsPtr,TCL_NAMESPACE_ONLY);
  if(!modPtr) {
    strcpy(zAppend,nsPtr->fullName);
    strcat(zAppend,"::compartment");
    modPtr = Tcl_CreateNamespace(interp, zAppend, NULL, NULL);
    Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
    Tcl_Export(interp, modPtr, "[a-z]*", 1);
  } else {
    strcpy(zAppend,modPtr->fullName);
  }
  
  strcpy(yAppend,zAppend); strcat(yAppend,"::add");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_add,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::create");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_add,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::cid");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_cid,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::condition");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_condition,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::count");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_count,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::exists");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_exists,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::flooding");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_flooding,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::for");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_for,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::foreach");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_foreach,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::groupid");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_groupid,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::group");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_groupid,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::kidlist");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_kidlist,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::list");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_list,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::list_changed");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_list_changed,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::list_crew");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_list_crew,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::list_detectors");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_list_detectors,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::list_eqpt");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_list_eqpt,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::list_exception");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_list_exception,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::list_portal");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_list_portal,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::list_sorted");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_list_sorted,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::list_weather");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_list_weather,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::nodedelta");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_nodedelta,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::delta");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_nodedelta,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::nodeget");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_nodeget,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::get");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_nodeget,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::nodeprior");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_nodeprior,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::nodeput");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_nodeput,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::put");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_nodeput,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::nodewith");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_nodewith,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::with");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_nodewith,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::passage");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_passage,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::redraw");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_redraw,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::repair");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_repair,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::reset");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_reset,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::setting");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_setting,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::spec_get");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_spec_get,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::spec_put");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_spec_put,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::spec_replace");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_spec_replace,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::step");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_step,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::struct_get");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_struct_get,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::struct_put");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_struct_put,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::suppressors");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_suppressors,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::type");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_type,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::typeid");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_typeid,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::weather");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_weather,(ClientData)simPtr,NULL);
  strcpy(yAppend,zAppend); strcat(yAppend,"::witheach");
  Tcl_CreateObjCommand(interp,yAppend,(Tcl_ObjCmdProc *)Compartment_method_witheach,(ClientData)simPtr,NULL);
  return TCL_OK;
}