Aller au contenu

Photo

area report script


  • Veuillez vous connecter pour répondre
4 réponses à ce sujet

#1
rjshae

rjshae
  • Members
  • 4 485 messages
I put together the following rather long-ish script to give me a summary of an area so that I can check it for general details. Hopefully I got it all pasted in properly. Please give it a go and let me know how it might be improved. Thanks.

// area report
/*
  This script will produce a high-level summary report
  for an area. It can be called from the "On Client Enter"
  script of an area as follows:
  
    if ( GetLocalInt( OBJECT_SELF, "bPrintReport" )
      ExecuteScript( "area_report", OBJECT_SELF );
  
  Setting the local integer variable "bPrintReport=1" on
  the area will cause it to display the report on client
  entry.
*/
const string TAB = "  ";
const string CR = "\\n";
const string Y_ON = "<c=yellow>";
const string Y_OFF = "</c>";
const int DEFAULT_ENCDIFFMIN = 100;
const int DEFAULT_MINDC = 100;
const int DEFAULT_MINSTOREGOLD = 9999999;
const int DEFAULT_MAXBUYPRICE = 9999999;

// Struct for creature data
struct Creature {
  int total;
  int plot;
  int hidden;
  int friend;
  int neutral;
  int enemy;
  int pickpocketable;
  int disarmable;
  int lootable;
  int immortal;
  int spirit;
  int maxHP;
  int maxHD;
  int bestAC;
  int bestBAB;
  int total_items;
  int itemMaxValue;
  int itemsTotalValue;
  int droppableItems;
  int pickpocketableItems;
  string bestHPName;
  string bestHDName;
  string bestACName;
  string bestBABName;
  string highestCostItem;
};

// Structure for door data
struct Door {
  int total;
  int locked;
  int lockMinDC;
  int lockMaxDC;
  int lockReqKey;
  int lockable;
  int trapped;
  int trapMinDetectDC;
  int trapMaxDetectDC;
  int  trapMinDisarmDC;
  int trapMaxDisarmDC;
  int trapDisarmable;
  int partyTransition;
};

// Structure for encounter data
struct Encounter {
  int total;
  int active;
  int spawn;
  int difficultMin;
  int difficultMax;
};

// Structure for placeable data
struct Placeable {
  int total;
  int inventory;
  int useable;
  int collision;
  int total_items;
  int itemsTotalValue;
  int itemMaxValue;
  int locked;
  int lockMinDC;
  int lockMaxDC;
  int lockReqKey;
  int lockable;
  int trapped;
  int trapMinDetectDC;
  int trapMaxDetectDC;
  int  trapMinDisarmDC;
  int trapMaxDisarmDC;
  int trapDisarmable;
  int partyTransition;
  string highestCostItem;
};

// Structure for store data
struct Store {
  int total;
  int minGold;
  int maxGold;
  int minBuyPrice;
  int maxBuyPrice;
  int total_items;
  int itemsTotalValue;
  int itemMaxValue;
  string highestCostItem;
};

// Structure for trigger data
struct Trigger {
  int total;
  int trapped;
  int trapMinDetectDC;
  int trapMaxDetectDC;
  int  trapMinDisarmDC;
  int trapMaxDisarmDC;
  int trapDisarmable;
  int partyTransition;
};

// Initialize the creature data
struct Creature InitCreatureData()
{
  struct Creature sc;
  
  sc.total = 0;
  sc.plot = 0;
  sc.hidden = 0;
  sc.friend = 0;
  sc.neutral = 0;
  sc.enemy = 0;
  sc.pickpocketable = 0;
  sc.disarmable = 0;
  sc.lootable = 0;
  sc.immortal = 0;
  sc.spirit = 0;
  sc.maxHP = -1;
  sc.maxHD = -1;
  sc.bestAC = -1;
  sc.bestBAB = -1;
  sc.total_items = 0;
  sc.itemMaxValue = -1;
  sc.itemsTotalValue = 0;
  sc.droppableItems = 0;
  sc.pickpocketableItems = 0;
  
  sc.bestHPName = "";
  sc.bestHDName = "";
  sc.bestACName = "";
  sc.bestBABName = "";
  sc.highestCostItem = "";
  
