/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | * * -----------------------------------------------------------| \\._.// * * SmaugWiz (C) 1998 by Russ Pillsbury (Windows NT version) | (0...0) * * -----------------------------------------------------------| ).:.( * * SMAUG (C) 1994, 1995, 1996 by Derek Snider | {o o} * * -----------------------------------------------------------| / ' ' \ * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, |~'~.VxvxV.~'~* * Scryn, Swordbearer, Rennard, Tricops, and Gorog. | * * ------------------------------------------------------------------------ * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik Staerfeldt, Tom Madsen, and Katja Nyboe. * ****************************************************************************/ // mobiles.cpp #include "stdafx.h" #include "smaug.h" #include "Smaugx.h" #include "area.h" #include "class.h" #include "affect.h" #include "objects.h" #include "rooms.h" #include "skill.h" #include "Exits.h" CObjData::~CObjData () { STRFREE (m_pName); STRFREE (m_pDescription); STRFREE (m_pShortDescr); STRFREE (m_pActionDesc); while (! ExDesList.IsEmpty ()) delete (CExtraDescrData*) ExDesList.RemoveTail (); ExDesList.RemoveAll (); AffList.RemoveAll (); CMobProgActList *pNpact, *pMpact = mpact; while (pMpact) { pNpact = pMpact->GetNext (); delete pMpact; pMpact = pNpact; } } // Write a single object to a file void CObjData::Write (FILE *fp, int iNest, short StorageType, short ChLevel /* = 0 */) { CAffectData *paf; short wear, wear_loc, x; // Castrate storage characters. (Say what?!) if ((ChLevel && ChLevel < GetLevel ()) || (item_type == ITEM_KEY && ! IsClanObject ())) return; // Catch deleted objects -Thoric if (obj_extracted (this)) return; // Do NOT save prototype items! -Thoric if (IsPrototype ()) return; // Corpse saving. -- Altrag fprintf (fp, (StorageType == OS_CORPSE ? "#CORPSE\n" : "#OBJECT\n")); CObjIndexData &Idx = *GetIndex (); if (iNest) fprintf (fp, "Nest %d\n", iNest); if (count > 1) fprintf (fp, "Count %d\n", count ); if (QUICKMATCH (GetName (), Idx.GetName ()) == 0) fprintf (fp, "Name %s~\n", GetName ()); if (QUICKMATCH (GetShortDescr (), Idx.GetShortDescr ()) == 0) fprintf (fp, "ShortDescr %s~\n", GetShortDescr ()); if (QUICKMATCH (GetDescription (), Idx.GetDescription ()) == 0) fprintf (fp, "Description %s~\n", GetDescription ()); if (QUICKMATCH (GetActionDescr (), Idx.GetActionDescr ()) == 0) fprintf (fp, "ActionDesc %s~\n", GetActionDescr ()); fprintf (fp, "Vnum %d\n", Idx.vnum); if (StorageType == OS_CORPSE && GetInRoom ()) fprintf (fp, "Room %d\n", in_room->vnum); if (m_ExtraFlags != Idx.m_ExtraFlags) fprintf (fp, "ExtraFlags %s\n", m_ExtraFlags.PrintVector ()); if (wear_flags != Idx.wear_flags) fprintf (fp, "WearFlags %d\n", wear_flags); if (GetAntiClassFlags () != Idx.GetAntiClassFlags ()) { for (int cl=0; cl < ClassTable.GetCount (); ++cl) if (IsAntiClass (cl)) fprintf (fp, "AntiClass %s~\n", ClassTable.GetName (cl)); } wear_loc = -1; for (wear = 0; wear < MAX_WEAR; wear++) { for (x = 0; x < MAX_LAYERS; x++) if (save_equipment [wear][x] == this) { wear_loc = wear; break; } else if (! save_equipment [wear][x]) break; } if (wear_loc != -1) fprintf (fp, "WearLoc %d\n", wear_loc); if (item_type != Idx.item_type) fprintf (fp, "ItemType %d\n", item_type); if (weight != Idx.weight) fprintf (fp, "Weight %d\n", weight); if (GetLevel ()) fprintf (fp, "Level %d\n", GetLevel ()); if (timer) fprintf (fp, "Timer %d\n", timer); if (cost != Idx.cost) fprintf (fp, "Cost %d\n", cost); if (value [0] || value [1] || value [2] || value [3] || value [4] || value [5]) fprintf (fp, "Values %d %d %d %d %d %d\n", value [0], value [1], value [2], value [3], value [4], value [5]); switch (item_type) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: if (SkillTable.IsValid (value [1])) fprintf (fp, "Spell 1 '%s'\n", SkillTable.GetName (value [1])); if (SkillTable.IsValid (value [2])) fprintf (fp, "Spell 2 '%s'\n", SkillTable.GetName (value [2])); if (SkillTable.IsValid (value [3])) fprintf (fp, "Spell 3 '%s'\n", SkillTable.GetName (value [3])); break; case ITEM_STAFF: case ITEM_WAND: if (SkillTable.IsValid (value [3])) fprintf (fp, "Spell 3 '%s'\n", SkillTable.GetName (value [3])); break; case ITEM_SALVE: if (SkillTable.IsValid (value [4])) fprintf (fp, "Spell 4 '%s'\n", SkillTable.GetName (value [4])); if (SkillTable.IsValid (value [5])) fprintf (fp, "Spell 5 '%s'\n", SkillTable.GetName (value [5])); break; } POSITION apos = AffList.GetHeadPosition (); while (apos) { paf = AffList.GetNext (apos); // Save extra object affects -Thoric if (paf->type < 0 || paf->type >= SkillTable.GetCount ()) { fprintf (fp, "Affect %d %d %d %d '%s'\n", paf->type, paf->duration, ((paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_STRIPSN) && SkillTable.IsValid (paf->modifier)) ? SkillTable.GetSlot (paf->modifier) : paf->modifier, paf->location, paf->GetVectorName ()); } else fprintf (fp, "AffectData '%s' %d %d %d '%s'\n", SkillTable.GetName (paf->type), paf->duration, ((paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_STRIPSN) && SkillTable.IsValid (paf->modifier)) ? SkillTable.GetSlot (paf->modifier) : paf->modifier, paf->location, paf->GetVectorName ()); } POSITION pos = ExDesList.GetHeadPosition (); while (pos) { CExtraDescrData &Ed = *(CExtraDescrData*) ExDesList.GetNext (pos); fprintf (fp, "ExtraDescr %s~ %s~\n", Ed.keyword, Ed.GetDescription ()); } fprintf (fp, "End\n\n"); } // Create a new INDEX object (for online building) -Thoric // Option to clone an existing index object. CObjIndexData *make_object (int vnum, int cvnum, char *name) { CObjIndexData *pObjIndex, *cObjIndex; char buf [MAX_STRING_LENGTH]; if (cvnum > 0) cObjIndex = OIdxTable.GetObj (cvnum); else cObjIndex = NULL; pObjIndex = new CObjIndexData (vnum); pObjIndex->SetName (name); if (! cObjIndex) { sprintf (buf, "a newly created %s", name); pObjIndex->SetShortDescr (buf); sprintf (buf, "Some god dropped a newly created %s here.", name); pObjIndex->SetDescription (buf); pObjIndex->SetActionDescr (""); pObjIndex->item_type = ITEM_TRASH; pObjIndex->SetPrototype (); pObjIndex->wear_flags = 0; pObjIndex->value [0] = 0; pObjIndex->value [1] = 0; pObjIndex->value [2] = 0; pObjIndex->value [3] = 0; pObjIndex->weight = 1; pObjIndex->cost = 0; } else { pObjIndex->SetShortDescr (cObjIndex->GetShortDescr ()); pObjIndex->SetDescription (cObjIndex->GetDescription ()); pObjIndex->SetActionDescr (cObjIndex->GetActionDescr ()); pObjIndex->item_type = cObjIndex->item_type; pObjIndex->m_ExtraFlags = cObjIndex->m_ExtraFlags; pObjIndex->SetPrototype (); pObjIndex->wear_flags = cObjIndex->wear_flags; pObjIndex->value [0] = cObjIndex->value[0]; pObjIndex->value [1] = cObjIndex->value[1]; pObjIndex->value [2] = cObjIndex->value[2]; pObjIndex->value [3] = cObjIndex->value[3]; pObjIndex->weight = cObjIndex->weight; pObjIndex->cost = cObjIndex->cost; POSITION pos = cObjIndex->ExDesList.GetHeadPosition (); while (pos) { CExtraDescrData &Ced = *(CExtraDescrData*) cObjIndex->ExDesList.GetNext (pos); CExtraDescrData *ed = new CExtraDescrData; ed->keyword = QUICKLINK (Ced.keyword); ed->description = QUICKLINK (Ced.description); pObjIndex->ExDesList.AddTail (ed); top_ed++; } CAffectList &AList = pObjIndex->AffList; POSITION apos = AList.GetHeadPosition (); while (apos) { CAffectData *paf = new CAffectData (*AList.GetNext (apos)); pObjIndex->AddAffect (paf); ++top_affect; } } pObjIndex->count = 0; OIdxTable.Add (pObjIndex, vnum); return pObjIndex; } char* CObjIndexData::Read (FILE* fp, int AreaVersion) { int x1, x2, x3, x4, x5, x6; char letter; char *pLine; pLine = fread_line (fp); m_pName = ParseString (pLine, fp); pLine = fread_line (fp); m_pShortDescr = ParseString (pLine, fp); pLine = fread_line (fp); m_pDescription = ParseString (pLine, fp); pLine = fread_line (fp); m_pActionDesc = ParseString (pLine, fp); // Commented out by Narn, Apr/96 to allow item short descs like // Bonecrusher and Oblivion // m_pShortDescr [0] = LOWER (m_pShortDescr [0]); m_pDescription [0] = UPPER (m_pDescription [0]); pLine = fread_line (fp); item_type = ParseNumber (pLine); m_ExtraFlags.Parse (pLine); wear_flags = ParseNumber (pLine); layers = ParseNumber (pLine); pLine = fread_line (fp); x1 = x2 = x3 = x4 = x5 = x6 = 0; sscanf (pLine, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6); value [0] = x1; value [1] = x2; value [2] = x3; value [3] = x4; value [4] = x5; value [5] = x6; switch (item_type) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: pLine = fread_line (fp); value [1] = SkillTable.Lookup (ParseWord (pLine)); value [2] = SkillTable.Lookup (ParseWord (pLine)); value [3] = SkillTable.Lookup (ParseWord (pLine)); break; case ITEM_STAFF: case ITEM_WAND: pLine = fread_line (fp); value [3] = SkillTable.Lookup (ParseWord (pLine)); break; case ITEM_SALVE: pLine = fread_line (fp); value [4] = SkillTable.Lookup (ParseWord (pLine)); value [5] = SkillTable.Lookup (ParseWord (pLine)); break; } do { pLine = fread_line (fp); if (memcmp (pLine, "AntiClass", 9)) break; pLine += 9; CString s = ParseCString (pLine, fp); CClassData *pClass = ClassTable.Find (s); if (pClass) SetAntiClass (pClass->GetClass ()); else bug ("Unknown AntiClass: %s", NCCP s); } while (1); weight = ParseNumber (pLine); weight = UMAX (1, weight); cost = ParseNumber (pLine); level = ParseNumber (pLine); // Using old rent field for level storage for (;;) { pLine = fread_line (fp); letter = *pLine++; if (letter == 'A') { CAffectData *paf = new CAffectData; pLine = fread_line (fp); paf->location = ParseNumber (pLine); if (paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_STRIPSN || paf->location == APPLY_RECURRINGSPELL) then paf->modifier = slot_lookup (ParseNumber (pLine)); else paf->modifier = ParseNumber (pLine); AddAffect (paf); top_affect++; } else if (letter == 'E') { CExtraDescrData *ed = new CExtraDescrData; pLine = fread_line (fp); ed->keyword = ParseString (pLine, fp); pLine = fread_line (fp); ed->description = ParseString (pLine, fp); ExDesList.AddTail (ed); ++top_ed; } else if (letter == '>') { --pLine; ReadPrograms (pLine, fp); } else { --pLine; break; } } return pLine; // return the next line } // This procedure is responsible for reading any in_file OBJprograms. void CObjIndexData::ReadPrograms (char* pLine, FILE *fp) { char letter; BOOL done = FALSE; if ((letter = *pLine++) != '>') { bug ("Load_objects: vnum %d OBJPROG char", vnum); ThrowSmaugException (SE_OBJPROG); } CMobProgData *pMprg = new CMobProgData; ObjPrgList.AddTail (pMprg); while (! done) { pMprg->type = mprog_name_to_type (ParseWord (pLine)); switch (pMprg->type) { case ERROR_PROG: bug ("Load_objects: vnum %d OBJPROG type.", vnum); ThrowSmaugException (SE_OBJPROG); break; case IN_FILE_PROG: bug ("Error: Object %d. SmaugWiz does not handle " "file Object Progs.", vnum); ThrowSmaugException (SE_OBJPROG); break; default: m_Progtypes.SetBit (pMprg->type); pMprg->arglist = ParseString (pLine, fp); pLine = fread_line (fp); pMprg->comlist = ParseString (pLine, fp); pLine = fread_line (fp); switch (letter = *pLine++) { case '>': pMprg = new CMobProgData; ObjPrgList.AddTail (pMprg); break; case '|': done = TRUE; break; default: bug ("LoadObjects: vnum %d bad OBJPROG.", vnum); ThrowSmaugException (SE_OBJPROG); break; } break; } } } void CObjIndexData::Write (FILE *fp) { fprintf (fp, "#%d\n", vnum); fprintf (fp, "%s~\n", m_pName); fprintf (fp, "%s~\n", m_pShortDescr); fprintf (fp, "%s~\n", m_pDescription); fprintf (fp, "%s~\n", m_pActionDesc); fprintf (fp, "%d %s %d %d\n", item_type, NCCP m_ExtraFlags.PrintVector (), wear_flags, layers); int val0 = value [0]; int val1 = value [1]; int val2 = value [2]; int val3 = value [3]; int val4 = value [4]; int val5 = value [5]; switch (item_type) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: if (SkillTable.IsValid (val1)) val1 = SkillTable.GetSlot (val1); if (SkillTable.IsValid (val2)) val2 = SkillTable.GetSlot (val2); if (SkillTable.IsValid (val3)) val3 = SkillTable.GetSlot (val3); break; case ITEM_STAFF: case ITEM_WAND: if (SkillTable.IsValid (val3)) val3 = SkillTable.GetSlot (val3); break; case ITEM_SALVE: if (SkillTable.IsValid (val4)) val4 = SkillTable.GetSlot (val4); if (SkillTable.IsValid (val5)) val5 = SkillTable.GetSlot (val5); break; } if (val4 || val5) fprintf (fp, "%d %d %d %d %d %d\n", val0, val1, val2, val3, val4, val5); else fprintf (fp, "%d %d %d %d\n", val0, val1, val2, val3); switch (item_type) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: fprintf (fp, "'%s' '%s' '%s'\n", SkillTable.IsValid (value [1]) ? SkillTable.GetName (value [1]) : "NONE", SkillTable.IsValid (value [2]) ? SkillTable.GetName (value [2]) : "NONE", SkillTable.IsValid (value [3]) ? SkillTable.GetName (value [3]) : "NONE"); break; case ITEM_STAFF: case ITEM_WAND: fprintf (fp, "'%s'\n", SkillTable.IsValid (value [3]) ? SkillTable.GetName (value [3]) : "NONE"); break; case ITEM_SALVE: fprintf (fp, "'%s' '%s'\n", SkillTable.IsValid (value [4]) ? SkillTable.GetName (value [4]) : "NONE", SkillTable.IsValid (value [5]) ? SkillTable.GetName (value [5]) : "NONE"); break; } // Save Anti-class flags as class names for (int cl=0; cl < ClassTable.GetCount (); ++cl) if (IsAntiClass (cl)) fprintf (fp, "AntiClass %s~\n", ClassTable.GetName (cl)); fprintf (fp, "%d %d %d\n", weight, cost, level); POSITION pos = ExDesList.GetHeadPosition (); while (pos) { CExtraDescrData &Ed = *(CExtraDescrData*) ExDesList.GetNext (pos); fprintf (fp, "E\n%s~\n%s~\n", Ed.keyword, strip_cr (Ed.description)); } POSITION apos = AffList.GetHeadPosition (); while (apos) { CAffectData *paf = AffList.GetNext (apos); fprintf (fp, "A\n%d %d\n", paf->location, ((paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_STRIPSN) && SkillTable.IsValid (paf->modifier)) ? SkillTable.GetSlot (paf->modifier) : paf->modifier); } if (! ObjPrgList.IsEmpty ()) { POSITION pos = ObjPrgList.GetHeadPosition (); while (pos) { CMobProgData &Oprg = *(CMobProgData*) ObjPrgList.GetNext (pos); fprintf (fp, "> %s %s~\n%s~\n", mprog_type_to_name (Oprg.type), Oprg.arglist, strip_cr (Oprg.comlist)); } fprintf (fp, "|\n"); } } // clean out an object (index) (leave list pointers intact) -Thoric void CObjIndexData::Clear () { STRFREE (m_pName); STRFREE (m_pShortDescr); STRFREE (m_pDescription); STRFREE (m_pActionDesc); item_type = 0; m_AntiClassFlags.Empty (); m_ExtraFlags.Empty (); wear_flags = 0; count = 0; weight = 0; cost = 0; value [0] = 0; value [1] = 0; value [2] = 0; value [3] = 0; top_affect -= AffList.GetCount (); AffList.RemoveAll (); while (! ExDesList.IsEmpty ()) delete (CExtraDescrData*) ExDesList.RemoveTail (); ExDesList.RemoveAll (); } CObjIndexData::~CObjIndexData () { while (! ExDesList.IsEmpty ()) delete (CExtraDescrData*) ExDesList.RemoveTail (); ExDesList.RemoveAll (); AffList.RemoveAll (); while (! ObjPrgList.IsEmpty ()) delete (CMobProgData*) ObjPrgList.RemoveTail (); ObjPrgList.RemoveAll (); m_ObjList.RemoveAll (); } CObjIndexData *CObjIdxTable::Find (int vnum) { if (vnum < 0) return NULL; CObjIndexData *pIdx; for (pIdx = GetFirst (vnum); pIdx; pIdx = pIdx->GetNext ()) if (pIdx->vnum == vnum) return pIdx; return NULL; } // Translates obj virtual number to its obj index struct. // Hash table lookup. CObjIndexData *CObjIdxTable::GetObj (int vnum, BOOL bBug /* = FALSE */) { if (vnum < 0) vnum = 0; CObjIndexData *pIdx = Find (vnum); if (! pIdx && bBug) bug ("OIdxTable.GetObj: bad vnum %d.", vnum); return pIdx; } void CObjIdxTable::Add (CObjIndexData *pIndex, int vnum) { pIndex->SetNext (GetFirst (vnum)); SetFirst (GetHash (vnum), pIndex); ++m_Count; } void CObjIdxTable::Remove (CObjIndexData* pIdx) { CObjIndexData *tmp, *prev = NULL; int iHash = GetHash (pIdx->vnum); // Take the room index out of the hash list. for (tmp = m_ot [iHash]; tmp && tmp != pIdx; tmp = tmp->GetNext ()) prev = tmp; if (tmp) { if (prev) prev->SetNext (pIdx->GetNext ()); else m_ot [iHash] = pIdx->GetNext (); --m_Count; } } void CObjIdxTable::RemoveAll () { CObjIndexData *pNidx, *pIdx; for (int hash = 0; hash < MAX_KEY_HASH; ++hash) { pIdx = GetFirstByHash (hash); while (pIdx) { pNidx = pIdx->GetNext (); delete pIdx; pIdx = pNidx; } } Empty (); // clear pointers and count } void CObjectList::AddByLevel (CObjData* pObj, BOOL bLevSort) { BOOL bIns = FALSE; if (bLevSort) { POSITION CurPos, pos = GetHeadPosition (); while (pos) { CurPos = pos; if (GetNext (pos)->GetLevel () < pObj->GetLevel ()) { InsertBefore (CurPos, pObj); bIns = TRUE; break; } } } if (! bIns) CPtrList::AddTail (pObj); m_Loaded += pObj->count; } void CObjectList::AddTail (CObjData* obj) { CPtrList::AddTail (obj); m_Loaded += obj->count; } void CObjectList::Remove (CObjData* obj) { POSITION pos = Find (obj); if (pos) { RemoveAt (pos); m_Loaded -= obj->count; } } int CParseinfo::GetCount (ObjCountTypes type) { int count = 0; AApos = AllAreasList.GetHeadPosition (); while (AApos) { pAreaList = (CAreaList*) AllAreasList.GetNext (AApos); Apos = pAreaList->GetHeadPosition (); while (Apos) { CAreaData &Area = *pAreaList->GetNext (Apos); Ipos = Area.m_ObjIdxList.GetHeadPosition (); while (Ipos) { CObjIndexData &Idx = *(CObjIndexData*) Area.m_ObjIdxList.GetNext (Ipos); count += (type == COUNT_OBJS) ? Idx.m_ObjList.GetCount () : Idx.GetCount (); } } } return count; } // ParseAllObjects uses the CParseInfo structure to keep track of it's // current position. It returns each Object in each ObjectIndex in each // Area, and returns NULL when done. CObjData *CParseinfo::Parse (CAreaList& AList) { if (bFirst) { Apos = AList.GetHeadPosition (); bFirst = FALSE; } while (! Opos) { // if end of object list get next object list while (! Ipos) { // if end of index list get next index list if (! Apos) // if end of area list, done. return NULL; pIdxList = &AList.GetNext (Apos)->m_ObjIdxList; Ipos = pIdxList->GetHeadPosition (); } pObjList = &((CObjIndexData*) pIdxList->GetNext (Ipos))->m_ObjList; Opos = pObjList->GetHeadPosition (); } return pObjList->GetNext (Opos); } CObjData *CParseinfo::ParseAreaLists (CPtrList& AllAreasList) { if (bFirst) { AApos = AllAreasList.GetHeadPosition (); bFirst = FALSE; } while (! Opos) { // if end of object list get next object list while (! Ipos) { // if end of index list get next index list while (! Apos) {// if end of area list get next area list if (! AApos) // if end of all areas list, done. return NULL; pAreaList = (CAreaList*) AllAreasList.GetNext (AApos); Apos = pAreaList->GetHeadPosition (); } pIdxList = &pAreaList->GetNext (Apos)->m_ObjIdxList; Ipos = pIdxList->GetHeadPosition (); } pObjList = &((CObjIndexData*) pIdxList->GetNext (Ipos))->m_ObjList; Opos = pObjList->GetHeadPosition (); } return pObjList->GetNext (Opos); } // Clean out the object list void CObjectList::RemoveAll () { while (! IsEmpty ()) delete RemoveTail (); CPtrList::RemoveAll (); m_Loaded = 0; } CString CObjData::AntiClassNames () { CString s; for (int cl=0; cl < ClassTable.GetCount (); ++cl) if (IsAntiClass (cl)) { s += " Anti-"; s += ClassTable.GetName (cl); } return s; } BOOL CObjData::CanGo (short door) { CExitData &Ex = *GetExit (door); if (! &Ex) return FALSE; return Ex.GetToRoom () && ! Ex.IsDisabled () && ! Ex.IsClosed (); } // return TRUE if an object contains a trap -Thoric BOOL CObjData::IsTrapped () const { if (m_Content.IsEmpty ()) return FALSE; POSITION pos = m_Content.GetHeadPosition (); while (pos) if (m_Content.GetNext (pos)->item_type == ITEM_TRAP) return TRUE; return FALSE; } CExtraDescrData::~CExtraDescrData () { STRFREE (description); STRFREE (keyword); --top_ed; } #ifdef _DEBUG void CObjIndexData::Dump (CDumpContext& dc) const { CObject::Dump (dc); dc << "CObjIndexData Name: " << m_pName << "\n"; } void CObjData::Dump (CDumpContext& dc) const { // if (! memcmp (m_pName, "glass", 5)) { CObject::Dump (dc); dc << "CObjData Name: " << m_pName << "\n"; // } } #endif