  return sc;
}

// Initialize the door data
struct Door InitDoorData()
{
  struct Door sd;
  
  sd.total = 0;
  sd.locked = 0;
  sd.lockMinDC = 100;
  sd.lockMaxDC = 0;
  sd.lockReqKey = 0;
  sd.lockable = 0;
  sd.trapped = 0;
  sd.trapMinDetectDC = DEFAULT_MINDC;
  sd.trapMaxDetectDC = 0;
  sd.trapMinDisarmDC = DEFAULT_MINDC;
  sd.trapMaxDisarmDC = 0;
  sd.trapDisarmable = 0;
  sd.partyTransition = 0;
  
  return sd;
}

// Initialize the encounter data
struct Encounter InitEncounterData()
{
  struct Encounter se;
  
  se.total = 0;
  se.active = 0;
  se.spawn = 0;
  se.difficultMin = DEFAULT_ENCDIFFMIN;
  se.difficultMax = 0;
  
  return se;
}

// Initialize the placeable data
struct Placeable InitPlaceableData()
{
  struct Placeable sp;
  
  sp.total = 0;
  sp.inventory = 0;
  sp.useable = 0;
  sp.collision = 0;
  sp.total_items = 0;
  sp.itemsTotalValue = 0;
  sp.itemMaxValue = 0;
  sp.locked = 0;
  sp.lockMinDC = 100;
  sp.lockMaxDC = 0;
  sp.lockReqKey = 0;
  sp.lockable = 0;
  sp.trapped = 0;
  sp.trapMinDetectDC = DEFAULT_MINDC;
  sp.trapMaxDetectDC = 0;
  sp.trapMinDisarmDC = DEFAULT_MINDC;
  sp.trapMaxDisarmDC = 0;
  sp.trapDisarmable = 0;
  sp.partyTransition = 0;
  sp.highestCostItem = "";
  
  return sp;
}

// Initialize the store data
struct Store InitStoreData()
{
  struct Store ss;
  
  ss.total = 0;
  ss.minGold = DEFAULT_MINSTOREGOLD;
  ss.maxGold = 0;
  ss.minBuyPrice = DEFAULT_MAXBUYPRICE;
  ss.maxBuyPrice = 0;
  ss.total_items = 0;
  ss.itemsTotalValue = 0;
  ss.itemMaxValue = 0;
  ss.highestCostItem = "";
  
  return ss;
}

// Initialize the trigger data
struct Trigger InitTriggerData()
{
  struct Trigger st;
  
  int total = 0;
  int trapped = 0;
  int trapMinDetectDC = DEFAULT_MINDC;
  int trapMaxDetectDC = 0;
  int  trapMinDisarmDC = DEFAULT_MINDC;
  int trapMaxDisarmDC = 0;
  int trapDisarmable = 0;
  int partyTransition = 0;
  
  return st;
}

// Query the items for this creature and return updated data
struct Creature ExamineCreatureItems( object oCreature, struct Creature sc )
{
  int n;
  int pp = FALSE;
  
  // Cycle through each item
  object oItem = GetFirstItemInInventory( oCreature );
  while ( oItem != OBJECT_INVALID ) {
    sc.total_items++;
    if ( GetDroppableFlag( oItem ) )
      sc.droppableItems++;
    if ( GetPickpocketableFlag( oItem ) ) {
      sc.pickpocketableItems++;
      pp = TRUE; // Flag as pickpocketable
    }
    n = GetGoldPieceValue( oItem );
    sc.itemsTotalValue += n;
    if ( n > sc.itemMaxValue ) {
      sc.itemMaxValue = n;
      sc.highestCostItem = GetName( oItem );
    }
    oItem = GetNextItemInInventory( oCreature );
  }
  
  // At least one item it pickpocketable
  if ( pp )
    sc.pickpocketable++;
  
  return sc;
}

// Query this creature's attributes and return updated data
struct Creature ExamineCreature( object oCreature, object oPC, struct Creature sc )
{
  int n;
  
  sc.total++;
  if ( GetPlotFlag( oCreature ) ) 
    sc.plot++;
  if ( GetScriptHidden( oCreature ) ) 
    sc.hidden++;
  if ( GetIsSpirit( oCreature ) )
    sc.spirit++;
  if ( GetIsCreatureDisarmable( oCreature ) )
    sc.disarmable++;
  if ( GetLootable( oCreature ) )
    sc.lootable++;
  if ( GetImmortal( oCreature ) )
    sc.immortal++;
  
  n = GetMaxHitPoints( oCreature );
  string sName = "";
  if ( n > sc.maxHP ) {
    sName = GetName( oCreature );
    sc.bestHPName = sName;
    sc.maxHP = n;
  }
  n = GetHitDice( oCreature );
  if ( n > sc.maxHD ) {
    if ( sName == "" )
      sName = GetName( oCreature );
    sc.bestHDName = sName;
    sc.maxHD = n;
  }
  n = GetAC( oCreature );
  if ( n > sc.bestAC ) {
    if ( sName == "" )
      sName = GetName( oCreature );
    sc.bestACName = sName;
    sc.bestAC = n;
  }
  n = GetBaseAttackBonus( oCreature );
  if ( n > sc.bestBAB ) {
    if ( sName == "" )
      sName = GetName( oCreature );
    sc.bestBABName = sName;
    sc.bestBAB = n;
  }
  
  if ( GetIsEnemy( oPC, oCreature ) ) {
    sc.enemy++;
  } else {
    if ( GetIsNeutral( oPC, oCreature ) )
      sc.neutral++;
    else {
      if ( GetIsFriend( oPC, oCreature ) )
        sc.friend++;
    }
  }
  
  sc = ExamineCreatureItems( oCreature, sc );
  
  return sc;
}

// Query this door's attributes and return updated data
struct Door ExamineDoor( object oDoor, struct Door sd )
{
  int n;
  
  sd.total++;
  if ( GetLocked( oDoor ) ) {
    sd.locked++;
    
    n = GetLockUnlockDC( oDoor );
    if ( sd.lockMinDC > n )
      sd.lockMinDC = n;
    if ( sd.lockMaxDC < n )
      sd.lockMaxDC = n;
    if ( GetLockKeyRequired( oDoor ) )
      sd.lockReqKey++;
  }
  if ( GetLockLockable( oDoor ) )
    sd.lockable++;
  
  if ( GetIsTrapped( oDoor ) ) {
    sd.trapped++;
    
    n = GetTrapDetectDC( oDoor );
    if ( sd.trapMinDetectDC > n )
      sd.trapMinDetectDC = n;
    if ( sd.trapMaxDetectDC < n )
      sd.trapMaxDetectDC = n;
    
    n = GetTrapDisarmDC( oDoor );
    if ( sd.trapMinDisarmDC > n )
      sd.trapMinDisarmDC = n;
    if ( sd.trapMaxDisarmDC < n )
      sd.trapMaxDisarmDC = n;
    if ( GetTrapDisarmable( oDoor ) )
      sd.trapDisarmable++;
  }
  if ( GetIsPartyTransition( oDoor ) )
    sd.partyTransition++;
  
  return sd;
}

// Query this encounter's attributes and return updated data
struct Encounter ExamineEncounter( object oEncounter, struct Encounter se )
{
  int n;
  
  se.total++;
  if ( GetEncounterActive( oEncounter ) )
    se.active++;
  n = GetEncounterSpawnsMax( oEncounter );
  if ( n == 0 )
    se.spawn += 1;
  else
    se.spawn += n;
  n = GetEncounterDifficulty( oEncounter );
  if ( n < se.difficultMin )
    se.difficultMin = n;
  if ( n > se.difficultMax )
    se.difficultMax = n;
  
  return se;
}

// Query the items for this placeable and return updated data
struct Placeable ExaminePlaceableItems( object oPlaceable, struct Placeable sp )
{
  int n;
  
  object oItem = GetFirstItemInInventory( oPlaceable );
  while ( oItem != OBJECT_INVALID ) {
    sp.total_items++;
    n = GetGoldPieceValue( oItem );
    sp.itemsTotalValue += n;
    if ( n > sp.itemMaxValue ) {
      sp.highestCostItem = GetName( oItem );
      sp.itemMaxValue = n;
    }
    oItem = GetNextItemInInventory( oPlaceable );
  }
  
  return sp;
}

// Query this placeable's attributes and return updated data
struct Placeable ExaminePlaceable( object oPlaceable, struct Placeable sp )
{
  int n;
  
  sp.total++;
  if ( GetHasInventory( oPlaceable ) ) {
    sp.inventory++;
    sp = ExaminePlaceableItems( oPlaceable, sp );
  }
  if ( GetUseableFlag( oPlaceable ) )
    sp.useable++;
  if ( GetLocked( oPlaceable ) ) {
    sp.locked++;
    n = GetLockUnlockDC( oPlaceable );
    if ( sp.lockMinDC > n )
      sp.lockMinDC = n;
    if ( sp.lockMaxDC < n )
      sp.lockMaxDC = n;
    if ( GetLockKeyRequired( oPlaceable ) )
      sp.lockReqKey++;
  }
  if ( GetLockLockable( oPlaceable ) )
    sp.lockable++;
  
  if ( GetIsTrapped( oPlaceable ) ) {
    sp.trapped++;
    
    n = GetTrapDetectDC( oPlaceable );
    if ( sp.trapMinDetectDC > n )
      sp.trapMinDetectDC = n;
    if ( sp.trapMaxDetectDC < n )
      sp.trapMaxDetectDC = n;
    
    n = GetTrapDisarmDC( oPlaceable );
    if ( sp.trapMinDisarmDC > n )
      sp.trapMinDisarmDC = n;
    if ( sp.trapMaxDisarmDC < n )
      sp.trapMaxDisarmDC = n;
    if ( GetTrapDisarmable( oPlaceable ) )
      sp.trapDisarmable++;
  }
  
  if ( GetCollision( oPlaceable ) )
    sp.collision++;
  if ( GetIsPartyTransition( oPlaceable ) )
    sp.partyTransition++;
  
  return sp;
}

// Query the items for this store and return updated data
struct Store ExamineStoreItems( object oStore, struct Store ss )
{
  int n;
  
  object oItem = GetFirstItemInInventory( oStore );
  while ( oItem != OBJECT_INVALID ) {
    ss.total_items++;
    n = GetGoldPieceValue( oItem );
    ss.itemsTotalValue += n;
    if ( n > ss.itemMaxValue ) {
      ss.highestCostItem = GetName( oItem );
      ss.itemMaxValue = n;
    }
    oItem = GetNextItemInInventory( oStore );
  }
  
  return ss;
}

// Query this store's attributes and return updated data
struct Store ExamineStore( object oStore, struct Store ss )
{
  int n;
  
  ss.total++;
  n = GetStoreGold( oStore );
  if ( n > 0 ) {
    if ( ss.minGold > n )
      ss.minGold = n;
    if ( ss.maxGold < n )
      ss.maxGold = n;
  }
  n = GetStoreMaxBuyPrice( oStore );
  if ( n > 0 ) {
    if ( ss.minBuyPrice > n )
      ss.minBuyPrice = n;
    if ( ss.maxBuyPrice < n )
      ss.maxBuyPrice = n;
  }
  
  ss = ExamineStoreItems( oStore, ss );
  
  return ss;
}

// Query this trigger's attributes and return updated data
struct Trigger ExamineTrigger( object oStore, struct Trigger st )
{
  int n;
  
  st.total++;
  if ( GetIsTrapped( oStore ) ) {
    st.trapped++;
  
    n = GetTrapDetectDC( oStore );
    if ( st.trapMinDetectDC > n )
      st.trapMinDetectDC = n;
    if ( st.trapMaxDetectDC < n )
      st.trapMaxDetectDC = n;
    
    n = GetTrapDisarmDC( oStore );
    if ( st.trapMinDisarmDC > n )
      st.trapMinDisarmDC = n;
    if ( st.trapMaxDisarmDC < n )
      st.trapMaxDisarmDC = n;
    if ( GetTrapDisarmable( oStore ) )
      st.trapDisarmable++;
  }
  if ( GetIsPartyTransition( oStore ) )
    st.partyTransition++;
  
  return st;
}

// Generate a range string, or a single-value string if nMin == nMax
string ReportRange( int nMin, int nMax ) {
  string sRange;
  if ( nMin < nMax ) {
    sRange = IntToString( nMin ) + " to " + IntToString( nMax );
  } else {
    sRange += IntToString( nMax );
  }
  return sRange;
}

// Generate a report string on the locks for an object type
string ReportLock( int nLocked, int nLockable,
      int nLockMinDC, int nLockMaxDC, int nLockReqKey )
{
  string sReport = "";
  sReport = "- Locked: " + IntToString( nLocked ) + CR;
  if ( nLocked > 0 ) {
    sReport += "- Unlock DC: " +
      ReportRange( nLockMinDC, nLockMaxDC ) + CR;
    sReport += "- Key required: " + IntToString( nLockReqKey ) + CR;
  }
  sReport += "- Lockable: " + IntToString( nLockable ) + CR;
  return sReport;
}

// Generate a report string on the traps for an object type
string ReportTrap( int nTrapped, int nTrapDisarmable,
      int nTrapMinDetectDC, int nTrapMaxDetectDC,
      int nTrapMinDisarmDC, int nTrapMaxDisarmDC )
{
  string sReport = "";
  sReport = "- Trapped: " + IntToString( nTrapped ) + CR;
  if ( nTrapped > 0 ) {
    sReport += "- Detect DC: " +
      ReportRange( nTrapMinDetectDC, nTrapMaxDetectDC ) + CR;
    sReport += "- Disarmable: " + IntToString( nTrapDisarmable ) + CR;
    sReport += "- Disarm DC: " +
      ReportRange( nTrapMinDisarmDC, nTrapMaxDisarmDC ) + CR;
  }
  return sReport;
}

// Generate a report string on the area creatures
string ReportCreatures( struct Creature sc )
{
  string sReport;
  
  sReport = Y_ON + "Non-Party Creatures: " + Y_OFF +
    IntToString( sc.total ) + CR;
  if ( sc.total > 0 ) {
    sReport += "- Friends: " + IntToString( sc.friend ) + CR;
    sReport += "- Neutral: " + IntToString( sc.neutral ) + CR;
    sReport += "- Enemies: " + IntToString( sc.enemy ) + CR;
    sReport += "- Spirit: " + IntToString( sc.spirit ) + CR;
    sReport += "- Plot: " + IntToString( sc.plot ) + CR;
    sReport += "- Hidden: " + IntToString( sc.hidden ) + CR;
    sReport += "- Disarmable: " + IntToString( sc.disarmable ) + CR;
    sReport += "- Lootable: " + IntToString( sc.lootable ) + CR;
    sReport += "- Immortal: " + IntToString( sc.immortal ) + CR;
    sReport += "- Pickpocketable: " + IntToString( sc.pickpocketable )
      + CR;
    sReport += "- Highest HD Total: " +
      IntToString( sc.maxHD ) + " (" + sc.bestHDName + ")" + CR;
    sReport += "- Highest HP Total: " +
      IntToString( sc.maxHP ) + " (" + sc.bestHPName + ")" + CR;
    sReport += "- Best AC: " + 
      IntToString( sc.bestAC ) + " (" + sc.bestACName + ")" + CR;
    sReport += "- Best BAB: " +
      IntToString( sc.bestBAB ) + " (" + sc.bestBABName + ")" + CR;
  }
  return sReport;
}

// Generate a report string on the area doors
string ReportDoors( struct Door sd )
{
  string sReport;
  
  sReport = Y_ON + "Doors: " + Y_OFF + IntToString( sd.total ) + CR;
  if ( sd.total > 0 ) {
    sReport += ReportLock( sd.locked, sd.lockable,
      sd.lockMinDC, sd.lockMaxDC, sd.lockReqKey );
    sReport += ReportTrap( sd.trapped, sd.trapDisarmable,
      sd.trapMinDetectDC, sd.trapMaxDetectDC,
      sd.trapMinDisarmDC, sd.trapMaxDisarmDC );
    sReport += "- Party Transition: " +
      IntToString( sd.partyTransition ) + CR;
  }
  
  return sReport;
}

// Generate a report string on the area encounters
string ReportEncounters( struct Encounter se )
{
  string sReport;
  
  sReport = Y_ON + "Encounters: " + Y_OFF + IntToString( se.total ) + CR;
  if ( se.total > 0 ) {
    sReport += "- Active: " + IntToString( se.active ) + CR;
    sReport += "- Maximum Spawns: " + IntToString( se.spawn ) + CR;
    if ( se.difficultMin != DEFAULT_ENCDIFFMIN ) {
      sReport += "- Difficulty: " +
        ReportRange( se.difficultMin, se.difficultMax )
        + CR;
    }
  }
  
  return sReport;
}

// Generate a report string on the area items
string ReportItems( int total, int total_value,
    struct Creature sc, struct Placeable sp, struct Store ss )
{
  string sReport;
  int combined = total + sc.total_items + sp.total_items + ss.total_items;
  
  sReport = Y_ON + "Items: " + Y_OFF + IntToString( combined ) + CR;
  if ( total > 0 ) {
    sReport += "- Loose Items: " + IntToString( total ) + CR;
    sReport += "- Loose Items Total Value: " +
      IntToString( total_value ) + CR;
  }
  if ( sc.total_items > 0 ) {
    sReport += "- Creature Items: " +
      IntToString( sc.total_items ) + CR;
    sReport += "- Creature Droppable Items: " +
      IntToString( sc.droppableItems ) + CR;
    sReport += "- Creature Pickpocketable Items: " +
      IntToString( sc.pickpocketableItems ) + CR;
    sReport += "- Creature Item Max Value: " +
      IntToString( sc.itemMaxValue ) +
      " (" + sc.highestCostItem + ")" + CR;
    sReport += "- Creature Items Total Value: " +
      IntToString( sc.itemsTotalValue ) + CR;
  }
  if ( sp.total_items > 0 ) {
    sReport += "- Container Items: " +
      IntToString( sp.total_items ) + CR;
    sReport += "- Container Item Max Value: " +
      IntToString( sp.itemMaxValue ) + 
      " (" + sp.highestCostItem + ")" + CR;
    sReport += "- Container Items Total Value: " +
      IntToString( sp.itemsTotalValue ) + CR;
  }
  if ( ss.total_items > 0 ) {
    sReport += "- Store Items: " + IntToString( ss.total_items ) + CR;
    sReport += "- Store Item Max Value: " +
      IntToString( ss.itemMaxValue ) +
      " (" + ss.highestCostItem + ")" + CR;
    sReport += "- Store Items Total Value: " +
      IntToString( ss.itemsTotalValue ) + CR;
  }
  
  return sReport;
}

// Generate a report string on the area placeables
string ReportPlaceables( struct Placeable sp )
{
  string sReport;
  
  sReport = Y_ON + "Placeables: " + Y_OFF + IntToString( sp.total ) + CR;
  if ( sp.total > 0 ) {
    sReport += "- Have Inventory: " + IntToString( sp.inventory ) + CR;
    sReport += "- Useable: " + IntToString( sp.useable ) + CR;
    sReport += ReportLock( sp.locked, sp.lockable,
      sp.lockMinDC, sp.lockMaxDC, sp.lockReqKey );
    sReport += ReportTrap( sp.trapped, sp.trapDisarmable,
      sp.trapMinDetectDC, sp.trapMaxDetectDC,
      sp.trapMinDisarmDC, sp.trapMaxDisarmDC );
    sReport += "- Non-Collision: " +
      IntToString( sp.total - sp.collision ) + CR;
    sReport += "- Party Transition: " +
      IntToString( sp.partyTransition ) + CR;
  }
  
  return sReport;
}

// Generate a report string on the area stores
string ReportStores( struct Store ss )
{
  string sReport;
  
  sReport = Y_ON + "Stores: " + Y_OFF + IntToString( ss.total ) + CR;
  if ( ss.total > 0 ) {
    // Display the range of available store gold
    if ( ss.minGold < DEFAULT_MINSTOREGOLD ) {
      sReport += "- Store Gold: " +
        ReportRange( ss.minGold, ss.maxGold ) + CR;
    }
    
    // Display the range of maximum buy prices
    if ( ss.minBuyPrice < DEFAULT_MAXBUYPRICE ) {
      sReport += "- Max Buy Price: " +
        ReportRange( ss.minBuyPrice, ss.maxBuyPrice ) + CR;
    }
  }
  
  return sReport;
}

// Generate a report string on the area triggers
string ReportTriggers( struct Trigger st )
{
  string sReport;
  
  sReport = Y_ON + "Triggers: " + Y_OFF + IntToString( st.total ) + CR;
  if ( st.total > 0 ) {
    sReport += ReportTrap( st.trapped, st.trapDisarmable,
      st.trapMinDetectDC, st.trapMaxDetectDC,
      st.trapMinDisarmDC, st.trapMaxDisarmDC );
    sReport += "- Party Transition: " +
      IntToString( st.partyTransition ) + CR;
  }
  
  return sReport;
}

// Generate a report string on the objects in the area
string ReportAreaObjects( object oArea, object oPC )
{
  int nItems = 0;
  int nItemsTotalValue = 0;
  int nLights = 0;
  int nOther = 0;
  int nPlacedEffects = 0;
  int nWaypoints = 0;
  int nMapNotes = 0;
  
  string sReport = "";
  struct Creature creature = InitCreatureData();
  struct Door door = InitDoorData();
  struct Encounter encounter = InitEncounterData();
  struct Placeable placeable = InitPlaceableData();
  struct Store store = InitStoreData();
  struct Trigger trigger = InitTriggerData();
  
  // Cycle through the objects
  object oInArea = GetFirstObjectInArea();
  while ( oInArea != OBJECT_INVALID ) {
    int oType = GetObjectType( oInArea );
    switch( oType ) {
      case OBJECT_TYPE_CREATURE:
        // Check whether creature is a party member
        if ( GetFactionEqual( oPC, oInArea ) )
          break;
        
        creature = ExamineCreature( oInArea, oPC, creature );
        break;
        
      case OBJECT_TYPE_DOOR:
        door = ExamineDoor( oInArea, door );
        break;
        
      case OBJECT_TYPE_ENCOUNTER:
        encounter = ExamineEncounter( oInArea, encounter );
        break;
        
      case OBJECT_TYPE_ITEM:
        nItems++;
        nItemsTotalValue += GetGoldPieceValue( oInArea );
        break;
        
      case OBJECT_TYPE_LIGHT:
        nLights++;
        break;
        
      case OBJECT_TYPE_PLACEABLE:
        placeable = ExaminePlaceable( oInArea, placeable );
        break;
        
      case OBJECT_TYPE_PLACED_EFFECT:
        nPlacedEffects++;
        break;
        
      case OBJECT_TYPE_STORE:
        store = ExamineStore( oInArea, store );
        break;
        
      case OBJECT_TYPE_TRIGGER:
        trigger = ExamineTrigger( oInArea, trigger );
        break;
        
      case OBJECT_TYPE_WAYPOINT:
        nWaypoints++;
        if ( GetResRef( oInArea ) == "nw_mapnote001" )
          nMapNotes++;
        break;
        
      default:
        nOther++;
        break;
    }
    oInArea = GetNextObjectInArea();
  }
  
  // Generate the report
  sReport += CR + "<b>Objects</b>" + CR + CR;
  sReport += ReportCreatures( creature );
  sReport += ReportDoors( door );
  sReport += ReportEncounters( encounter );
  sReport += ReportItems( nItems, nItemsTotalValue,
    creature, placeable, store );
  sReport += Y_ON + "Lights: " + Y_OFF + IntToString( nLights ) + CR;
  sReport += ReportPlaceables( placeable );
  sReport += Y_ON + "Placed Effects: " + Y_OFF +
    IntToString( nPlacedEffects ) + CR;
  sReport += ReportStores( store );
  sReport += ReportTriggers( trigger );
  sReport += Y_ON + "Waypoints: " + Y_OFF +
    IntToString( nWaypoints ) + CR;
  sReport += "- Map Notes: " + IntToString( nMapNotes ) + CR;
  
  return sReport;
}

// Generate a report string about the basic properties of an area
string ReportAreaProperties( object oArea )
{
  string sReport = "";
  int nWidth = GetAreaSize( AREA_WIDTH, oArea );
  int nHeight = GetAreaSize( AREA_HEIGHT, oArea );
  
  sReport += CR + "<b>Properties</b>" + CR + CR;
  sReport += Y_ON + "Name: " + Y_OFF + GetName( oArea ) + CR;
  sReport += Y_ON + "Width: " + Y_OFF + IntToString( nWidth ) + CR;
  sReport += Y_ON + "Height: " + Y_OFF + IntToString( nWidth ) + CR;
  sReport += Y_ON + "Daytime? " + Y_OFF +
    ( GetIsDay() ? "Yes" : "No" ) + CR;
  sReport += Y_ON + "Underground? " + Y_OFF +
    ( GetIsAreaAboveGround( oArea ) ? "No" : "Yes" ) + CR;
  sReport += Y_ON + "Natural? " + Y_OFF +
    ( GetIsAreaNatural( oArea ) ? "Yes" : "No" ) + CR;
  sReport += Y_ON + "Interior? " + Y_OFF +
    ( GetIsAreaInterior( oArea ) ? "Yes" : "No" ) + CR;
  
  return sReport;
}

// Generate a string containing a report about the area
string GetAreaReport( object oPC )
{
  string sReport = "<b>Area Report</b>" + CR + CR;
  object oArea = GetArea( oPC );
  
  sReport += ReportAreaProperties( oArea );
  sReport += ReportAreaObjects( oArea, oPC );
  
  return sReport;
}

void main() {
  object oPC = (GetPCSpeaker()==OBJECT_INVALID?OBJECT_SELF:GetPCSpeaker());
  if ( !GetIsPC(oPC) )
    oPC = GetFirstPC();
  
  // Generate the report
  string sMsg = GetAreaReport( oPC );
  
  // Display the report
  DisplayMessageBox(
    oPC,   // Display a message box for this PC
    -1,   // string ref to display
    sMsg,   // Message to display
    "",   // Callback for clicking the OK button
    "",   // Callback for clicking the Cancel button
    FALSE,   // Do not display the Cancel button
    "SCREEN_MESSAGEBOX_REPORT", // Display the tutorial message box   
    -1,   // OK string ref
    "",   // OK string
    -1,   // Cancel string ref
    ""    // Cancel string
  );
}

Modifié par rjshae, 05 août 2010 - 02:35 .


#2
rjshae

rjshae
  • Members
  • 4 485 messages
Ah crud, it wiped out the indentation.

Okay, it's fixed now... sort of.

Modifié par rjshae, 04 août 2010 - 03:56 .


#3
.Lv

.Lv
  • Members
  • 6 messages
Wow. I hope you did not create it with the toolset... I did not try the script but I have general coding remarks that I think you should look at.

You should seriously reconsider string ReportAreaObjects(object, object); :
- first of all any function that takes more than one screen full of code should be (there are exceptions though)...
- such a function (using lots of GetFirst*/Next*, looping though many objects..) will probably run into a too many instructions error (use DelayCommand to avoid that).

Dividing your code (especially the above function) into several other functions which are delayed also helps the server's CPU not to cause lag.

Also think about using data structures, nwscript does not provide many but you can use structures (some nwnx plugins do provide some like arrays, string tokenizer..).

Hope that helps you.. at least a bit.


P.S. By the way you can find the formatted script on pastebin...

Modifié par .Lv, 03 août 2010 - 08:59 .


#4
rjshae

rjshae
  • Members
  • 4 485 messages
Thanks for the response. Could the code be written better? Well sure, but it only needs to run once per area, so I didn't sweat the performance. Point taken about the First/Next loops; I'll work on that. But for the most part, I didn't see much benefit in partitioning up the main loop; it's mainly just a bunch of integer incrementations, so I'd just be passing a slew of variables back and forth. But yeah, I could put the variables in structs and use subroutines to divide it up more.

Yes, I used the toolset to edit the script. Shrug.

Okay, it was re-written to use structs and to divide the job into finer grained subroutines. The lack of an ability to call structs by reference makes it somewhat less efficient, but oh well...

Thanks. :)

Modifié par rjshae, 05 août 2010 - 02:37 .


#5
c i p h e r

c i p h e r
  • Members
  • 261 messages
Neat idea. Definitely a good thing for QA purposes. :)