All Projects


IDSeverity[[state]]OpenedOpened byAssigned ToSummary[[changedby]]Last EditedPrivate
 6227 Medium20.11.2013Ralph CampbellDavide VescoviniTuathanach Problems creating new Platinum Steel blades 01.01.2014No5 Task Description

The main problem is that there seems to be no step to make Platinum Steel X Brittle Blade. (where X != Longsword)

Shape 5 Heated Platinum Steel Ingots into Platinum Steel Knife Alpha Blade using Anvil with a Hammer. (OK)
Forge Platinum Steel Knife Alpha Blade into Heated Platinum Steel Knife Alpha Blade using Forge. (OK)
Forge Heated Platinum Steel Knife Alpha Blade into Super Heated Platinum Steel Knife Alpha Blade using Forge. (OK)
Forge Super Heated Platinum Steel Knife Alpha Blade into Red Hot Platinum Steel Knife Alpha Blade using Forge. (OK)
⇒ no step for Quench Red Hot Platinum Steel Knife Alpha Blade into Platinum Steel Knife Brittle Blade. (it goes back to Alpha Blade)

I never noticed before, but it seems you can:
Sharpen Brittle X Blade into X Blade using Sharpening Stone.
for all types of blades. This seems like a shortcut (I suppose you get a lower quality blade).

Many rules using Master Crafted Hammer seem to be missing.

Quenching takes a long time compared to Platinum Steel Longswords or other blades.

Dropping a stack (>1 item) of Platinum Steel Ingots into the Forge with
“Forging Platinum Steel Blades” in mind, you don’t know what is going to happen.
But works OK if dropped as single ingots (they become heated).
Same is true for Platinum Steel Stocks.
This differs from the way other metals work which I suppose is OK, just odd.

 6178 Low08.10.2013Ralph CampbellRalph Campbell Remove redundant and confusing definitions for ANY_BULK ...10.10.2013No Task Description

ANY_BULK_SLOT and ANY_EMPTY_BULK_SLOT are aliases of PSCHARACTER_SLOT_NONE
and PSCHARACTER_SLOT_STORAGE. This is rather confusing and dangerous since
it could lead to something being placed in storage that was not intended.

Index: src/server/bulkobjects/pscharacter.h
===================================================================
--- src/server/bulkobjects/pscharacter.h	(revision 8857)
+++ src/server/bulkobjects/pscharacter.h	(working copy)
@@ -560,13 +560,6 @@
 
 //-----------------------------------------------------------------------------
 
-
-#define ANY_BULK_SLOT        -1
-#define ANY_EMPTY_BULK_SLOT  -2
-
-
-//-----------------------------------------------------------------------------
-
 struct Stance
 {
     unsigned int stance_id;
Index: src/server/bulkobjects/pscharinventory.cpp
===================================================================
--- src/server/bulkobjects/pscharinventory.cpp	(revision 8857)
+++ src/server/bulkobjects/pscharinventory.cpp	(working copy)
@@ -738,10 +738,10 @@
     if (container)
         stack = false;
 
-    /** If we were passed ANY_BULK_SLOT or ANY_EMPTY_BULK_SLOT we need to scan the possible
+    /** If we were passed PSCHARACTER_SLOT_NONE we need to scan the possible
      * slots and try to find a valid place to put this item.  (non-negative slot number)
      * Otherwise, we'll just skip over these and attempt to place in the given slot.  If
-     * that fails, we'll return false and possibly call this again specifying ANY_BULK_SLOT.
+     * that fails, we'll return false and possibly call this again specifying PSCHARACTER_SLOT_NONE.
      */
     size_t i;
     size_t itemIndex = SIZET_NOT_FOUND;
@@ -749,7 +749,7 @@
 
 
     // Next see if we can stack this with an existing stack in inventory
-    if (stack && slot == ANY_BULK_SLOT && item->GetIsStackable())
+    if (stack && slot == PSCHARACTER_SLOT_NONE && item->GetIsStackable())
     {
 
         itemIndices = FindCompatibleStackedItems(item, true, precise);
Index: src/server/bulkobjects/pscharinventory.h
===================================================================
--- src/server/bulkobjects/pscharinventory.h	(revision 8857)
+++ src/server/bulkobjects/pscharinventory.h	(working copy)
@@ -76,8 +76,6 @@
 
 //-----------------------------------------------------------------------------
 
-#define ANY_EMPTY_BULK_SLOT  -2
-
 /** This class handles the details behind a characters inventory system.
   */
 class psCharacterInventory
@@ -234,7 +232,7 @@
      * @param test Are we just testing if we can put this into the slot
      * @param stack Should the item be stacked?
      * @param slot The slot in which we want to place an item.
-     *             (may be a slot number, ANY_BULK_SLOT, or ANY_EMPTY_BULK_SLOT)
+     *             (may be a slot number, or PSCHARACTER_SLOT_NONE)
      * @param container Pointer to container.
      * @param precise Says whathever if the stacking should be precise and not ignore
      *                properties like quality.
Index: src/server/bulkobjects/psinventorycachesvr.cpp
===================================================================
--- src/server/bulkobjects/psinventorycachesvr.cpp	(revision 8857)
+++ src/server/bulkobjects/psinventorycachesvr.cpp	(working copy)
@@ -66,9 +66,9 @@
 
 bool psInventoryCacheServer::ClearSlot(INVENTORY_SLOT_NUMBER slot)
 {
-    if (slot<ANY_EMPTY_BULK_SLOT || slot>=PSCHARACTER_SLOT_BULK_END)
+    if (slot<0 || slot>=PSCHARACTER_SLOT_BULK_END)
     {
-        SetCacheStatus(INVALID);    // somethings gone wrong; force entire
+        SetCacheStatus(INVALID);    // something has gone wrong; force entire
                                     // inventory update next time
         return false;
     }

FIXME

 6169 Low01.10.2013Ralph CampbellRalph Campbell Fix container ID for wooden bowl contents. 01.10.2013No Task Description

The standalone server database defines 3 items that should be in the wooden bowl but have the wrong container ID.
Just create the database before and after the change to verify the fix.

Index: src/server/database/mysql/item_instances.sql
===================================================================
--- src/server/database/mysql/item_instances.sql	(revision 8828)
+++ src/server/database/mysql/item_instances.sql	(working copy)
@@ -134,9 +134,9 @@
 
 # Wooden bowl and contents
 INSERT INTO `item_instances` VALUES (75,0,0,0,0,1,0,0,0,3,-3.7,1.07,-180.58,0,0,0,0,50,50,70,0,'NOPICKUP',0,-1,'','','',NULL,'0',0,0,0);
-INSERT INTO `item_instances` VALUES (76,0,2,70,1,1,0,0,0,3,0,0,0,0,0,0,0,50,-1,60,0,'',0,-1,'','','',NULL,'0',0,0,0);
-INSERT INTO `item_instances` VALUES (77,0,2,70,2,2,0,0,0,3,0,0,0,0,0,0,0,50,-1,61,0,'',0,-1,'','','',NULL,'0',0,0,0);
-INSERT INTO `item_instances` VALUES (78,0,2,70,3,7,0,0,0,3,0,0,0,0,0,0,0,50,-1,62,0,'',0,-1,'','','',NULL,'0',0,0,0);
+INSERT INTO `item_instances` VALUES (76,0,2,75,1,1,0,0,0,3,0,0,0,0,0,0,0,50,-1,60,0,'',0,-1,'','','',NULL,'0',0,0,0);
+INSERT INTO `item_instances` VALUES (77,0,2,75,2,2,0,0,0,3,0,0,0,0,0,0,0,50,-1,61,0,'',0,-1,'','','',NULL,'0',0,0,0);
+INSERT INTO `item_instances` VALUES (78,0,2,75,3,7,0,0,0,3,0,0,0,0,0,0,0,50,-1,62,0,'',0,-1,'','','',NULL,'0',0,0,0);
 
 # Book container and contents
 INSERT INTO `item_instances` VALUES (80,0,0,0,0,1,0,0,0,3,-56.16,-3,-154.73,0,4.74,0,0,50,50,234,0,'NOPICKUP',0,-1,'','','',NULL,'0',0,0,0);

FIXME

 6163 Medium24.09.2013Ralph Campbell clean up (most) compiler warnings 26.09.2013No1 Task Description

If you do “./configure –enable-debug” and compile PS, you will see a lot of compiler warnings.
These changes will fix most of the warnings. I left out the changes for -Wreorder.

Index: src/client/charapp.cpp
===================================================================
--- src/client/charapp.cpp	(revision 8809)
+++ src/client/charapp.cpp	(working copy)
@@ -1332,7 +1332,7 @@
         trait = trait->next_trait;
     }
 
-    return true;
+    return result;
 }
 
 void psCharAppearance::DefaultMaterial(csString& part)
Index: src/client/clientsongmngr.cpp
===================================================================
--- src/client/clientsongmngr.cpp	(revision 8809)
+++ src/client/clientsongmngr.cpp	(working copy)
@@ -62,7 +62,7 @@
 {
     // updating state
     sheet = musicalSheet;
-    mainSongID = PENDING;
+    mainSongID = (uint)PENDING;
 
     // request to server
     psMusicalSheetMessage musicalSheetMessage(0, itemID, true, true, "", sheet);
@@ -97,7 +97,7 @@
 
     // checking main player song
     if(mainSongID != NO_SONG
-       && mainSongID != PENDING
+       && mainSongID != (uint)PENDING
        && !sndMngr->IsSoundValid(mainSongID))
     {
         StopMainPlayerSong(false);
@@ -209,7 +209,7 @@
         {
             csString errorStr;
 
-            if(mainSongID == PENDING) // no instrument equipped, invalid MusicXML or low skill
+            if(mainSongID == (uint)PENDING) // no instrument equipped, invalid MusicXML or low skill
             {
                 // updating mainSongId
                 mainSongID = NO_SONG;
Index: src/client/gui/pawsactivemagicwindow.cpp
===================================================================
--- src/client/gui/pawsactivemagicwindow.cpp	(revision 8809)
+++ src/client/gui/pawsactivemagicwindow.cpp	(working copy)
@@ -278,9 +278,7 @@
 
 void pawsActiveMagicWindow::AutoResize()
 {
-    int horizPadding = 0,
-        vertPadding = 0,
-        buffSize = 0,
+    int buffSize = 0,
         t = 0;
 
     if(!buffList)
Index: src/client/gui/pawsdndbutton.cpp
===================================================================
--- src/client/gui/pawsdndbutton.cpp	(revision 8809)
+++ src/client/gui/pawsdndbutton.cpp	(working copy)
@@ -285,6 +285,7 @@
 
 bool pawsDnDButton::OnMouseDown(int button, int modifiers, int x, int y)
 {
+#if 0
     bool empty;
 
     if(GetMaskingImage())
@@ -299,6 +300,7 @@
     {
         empty = true;
     }
+#endif
 
     if(button==csmbLeft && (dragDrop || psengine->GetSlotManager()->IsDragging()))
     {
Index: src/client/gui/pawsscrollmenu.cpp
===================================================================
--- src/client/gui/pawsscrollmenu.cpp	(revision 8809)
+++ src/client/gui/pawsscrollmenu.cpp	(working copy)
@@ -111,8 +111,6 @@
 
 bool pawsScrollMenu::PostSetup()
 {
-    size_t i;
-
     //set defaults
     buttonHeight = screenFrame.Height();
     buttonWidth = buttonHeight;
@@ -205,7 +203,7 @@
 
         if(screenFrame.Width() > screenFrame.Height())   //horizontal case
         {
-            //leftEdge =  (LeftScrollMode>ScrollMenuOptionDISABLED?buttonHeight/2 + BUTTON_PADDING:0) \
+            //leftEdge =  (LeftScrollMode>ScrollMenuOptionDISABLED?buttonHeight/2 + BUTTON_PADDING:0)
             //            + (EditLockMode>0?buttonHeight/2:0) +BUTTON_PADDING;
             //edgeSpace = leftEdge + (RightScrollMode>ScrollMenuOptionDISABLED?buttonHeight/2 + BUTTON_PADDING:0);
             leftEdge = (LeftScrollMode!=ScrollMenuOptionDISABLED?buttonHeight/2:0) \
@@ -287,11 +285,11 @@
         int buttonCol = buttonLocation==0?BUTTON_PADDING:buttonLocation,
             buttonRow = 1;
 
-        for(int i=0; i<Buttons.GetSize(); i++)
+        for(size_t i=0; i<Buttons.GetSize(); i++)
         {
             if(!Buttons[i])
             {
-                printf("pawsScrollMenu::OnResize - ERROR Button[ %i ] is null\n", i);
+                printf("pawsScrollMenu::OnResize - ERROR Button[ %zi ] is null\n", i);
                 continue;
             }
             //perform layout
@@ -494,7 +492,7 @@
     {
         case 101:    //Edit Lock Button - prevents editing & drag-n-drop
         {
-            for(int i=0; i<Buttons.GetSize(); i++)
+            for(size_t i=0; i<Buttons.GetSize(); i++)
             {
                 ((pawsDnDButton*)Buttons[i])->SetDnDLock(EditLockButton->GetState());
             }
@@ -521,7 +519,7 @@
 
 bool pawsScrollMenu::LoadArrays(csArray<csString> &name, csArray<csString> &icon, csArray<csString> &toolTip, csArray<csString> &action, int baseIndex, pawsWidget* widget)
 {
-    int innerSize = 0;
+    size_t innerSize = 0;
 
     if(widget)
     {
@@ -545,10 +543,8 @@
         innerSize = innerSize<toolTip.GetSize()?toolTip.GetSize():innerSize;
     }
 
-    for(int i=0; i<innerSize; i++)
+    for(size_t i=0; i<innerSize; i++)
     {
-        int buttonPos;
-
         pawsDnDButton* button;
         button = new pawsDnDButton;
         ButtonHolder->AddChild(button);
@@ -587,11 +583,9 @@
 
 bool pawsScrollMenu::LoadSingle(csString name, csString icon, csString toolTip, csString action, int Index, pawsWidget* widget, bool IsEnabled)
 {
-    int buttonPos;
-
     pawsDnDButton* button;
     button = new pawsDnDButton;
-    if(Index>Buttons.GetSize() || Index==-1)
+    if((size_t)Index>Buttons.GetSize() || Index==-1)
     {
         //append
         ButtonHolder->AddChild(button);
@@ -636,12 +630,9 @@
 
     if(match!=NULL)
     {
-        int preRemovalSize = ButtonHolder->GetChildrenCount(),
-            postRemovalSize = 0;
         ButtonHolder->RemoveChild(match);
-        postRemovalSize = ButtonHolder->GetChildrenCount();
 
-        for(int i=0; i<Buttons.GetSize(); i++)
+        for(size_t i=0; i<Buttons.GetSize(); i++)
         {
             if(Buttons[i]==match)
             {
@@ -682,7 +673,7 @@
 {
     int total=0;
 
-    for(int i=0; i< Buttons.GetSize(); i++)
+    for(size_t i=0; i< Buttons.GetSize(); i++)
     {
         if(Buttons[i])
             total+= CalcButtonSize((pawsDnDButton*)Buttons[i]);
@@ -801,7 +792,7 @@
     else
     {
         EditLockMode=false;
-        for(int i=0; i<Buttons.GetSize(); i++)
+        for(size_t i=0; i<Buttons.GetSize(); i++)
         {
             ((pawsDnDButton*)Buttons[i])->SetDnDLock(false);
         }
Index: src/client/gui/pawssheetline.cpp
===================================================================
--- src/client/gui/pawssheetline.cpp	(revision 8809)
+++ src/client/gui/pawssheetline.cpp	(working copy)
@@ -360,7 +360,7 @@
     int vCPos;                  // vertical position of the central C
 
     int prevNotePos;
-    int lastDownNote;           // position of the last note that must be drawn downwards
+    size_t lastDownNote;        // position of the last note that must be drawn downwards
 
     size_t notesLength = notes.GetSize();
 
@@ -440,7 +440,7 @@
     // drawing chord
     for(size_t i = 0; i < notesLength; i++)
     {
-        short int notePos = notes[i].position;
+        int notePos = notes[i].position;
 
         int nextHPosUpString = horizontalPos;
         int nextHPosLowString = horizontalPos;
@@ -1557,7 +1557,7 @@
         size = newSize;
     }
 
-    if(noteLength != pawsLine->noteCharLength)
+    if(noteLength != (uint)pawsLine->noteCharLength)
     {
         isChanged = true;
         noteLength = pawsLine->noteCharLength;
Index: src/client/gui/shortcutwindow.cpp
===================================================================
--- src/client/gui/shortcutwindow.cpp	(revision 8809)
+++ src/client/gui/shortcutwindow.cpp	(working copy)
@@ -322,7 +322,6 @@
         {
             //get a ptr to the txture manager so we can look at the elementList, which stores the icon names.
             pawsTextureManager *tm = PawsManager::GetSingleton().GetTextureManager();
-            int i = tm->elementList.GetSize();
         
             //build an array of the icon names
             csHash<csRef<iPawsImage>, csString>::GlobalIterator Iter(tm->elementList.GetIterator());
@@ -367,7 +366,7 @@
                 {
                     //remove key bindings
                     csString editedCmd;
-                    editedCmd.Format("Shortcut %d",edit+1);
+                    editedCmd.Format("Shortcut %zd",edit+1);
                     psengine->GetCharControl()->RemapTrigger(editedCmd,psControl::NONE,0,0);
 
                     ((pawsDnDButton *)editedButton)->Clear();
@@ -650,7 +649,7 @@
     CommandFileName.Insert( 0, "/planeshift/userdata/options/shortcutcommands_" );
     CommandFileName.Append( ".xml" );
     bool found = false;
-    int i;
+    size_t i;
     for (i = 0;i < cmds.GetSize();i++)
     {
         if (cmds[i].IsEmpty())
@@ -677,12 +676,12 @@
         if (cmds[i].IsEmpty())
             continue;
         parent = parentMain->CreateNodeBefore (CS_NODE_ELEMENT);
-        temp.Format("shortcut%d", i + 1);
+        temp.Format("shortcut%zd", i + 1);
         parent->SetValue(temp);
 
         if (names[i].IsEmpty())
         {
-            temp.Format("%d", i);
+            temp.Format("%zd", i);
             parent->SetAttribute("name", temp);
         }
         else
@@ -820,7 +819,7 @@
         return true;
 
     csString editedCmd;
-    editedCmd.Format("Shortcut %d",edit+1);
+    editedCmd.Format("Shortcut %zd",edit+1);
 
     bool changed = false;
 
Index: src/client/gui/shortcutwindow.h
===================================================================
--- src/client/gui/shortcutwindow.h	(revision 8809)
+++ src/client/gui/shortcutwindow.h	(working copy)
@@ -142,7 +142,7 @@
 
     csString buttonBackgroundImage;
 
-    int edit;
+    size_t edit;
     pawsWidget *editedButton;
 
     virtual void HandleMessage(MsgEntry *msg);
Index: src/client/pscamera.cpp
===================================================================
--- src/client/pscamera.cpp	(revision 8809)
+++ src/client/pscamera.cpp	(working copy)
@@ -725,7 +725,6 @@
     csVector3 oldTarget = GetTarget(CAMERA_ACTUAL_DATA);
     view->GetCamera()->OnlyPortals(true);
     bool mirrored = view->GetCamera()->IsMirrored();
-    csVector3 oldOrigin = view->GetCamera()->GetTransform().GetOrigin();
 
     // Do a hitbeam between Position and Target to find the correct sector and coordinates.
     view->GetCamera()->GetTransform().SetOrigin(actorPos);
@@ -1708,11 +1707,10 @@
 {
     float cosYaw, sinYaw;
     float cosPit, sinPit;
-    float cosRol, sinRol;
+    // at this point, our camera doesn't support Roll
 
     cosYaw = cosf(GetYaw(mode));    sinYaw = sinf(GetYaw(mode));
     cosPit = cosf(GetPitch(mode));  sinPit = sinf(GetPitch(mode));
-    cosRol = 1.0f;                        sinRol = 0.0f;  // at this point, our camera doesn't support Roll
 
     if (cosPit == 0.0f)
         cosPit = 0.001f;
@@ -1739,11 +1737,10 @@
 {
     float cosYaw, sinYaw;
     float cosPit, sinPit;
-    float cosRol, sinRol;
+    // at this point, our camera doesn't support Roll
 
     cosYaw = cosf(GetYaw(mode));    sinYaw = sinf(GetYaw(mode));
     cosPit = cosf(GetPitch(mode));  sinPit = sinf(GetPitch(mode));
-    cosRol = 1.0f;                        sinRol = 0.0f;  // at this point, our camera doesn't support Roll
 
     if (cosPit == 0.0f)
         cosPit = 0.001f;
@@ -1847,7 +1844,6 @@
     const float INITIAL_DISTANCE = 200;     // we begin from this value
     static bool calledFirstTime = true;
 
-    static csTicks lastTime;                // when was this method last called ?
     csTicks currTime;                       // the current time
     static float lastChangeTime;            // when did we change the distance last time ?
 
@@ -1860,7 +1856,6 @@
     if (calledFirstTime)
     {
         calledFirstTime = false;
-        lastTime = csGetTicks();
         lastChangeTime = csGetTicks();
         return;
     }
@@ -1908,8 +1903,6 @@
     }
 
     //Error2("%s", debug.GetData());
-
-    lastTime = currTime;
 }
 
 
Index: src/common/effects/pseffectmanager.cpp
===================================================================
--- src/common/effects/pseffectmanager.cpp	(revision 8809)
+++ src/common/effects/pseffectmanager.cpp	(working copy)
@@ -219,7 +219,6 @@
 
 bool psEffectManager::LoadFromDirectory(const csString & path, bool includeSubDirs, iView * parentView)
 {
-    bool success = true;
 #ifndef DONT_DO_EFFECTS
     csRef<iVFS> vfs =  csQueryRegistry<iVFS> (psCSSetup::object_reg);
     assert(vfs);
@@ -256,7 +255,7 @@
             {
                 if (!LoadFromDirectory(file, true, parentView))
                 {
-                    success = false;
+                    return false;
                 }
             }
         }
Index: src/common/music/scoreelements.cpp
===================================================================
--- src/common/music/scoreelements.cpp	(revision 8809)
+++ src/common/music/scoreelements.cpp	(working copy)
@@ -102,7 +102,7 @@
         if(nameHash == 0)
         {
             nameHash = &prevAccidentals.Put(note.octave,
-                csHash<Accidental, char>::csHash(PREV_ACCIDENTALS_NAME_SIZE));
+                csHash<Accidental, char>(PREV_ACCIDENTALS_NAME_SIZE));
             nameHash->Put(note.name, note.writtenAccidental);
         }
         else
@@ -398,7 +398,6 @@
     else if(currDuration < measDuration) // fill
     {
         Duration tempDuration;
-        MeasureElement* rest = 0;
 
         while(currDuration < measDuration)
         {
Index: src/common/music/scoreelements.h
===================================================================
--- src/common/music/scoreelements.h	(revision 8809)
+++ src/common/music/scoreelements.h	(working copy)
@@ -63,6 +63,8 @@
      */
     MeasureElement(Duration duration);
 
+    virtual ~MeasureElement() {}
+
     /**
      * Get the duration of this element.
      *
Index: src/common/paws/pawstextbox.cpp
===================================================================
--- src/common/paws/pawstextbox.cpp	(revision 8809)
+++ src/common/paws/pawstextbox.cpp	(working copy)
@@ -36,6 +36,7 @@
 #include "util/log.h"
 #include "util/strutil.h"
 #include "util/psstring.h"
+#include "util/psconst.h"
 
 #define BORDER_SIZE            2 // For pawsFadingTextBox
 
@@ -651,7 +652,7 @@
         }
 
         last = message.FindLast("\n");
-        if(last == (size_t)-1)
+        if(last == SIZET_NOT_FOUND)
         {
             cutMessages.Push(message);
             break;
@@ -720,12 +721,12 @@
         while(textStart < messageText.Length())
         {
             size_t pos = messageText.FindFirst(ESCAPECODE, textStart);
-            if(pos == (size_t) - 1)
+            if(pos == SIZET_NOT_FOUND)
                 textEnd = messageText.Length();
             else
                 textEnd = pos;
 
-            if(textStart == 0 && pos == (size_t) - 1)
+            if(textStart == 0 && pos == SIZET_NOT_FOUND)
             {
                 int dummyX = -1;
                 SplitMessage(messageText, colour, size, msgLine, dummyX);
@@ -744,7 +745,7 @@
             }
             textStart = textEnd;
 
-            if(pos != (size_t)-1 && pos + LENGTHCODE <= messageText.Length())
+            if(pos != SIZET_NOT_FOUND && pos + LENGTHCODE <= messageText.Length())
             {
                 int r, g, b;
                 if(!psColours::ParseColour(messageText.GetData() + pos, r, g, b, size))
@@ -1339,7 +1340,7 @@
         {
             if(cursorPosition >= text.Length())
                 break;
-            if(cursorPosition != (size_t)-1)
+            if(cursorPosition != SIZET_NOT_FOUND)
             {
                 if(pawsTextBox::CountCodePoints(text, 0, cursorPosition) - pawsTextBox::CountCodePoints(text, 0, start) < 5)
                     start = (int)pawsTextBox::RewindCodePoints(text, cursorPosition, 5);
@@ -1586,7 +1587,7 @@
         csString tmpString;
         size_t oldSpace = 0;
         size_t foundSpace = text.Find(" ", oldSpace);
-        while(foundSpace != (size_t)-1)
+        while(foundSpace != SIZET_NOT_FOUND)
         {
             text.SubString(tmpString, oldSpace, foundSpace-oldSpace);
             // now do the spellchecking
@@ -1711,7 +1712,6 @@
 
 void pawsMultiLineTextBox::OrganizeText(const char* newText)
 {
-    int greyedOut = 0;
     csString text(newText);
 
     // Check if we end with \n
@@ -1821,7 +1821,7 @@
 
     psString str(newText);
     size_t pos = str.FindSubString("\r");
-    while(pos != (size_t)-1)
+    while(pos != SIZET_NOT_FOUND)
     {
         str = str.Slice(0,pos) + "\n" + str.Slice(pos+2,str.Length()-pos-2);
         pos = str.FindSubString("\r");
@@ -2179,7 +2179,7 @@
     currentPageNum = 0;
     psString str(newText);
     size_t pos = str.FindSubString("\r");
-    while(pos != (size_t)-1)
+    while(pos != SIZET_NOT_FOUND)
     {
         str = str.Slice(0,pos) + "\n" + str.Slice(pos+2,str.Length()-pos-2);
         pos = str.FindSubString("\r");
@@ -2628,11 +2628,11 @@
     }
 
     csString temp = srcs;
-    unsigned int pos;
-    unsigned int sz = 0;
+    size_t pos;
+    size_t sz = 0;
 
     //process the src attribute and push corresponding PictureInfo into picsInfo array
-    while((pos = temp.FindFirst(';')) != -1)
+    while((pos = temp.FindFirst(';')) != SIZET_NOT_FOUND)
     {
         csString sub;
         temp.SubString(sub,0,pos);
@@ -2757,7 +2757,7 @@
 
     psString str(newtext);
     size_t pos = str.FindSubString("\r");
-    while(pos != (size_t)-1)
+    while(pos != SIZET_NOT_FOUND)
     {
         str = str.Slice(0, pos) + "\n" + str.Slice(pos+2, str.Length()-pos-2);
         pos = str.FindSubString("\r");
@@ -3002,11 +3002,11 @@
     }
 
     csString temp = srcs;
-    unsigned int pos;
-    unsigned int sz = 0;
+    size_t pos;
+    size_t sz = 0;
 
     //process the src attribute and push corresponding PictureInfo into picsInfo array
-    while((pos = temp.FindFirst(';')) != -1)
+    while((pos = temp.FindFirst(';')) != SIZET_NOT_FOUND)
     {
         csString sub;
         temp.SubString(sub,0,pos);
@@ -3131,7 +3131,7 @@
 
     psString str(newtext);
     size_t pos = str.FindSubString("\r");
-    while(pos != (size_t)-1)
+    while(pos != SIZET_NOT_FOUND)
     {
         str = str.Slice(0, pos) + "\n" + str.Slice(pos+2, str.Length()-pos-2);
         pos = str.FindSubString("\r");
Index: src/plugins/common/recast/celhpf.cpp
===================================================================
--- src/plugins/common/recast/celhpf.cpp	(revision 8809)
+++ src/plugins/common/recast/celhpf.cpp	(working copy)
@@ -1157,7 +1157,7 @@
   csRefArray<iSector>::Iterator it = sectors.GetIterator();
   int numSectors = sectors.GetSize();
   int currentSector = 1;
-  csPrintf("Total sectors to parse: \n", numSectors);
+  csPrintf("Total sectors to parse: %d\n", numSectors);
   while (it.HasNext())
   {
     csPrintf("Parsing sector %d/%d \n", currentSector, numSectors);
@@ -1423,7 +1423,7 @@
   csHash<csRef<iSector>, const char*> sectors;
   if(!ParseMeshes(meshesNode, sectors, navStruct, vfs, params))
   {
-      return false;
+      return 0;
   }
 
   // Read high level graph
@@ -1431,7 +1431,7 @@
   csRef<iCelGraph> graph = scfCreateInstance<iCelGraph>("cel.celgraph");
   if(!ParseGraph(graphNode, graph, sectors))
   {
-      return false;
+      return 0;
   }
   navStruct->SetHighLevelGraph(graph);
 
Index: src/plugins/common/recast/celnavmesh.cpp
===================================================================
--- src/plugins/common/recast/celnavmesh.cpp	(revision 8809)
+++ src/plugins/common/recast/celnavmesh.cpp	(working copy)
@@ -2658,13 +2658,6 @@
 
 iCelNavMesh* celNavMeshBuilder::LoadNavMesh (iFile* file)
 {
-  float bMin[3];
-  float bMax[3];
-  for (int i = 0; i < 3; i++)
-  {
-    bMin[i] = boundingMin[i];
-    bMax[i] = boundingMax[i];
-  }
   navMesh.AttachNew(new celNavMesh(objectRegistry));
   navMesh->LoadNavMesh(file);
   return navMesh;
Index: src/plugins/common/recast/recastnavigation/MeshLoaderObj.cpp
===================================================================
--- src/plugins/common/recast/recastnavigation/MeshLoaderObj.cpp	(revision 8809)
+++ src/plugins/common/recast/recastnavigation/MeshLoaderObj.cpp	(working copy)
@@ -77,7 +77,6 @@
 
 static char* parseRow(char* buf, char* bufEnd, char* row, int len)
 {
-	bool cont = false;
 	bool start = true;
 	bool done = false;
 	int n = 0;
@@ -89,7 +88,6 @@
 		switch (c)
 		{
 			case '\\':
-				cont = true; // multirow
 				break;
 			case '\n':
 				if (start) break;
@@ -102,7 +100,6 @@
 				if (start) break;
 			default:
 				start = false;
-				cont = false;
 				row[n++] = c;
 				if (n >= len-1)
 					done = true;
Index: src/plugins/common/soundmanager/psentity.cpp
===================================================================
--- src/plugins/common/soundmanager/psentity.cpp	(revision 8809)
+++ src/plugins/common/soundmanager/psentity.cpp	(working copy)
@@ -256,7 +256,7 @@
     return false;
 }
 
-void psEntity::SetState(uint newState, bool forceChange, bool setReady)
+void psEntity::SetState(int newState, bool forceChange, bool setReady)
 {
     EntityState* entityState;
 
Index: src/plugins/common/soundmanager/psentity.h
===================================================================
--- src/plugins/common/soundmanager/psentity.h	(revision 8809)
+++ src/plugins/common/soundmanager/psentity.h	(working copy)
@@ -182,7 +182,7 @@
     /**
      * Gets the state of the entity
      */
-    uint GetState()
+    int GetState()
     {
         return state;
     };
@@ -199,7 +199,7 @@
      * play the new state sounds by stopping any eventual playing sound and
      * resetting the delay.
      */
-    void SetState(uint state, bool forceChange, bool setReady);
+    void SetState(int state, bool forceChange, bool setReady);
 
     /**
      * Force this entity to play the sound associated to its current state.
@@ -243,7 +243,7 @@
         int timeOfDayStart;         ///< time when this entity starts playing.
         int timeOfDayEnd;           ///< time when this entity stops.
 
-        uint fallbackState;         ///< the stateID that is activated after this one.
+        int fallbackState;          ///< the stateID that is activated after this one.
         float fallbackProbability;  ///< the probability per second that the fallbackState is activated.
 
         int references;             ///< how many psEntity point to this EntityState.
@@ -254,7 +254,7 @@
     bool isFactoryEntity;               ///< true if this is a factory entity, false if it's a mesh entity.
     csString entityName;                ///< name of the entity associated to this object.
 
-    uint state;                         ///< current state of this entity. A negative value means that this entity is in an undefined state.
+    int state;                         ///< current state of this entity. A negative value means that this entity is in an undefined state.
     int when;                           ///< counter to keep track when it has been played - zero means i may play at any time (in ms)
     uint id;                            ///< the id of the mesh object whose sound is controlled by this entity.
     float minRange;                     ///< minimum distance at which this entity can be heard
Index: src/server/bulkobjects/pscharacter.cpp
===================================================================
--- src/server/bulkobjects/pscharacter.cpp	(revision 8809)
+++ src/server/bulkobjects/pscharacter.cpp	(working copy)
@@ -928,7 +928,6 @@
     if(!last_login)
     {
         time_t curr=time(0);
-        tm result;
         //TOFIX: gmtime is not thread safe, but windows uses gmtime_s() and linux gmtime_r()
         //       so we need a wrapper function or similar
         tm* gmtm = gmtime(&curr);
Index: src/server/gem.cpp
===================================================================
--- src/server/gem.cpp	(revision 8809)
+++ src/server/gem.cpp	(working copy)
@@ -4411,7 +4411,6 @@
     activeSpells.Push(asp);
 
     csString   lname = asp->Name();
-    psSpell*   lspell;
     csString   imageName;
     if(!lname)
     {
Index: src/server/minigamemanager.cpp
===================================================================
--- src/server/minigamemanager.cpp	(revision 8809)
+++ src/server/minigamemanager.cpp	(working copy)
@@ -1274,6 +1274,8 @@
             case DIAGONAL :
                 if(row1==row2 || col1==col2) return false;
                 break;
+            default:
+                break;
         }
     }
 
Index: src/tools/navgen/navgen.cpp
===================================================================
--- src/tools/navgen/navgen.cpp	(revision 8809)
+++ src/tools/navgen/navgen.cpp	(working copy)
@@ -137,7 +137,6 @@
         csRef<iStringArray> meshFiles = vfs->FindFiles(meshes);
         csRef<iStringArray> worldFiles = vfs->FindFiles(world);
 
-        size_t loadCount = meshFiles->GetSize() + worldFiles->GetSize();
         size_t progress = 0;
 
         csPrintf("Caching meshes...\n");
@@ -212,7 +211,6 @@
         }
 
         csPrintf("Finishing world load...\n");
-        size_t loadCount = loader->GetLoadingCount();
         while(loader->GetLoadingCount())
         {
             loader->ContinueLoading(true);
@@ -242,7 +240,7 @@
         // get list of loaded sectors
         csRefArray<iSector> sectors;
         csRef<iSectorList> sectorList = engine->GetSectors();
-        for(size_t i = 0; i < sectorList->GetCount(); i++)
+        for(int i = 0; i < sectorList->GetCount(); i++)
         {
             sectors.Push(sectorList->Get(i));
         }
Index: src/tools/pawseditor/pemenu.cpp
===================================================================
--- src/tools/pawseditor/pemenu.cpp	(revision 8809)
+++ src/tools/pawseditor/pemenu.cpp	(working copy)
@@ -48,8 +48,6 @@
 
 bool peMenu::OnButtonPressed(int mouseButton, int keyModifier, pawsWidget* widget)
 {
-pawsFileNavigation * pawsFN;
-
     pePawsManager * pePaws = static_cast<pePawsManager *>(PawsManager::GetSingletonPtr());
     switch ( widget->GetID() )
     {
@@ -60,7 +58,7 @@
 
     case 101:
     case 102:
-        pawsFN = pawsFileNavigation::Create("/this/data/gui/","|*.xml|",
+        (void) pawsFileNavigation::Create("/this/data/gui/","|*.xml|",
                                    new OnFileSelected( this , widget->GetID() ), "data/pawseditor/filenavigation.xml");
         return true;
         break;
Index: src/tools/wordnet/search.c
===================================================================
--- src/tools/wordnet/search.c	(revision 8809)
+++ src/tools/wordnet/search.c	(working copy)
@@ -791,7 +791,9 @@
 {
     int i, j, idx;
     SynsetPtr cursyn;
+#ifdef FOOP
     long int prlist[1024];
+#endif
     char prefix[40], tbuf[20];
 
     interface_doevents();
@@ -823,16 +825,20 @@
 
 	    /* only print synset once, even if more than one link */
 
+#ifdef FOOP
 	    for (j = 0; j < idx; j++) {
-#ifdef FOOP
 		if (synptr->ptroff[i] == prlist[j]) {
 		    break;
 		}
+	    }
+#else
+            j = idx;
 #endif
-	    }
 
 	    if (j == idx) {
+#ifdef FOOP
 		prlist[idx++] = synptr->ptroff[i];
+#endif
 		printspaces(TRACEP, 2);
 		printsynset("=> ", cursyn, "\n", DEFON, ALLWORDS,
 			    SKIP_ANTS, PRINT_MARKER);

FIXME

 6162 Medium22.09.2013Ralph Campbell Fix BgLoader to handle sequences and triggers 26.09.2013No3 Task Description

The BgLoader works fairly well but needs to be kept up-to-date with changes in the Crystalspace csThreadedLoader implementation.
The BgLoader works by parsing all the Engine content XML files, allocating data structures to hold parts of the XML data, and then using the csThreadedLoader to load Engine objects as needed (proximity, sector crossings, etc.).
The Engine objects have to be created in the correct order - children first, then parents, grandparents, etc.
The set of changes below is sufficient to make the water wheels in the Hydlaa sewers rotate.
There are a few sequences in hydlaa_jayose that create sequences with Lights changing color but I’m not sure those are working since I’m not sure where to look for the light specified in the world data.
Anyway, this code is a definite improvement over the current code and I can make more changes if needed.
Someone from the art team might try adding more sequences and triggers and let me know how it turns out.
“patch -p0 < data” is your friend. :-)

Index: src/plugins/common/bgloader/loader.cpp
===================================================================
--- src/plugins/common/bgloader/loader.cpp	(revision 8807)
+++ src/plugins/common/bgloader/loader.cpp	(working copy)
@@ -44,7 +44,7 @@
 SCF_IMPLEMENT_FACTORY(BgLoader)
 
 BgLoader::BgLoader(iBase *p)
-  : scfImplementationType (this, p), loadOffset(0), delayedOffset(0), loadCount(0),
+  : scfImplementationType (this, p), loadOffset(0), delayedOffset(0),
     loadRange(500), validPosition(false), loadStep(0), currRot_h(0), currRot_v(0), resetHitbeam(true)
 {
 }
@@ -63,7 +63,7 @@
 
     engine = csQueryRegistry<iEngine> (object_reg);
     g2d = csQueryRegistryOrLoad<iGraphics2D> (object_reg, "crystalspace.graphics2d.null");
-    tloader = csQueryRegistryOrLoad<iThreadedLoader> (object_reg, "crystalspace.level.loader");
+    tloader = csQueryRegistryOrLoad<iThreadedLoader> (object_reg, "crystalspace.level.threadedloader");
     tman = csQueryRegistry<iThreadManager> (object_reg);
     vfs = csQueryRegistry<iVFS> (object_reg);
     parserData.svstrings = csQueryRegistryTagInterface<iShaderVarStringSet>(object_reg, "crystalspace.shader.variablenameset");
Index: src/plugins/common/bgloader/loader.h
===================================================================
--- src/plugins/common/bgloader/loader.h	(revision 8807)
+++ src/plugins/common/bgloader/loader.h	(working copy)
@@ -78,6 +78,15 @@
     extern const char sector[7];
 }
 
+/**
+ * The BgLoader is a wrapper around the Crystalspace iThreadedLoader interface.
+ * The main idea is to read all the files that iThreadedLoader would read
+ * but instead of creating the iEngine objects, the XML information is saved
+ * and used later to create the iEngine objects. The iEngine objects are
+ * created when the player's character is moved across sectors or comes within
+ * visible range of an object. Thus, the BgLoader can load and unload
+ * iEngine objects as needed, saving memory and load time.
+ */
 class BgLoader : public ThreadedCallable<BgLoader>,
                  public scfImplementation3<BgLoader,
                                            iBgLoader,
@@ -170,7 +179,7 @@
    /**
     * Returns the number of objects currently loading.
     */
-    size_t GetLoadingCount() { return loadCount; }
+    size_t GetLoadingCount() { return loadList.GetSize(); }
 
    /**
     * Returns a pointer to the object registry.
@@ -312,7 +321,6 @@
     void RegisterPendingObject(Loadable* obj)
     {
         CS::Threading::RecursiveMutexScopedLock lock(loadLock);
-        ++loadCount;
         loadList.Push(obj);
     }
 
@@ -328,8 +336,6 @@
             --loadOffset;
         }
         loadList.DeleteIndex(index);
-
-        --loadCount;
     }
 
     // register delayed loader
@@ -374,6 +380,9 @@
     class Sector;
     class Zone;
     class Texture;
+    class MeshObj;
+    class Sequence;
+    class Light;
     struct ParserData;
     struct GlobalParserData;
 
@@ -394,6 +403,9 @@
         }
     };
 
+    /**
+     * LockedType is used to store BgLoader objects.
+     */
     template<typename T, bool check = true> struct LockedType
     {
     public:
@@ -402,7 +414,7 @@
         csStringSet stringSet;
         CS::Threading::ReadWriteMutex lock;
 
-        csPtr<T> Get(const csString& name)
+        csPtr<T> Get(const char* name)
         {
             csRef<T> object;
             CS::Threading::ScopedReadLock scopedLock(lock);
@@ -444,7 +456,7 @@
             }
         }
 
-        void Delete(const csString& name)
+        void Delete(const char* name)
         {
             CS::Threading::ScopedWriteLock scopedLock(lock);
             if(stringSet.Contains(name))
@@ -479,6 +491,7 @@
         }
     };
 
+    // Loaded unconditionally - not range based.
     class AlwaysLoaded
     {
     public:
@@ -493,6 +506,9 @@
         }
     };
 
+    /**
+     * Base class for BgLoader objects.
+     */
     class Loadable : public csObject
     {
     public:
@@ -511,6 +527,9 @@
         {
         }
 
+        /*
+         * Return true if underlying CS object was loaded.
+         */
         bool Load(bool wait = false)
         {
             CS::Threading::RecursiveMutexScopedLock lock(busy);
@@ -857,8 +876,7 @@
                 csRef<iBase> rawObj = status->GetResultRefPtr();
                 if(rawObj.IsValid())
                 {
-                    csRef<T> obj = scfQueryInterface<T>(status->GetResultRefPtr());
-                    return csPtr<T>(obj);
+                    return scfQueryInterface<T>(rawObj);
                 }
             }
 
@@ -1027,19 +1045,24 @@
         }
 
         // workaround for bug in gcc 4.0: fails to parse default function argument in template classes
-        const csRef<T>& GetDependency(const csString& name) const
+        const csRef<T>& GetDependency(const char* name) const
         {
             return GetDependency(name, csRef<T>());
         }
 
-        const csRef<T>& GetDependency(const csString& name, const csRef<T>& fallbackobj) const
+        const csRef<T>& GetDependency(const char* name, const csRef<T>& fallbackobj) const
         {
             CS::Threading::RecursiveMutexScopedLock lock(busy);
-            HashObjectType fallback(fallbackobj);
             const HashObjectType& ref = objects.Get(name,fallbackobj);
             return ref.obj;
         }
 
+        bool HasDependency(const char* name) const
+        {
+            CS::Threading::RecursiveMutexScopedLock lock(busy);
+            return objects.Contains(name);
+        }
+
         HashType& GetDependencies()
         {
             return objects;
@@ -1147,28 +1170,55 @@
         void ParseMaterialReference(GlobalParserData& data, const char* name, const char* parentName, const char* type);
     };
 
-    class Trigger : public TrivialLoadable<iSequenceTrigger,ObjectNames::trigger>, public AlwaysLoaded
+    class Trigger : public ObjectLoader<Sequence>,
+                    public ObjectLoader<MeshObj>,
+                    public ObjectLoader<Light>,
+                    public TrivialLoadable<iSequenceTrigger,ObjectNames::trigger>,
+                    public AlwaysLoaded
     {
     public:
+        using ObjectLoader<Sequence>::AddDependency;
+        using ObjectLoader<MeshObj>::AddDependency;
+        using ObjectLoader<Light>::AddDependency;
+
         Trigger(BgLoader* parent) : TrivialLoadable<iSequenceTrigger,ObjectNames::trigger>(parent)
         {
         }
 
         bool LoadObject(bool wait)
         {
-            return TrivialLoadable<iSequenceTrigger,ObjectNames::trigger>::LoadObject(true);
+            bool ready = ObjectLoader<Sequence>::LoadObjects(true);
+            ready &= ObjectLoader<MeshObj>::LoadObjects(true);
+            ready &= ObjectLoader<Light>::LoadObjects(true);
+            ready &= TrivialLoadable<iSequenceTrigger,ObjectNames::trigger>::LoadObject(true);
+            return ready;
+            //return TrivialLoadable<iSequenceTrigger,ObjectNames::trigger>::LoadObject(true);
         }
 
+        void UnloadObject()
+        {
+            TrivialLoadable<iSequenceTrigger,ObjectNames::trigger>::UnloadObject();
+            ObjectLoader<Sequence>::UnloadObjects();
+            ObjectLoader<MeshObj>::UnloadObjects();
+            ObjectLoader<Light>::UnloadObjects();
+        }
+
         bool Parse(iDocumentNode* node, ParserData& data);
     };
 
-    class Sequence : public ObjectLoader<Sequence>, public ObjectLoader<Trigger>,
+    class Sequence : public ObjectLoader<Sequence>,
+                     public ObjectLoader<Trigger>,
+                     public ObjectLoader<Light>,
+                     public ObjectLoader<MeshObj>,
+                     public MaterialLoader,
                      public TrivialLoadable<iSequenceWrapper,ObjectNames::sequence>,
                      public AlwaysLoaded
     {
     public:
         using ObjectLoader<Sequence>::AddDependency;
         using ObjectLoader<Trigger>::AddDependency;
+        using ObjectLoader<Light>::AddDependency;
+        using ObjectLoader<MeshObj>::AddDependency;
 
         Sequence(BgLoader* parent) : TrivialLoadable<iSequenceWrapper,ObjectNames::sequence>(parent)
         {
@@ -1184,6 +1234,11 @@
             bool ready = true;
             if(ready)
             {
+                ready = ObjectLoader<MeshObj>::LoadObjects(wait);
+            }
+
+            if(ready)
+            {
                 ready = ObjectLoader<Sequence>::LoadObjects(wait);
             }
 
@@ -1201,21 +1256,18 @@
 
         void UnloadObject()
         {
+            TrivialLoadable<iSequenceWrapper,ObjectNames::sequence>::UnloadObject();
+            ObjectLoader<Sequence>::UnloadObjects();
             ObjectLoader<Trigger>::UnloadObjects();
-            ObjectLoader<Sequence>::UnloadObjects();
-            TrivialLoadable<iSequenceWrapper,ObjectNames::sequence>::UnloadObject();
+            ObjectLoader<MeshObj>::UnloadObjects();
         }
     };
 
-    class Light : public Loadable, public RangeBased, public ObjectLoader<Sequence>,
-                  public ObjectLoader<Trigger>
+    class Light : public Loadable, public RangeBased
     {
     public:
         typedef iLight ObjectType;
 
-        using ObjectLoader<Sequence>::AddDependency;
-        using ObjectLoader<Trigger>::AddDependency;
-
         Light(BgLoader* parent) : Loadable(parent)
         {
         }
@@ -1227,8 +1279,7 @@
 
         csPtr<iLight> GetObject()
         {
-            csRef<iLight> obj(light);
-            return csPtr<iLight>(obj);
+            return csPtr<iLight>(light);
         }
 
     private:
@@ -1371,15 +1422,12 @@
 
     class MeshObj : public TrivialLoadable<iMeshWrapper,ObjectNames::meshobj>,
                     public RangeBased, public ObjectLoader<Texture>,
-                    public MaterialLoader, public ObjectLoader<MeshFact>,
-                    public ObjectLoader<Sequence>, public ObjectLoader<Trigger>
+                    public MaterialLoader, public ObjectLoader<MeshFact>
     {
     public:
         using ObjectLoader<Texture>::AddDependency;
         using ObjectLoader<Material>::AddDependency;
         using ObjectLoader<MeshFact>::AddDependency;
-        using ObjectLoader<Sequence>::AddDependency;
-        using ObjectLoader<Trigger>::AddDependency;
 
         MeshObj(BgLoader* parent) : TrivialLoadable<iMeshWrapper,ObjectNames::meshobj>(parent)
         {
@@ -1729,6 +1777,8 @@
     /* Internal unloading methods. */
     void CleanDisconnectedSectors(Sector* sector);
 
+    bool LoadSequencesAndTriggers (iDocumentNode* snode, iDocumentNode* tnode, ParserData& data);
+
     // Pointers to other needed plugins.
     iObjectRegistry* object_reg;
     csRef<iEngine> engine;
@@ -1749,9 +1799,6 @@
     csArray<csPtrKey<Loadable> > loadList;
     csArray<csPtrKey<iDelayedLoader> > delayedLoadList;
 
-    // number of objects currently loading
-    size_t loadCount;
-
     // Our load range ^_^
     float loadRange;
 
Index: src/plugins/common/bgloader/loader_objects.cpp
===================================================================
--- src/plugins/common/bgloader/loader_objects.cpp	(revision 8807)
+++ src/plugins/common/bgloader/loader_objects.cpp	(working copy)
@@ -145,22 +145,11 @@
 	parent->GetLights()->Add(light);
     }
 
-    // Load all light sequences.
-    bool ready = ObjectLoader<Sequence>::LoadObjects(wait);
-
-    if(ready)
-    {
-        ready &= ObjectLoader<Trigger>::LoadObjects(wait);
-    }
-
-    return ready;
+    return true;
 }
 
 void BgLoader::Light::UnloadObject()
 {
-    ObjectLoader<Trigger>::UnloadObjects();
-    ObjectLoader<Sequence>::UnloadObjects();
-
     Loadable::CheckRemove<iLight,ObjectNames::light>(light);
 }
 
@@ -289,16 +278,6 @@
         ready = TrivialLoadable<iMeshWrapper,ObjectNames::meshobj>::LoadObject(wait);
     }
 
-    if(ready)
-    {
-        ready = ObjectLoader<Sequence>::LoadObjects(wait);
-    }
-
-    if(ready)
-    {
-        ready &= ObjectLoader<Trigger>::LoadObjects(wait);
-    }
-
     return ready;
 }
 
@@ -346,9 +325,6 @@
 
 void BgLoader::MeshObj::UnloadObject()
 {
-    ObjectLoader<Trigger>::UnloadObjects();
-    ObjectLoader<Sequence>::UnloadObjects();
-
     TrivialLoadable<iMeshWrapper,ObjectNames::meshobj>::UnloadObject();
 
     ObjectLoader<Texture>::UnloadObjects();
Index: src/plugins/common/bgloader/parser.cpp
===================================================================
--- src/plugins/common/bgloader/parser.cpp	(revision 8807)
+++ src/plugins/common/bgloader/parser.cpp	(working copy)
@@ -75,18 +75,18 @@
                     {
                         csRef<iDocumentNode> shaderNode(nodeItr->Next());
 
-                        csString typeName(shaderNode->GetNode("type")->GetContentsValue());
-                        csString shaderName(shaderNode->GetAttributeValue("name"));
+                        const char* typeName = shaderNode->GetNode("type")->GetContentsValue();
+                        const char* shaderName = shaderNode->GetAttributeValue("name");
 
                         csRef<iDocumentNode> file = shaderNode->GetNode("file");
                         if(file.IsValid())
                         {
-                            csString fileName(file->GetContentsValue());
+                            const char* fileName = file->GetContentsValue();
                             if(parserData.shaders.Contains(fileName) == csArrayItemNotFound)
                             {
                                 CS::Threading::ScopedWriteLock lock(parserData.shaderLock);
-                                parserData.shaders.Push(file->GetContentsValue());
-                                csRef<iThreadReturn> shaderRet = tloader->LoadShader(path, file->GetContentsValue());
+                                parserData.shaders.Push(fileName);
+                                csRef<iThreadReturn> shaderRet = tloader->LoadShader(path, fileName);
                                 if(parserData.config.blockShaderLoad)
                                 {
                                     shaderRet->Wait();
@@ -107,18 +107,18 @@
                     while(nodeItr->HasNext())
                     {
                         csRef<iDocumentNode> aliasNode(nodeItr->Next());
-                        csString shaderName(aliasNode->GetAttributeValue("name"));
+                        const char* shaderName = aliasNode->GetAttributeValue("name");
                         csString aliasName(aliasNode->GetAttributeValue("alias"));
 
                         csRef<iDocumentNode> file = aliasNode->GetNode("file");
                         if(file.IsValid())
                         {
-                            csString fileName(file->GetContentsValue());
+                            const char* fileName = file->GetContentsValue();
                             if(parserData.shaders.Contains(fileName) == csArrayItemNotFound)
                             {
                                 CS::Threading::ScopedWriteLock lock(parserData.shaderLock);
-                                parserData.shaders.Push(file->GetContentsValue());
-                                csRef<iThreadReturn> shaderRet = tloader->LoadShader(path, file->GetContentsValue());
+                                parserData.shaders.Push(fileName);
+                                csRef<iThreadReturn> shaderRet = tloader->LoadShader(path, fileName);
                                 if(parserData.config.blockShaderLoad)
                                 {
                                     shaderRet->Wait();
@@ -409,7 +409,7 @@
 
                 case PARSERTOKEN_SECTOR:
                 {
-                    csString sectorName = node->GetContentsValue();
+                    const char* sectorName = node->GetContentsValue();
                     targetSector = csRef<Sector>(parserData.data.sectors.Get(sectorName));
 
                     if(!targetSector)
@@ -759,7 +759,7 @@
                 case PARSERTOKEN_SETFOG:
                 case PARSERTOKEN_FADEFOG:
                 {
-                    csString name(node->GetAttributeValue("sector"));
+                    const char* name = node->GetAttributeValue("sector");
                     csRef<Sector> s = parserData.data.sectors.Get(name);
 
                     if(s.IsValid())
@@ -770,7 +770,7 @@
                     else
                     {
                         csString msg;
-                        msg.Format("Invalid sector reference '%s' in sequence '%s'", name.GetData(), GetName());
+                        msg.Format("Invalid sector reference '%s' in sequence '%s'", name, GetName());
                         CS_ASSERT_MSG(msg.GetData(), false);
                         failed = true;
                     }
@@ -784,18 +784,17 @@
                 case PARSERTOKEN_ROTATE:
                 case PARSERTOKEN_MOVE:
                 {
-                    csString name(node->GetAttributeValue("mesh"));
+                    const char* name = node->GetAttributeValue("mesh");
                     csRef<MeshObj> m = parserData.data.meshes.Get(name);
 
                     if(m.IsValid())
                     {
-                        m->AddDependency(self);
-                        parents.Push(m);
+                        AddDependency(m);
                     }
                     else
                     {
                         csString msg;
-                        msg.Format("Invalid mesh reference '%s' in sequence '%s'", name.GetData(), GetName());
+                        msg.Format("Invalid mesh reference '%s' in sequence '%s'", name, GetName());
                         CS_ASSERT_MSG(msg.GetData(), false);
                         failed = true;
                     }
@@ -808,18 +807,17 @@
                 case PARSERTOKEN_FADELIGHT:
                 case PARSERTOKEN_SETLIGHT:
                 {
-                    csString name(node->GetAttributeValue("light"));
+                    const char* name = node->GetAttributeValue("light");
                     csRef<Light> l = parserData.lights.Get(name);
 
                     if(l.IsValid())
                     {
-                        l->AddDependency(self);
-                        parents.Push(l);
+                        AddDependency(l);
                     }
                     else
                     {
                         csString msg;
-                        msg.Format("Invalid light reference '%s' in sequence '%s'", name.GetData(), GetName());
+                        msg.Format("Invalid light reference '%s' in sequence '%s'", name, GetName());
                         CS_ASSERT_MSG(msg.GetData(), false);
                         failed = true;
                     }
@@ -829,7 +827,7 @@
                 // sequence types operating on a sequence.
                 case PARSERTOKEN_RUN:
                 {
-                    csString name(node->GetAttributeValue("sequence"));
+                    const char* name = node->GetAttributeValue("sequence");
                     csRef<Sequence> seq = parserData.sequences.Get(name);
 
                     if(seq.IsValid())
@@ -840,7 +838,7 @@
                     else
                     {
                         csString msg;
-                        msg.Format("Invalid sequence reference '%s' in sequence '%s'", name.GetData(), GetName());
+                        msg.Format("Invalid sequence reference '%s' in sequence '%s'", name, GetName());
                         CS_ASSERT_MSG(msg.GetData(), false);
                         failed = true;
                     }
@@ -853,7 +851,7 @@
                 case PARSERTOKEN_CHECK:
                 case PARSERTOKEN_TEST:
                 {
-                    csString name(node->GetAttributeValue("trigger"));
+                    const char* name = node->GetAttributeValue("trigger");
                     csRef<Trigger> t = parserData.triggers.Get(name);
 
                     if(t.IsValid())
@@ -863,14 +861,14 @@
                     else
                     {
                         csString msg;
-                        msg.Format("Invalid trigger reference '%s' in sequence '%s'", name.GetData(), GetName());
+                        msg.Format("Invalid trigger reference '%s' in sequence '%s'", name, GetName());
                         CS_ASSERT_MSG(msg.GetData(), false);
                         failed = true;
                     }
                 }
                 break;
 
-                // miscallenous sequence types.
+                // miscellanous sequence types.
                 case PARSERTOKEN_DELAY:
                 case PARSERTOKEN_SETVAR:
                 default:
@@ -923,7 +921,7 @@
                 // triggers fired by a sector.
                 case PARSERTOKEN_SECTORVIS:
                 {
-                    csString name(node->GetAttributeValue("sector"));
+                    const char* name = node->GetAttributeValue("sector");
                     csRef<Sector> s = parserData.data.sectors.Get(name);
 
                     if(s.IsValid())
@@ -934,7 +932,7 @@
                     else
                     {
                         csString msg;
-                        msg.Format("Invalid sector reference '%s' in trigger '%s'", name.GetData(), GetName());
+                        msg.Format("Invalid sector reference '%s' in trigger '%s'", name, GetName());
                         CS_ASSERT_MSG(msg.GetData(), false);
                         failed = true;
                     }
@@ -944,18 +942,17 @@
                 // triggers fired by a mesh.
                 case PARSERTOKEN_ONCLICK:
                 {
-                    csString name(node->GetAttributeValue("mesh"));
+                    const char* name = node->GetAttributeValue("mesh");
                     csRef<MeshObj> m = parserData.data.meshes.Get(name);
 
                     if(m.IsValid())
                     {
-                        m->AddDependency(self);
-                        parents.Push(m);
+                        AddDependency(m);
                     }
                     else
                     {
                         csString msg;
-                        msg.Format("Invalid mesh reference '%s' in trigger '%s'", name.GetData(), GetName());
+                        msg.Format("Invalid mesh reference '%s' in trigger '%s'", name, GetName());
                         CS_ASSERT_MSG(msg.GetData(), false);
                         failed = true;
                     }
@@ -965,18 +962,17 @@
                 // triggers fired by a light.
                 case PARSERTOKEN_LIGHTVALUE:
                 {
-                    csString name(node->GetAttributeValue("light"));
+                    const char* name = node->GetAttributeValue("light");
                     csRef<Light> l = parserData.lights.Get(name);
 
                     if(l.IsValid())
                     {
-                        l->AddDependency(self);
-                        parents.Push(l);
+                        AddDependency(l);
                     }
                     else
                     {
                         csString msg;
-                        msg.Format("Invalid light reference '%s' in trigger '%s'", name.GetData(), GetName());
+                        msg.Format("Invalid light reference '%s' in trigger '%s'", name, GetName());
                         CS_ASSERT_MSG(msg.GetData(), false);
                         failed = true;
                     }
@@ -986,25 +982,30 @@
                 // triggers fired by a sequence.
                 case PARSERTOKEN_FIRE:
                 {
-                    csString name(node->GetAttributeValue("sequence"));
+                    const char* name = node->GetAttributeValue("sequence");
                     csRef<Sequence> seq = parserData.sequences.Get(name);
 
                     if(seq.IsValid())
                     {
-                        seq->AddDependency(self);
-                        parents.Push(seq);
+                        // Since sequences are parsed first, if it has
+                        // a dependency on this trigger, there is a loop.
+                        if(seq->ObjectLoader<Trigger>::HasDependency(GetName()))
+                        {
+                            seq->ObjectLoader<Trigger>::RemoveDependency(this);
+                        }
+                        AddDependency(seq);
                     }
                     else
                     {
                         csString msg;
-                        msg.Format("Invalid sequence reference '%s' in trigger '%s'", name.GetData(), GetName());
+                        msg.Format("Invalid sequence reference '%s' in trigger '%s'", name, GetName());
                         CS_ASSERT_MSG(msg.GetData(), false);
                         failed = true;
                     }
                 }
                 break;
 
-                // triggers fired by a miscallenous operation.
+                // triggers fired by a miscellanous operation.
                 case PARSERTOKEN_MANUAL:
                 default:
                 {
@@ -1099,6 +1100,8 @@
                 bool portalsOnly = parserData.config.portalsOnly;
                 bool meshesOnly = parserData.config.meshesOnly;
                 data.parsedMeshFact = false;
+                csRef<iDocumentNode> sequences;
+                csRef<iDocumentNode> triggers;
 
                 csRef<iDocumentNodeIterator> nodeIt(root->GetNodes());
                 while(nodeIt->HasNext())
@@ -1230,7 +1233,7 @@
                         // Parse sector.
                         case PARSERTOKEN_SECTOR:
                         {
-                            csString name(node->GetAttributeValue("name"));
+                            const char* name = node->GetAttributeValue("name");
                             csRef<Sector> sector = parserData.sectors.Get(name);
                             if(!sector.IsValid())
                             {
@@ -1243,7 +1246,7 @@
                                 parserData.sectors.Delete(name);
 
                                 csString msg;
-                                msg.Format("Sector %s failed to parse!", name.GetData());
+                                msg.Format("Sector %s failed to parse!", name);
                                 CS_ASSERT_MSG(msg.GetData(), false);
                             }
                         }
@@ -1269,39 +1272,7 @@
                             {
                                 break;
                             }
-
-                            // do a 2 pass parsing of sequences
-                            // first create all sequences.
-                            csRef<iDocumentNodeIterator> sequenceIt(node->GetNodes("sequence"));
-                            while(sequenceIt->HasNext())
-                            {
-                                csRef<iDocumentNode> sequenceNode(sequenceIt->Next());
-                                csString sequenceName(sequenceNode->GetAttributeValue("name"));
-
-                                csRef<Sequence> seq;
-                                seq.AttachNew(new Sequence(this));
-                                data.sequences.Put(seq, sequenceName);
-                            }
-
-                            // now actually parse them.
-                            sequenceIt = node->GetNodes("sequence");
-                            while(sequenceIt->HasNext())
-                            {
-                                csRef<iDocumentNode> sequenceNode(sequenceIt->Next());
-                                csString sequenceName(sequenceNode->GetAttributeValue("name"));
-
-                                csRef<Sequence> seq = data.sequences.Get(sequenceName);
-
-                                if(!seq->Parse(sequenceNode, data))
-                                {
-                                    // failed to parse the sequence, remove it from the lookup table
-                                    data.sequences.Delete(sequenceName);
-
-                                    csString msg;
-                                    msg.Format("Sequence %s failed to parse!", sequenceName.GetData());
-                                    CS_ASSERT_MSG(msg.GetData(), false);
-                                }
-                            }
+                            sequences = node;
                         }
                         break;
 
@@ -1311,35 +1282,15 @@
                             {
                                 break;
                             }
-
-                            csRef<iDocumentNodeIterator> triggerIt(node->GetNodes("trigger"));
-                            while(triggerIt->HasNext())
-                            {
-                                csRef<iDocumentNode> triggerNode(triggerIt->Next());
-                                csString triggerName(triggerNode->GetAttributeValue("name"));
-
-                                csRef<Trigger> trigger = data.triggers.Get(triggerName);
-                                if(!trigger.IsValid())
-                                {
-                                    // not yet loaded, attach a new one
-                                    trigger.AttachNew(new Trigger(this));
-                                    data.triggers.Put(trigger, triggerName);
-                                }
-
-                                if(!trigger->Parse(triggerNode, data))
-                                {
-                                    // failed to parse the trigger, remove it from the lookup table
-                                    data.triggers.Delete(triggerName);
-
-                                    csString msg;
-                                    msg.Format("Trigger %s failed to parse!", triggerName.GetData());
-                                    CS_ASSERT_MSG(msg.GetData(), false);
-                                }
-                            }
+                            triggers = node;
                         }
                         break;
                     }
                 }
+                // Sequences and triggers are parsed at the end because
+                // all sectors and other objects need to be present.
+                if (!LoadSequencesAndTriggers(sequences, triggers, data))
+                    return false;
             }
 
             // Wait for plugin and shader loads to finish.
@@ -1348,6 +1299,121 @@
         
         return true;
     }
+
+  bool BgLoader::LoadSequencesAndTriggers (iDocumentNode* snode,
+                                           iDocumentNode* tnode,
+                                           ParserData& data)
+  {
+    // We load sequences and triggers in three passes.
+    // In the first pass, we will create all triggers.
+    // In the second pass, we will create and parse sequences.
+    // In the third pass, we will parse the triggers.
+    // This will create the data structures and dependencies but
+    // not the actual Crystalspace engine data structures until
+    // they are visible or needed.
+    // It also makes sure that sequences are created before triggers
+    // regardless of the order they may appear in the XML file.
+
+    if (tnode)
+    {
+      csRef<iDocumentNodeIterator> it = tnode->GetNodes ();
+      while (it->HasNext ())
+      {
+        csRef<iDocumentNode> child = it->Next ();
+        if (child->GetType () != CS_NODE_ELEMENT)
+          continue;
+        const char* value = child->GetValue ();
+        csStringID id = parserData.xmltokens.Request (value);
+        switch (id)
+        {
+        case PARSERTOKEN_TRIGGER:
+          {
+            const char* name = child->GetAttributeValue ("name");
+            csRef<Trigger> trig;
+            trig.AttachNew(new Trigger(this));
+            data.triggers.Put(trig, name);
+            trig->SetName(name);
+          }
+          break;
+        default:
+          parserData.syntaxService->ReportBadToken (child);
+          return false;
+        }
+      }
+    }
+
+    if (snode)
+    {
+      csRef<iDocumentNodeIterator> it = snode->GetNodes ();
+      while (it->HasNext ())
+      {
+        csRef<iDocumentNode> child = it->Next ();
+        if (child->GetType () != CS_NODE_ELEMENT)
+          continue;
+        const char* value = child->GetValue ();
+        csStringID id = parserData.xmltokens.Request (value);
+        switch (id)
+        {
+        case PARSERTOKEN_SEQUENCE:
+          {
+            const char* name = child->GetAttributeValue ("name");
+            csRef<Sequence> seq;
+            seq.AttachNew(new Sequence(this));
+            data.sequences.Put(seq, name);
+            if (!seq->Parse (child, data))
+            {
+              data.sequences.Delete(name);
+              csString msg;
+              msg.Format("Sequence %s failed to parse!", name);
+              CS_ASSERT_MSG(msg.GetData(), false);
+              return false;
+            }
+            break;
+          }
+        default:
+          parserData.syntaxService->ReportBadToken (child);
+          return false;
+        }
+      }
+    }
+
+    if (tnode)
+    {
+      csRef<iDocumentNodeIterator> it = tnode->GetNodes ();
+      while (it->HasNext ())
+      {
+        csRef<iDocumentNode> child = it->Next ();
+        if (child->GetType () != CS_NODE_ELEMENT)
+          continue;
+        const char* value = child->GetValue ();
+        csStringID id = parserData.xmltokens.Request (value);
+        switch (id)
+        {
+        case PARSERTOKEN_TRIGGER:
+          {
+            const char* name = child->GetAttributeValue ("name");
+            csRef<Trigger> trig (data.triggers.Get(name));
+            if (!trig->Parse (child, data))
+            {
+              // failed to parse the trigger, remove it from the lookup table
+              data.triggers.Delete(name);
+              csString msg;
+              msg.Format("Trigger %s failed to parse!", name);
+              CS_ASSERT_MSG(msg.GetData(), false);
+              return false;
+            }
+            break;
+          }
+        default:
+          parserData.syntaxService->ReportBadToken (child);
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+
 }
 CS_PLUGIN_NAMESPACE_END(bgLoader)
 
Index: src/plugins/common/bgloader/parser.tok
===================================================================
--- src/plugins/common/bgloader/parser.tok	(revision 8807)
+++ src/plugins/common/bgloader/parser.tok	(working copy)
@@ -22,7 +22,9 @@
 CS_TOKEN_LIST_TOKEN(SECTOR)
 CS_TOKEN_LIST_TOKEN(START)
 CS_TOKEN_LIST_TOKEN(SEQUENCES)
+CS_TOKEN_LIST_TOKEN(SEQUENCE)
 CS_TOKEN_LIST_TOKEN(TRIGGERS)
+CS_TOKEN_LIST_TOKEN(TRIGGER)
 CS_TOKEN_LIST_TOKEN(PORTALS)
   // object types
 CS_TOKEN_LIST_TOKEN(MESHFACT)

FIXME

 6161 Medium22.09.2013Ralph Campbell syntax error in quest_scripts.sql 25.09.2013No Task Description

Line 64 of src/server/database/mysql/quest_scripts.sql ends in a ‘;’ but should end in a ‘,’ since there is another line that follows to insert the record ‘213’.

 6150 Medium11.09.2013Ralph CampbellVenalan Typos in various quests 20.11.2013No5 Task Description

Dark Way Master Training:
“Here are bracers” ⇒ “Here are my bracers” “one for every hand” ⇒ “one in each hand” “buy all the glyph he sells” ⇒ “buy all the glyphs he sells” “Evelyn pupils” ⇒ “Evelyn’s pupils” “discover others of them” ⇒ “discover more of them” “Evelyn tongue” ⇒ “Evelyn’s tongue” “Take you bracers” ⇒ “Take your bracers” “show me it when you will be ready for the next lessons” ⇒ “show it to me when you are ready for the next lesson” ⇒ “until you will become” ⇒ “until you become”

Knowledge and Practical of the Dark Way Master:
“Evelyn give a coy smile” ⇒ “Evelyn gives a coy smile” “for well deserved reason” ⇒ “for a well deserved reason” “Evelyn eyes” ⇒ “Evelyn’s eyes” “Evelyn brief smile” ⇒ “Evelyn’s brief smile” “Some other are” ⇒ “Some others are” “normal life for now on” ⇒ “normal life from now on” “Other inside of you” ⇒ “Others inside of you” “Evelyn makes a pause” ⇒ “Evelyn pauses”

The Dark Way Master:
“I have the prove of being” ⇒ “I have the proof of being” “And you have to contrast it” ⇒ “And you have to resist it”

Knowledge of the Dark Way Adept:
“When Amakeer low his head to look they are motionless, already died.” ⇒ “When Amakeer lowers his head to look, they are motionless, already dead.”

 6128 Medium18.08.2013Ralph CampbellRalph Campbell psCharacter::SetActor() uses uninitialized gemActor::co ...24.01.2014No2 Task Description

If you run valgrind on the psserver as in  bug 6126 , you will see that
psCharacter::SetActor() uses gemActor::combat_stance before it is initialized.
The fix is to initialize the variable sooner.

Index: src/server/gem.cpp
===================================================================
--- src/server/gem.cpp	(revision 8767)
+++ src/server/gem.cpp	(working copy)
@@ -2171,6 +2186,7 @@
         return;
     }
 
+    combat_stance = CombatManager::GetStance(cachemanager,"None");
     chardata->SetActor(this);
 
     if(!InitCharData(clientRef))
@@ -2181,7 +2197,6 @@
 
     if(psChar->IsStatue())
         player_mode = PSCHARACTER_MODE_STATUE;
-    combat_stance = CombatManager::GetStance(cachemanager,"None");
 
     Debug6(LOG_NPC,GetEID().Unbox(),"Successfully created actor %s at %1.2f,%1.2f,%1.2f in sector %s.\n",
            factname,pos.x,pos.y,pos.z,GetSectorName());

FIXME

 6126 Medium17.08.2013Ralph Campbell Memory leak in psCharacterQuestManager and CacheManager 25.09.2013No Task Description

After fixing the memory leaks with just starting and stopping the psserver,
the next set of fixes is based on running valgrind on the server but without the “quit” at the end of test.script.
These leaks were found by just logging in a character (such as Vengence), logging out, and quitting the server.

Index: src/server/bulkobjects/pscharquestmgr.cpp
===================================================================
--- src/server/bulkobjects/pscharquestmgr.cpp	(revision 8767)
+++ src/server/bulkobjects/pscharquestmgr.cpp	(working copy)
@@ -76,6 +76,10 @@
 
 psCharacterQuestManager::~psCharacterQuestManager()
 {
+    while (assignedQuests.GetSize())
+    {
+        delete assignedQuests.Pop();
+    }
     assignedQuests.DeleteAll();
 }    
 
Index: src/server/cachemanager.cpp
===================================================================
--- src/server/cachemanager.cpp	(revision 8767)
+++ src/server/cachemanager.cpp	(working copy)
@@ -401,6 +401,7 @@
     }
 
     delete lootRandomizer;
+    delete [] compressed_msg_strings;
     // ToDo: unload everything else
 }
 

FIXME

 6125 Medium16.08.2013Ralph Campbell One more memory leak in client and server 20.11.2013No1 Task Description

Since the psfRegisterMsgFactoryFunction() creates an array of MsgFactoryItem that is stored in a global variable,
these need to be deleted at the end. I defined a psfUnRegisterMsgFactories() function to do that.

Index: src/client/psengine.cpp
===================================================================
--- src/client/psengine.cpp	(revision 8767)
+++ src/client/psengine.cpp	(working copy)
@@ -1997,6 +1997,9 @@
     delete psengine;
     psengine = NULL;
 
+    // Free registered message factories.
+    psfUnRegisterMsgFactories();
+
     delete CSSetup;
 
     Notify1(LOG_ANY,"Destroying application...");
Index: src/common/net/messages.cpp
===================================================================
--- src/common/net/messages.cpp	(revision 8767)
+++ src/common/net/messages.cpp	(working copy)
@@ -7897,6 +7897,12 @@
     msgfactory->messages.Push(newfac);
 }
 
+void psfUnRegisterMsgFactories(void)
+{
+    if (msgfactory)
+        msgfactory->messages.DeleteAll();
+}
+
 psMessageCracker* psfCreateMsg(int msgtype,
                                MsgEntry* me,
                                NetBase::AccessPointers * accessPointers )
Index: src/common/net/messages.h
===================================================================
--- src/common/net/messages.h	(revision 8767)
+++ src/common/net/messages.h	(working copy)
@@ -391,6 +391,7 @@
 void DecodeMessage(MsgEntry* me, NetBase::AccessPointers* accessPointers, bool filterhex, csString& msgText, int& filterNumber);
 
 void psfRegisterMsgFactoryFunction(psfMsgFactoryFunc factoryfunc, int msgtype, const char* msgtypename);
+void psfUnRegisterMsgFactories(void);
 psMessageCracker* psfCreateMsg(int msgtype,
                                MsgEntry* me,
                                NetBase::AccessPointers* accessPointers);
Index: src/server/main.cpp
===================================================================
--- src/server/main.cpp	(revision 8767)
+++ src/server/main.cpp	(working copy)
@@ -30,6 +30,7 @@
 #include "util/serverconsole.h"
 #include "util/log.h"
 #include "util/pscssetup.h"
+#include "net/messages.h"
 
 
 // ----------------------------------------------------------------
@@ -79,8 +80,10 @@
     psserver->MainLoop ();
     
     delete psserver;
-    
 
+    // Free registered message factories.
+    psfUnRegisterMsgFactories();
+
     // Save Configuration
     csRef<iConfigManager> cfgmgr= csQueryRegistry<iConfigManager> (object_reg);
     if (cfgmgr)

FIXME

 6124 Medium16.08.2013Ralph CampbellRalph Campbell Memory leak in psItemStats::ReadItemStats() 24.01.2014No Task Description

The csStringArray::Pop() function returns a char* that must be “delete []” ed.
Since csString::csString(char*) creates a copy of the char* string, this causes a memory leak.
The fix can be verified with valgrind as in  bug 6114 .
With all of my psserver changes applied, valgrind reports no errors!

Index: src/server/bulkobjects/psitemstats.cpp
===================================================================
--- src/server/bulkobjects/psitemstats.cpp	(revision 8767)
+++ src/server/bulkobjects/psitemstats.cpp	(working copy)
@@ -640,12 +640,13 @@
     strTmpAmmoList.Split(strTmpAmmoListArray, ',');
     while (!strTmpAmmoListArray.IsEmpty())
     {
-        csString currAmmo = strTmpAmmoListArray.Pop();
-        unsigned int ammoID = atoi(currAmmo.GetDataSafe());
+        char* currAmmo = strTmpAmmoListArray.Pop();
+        unsigned int ammoID = atoi(currAmmo);
         if (ammoID != 0)
         {
             ammo_types.Add(ammoID);
         }
+        delete [] currAmmo;
     }
 
 

FIXME

 6123 Medium16.08.2013Ralph CampbellRalph Campbell Memory leak in CacheManager when loading craft messages 24.01.2014No Task Description

If you run valgrind as in  bug 6114 , you will see stack traces with CacheManager::PreloadCraftMessages().
You won’t see them after applying these changes.

Index: src/server/cachemanager.cpp
===================================================================
--- src/server/cachemanager.cpp	(revision 8767)
+++ src/server/cachemanager.cpp	(working copy)
@@ -1700,6 +1700,7 @@
                     delete iArray;
                 }
             }
+            delete iHash;
         }
     }
 
@@ -1720,9 +1721,13 @@
                     delete iArray;
                 }
             }
+            delete iHash;
         }
     }
 
+    delete txItemHash;
+    delete txResultHash;
+
     return false;
 }
 

FIXME

 6122 Medium16.08.2013Ralph CampbellRalph Campbell Memory leak of NpcDialogMenu objects 24.01.2014No Task Description

If you run valgrind on the test server as in  bug 6114 , you will see that NpcDialogMenu objects are lost when quest scripts are loaded by QuestManager::ParseQuestScript().
To verify this is the fix, just rerun valgrind after applying these changes.

Index: src/server/bulkobjects/dictionary.cpp
===================================================================
--- src/server/bulkobjects/dictionary.cpp	(revision 8767)
+++ src/server/bulkobjects/dictionary.cpp	(working copy)
@@ -95,6 +95,9 @@
     csHash<NpcResponse*>::GlobalIterator responsesIter(responses.GetIterator());
     while(responsesIter.HasNext())
         delete responsesIter.Next();
+    csHash<NpcDialogMenu*, csString>::GlobalIterator menuIter(initial_popup_menus.GetIterator());
+    while(menuIter.HasNext())
+        delete menuIter.Next();
     wnclose();
     dict = NULL;
 }
@@ -427,6 +430,7 @@
         if (!AddTrigger(db,trigger_id,newresp->id))
         {
             Error2("Failed to load trigger for resp: %d",newresp->id);
+            delete newresp;
             return false;
         }
 
@@ -1194,6 +1198,11 @@
     active_quest = -1;
 }
 
+NpcResponse::~NpcResponse()
+{
+    delete menu;
+}
+
 bool NpcResponse::Load(iResultRow& row)
 {
     id             = row.GetInt("id");
Index: src/server/bulkobjects/dictionary.h
===================================================================
--- src/server/bulkobjects/dictionary.h	(revision 8767)
+++ src/server/bulkobjects/dictionary.h	(working copy)
@@ -349,7 +349,7 @@
     };
 
     NpcResponse();
-    virtual ~NpcResponse() {}
+    virtual ~NpcResponse();
     
     bool Load(iResultRow& row);
 

FIXME

 6121 Medium16.08.2013Ralph CampbellJoe Lyon minor memory leak in error case in QuestManager::ParseQ ...20.11.2013No Task Description

I found this by code inspection. You would need to create a quest script with an error to cause a leak.

Index: src/server/questmanager.cpp
===================================================================
--- src/server/questmanager.cpp	(revision 8767)
+++ src/server/questmanager.cpp	(working copy)
@@ -900,6 +900,7 @@
                        mainQuest->GetName(),block.GetData());
                 lastError.Format("Could not determine triggers in script '%s', in line <%s>", mainQuest->GetName(),block.GetData());
 
+                delete menu;
                 return line_number;
             }
 

FIXME

 6120 Medium15.08.2013Ralph CampbellRalph Campbell Memory leak in NetManager::Create() 24.01.2014No Task Description
The classes NetManagerStarter and Thread have a reference count loop
so that neither is properly destroyed.
I propose simplifying NetManger and making NetManagerStarter do the
work of stopping and destroying the NetManager instance.
You can verify this as in bug 6114 and not seeing NetManager::Create()
in the valgrind memory leak list.


Index: src/server/netmanager.cpp
===================================================================
--- src/server/netmanager.cpp	(revision 8766)
+++ src/server/netmanager.cpp	(working copy)
@@ -83,18 +83,14 @@
 };
 
 
-NetManager::NetManager(csRef<CS::Threading::Thread> _thread)
+NetManager::NetManager()
     : NetBase (1000),stop_network(false)
 {
-    thread=_thread;
     port=0;
 }
 
 NetManager::~NetManager()
 {
-    stop_network = true;
-    thread->Wait ();
-    thread = NULL;
 }
 
 bool NetManager::Initialize(CacheManager* cachemanager, int client_firstmsg, int npcclient_firstmsg, int timeout)
@@ -115,12 +111,12 @@
     return true;
 }
 
-class NetManagerStarter : public CS::Threading::Runnable
+class NetManagerStarter : public CS::Threading::Runnable, public Singleton<NetManagerStarter>
 {
 	CacheManager *cacheManager;
 public:
-    csRef<NetManager> netManager;
-    csRef<CS::Threading::Thread> thread;
+    NetManager* netManager;
+    CS::Threading::Thread* thread;
     CS::Threading::Mutex doneMutex;
     CS::Threading::Condition initDone;
     int client_firstmsg;
@@ -130,6 +126,8 @@
 
     NetManagerStarter(CacheManager *cachemanager, int _client_firstmsg, int _npcclient_firstmsg, int _timeout)
     {
+        netManager = NULL;
+        thread = NULL;
     	cacheManager = cachemanager;
         client_firstmsg = _client_firstmsg;
         npcclient_firstmsg = _npcclient_firstmsg;
@@ -141,7 +139,7 @@
         {
             CS::Threading::MutexScopedLock lock (doneMutex);
             // construct the netManager is its own thread to avoid wrong warnings of dynamic thread checking via valgrind
-            netManager.AttachNew(new NetManager(thread));
+            netManager = new NetManager();
             if (!netManager->Initialize(cacheManager, client_firstmsg, npcclient_firstmsg,
                     timeout))
             {
@@ -161,18 +159,16 @@
 
 NetManager* NetManager::Create(CacheManager* cacheManager, int client_firstmsg, int npcclient_firstmsg, int timeout)
 {
-    csRef<NetManagerStarter> netManagerStarter;
-    netManagerStarter.AttachNew (new NetManagerStarter(cacheManager, client_firstmsg, npcclient_firstmsg, timeout));
-    csRef<CS::Threading::Thread> thread;
-    thread.AttachNew (new CS::Threading::Thread (netManagerStarter));
-    netManagerStarter->thread = thread;
+    NetManagerStarter* netManagerStarter =
+        new NetManagerStarter(cacheManager, client_firstmsg, npcclient_firstmsg, timeout);
+    netManagerStarter->thread = new CS::Threading::Thread (netManagerStarter);
 
     // wait for initialization to be finished
     {
         CS::Threading::MutexScopedLock lock (netManagerStarter->doneMutex);
-        thread->Start();
+        netManagerStarter->thread->Start();
         
-        if (!thread->IsRunning())
+        if (!netManagerStarter->thread->IsRunning())
         {
             return NULL;        
         }
@@ -182,6 +178,18 @@
     return netManagerStarter->netManager;
 }
 
+void NetManager::Destroy()
+{
+    // Handle stopping and destroying the network thread in the main thread.
+    NetManagerStarter* netManagerStarter =
+        NetManagerStarter::GetSingletonPtr();
+    netManagerStarter->netManager->stop_network = true;
+    netManagerStarter->thread->Wait();
+    delete netManagerStarter->netManager;
+    delete netManagerStarter->thread;
+    delete netManagerStarter;
+}
+
 bool NetManager::HandleUnknownClient (LPSOCKADDR_IN addr, MsgEntry* me)
 {
     psMessageBytes* msg = me->bytes;
@@ -464,7 +472,6 @@
 
     printf("Network thread started!\n");
 
-    stop_network = false;
     while ( !stop_network )
     {
         if (!IsReady())
Index: src/server/netmanager.h
===================================================================
--- src/server/netmanager.h	(revision 8766)
+++ src/server/netmanager.h	(working copy)
@@ -46,10 +46,10 @@
  * other threads can register a message queue and the network thread will sort
  * messages for them and put them in their queue.
  */
-class NetManager : public NetBase, public CS::Threading::Runnable
+class NetManager : public NetBase
 {
 public:
-    NetManager(csRef<CS::Threading::Thread> _thread);
+    NetManager();
     ~NetManager();
 
     /**
@@ -72,6 +72,8 @@
     
     static NetManager* Create(CacheManager* cacheManager, int client_firstmsg, int npcclient_firstmsg, int timeout=15000);
 
+    static void Destroy();
+
     /**
      * This broadcasts the same msg out to a bunch of Clients.
      *
@@ -216,8 +218,6 @@
      */
     void CheckResendPkts(void);
 
-    csRef<CS::Threading::Thread> thread;
-   
     /// list of connected clients
     ClientConnectionSet clients;
 
Index: src/server/psserver.cpp
===================================================================
--- src/server/psserver.cpp	(revision 8766)
+++ src/server/psserver.cpp	(working copy)
@@ -168,6 +168,8 @@
             }
         }
         while(p);
+
+        NetManager::Destroy();
     }
 
     delete economymanager;
@@ -176,7 +178,6 @@
     delete entitymanager;
     delete usermanager;
     delete exchangemanager;
-    delete netmanager;
     delete marriageManager;
     delete spawnmanager;
     delete adminmanager;

FIXME

 6116 Medium14.08.2013Ralph CampbellRalph Campbell Memory leak when deleting gemContainer 27.11.2013No Task Description

The psItems created in SpawnManager::RepopulateItems() are either assigned to a gemItem or a gemContainer.
This change makes sure the items in containers are deleted when the container is deleted.
To reproduce and verify, you may need to fix the mysql item_instances.sql so that items 76, 77, 78 refer to item 75 instead of 70 as the container ID.
See  bug 6114  for details on running valgrind.

Index: src/server/gem.h
===================================================================
--- src/server/gem.h	(revision 8762)
+++ src/server/gem.h	(working copy)
@@ -799,6 +804,8 @@
         float zrotangle,
         int clientnum);
 
+    ~gemContainer();
+
     /**
      * Check if a item can be added to a container.
      */
Index: src/server/gem.cpp
===================================================================
--- src/server/gem.cpp	(revision 8762)
+++ src/server/gem.cpp	(working copy)
@@ -1691,6 +1691,14 @@
 {
 }
 
+gemContainer::~gemContainer()
+{
+    while (itemlist.GetSize())
+    {
+        delete itemlist.Pop();
+    }
+}
+
 bool gemContainer::CanAdd(unsigned short amountToAdd, psItem *item, int slot, csString &reason)
 {
     if (!item)

FIXME

 6115 Medium14.08.2013Ralph CampbellRalph CampbellJoe Lyon Memory leak in TutorialMsgOp 20.11.2013No2 Task Description

To reproduce, run valgrind as in  bug 6114 .
This is a simple case of the destructor not deleting the private object.

Index: src/server/scripting.cpp
===================================================================
--- src/server/scripting.cpp	(revision 8762)
+++ src/server/scripting.cpp	(working copy)
@@ -2677,8 +2677,8 @@
 class TutorialMsgOp : public Imperative1
 {
 public:
-    TutorialMsgOp() : Imperative1() { }
-    virtual ~TutorialMsgOp() { }
+    TutorialMsgOp() : Imperative1(), expr(0) { }
+    virtual ~TutorialMsgOp() { delete expr; }
 
     bool Load(iDocumentNode* top)
     {

FIXME

 6114 Medium13.08.2013Ralph CampbellRalph Campbell There is a serious server memory leak with psItem. 24.01.2014No2 Task Description
To reproduce the problem, run:

valgrind --leak-check=full --log-file=vgs1 ./psserver --run=/this/test.script

where test.script contains:
loadmap npcroom1
loadmap npcroom2
loadmap npcroom_corr
loadmap podium
spawn
ready
quit

 112 bytes in 2 blocks are definitely lost in loss record 34 of 66
    at 0x4A08361: operator new(unsigned long) (vg_replace_malloc.c:298)
    by 0x47FFE5: SpawnManager::SpawnHuntLocations(Result&, psSectorInfo*) (spawnmanager.cpp:459)
    by 0x4804AE: SpawnManager::LoadHuntLocations(psSectorInfo*) (spawnmanager.cpp:398)
    by 0x4B6CC7: com_spawn(char const*) (command.cpp:568)
    by 0x7239E0: execute_line(char const*, csString*) [clone .constprop.18] (serverconsole.cpp:157)
    by 0x723E5F: ServerConsole::ExecuteScript(char const*) (serverconsole.cpp:209)
    by 0x724302: ServerConsole::Run() (serverconsole.cpp:227)
    by 0x4ECF40C: CS::Threading::Implementation::(anonymous namespace)::proxyFunc(void*) (pthread_thread.cpp:53)
    by 0x36DCE07D14: start_thread (pthread_create.c:308)
    by 0x36DCAF253C: clone (clone.S:114)

The problem is that gemItem and psItem use csWeakRef incorrectly.
There has to be an original reference that is released and then
all the csWeakRef references are magically set to NULL.
The current code creates psItems in CacheManager::LoadWorldItems()
but those references are never released.
It they were, then the csWeakRef in gemItem would be set to NULL
defeating the purpose of the itemdata pointer.
  com_spawn()
    SpawnManager::RepopulateItems()
      csArray<psItem*> items;
      CacheManager::LoadWorldItems()
        item = psCharacterInventory::GetItemFactory()
        items.Push(item)     // items array in RepopulateItems() is filled
      entityManager->CreateItem(item)  // item reference transferred to gemItem
        obj = new gemItem(item)
gemItem logically holds the reference to the psItem but never releases it
when the gemItem is destroyed.
The fix is to make gemItem do the delete of the psItem.

To verify the problem is fixed, rerun valgrind and see that the
stack traces with SpawnManager::LoadHuntLocations() are gone.

Index: src/server/bulkobjects/psitem.h
===================================================================
--- src/server/bulkobjects/psitem.h	(revision 8762)
+++ src/server/bulkobjects/psitem.h	(working copy)
@@ -234,7 +234,7 @@
 *  TODO: Add effect data - such as spell effects or poision or whatever.
 *  TODO: Merge various mutually exclusive stats into unions to save space.
 */
-class psItem : public iScriptableVar, public iDeleteObjectCallback, public CS::Utility::WeakReferenced
+class psItem : public iScriptableVar, public iDeleteObjectCallback
 {
 public:
 
Index: src/server/entitymanager.cpp
===================================================================
--- src/server/entitymanager.cpp	(revision 8762)
+++ src/server/entitymanager.cpp	(working copy)
@@ -831,8 +831,7 @@
     return obj;
 }
 
-
-gemItem* EntityManager::CreateItem(psItem *& iteminstance, bool transient, int tribeID)
+gemItem* EntityManager::CreateItem(psItem* iteminstance, bool transient, int tribeID)
 {
     psSectorInfo *sectorinfo;
     csVector3 newpos;
Index: src/server/entitymanager.h
===================================================================
--- src/server/entitymanager.h	(revision 8762)
+++ src/server/entitymanager.h	(working copy)
@@ -111,7 +111,7 @@
 
     bool CreateActionLocation(psActionLocation *instance, bool transient);
 
-    gemItem* CreateItem(psItem*& iteminstance, bool transient, int tribeID = 0);
+    gemItem* CreateItem(psItem* iteminstance, bool transient, int tribeID = 0);
     gemItem* MoveItemToWorld(psItem*       keyItem,
                              InstanceID  instance,
                              psSectorInfo* sectorinfo,
Index: src/server/gem.cpp
===================================================================
--- src/server/gem.cpp	(revision 8762)
+++ src/server/gem.cpp	(working copy)
@@ -1238,7 +1238,7 @@
 // gemItem
 //--------------------------------------------------------------------------------------
 
-gemItem::gemItem(GEMSupervisor* gemsupervisor, CacheManager* cachemanager, EntityManager* entitymanager, csWeakRef<psItem> item,
+gemItem::gemItem(GEMSupervisor* gemsupervisor, CacheManager* cachemanager, EntityManager* entitymanager, psItem* item,
                      const char* factname,
                      InstanceID instance,
                      iSector* room,
@@ -1678,7 +1678,7 @@
 //--------------------------------------------------------------------------------------
 
 gemContainer::gemContainer(GEMSupervisor* gemsupervisor, CacheManager* cachemanager,
-		EntityManager* entitymanager, csWeakRef<psItem> item,
+		EntityManager* entitymanager, psItem* item,
              const char* factname,
              InstanceID myInstance,
              iSector* room,
Index: src/server/gem.h
===================================================================
--- src/server/gem.h	(revision 8762)
+++ src/server/gem.h	(working copy)
@@ -637,7 +637,7 @@
 class gemItem : public gemActiveObject
 {
 protected:
-    csWeakRef<psItem> itemdata;
+    psItem* itemdata;
     csString itemType;
     float xRot;
     float yRot;
@@ -648,7 +648,7 @@
     gemItem(GEMSupervisor* gemsupervisor,
     		CacheManager* cachemanager,
     		EntityManager* entitymanager,
-    		csWeakRef<psItem> item,
+    		psItem* item,
         const char* factname,
         InstanceID myInstance,
         iSector* room,
@@ -658,6 +658,11 @@
         float zrotangle,
         int clientnum);
 
+    virtual ~gemItem()
+    {
+        delete itemdata;
+    }
+
     void SetTribeID(uint32_t id) { tribeID = id; }
     uint32_t  GetTribeID() { return tribeID; }
 
@@ -789,7 +794,7 @@
 public:
     gemContainer(GEMSupervisor* gemSupervisor, CacheManager* cachemanager,
     		EntityManager* entitymanager,
-    		csWeakRef<psItem> item,
+    		psItem* item,
         const char* factname,
         InstanceID myInstance,
         iSector* room,
Index: src/server/workmanager.h
===================================================================
--- src/server/workmanager.h	(revision 8762)
+++ src/server/workmanager.h	(working copy)
@@ -842,7 +842,7 @@
     float resultQuality;
     float KFactor;
     INVENTORY_SLOT_NUMBER transSlot;
-    csWeakRef<psItem> item;
+    psItem* item;
     psItem* workItem;
     int transType;
 };

FIXME

 6093 Medium29.07.2013Ralph CampbellJoe Lyon Always call CancelDrag() if dropping to starting slot. 20.11.2013No Task Description

I’m not sure why drag and dropping a split stack is handled differently than a single item.
There is no message to the server to undo so it is just a local operation.
I made the change below and it seems to work fine for me.
Also, use the defined constants from Crystalspace instead of hard coding mouse button values.

Index: src/client/psslotmgr.cpp
===================================================================
--- src/client/psslotmgr.cpp	(revision 8743)
+++ src/client/psslotmgr.cpp	(working copy)
@@ -76,7 +76,7 @@
         }
         else if(ev.Name == MouseDown)
         {
-            if(button == 0) // Left
+            if(button == csmbLeft) // Left
             {
                 if(isPlacing)
                 {
@@ -89,7 +89,7 @@
                     PlaceItem();
                 }
             }
-            else if(button == 1) // right
+            else if(button == csmbRight) // right
             {
                 if(!isRotating)
                 {
@@ -113,7 +113,7 @@
         }
         else if(ev.Name == MouseUp)
         {
-            if(button == 1) // right
+            if(button == csmbRight) // right
             {
                 if(isRotating)
                 {
@@ -370,8 +370,8 @@
     }
     else
     {
-        //do nothing if it's the same slot and we aren't dragging a split item
-        if(slot == draggingSlot.slot && !draggingSlot.split)
+        //do nothing if it's the same slot
+        if(slot == draggingSlot.slot)
         {
             CancelDrag();
             return;

FIXME

 6089 Medium25.07.2013Ralph CampbellJoe Lyon memory leak in waypoint.h 20.11.2013No2 Task Description

I was using valgrind to find memory leaks in the PS server and found this.
Although a `WaypointAlias` is freed in `RemoveAlias`, it is not freed when `aliases` is destroyed.
The easy way to be sure the memory is freed is to use csPDelArray<T> instead of csArray<T*>.

Index: src/common/util/waypoint.h
===================================================================
--- src/common/util/waypoint.h	(revision 8743)
+++ src/common/util/waypoint.h	(working copy)
@@ -83,7 +83,7 @@
 public:
     Location                   loc;            ///< Id and position
     csString                   group;          ///< Hold group name for this waypoint if any.
-    csArray<WaypointAlias*>    aliases;        ///< Hold aliases for this waypoint
+    csPDelArray<WaypointAlias> aliases;        ///< Hold aliases for this waypoint
 
     csArray<Waypoint*>         links;          ///< Links to other waypoinst connected with paths from this node.
     csArray<float>             dists;          ///< Distances of each link.
Index: src/common/util/waypoint.cpp
===================================================================
--- src/common/util/waypoint.cpp	(revision 8743)
+++ src/common/util/waypoint.cpp	(working copy)
@@ -274,9 +274,7 @@
     {
         if (aliasName.CompareNoCase(aliases[i]->alias))
         {
-            WaypointAlias* alias = aliases[i];
             aliases.DeleteIndexFast(i);
-            delete alias;
             return;
         }
     }

FIXME

 6088 Medium25.07.2013Ralph CampbellJoe Lyon train can be used uninitialized in pawsskillwindow.cpp 20.11.2013No Task Description

I was using valgrind to find bugs and found that `train` can be used uninitialized in pawsskillwindow.cpp.
I added `foundSeleced` for good measure.

Index: src/client/gui/pawsskillwindow.cpp
===================================================================
--- src/client/gui/pawsskillwindow.cpp	(revision 8743)
+++ src/client/gui/pawsskillwindow.cpp	(working copy)
@@ -61,6 +61,8 @@
     skillString.Clear();
     skillDescriptions.DeleteAll();
     filter = false;
+    train = false;
+    foundSelected = false;
 
     hitpointsMax = 0;
     manaMax = 0;

FIXME

 6087 Medium25.07.2013Ralph CampbellJoe Lyon buttonWidth used uninitialized in shortcutWindow 20.11.2013No2 Task Description

I was using valgrind to find bugs and found that buttonWidth can be uninitialized if the data/gui/shortcutwindow.xml doesn’t specify a buttonWidth attribute.

Index: src/client/gui/shortcutwindow.cpp
===================================================================
--- src/client/gui/shortcutwindow.cpp	(revision 8743)
+++ src/client/gui/shortcutwindow.cpp	(working copy)
@@ -67,6 +67,8 @@
     shortcutText = NULL;
     textBox = NULL;
     labelBox = NULL;
+    buttonWidth = 0;
+    scrollSize = 0;
 }
 
 

FIXME

 6086 Medium25.07.2013Ralph CampbellJoe Lyon Vital data used when uninitialized 20.11.2013No Task Description

I was using valgrind to find bugs and found that Vital.drRate was being used when uninitialized.
Rather than try to initialize struct Vital in src/common/rpgrules/vitals.h I think the cleaner solution is to add constructors in struct Vital.

Index: src/client/clientvitals.h
===================================================================
--- src/client/clientvitals.h	(revision 8743)
+++ src/client/clientvitals.h	(working copy)
@@ -37,6 +37,8 @@
 /// A character vital (such as HP or Mana) - client side
 struct Vital
 {
+    Vital() : value(0.0), drRate(0.0) {}
+
     float value;
     float drRate;
 };
Index: src/common/rpgrules/vitals.h
===================================================================
--- src/common/rpgrules/vitals.h	(revision 8743)
+++ src/common/rpgrules/vitals.h	(working copy)
@@ -75,11 +75,6 @@
         experiencePoints  = 0;
         progressionPoints = 0;
         lastDRUpdate = 0;
-        for(int i = 0; i < VITAL_COUNT; i++)
-        {
-            vitals[i].value = 0;
-            origVitals[i].value = 0;
-        }
     }
     ~psVitalManager() {}
     
Index: src/server/bulkobjects/servervitals.h
===================================================================
--- src/server/bulkobjects/servervitals.h	(revision 8743)
+++ src/server/bulkobjects/servervitals.h	(working copy)
@@ -64,6 +64,8 @@
 /// A character vital (such as HP or Mana) - server side.
 struct Vital
 {
+    Vital() : value(0.0) {}
+
     float value;
     VitalBuffable drRate; ///< Amount added to this vital each second
     VitalBuffable max;

FIXME

 6077 Medium20.07.2013Ralph CampbellRalph CampbellJoe Lyon GetPSMouseMods() doesn't get modifiers correctly (fix i ...20.11.2013No1 Task Description

valgrind warned about a conditional branch based on an uninitialized variable and I traced it to the following.
The code for GetPSMouseMods() wasn’t following what csMouseEventHelper::GetEventData() does.

Index: src/client/pscharcontrol.cpp
===================================================================
--- src/client/pscharcontrol.cpp	(revision 8675)
+++ src/client/pscharcontrol.cpp	(working copy)
@@ -136,7 +136,10 @@
         return 0;
     }
     uint32 modifiers;
-    event->Retrieve( "keyModifiers", modifiers );
+    const void* m;
+    size_t mSize;
+    (void) event->Retrieve("keyModifiers", m, mSize);
+    modifiers = csKeyEventHelper::GetModifiersBits (*((csKeyModifiers*)m));
     return modifiers & PS_MODS_MASK;
 }
 

FIXME

 6075 Medium17.07.2013Ralph CampbellRalph Campbell Display of items in containers in a character's invento ...20.11.2013No8 Task Description

The problem is that there are many different “slot” numbering conventions
and the slot number is not being converted correctly as it goes between
different numbering schemes.

1) The number the client uses to find a pawsSlot.
2) The publish/subscribe string the client uses to update a pawsSlot.
3) The number in the message to/from client and server.
4) The number in the server psCharacterInventory/psItem.
5) The location_in_parent number in the database.

For example, let’s say there is a glyph sack in bulk inventory PSCHARACTER_SLOT_BULK10 (25).
The client pawsContainerDescWindow::HandleViewContainer()
currently creates pawsSlots for 12 rows of 4 columns and numbers them 0 to 47.
It also subscribes to events “slotinv_%d” 25 * 100 + [0-47] + 16 and “sigClearInventorySlots”.
When the pawsSlot subscribes, the event from psInventoryCache will
fill the contents of the pawsSlot duplicating what HandleViewContainer()
is about to publish.

The first bug is that maybe the server shouldn’t send data for the contents
of containers in inventory in the MSGTYPE_GUIINVENTORY message.
That solves the duplication of “slotinv_%d” events and reduces network traffic.
But the current client can “/equip” items contained in containers so
maybe we should preserve that.
I decided to make the psInventoryCache::SetInventoryItem() not publish
the update for items in containers to avoid the collision.

The second bug is that when an item is dragged from bulk inventory to
a container in the inventory, the slotID for the container is sent
as slotID but the server returns a MSGTYPE_VIEW_CONTAINER message with the
slotID + 16. This is because SlotManager::MoveFromInventory() converts the
message slotID to containerID * 100 + slotID + 16 but in
psItem::UpdateInventoryStatus() the loc_in_parent is computed as “slot % 100”.

I decided to fix this on the client by subscribing to
containerID * 100 + slotID + 16 but publishing events with just
containerID * 100 + slotID.

The alternative would be to change the server to not add +16 and update the database
item_instances loc_in_parent for items in containers.

Index: src/client/gui/pawscontainerdescwindow.cpp
===================================================================
--- src/client/gui/pawscontainerdescwindow.cpp	(revision 8702)
+++ src/client/gui/pawscontainerdescwindow.cpp	(working copy)
@@ -104,7 +104,7 @@
         mesg.stackCount = -1; // hardcoded signal that item is not owned by this player
     }
 
-    sigData.Format("invslot_%d", mesg.containerID.Unbox() * 100 + mesg.slotID + 16);
+    sigData.Format("invslot_%d", mesg.containerID.Unbox() * 100 + mesg.slotID);
     if (!mesg.clearSlot)
     {
         data.Format("%s %d %d %s %s %s", mesg.icon.GetData(), mesg.stackCount, 0, mesg.meshName.GetData(), mesg.materialName.GetData(), mesg.name.GetData());
@@ -166,6 +166,9 @@
                     slot->SetSlotID(i*cols+j);
                     //slot->SetDefaultToolTip("Empty");
 
+                    // Note that the server adds +16 to the slotID that the
+                    // client sends so we subscribe to the slotID+16
+                    // but publish without the +16 to compensate.
                     csString slotName;
                     slotName.Format("invslot_%d", mesg.containerID * 100 + i*cols+j + (mesg.containerID < 100 ? 16 : 0));
                     slot->SetSlotName(slotName);
@@ -174,19 +177,16 @@
                     // invslot_n, or else the cached clear signal will override
                     // the signal with the cached slot data, resulting in an
                     // empty window.
-                    if (containerID < 100)
-                        PawsManager::GetSingleton().Subscribe("sigClearInventorySlots", slot);
                     PawsManager::GetSingleton().Subscribe("sigClearContainerSlots", slot);
                     PawsManager::GetSingleton().Subscribe(slotName, slot);
                 }
             }
         }
-        if (containerID > 100)
-            PawsManager::GetSingleton().Publish("sigClearContainerSlots");
+        PawsManager::GetSingleton().Publish("sigClearContainerSlots");
         for (size_t i=0; i < mesg.contents.GetSize(); i++)
         {
             csString sigData, data;
-            sigData.Format("invslot_%u", mesg.containerID * 100 + mesg.contents[i].slotID + 16);
+            sigData.Format("invslot_%u", mesg.containerID * 100 + mesg.contents[i].slotID);
 
             data.Format( "%s %d %d %s %s %s", mesg.contents[i].icon.GetData(),
                          mesg.contents[i].stackCount,
Index: src/client/psinventorycache.cpp
===================================================================
--- src/client/psinventorycache.cpp	(revision 8702)
+++ src/client/psinventorycache.cpp	(working copy)
@@ -107,41 +107,38 @@
                                         csString iconImage,
                                         int purifyStatus)
 {
-    if (itemhash.Get(slot,NULL))
+    CachedItemDescription* id = itemhash.Get(slot, NULL);
+    if (!id)
     {
-        CachedItemDescription* id = itemhash.Get(slot,NULL);
-        itemBySlot.Delete(id);
-        delete id;
+        id = new CachedItemDescription;
+        id->slot = slot;
+        itemhash.PutUnique(slot, id);
+        itemBySlot.InsertSorted(id, CachedItemDescription::CompareSlot);
     }
 
-    //printf("Setting item %s in slot %d\n", name.GetDataSafe(), slot);
+    id->containerID = containerID;
+    id->name = name;
+    id->meshName = meshName;
+    id->materialName = materialName;
+    id->weight = weight;
+    id->size = size;
+    id->stackCount = stackCount;
+    id->iconImage = iconImage;
+    id->purifyStatus = purifyStatus;
 
-    CachedItemDescription* newItem = new CachedItemDescription;
-    newItem->slot = slot;
-    newItem->containerID = containerID;
-    newItem->name = name;
-    newItem->meshName = meshName;
-    newItem->materialName = materialName;
-    newItem->weight = weight;
-    newItem->size = size;
-    newItem->stackCount = stackCount;
-    newItem->iconImage = iconImage;
-    newItem->purifyStatus = purifyStatus;
-
-    itemhash.PutUnique(slot, newItem);
-    itemBySlot.InsertSorted(newItem, CachedItemDescription::CompareSlot);
-
-    if (newItem && newItem->stackCount>0 && newItem->iconImage.Length() != 0)
+    // Don't publish slot updates for items in containers.
+    // That is handled by pawsContainerDescWindow.
+    if (id->stackCount>0 && id->iconImage.Length() != 0 && slot < 100)
     {
         csString sigData, data;
         sigData.Format("invslot_%d", slot);
 
-        data.Format( "%s %d %d %s %s %s", newItem->iconImage.GetData(),
-                     newItem->stackCount,
-                     newItem->purifyStatus,
-                     newItem->meshName.GetData(),
-                     newItem->materialName.GetData(),
-                     newItem->name.GetData());
+        data.Format( "%s %d %d %s %s %s", id->iconImage.GetData(),
+                     id->stackCount,
+                     id->purifyStatus,
+                     id->meshName.GetData(),
+                     id->materialName.GetData(),
+                     id->name.GetData());
 
         PawsManager::GetSingleton().Publish(sigData, data);
     }

FIXME

 6074 Medium17.07.2013Ralph CampbellJoe Lyon Use correct type for timeDelay in pawsnpcdialog.h (fix  ...20.11.2013No Task Description

From code inspection and gcc unsigned vs int warnings I found this.

Index: src/client/gui/pawsnpcdialog.h
===================================================================
--- src/client/gui/pawsnpcdialog.h      (revision 8702)
+++ src/client/gui/pawsnpcdialog.h      (working copy)
@@ -173,7 +173,7 @@
     bool enabledChatBubbles;       ///< Stores the state of chat bubbles.
     bool clickedOnResponseBubble;  ///< flag when player clicks on the response bubble
     bool gotNewMenu;               ///< keeps track of the incoming new menu message
-    int timeDelay;                 ///< calculates the time needed to read the last npc say
+    csTicks timeDelay;             ///< calculates the time needed to read the last npc say
     int questIDFree;               ///< Keeps the value of the quest if the free text question was triggered.

     pawsListBox* responseList;

FIXME

 6073 Medium17.07.2013Ralph CampbellRalph Campbell pawsContainerDescWindow::GetSlot() returns the wrong sl ...20.11.2013No2 Task Description

The code to get a pawsSlot from the container based on slotID is wrong since there can be more or less columns than 6.
Here is the fix.

Index: src/client/gui/pawscontainerdescwindow.cpp
===================================================================
--- src/client/gui/pawscontainerdescwindow.cpp	(revision 8702)
+++ src/client/gui/pawscontainerdescwindow.cpp	(working copy)
@@ -341,10 +341,11 @@
 
 pawsSlot* pawsContainerDescWindow::GetSlot(int slotID)
 {
-    int col = slotID%6;
-    int row = (slotID-col)/6;
+    int cols = contents->GetTotalColumns();
+    int col = slotID % cols;
+    int row = slotID / cols;
 
-    if (col > 0 && col < contents->GetTotalColumns())
+    if (col >= 0 && col < cols)
     {
         pawsListBoxRow* listRow = contents->GetRow(row);
         if (listRow)

FIXME

 6072 Medium17.07.2013Ralph CampbellJoe Lyon pawsInventoryWindow::UpdateFromContainer() test is wron ...20.11.2013No2 Task Description

The code tests fromContainerID twice which is obviously wrong since the first “if” means the second “if” never executes.
Here is the what I think the correct code is.

Index: src/client/gui/inventorywindow.cpp
===================================================================
--- src/client/gui/inventorywindow.cpp	(revision 8702)
+++ src/client/gui/inventorywindow.cpp	(working copy)
@@ -343,7 +343,7 @@
     // Find the fromSlot
     if (fromContainerID == CONTAINER_INVENTORY_BULK)
     {
-        if (fromContainerID >= 0 && fromContainerID < INVENTORY_BULK_COUNT)
+        if (fromSlotID >= 0 && fromSlotID < INVENTORY_BULK_COUNT)
         {
             fromSlot = bulkSlots[fromSlotID];
         }

FIXME

 6058 Medium06.07.2013Ralph CampbellJoe Lyon Use virtual descructor in SoundSectorManager (fix inclu ...20.11.2013No Task Description

I noticed a memory leak with valgrind involving SoundSectorManager and also a compiler warning that said a non-virtual destructor was being called on a polymorphic class.
The fix is simple:

Index: src/plugins/common/soundmanager/sectormngr.h
===================================================================
--- src/plugins/common/soundmanager/sectormngr.h	(revision 8675)
+++ src/plugins/common/soundmanager/sectormngr.h	(working copy)
@@ -61,7 +61,7 @@
     /**
      * Destructor.
      */
-    ~SoundSectorManager();
+    virtual ~SoundSectorManager();
 
     /**
      * Load all sound sectors defined in XML files stored in the areas folder. Its

FIXME

 6057 Medium05.07.2013Ralph CampbellJoe Lyon uninitialized variable mods in psControl (fix included) 13.07.2013No Task Description

Valgrind reported a branch based on an uninitialized variable.
Looking at the code, this was pretty easy to spot.

Index: src/client/pscharcontrol.h
===================================================================
--- src/client/pscharcontrol.h	(revision 8675)
+++ src/client/pscharcontrol.h	(working copy)
@@ -68,7 +68,7 @@
     };
         
     psControl(const char* n, PressType t, TriggerFunction f)
-        : name(n), state(false), device(NONE), button(0), type(t), function(f),
 data(NULL) {}
+        : name(n), state(false), device(NONE), button(0), mods(0), type(t), fun
ction(f), data(NULL) {}
     
     csString name;             ///< Name of this control
     bool state;                ///< Is this active?

FIXME

 6054 Medium01.07.2013Ralph CampbellRalph CampbellJoe Lyon Fix memory leaks in pscelclient.cpp (fix included) 20.11.2013No1 Task Description

I was using valgrind to find memory leaks and found a couple of problems in pscelclient.
The unresolved sector isn’t released at the end, and “csHash<ItemEffect*, csString> effectItems” doesn’t delete the ItemEffect, just the pointer.
If PutUnique() does find a matching entry, the old entry value is leaked when the new value replaces the pointer.
I think mesh names are unique so probably not a real issue but I put the check in anyway.
The call to “psengine→UnregisterDelayedLoader()” in ~GEMClientObject() is to protect against the engine calling into a deleted GEMClientObject.
I threw in the minor optimization for GEMClientActor::GetSector() since it is in the same file.

Index: src/client/pscelclient.cpp
===================================================================
--- src/client/pscelclient.cpp	(revision 8675)
+++ src/client/pscelclient.cpp	(working copy)
@@ -125,16 +124,20 @@
         msghandler->Unsubscribe(this, MSGTYPE_STATS);
     }
 
-    if(clientdr)
-        delete clientdr;
-    if(entityLabels)
-        delete entityLabels;
-    if(shadowManager)
-        delete shadowManager;
+    delete clientdr;
+    delete entityLabels;
+    delete shadowManager;
 
-
     entities.DeleteAll();
     entities_hash.DeleteAll();
+
+    // Delete effectItems
+    csHash<ItemEffect*, csString>::GlobalIterator i = effectItems.GetIterator();
+    while (i.HasNext())
+    {
+        delete i.Next();
+    }
+    effectItems.DeleteAll();
 }
 
 
@@ -376,7 +379,11 @@
                     ie->lights.PushSmart(li);
                 }
                 ie->activeOnGround = itemeffect->GetAttributeValueAsBool("activeonground");
-                effectItems.PutUnique(csString(itemeffect->GetAttributeValue("meshname")), ie);
+                csString meshname = itemeffect->GetAttributeValue("meshname");
+                if (!effectItems.Get(meshname, 0))
+                    effectItems.Put(meshname, ie);
+                else
+                    delete ie;
             }
         }
     }
@@ -1089,6 +1047,7 @@
         cel->UnattachObject(pcmesh->QueryObject(), this);
         psengine->GetEngine()->RemoveObject(pcmesh);
     }
+    psengine->UnregisterDelayedLoader(this);
 }
 
 int GEMClientObject::GetMasqueradeType(void)
@@ -1551,11 +1510,7 @@
 
 iSector* GEMClientActor::GetSector() const
 {
-    csVector3 pos;
-    float yrot;
-    iSector* sector;
-    linmove->GetLastPosition(pos,yrot, sector);
-    return sector;
+    return linmove->GetSector();
 }
 
 bool GEMClientActor::NeedDRUpdate(unsigned char &priority)
Index: src/client/pscelclient.h
===================================================================
--- src/client/pscelclient.h	(revision 8675)
+++ src/client/pscelclient.h	(working copy)
@@ -310,7 +308,7 @@
     GEMClientActor* local_player;
 
     csList<UnresolvedPos*> unresPos;   ///< list of entities with unresolved location
-    iSector * unresSector;             ///< sector where we keep these entities
+    csRef<iSector> unresSector;        ///< sector where we keep these entities
 };
 
 enum GEMOBJECT_TYPE

FIXME

 6053 Medium01.07.2013Ralph CampbellJoe Lyon Eliminate false error messages about empty text documen ...20.11.2013No2 Task Description

It is not an error for the paws textbox to have no initial text.
The problem is that the call to ParseStringGetNode defaults to verbose warnings.
The fix is to set verbose false.

Index: src/common/paws/pawstextbox.cpp
===================================================================
--- src/common/paws/pawstextbox.cpp	(revision 8675)
+++ src/common/paws/pawstextbox.cpp	(working copy)
@@ -2653,7 +2653,7 @@
 void pawsDocumentView::OrganizeContent(const char* newtext)
 {
     csString str(newtext);
-    csRef<iDocumentNode> root = ParseStringGetNode(str, "Contents");
+    csRef<iDocumentNode> root = ParseStringGetNode(str, "Contents", false);
 
     if(root == 0)
         return;
@@ -3027,7 +3027,7 @@
 void pawsMultiPageDocumentView::OrganizeContent(const char* newtext)
 {
     csString str(newtext);
-    csRef<iDocumentNode> root = ParseStringGetNode(str, "Contents");
+    csRef<iDocumentNode> root = ParseStringGetNode(str, "Contents", false);
 
     if(root == 0)
         return;

FIXME

 6052 Medium01.07.2013Ralph CampbellRalph CampbellJoe Lyon Memory leak in src/common/sound/manager.cpp (fix includ ...20.11.2013No2 Task Description

I was using valgrind to find memory leaks and found this one.
The problem is that csArray<T*> deletes the pointer but that doesn’t cause the memory to be freed.
The fix is to use csPDelArray<T>.

Index: src/common/sound/manager.cpp
===================================================================
--- src/common/sound/manager.cpp	(revision 8675)
+++ src/common/sound/manager.cpp	(working copy)
@@ -72,12 +72,6 @@
 
     UpdateSound();
 
-    // FIXME we must delete all SoundControls
-    for (size_t i = 0; i < soundController.GetSize(); i++)
-    {
-        delete soundController[i];
-    }
-    
     soundController.DeleteAll();
 
     delete soundSystem;
@@ -214,7 +208,6 @@
 void SoundSystemManager::StopSound (SoundHandle *handle)
 {
     soundHandles.Delete(handle);
-    delete handle;
 }
 
 /*
Index: src/common/sound/manager.h
===================================================================
--- src/common/sound/manager.h	(revision 8675)
+++ src/common/sound/manager.h	(working copy)
@@ -27,7 +27,7 @@
 #include <cssysdef.h>
 #include <iutil/objreg.h>
 #include <csgeom/vector3.h>
-#include <csutil/array.h>
+#include <csutil/parray.h>
 
 class SoundSystem;
 class SoundData;
@@ -160,9 +160,9 @@
     private:
     SoundSystem         *soundSystem;
     SoundData           *soundData;
-    csArray<SoundControl *> soundController;    ///< array which contains  all SoundControls
+    csPDelArray<SoundControl> soundController;  ///< array which contains all SoundControls
 
-    csArray<SoundHandle *>  soundHandles;       ///< array which contains all SoundHandles
+    csPDelArray<SoundHandle> soundHandles;      ///< array which contains all SoundHandles
 
     csTicks                 SndTime;            ///< current csticks
     csTicks                 LastUpdateTime;     ///< when the last update happened

FIXME

 6051 Medium01.07.2013Ralph CampbellJoe Lyon Memory leak in pseffectobj.cpp (fix included) 20.11.2013No Task Description

I was using valgrind to find memory leaks and found this one.
The psEffectObjKeyFrameGroup::Clone() returns a reference counted object pointer and assigns it to a csRef<> but that increments the refcount once too many.
The solution is to return a csPtr<> instead.

Index: src/common/effects/pseffectobj.cpp
===================================================================
--- src/common/effects/pseffectobj.cpp	(revision 8675)
+++ src/common/effects/pseffectobj.cpp	(working copy)
@@ -315,14 +315,15 @@
     keyFrames.DeleteAll();
 }
 
-psEffectObjKeyFrameGroup* psEffectObjKeyFrameGroup::Clone() const
+csPtr<psEffectObjKeyFrameGroup> psEffectObjKeyFrameGroup::Clone() const
 {
-    psEffectObjKeyFrameGroup* clone = new psEffectObjKeyFrameGroup();
+    csRef<psEffectObjKeyFrameGroup> clone;
+    clone.AttachNew(new psEffectObjKeyFrameGroup());
     for (size_t i = 0; i < keyFrames.GetSize(); i++)
     {
         clone->Push(new psEffectObjKeyFrame(keyFrames[i]));
     }
-    return clone;
+    return csPtr<psEffectObjKeyFrameGroup> (clone);
 }
 
 bool psEffectObjKeyFrameGroup::SetFrameParamScalings(const float* scale)
Index: src/common/effects/pseffectobj.h
===================================================================
--- src/common/effects/pseffectobj.h	(revision 8675)
+++ src/common/effects/pseffectobj.h	(working copy)
@@ -175,7 +175,7 @@
     /**
      * Clones the key frame group object.
      */
-    psEffectObjKeyFrameGroup* Clone() const;
+    csPtr<psEffectObjKeyFrameGroup> Clone() const;
 
     /**
      * Adjust each parameter in each frame that have the use_scale

FIXME

 6050 Medium01.07.2013Ralph CampbellJoe Lyon Remove unused variables in pscamera.cpp (fix included) 20.11.2013No Task Description

If you use configure –enabled-debug and compile PS, the following are flagged as set but not used.

Index: src/client/pscamera.cpp
===================================================================
--- src/client/pscamera.cpp	(revision 8675)
+++ src/client/pscamera.cpp	(working copy)
@@ -725,7 +723,6 @@
     csVector3 oldTarget = GetTarget(CAMERA_ACTUAL_DATA);
     view->GetCamera()->OnlyPortals(true);
     bool mirrored = view->GetCamera()->IsMirrored();
-    csVector3 oldOrigin = view->GetCamera()->GetTransform().GetOrigin();
 
     // Do a hitbeam between Position and Target to find the correct sector and coordinates.
     view->GetCamera()->GetTransform().SetOrigin(actorPos);
@@ -1708,11 +1705,11 @@
 {
     float cosYaw, sinYaw;
     float cosPit, sinPit;
-    float cosRol, sinRol;
+    // float cosRol, sinRol;
 
     cosYaw = cosf(GetYaw(mode));    sinYaw = sinf(GetYaw(mode));
     cosPit = cosf(GetPitch(mode));  sinPit = sinf(GetPitch(mode));
-    cosRol = 1.0f;                        sinRol = 0.0f;  // at this point, our camera doesn't support Roll
+    // cosRol = 1.0f;                  sinRol = 0.0f;  // at this point, our camera doesn't support Roll
 
     if (cosPit == 0.0f)
         cosPit = 0.001f;
@@ -1739,11 +1736,11 @@
 {
     float cosYaw, sinYaw;
     float cosPit, sinPit;
-    float cosRol, sinRol;
+    // float cosRol, sinRol;
 
     cosYaw = cosf(GetYaw(mode));    sinYaw = sinf(GetYaw(mode));
     cosPit = cosf(GetPitch(mode));  sinPit = sinf(GetPitch(mode));
-    cosRol = 1.0f;                        sinRol = 0.0f;  // at this point, our camera doesn't support Roll
+    // cosRol = 1.0f;                  sinRol = 0.0f;  // at this point, our camera doesn't support Roll
 
     if (cosPit == 0.0f)
         cosPit = 0.001f;

@@ -1847,7 +1838,6 @@
     const float INITIAL_DISTANCE = 200;     // we begin from this value
     static bool calledFirstTime = true;
 
-    static csTicks lastTime;                // when was this method last called ?
     csTicks currTime;                       // the current time
     static float lastChangeTime;            // when did we change the distance last time ?
 
@@ -1860,7 +1850,6 @@
     if (calledFirstTime)
     {
         calledFirstTime = false;
-        lastTime = csGetTicks();
         lastChangeTime = csGetTicks();
         return;
     }
@@ -1908,8 +1897,6 @@
     }
 
     //Error2("%s", debug.GetData());
-
-    lastTime = currTime;
 }
 
 

FIXME

 6049 Medium01.07.2013Ralph Campbell flyspray doesn't honor the code tag unless there is mor ...28.05.2020No Task Description

I noticed that the code tags don’t seem to take effect unless there is more stuff after the closing tag.

  if (a < b)
    c = 0;

Here is more text.

  #include "fix.h"
 6048 Medium01.07.2013Ralph CampbellJoe Lyon Uninitialized variable drRate used in vitals (fix inclu ...20.11.2013No Task Description

I was using valgrind to find memory leaks but it also finds places where branches are taken based on uninitialized data.
The psVitalManager<Vital> class clears the value field but doesn’t know about the drRate field in Vital.
Here is the fix that I used.

Index: src/client/clientvitals.cpp
===================================================================
--- src/client/clientvitals.cpp (revision 8675)
+++ src/client/clientvitals.cpp (working copy)
@@ -40,6 +40,12 @@
 {
     counter = 0;
     counterSet = false;
+
+    // psVitalManager initializes vitals[i].value but not drRate.
+    for(int i = 0; i < VITAL_COUNT; i++)
+    {
+        vitals[i].drRate = 0;
+    }
 }

Note: the code tags don’t seem to take effect unless there is more text at the end.

 6016 Medium02.06.2013Ralph CampbellRalph Campbell Use CS AttachNew() instead of casting to csPtr 24.01.2014No1 Task Description

This cleans up the PS code to use the standard Crystalspace method for attaching a new object to a csRef.
The easiest way to update the code is to copy the diff below into a file and do “patch -p0 < diff_file”.

Index: src/client/autoexec.cpp

— src/client/autoexec.cpp (revision 8702)
+++ src/client/autoexec.cpp (working copy)
@@ -151,7 +151,8 @@

       return;
   }
   // Save the autoexec commands

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   csRef<iDocumentNode> root = doc->CreateRoot ();
   csRef<iDocumentNode> mainNode = root->CreateNodeBefore(CS_NODE_ELEMENT);

Index: src/client/gui/bartender.cpp

— src/client/gui/bartender.cpp (revision 8702)
+++ src/client/gui/bartender.cpp (working copy)
@@ -106,7 +106,8 @@
pawsBartenderWindow::~pawsBartenderWindow()
{

   //prepares the file for writing

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   csRef<iDocumentNode> root = doc->CreateRoot ();
   csRef<iDocumentNode> bartenderNode = root->CreateNodeBefore(CS_NODE_ELEMENT);

Index: src/client/gui/chatwindow.cpp

— src/client/gui/chatwindow.cpp (revision 8702)
+++ src/client/gui/chatwindow.cpp (working copy)
@@ -1140,7 +1140,8 @@

       return;
   }


- csRef<iDocumentSystem> docsys = csPtr<iDocumentSystem> (new csTinyDocumentSystem ());
+ csRef<iDocumentSystem> docsys;
+ docsys.AttachNew(new csTinyDocumentSystem ());

   csRef<iDocument> doc = docsys->CreateDocument();
   csRef<iDocumentNode> root, chatNode, colorNode, optionNode,looseNode,filtersNode,

Index: src/client/gui/pawsactivemagicwindow.cpp

— src/client/gui/pawsactivemagicwindow.cpp (revision 8702)
+++ src/client/gui/pawsactivemagicwindow.cpp (working copy)
@@ -177,7 +177,8 @@

   csRef<iFile> file;
   file = psengine->GetVFS()->Open(CONFIG_ACTIVEMAGIC_FILE_NAME,VFS_FILE_WRITE);


- csRef<iDocumentSystem> docsys = csPtr<iDocumentSystem> (new csTinyDocumentSystem ());
+ csRef<iDocumentSystem> docsys;
+ docsys.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = docsys->CreateDocument();        
   csRef<iDocumentNode> root,defaultRoot, activeMagicNode, activeMagicOptionsNode, showWindowNode;

Index: src/client/gui/pawsconfigtooltips.cpp

— src/client/gui/pawsconfigtooltips.cpp (revision 8702)
+++ src/client/gui/pawsconfigtooltips.cpp (working copy)
@@ -139,7 +139,8 @@

   csRef<iFile> file;
   file = psengine->GetVFS()->Open(CONFIG_TOOLTIPS_FILE_NAME,VFS_FILE_WRITE);


- csRef<iDocumentSystem> docsys = csPtr<iDocumentSystem> (new csTinyDocumentSystem ());
+ csRef<iDocumentSystem> docsys;
+ docsys.AttachNew(new csTinyDocumentSystem ());

   csRef<iDocument> doc = docsys->CreateDocument();
   csRef<iDocumentNode> root, defaultRoot, TooltipsNode, showTooltipsNode, showBgColorNode, BgColorNode, FontColorNode, ShadowColorNode;

Index: src/client/gui/pawsignore.cpp

— src/client/gui/pawsignore.cpp (revision 8702)
+++ src/client/gui/pawsignore.cpp (working copy)
@@ -144,7 +144,8 @@
void pawsIgnoreWindow::SaveIgnoreList()
{

   csRef<iVFS> vfs =  csQueryRegistry<iVFS> (PawsManager::GetSingleton().GetObjectRegistry());

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   csRef<iDocumentNode> root = doc->CreateRoot();

Index: src/client/gui/pawsilluminationwindow.cpp

— src/client/gui/pawsilluminationwindow.cpp (revision 8702)
+++ src/client/gui/pawsilluminationwindow.cpp (working copy)
@@ -828,7 +828,7 @@

   csRef<iDocumentSystem>  xml;
   xml =  csQueryRegistry<iDocumentSystem> ( psengine->GetObjectRegistry() );
   if (!xml)

- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   const char* error = doc->Parse( xmlstr );

@@ -883,7 +883,7 @@

   csRef<iDocumentSystem>  xml;
   xml =  csQueryRegistry<iDocumentSystem> ( psengine->GetObjectRegistry() );
   if (!xml)

- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   const char* error = doc->Parse( xmlstr );

Index: src/client/gui/pawsnpcdialog.cpp

— src/client/gui/pawsnpcdialog.cpp (revision 8702)
+++ src/client/gui/pawsnpcdialog.cpp (working copy)
@@ -354,7 +354,8 @@

   questInfo.DeleteAll();
   displayIndex = 0;


- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc= xml->CreateDocument();
   const char* error = doc->Parse(xmlstr);

@@ -887,7 +888,8 @@

   csRef<iFile> file;
   file = psengine->GetVFS()->Open(CONFIG_NPCDIALOG_FILE_NAME,VFS_FILE_WRITE);


- csRef<iDocumentSystem> docsys = csPtr<iDocumentSystem> (new csTinyDocumentSystem());
+ csRef<iDocumentSystem> docsys;
+ docsys.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = docsys->CreateDocument();
   csRef<iDocumentNode> root,defaultRoot, npcDialogNode, npcDialogOptionsNode, useNpcDialogNode;

Index: src/client/gui/pawsquestwindow.cpp

— src/client/gui/pawsquestwindow.cpp (revision 8702)
+++ src/client/gui/pawsquestwindow.cpp (working copy)
@@ -617,7 +617,8 @@

   // Save quest notes to a local file
   char temp[20];

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   csRef<iDocumentNode> root = doc->CreateRoot();
   csRef<iDocumentNode> parentMain = root->CreateNodeBefore(CS_NODE_ELEMENT);

Index: src/client/gui/shortcutwindow.cpp

— src/client/gui/shortcutwindow.cpp (revision 8702)
+++ src/client/gui/shortcutwindow.cpp (working copy)
@@ -548,7 +548,8 @@

       return ;
   // Save the commands with their labels

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   csRef<iDocumentNode> root = doc->CreateRoot ();
   csRef<iDocumentNode> parentMain = root->CreateNodeBefore(CS_NODE_ELEMENT);

Index: src/client/pscamera.cpp

— src/client/pscamera.cpp (revision 8702)
+++ src/client/pscamera.cpp (working copy)
@@ -72,7 +72,7 @@
psCamera::psCamera()

       : psCmdBase(psengine->GetMsgHandler(), psengine->GetCmdHandler(), PawsManager::GetSingleton().GetObjectRegistry())

{
- view = csPtr<iView> (new csView(psengine→GetEngine(), psengine→GetG3D()));
+ view.AttachNew(new csView(psengine→GetEngine(), psengine→GetG3D()));

   view->GetCamera()->SetViewportSize (psengine->GetG3D()->GetWidth(),
       psengine->GetG3D()->GetHeight());


Index: src/client/pscelclient.cpp

— src/client/pscelclient.cpp (revision 8702)
+++ src/client/pscelclient.cpp (working copy)
@@ -961,7 +961,8 @@

void psCelClient::AttachObject(iObject* object, GEMClientObject* clientObject)
{
- csRef<psGemMeshAttach> attacher = csPtr<psGemMeshAttach> (new psGemMeshAttach(clientObject));
+ csRef<psGemMeshAttach> attacher;
+ attacher.AttachNew(new psGemMeshAttach(clientObject));

   attacher->SetName(clientObject->GetName());  // @@@ For debugging mostly.
   csRef<iObject> attacher_obj(scfQueryInterface<iObject> (attacher));
   object->ObjAdd(attacher_obj);

Index: src/client/psengine.cpp

— src/client/psengine.cpp (revision 8702)
+++ src/client/psengine.cpp (working copy)
@@ -263,7 +263,7 @@

   drawScreen = true;


- cal3DCallbackLoader = csPtr<psCal3DCallbackLoader> (new psCal3DCallbackLoader(objectreg));
+ cal3DCallbackLoader.AttachNew(new psCal3DCallbackLoader(objectreg));

   BrightnessCorrection = 0.0f;


@@ -491,10 +491,10 @@
#if defined(CS_PLATFORM_UNIX) && defined(INCLUDE_CLIPBOARD)

       event_selectionnotify = csevSelectionNotify(object_reg);

#endif
- eventHandlerLogic = csPtr<LogicEventHandler> (new LogicEventHandler(this));
- eventHandler2D = csPtr<EventHandler2D> (new EventHandler2D(this));
- eventHandler3D = csPtr<EventHandler3D> (new EventHandler3D(this));
- eventHandlerFrame = csPtr<FrameEventHandler> (new FrameEventHandler(this));
+ eventHandlerLogic.AttachNew(new LogicEventHandler(this));
+ eventHandler2D.AttachNew(new EventHandler2D(this));
+ eventHandler3D.AttachNew(new EventHandler3D(this));
+ eventHandlerFrame.AttachNew(new FrameEventHandler(this));

       csEventID esublog[] =
       {

@@ -578,9 +578,9 @@

       lastLoadingCount = 1;
       // Initialize Networking

- if(!netmanager)
+ if(!netmanager.IsValid())

       {

- netmanager = csPtr<psNetManager> (new psNetManager);
+ netmanager.AttachNew(new psNetManager);

           if(!netmanager->Initialize(object_reg))
           {

@@ -592,20 +592,14 @@

       inventoryCache = new psInventoryCache();
       guiHandler = new GUIHandler();

- celclient = csPtr<psCelClient> (new psCelClient());
+ celclient.AttachNew(new psCelClient());

       slotManager = new psSlotManager();
       songManager = new ClientSongManager();

- modehandler = csPtr<ModeHandler> (new ModeHandler(celclient,netmanager→GetMsgHandler(),object_reg));
- actionhandler = csPtr<ActionHandler> (new ActionHandler(netmanager→GetMsgHandler(), object_reg));
- zonehandler = csPtr<ZoneHandler> (new ZoneHandler(netmanager→GetMsgHandler(), celclient));
+ modehandler.AttachNew(new ModeHandler(celclient,netmanager→GetMsgHandler(),object_reg));
+ actionhandler.AttachNew(new ActionHandler(netmanager→GetMsgHandler(), object_reg));
+ zonehandler.AttachNew(new ZoneHandler(netmanager→GetMsgHandler(), celclient));

       questionclient = new psQuestionClient(GetMsgHandler(), object_reg);


- if(!zonehandler→IsValid())
- {
- lasterror = “Couldn’t init Zone Handler.”;
- Error2(”FATAL ERROR: %s”, lasterror.GetData());
- PS_PAUSEEXIT(1);
- }

       if(!celclient->Initialize(object_reg, GetMsgHandler()))
       {
           lasterror = "Couldn't init Cel Manager.";

Index: src/client/psnetmanager.cpp

— src/client/psnetmanager.cpp (revision 8702)
+++ src/client/psnetmanager.cpp (working copy)
@@ -58,26 +58,26 @@

   connection->SetEngine(psengine->GetEngine());


- msghandler = csPtr<ClientMsgHandler> (new ClientMsgHandler);
+ msghandler.AttachNew(new ClientMsgHandler);

   bool rc = msghandler->Initialize((NetBase*) connection, object_reg);
   if (!rc)
       return false;


- cmdhandler = csPtr<CmdHandler> (new CmdHandler(object_reg));
+ cmdhandler.AttachNew(new CmdHandler(object_reg));

- usercmds = csPtr<psUserCommands> (new psUserCommands(msghandler, cmdhandler, object_reg));
+ usercmds.AttachNew(new psUserCommands(msghandler, cmdhandler, object_reg));

   if (!usercmds->LoadEmotes())
   {
       return false;
   }
   

- guildcmds = csPtr<psGuildCommands>(new psGuildCommands(msghandler, cmdhandler, object_reg ));
- groupcmds = csPtr<psGroupCommands> (new psGroupCommands(msghandler, cmdhandler, object_reg));
+ guildcmds.AttachNew(new psGuildCommands(msghandler, cmdhandler, object_reg));
+ groupcmds.AttachNew(new psGroupCommands(msghandler, cmdhandler, object_reg));

   

- utilcmds = csPtr<psUtilityCommands> (new psUtilityCommands(msghandler, cmdhandler, object_reg));
- admincmds = csPtr<psAdminCommands> (new psAdminCommands(msghandler, cmdhandler, object_reg));
+ utilcmds.AttachNew(new psUtilityCommands(msghandler, cmdhandler, object_reg));
+ admincmds.AttachNew(new psAdminCommands(msghandler, cmdhandler, object_reg));

- authclient = csPtr<psAuthenticationClient> (new psAuthenticationClient(GetMsgHandler()));
+ authclient.AttachNew(new psAuthenticationClient(GetMsgHandler()));

   return true;

}
Index: src/common/effects/pseffect.cpp

— src/common/effects/pseffect.cpp (revision 8702)
+++ src/common/effects/pseffect.cpp (working copy)
@@ -246,7 +246,7 @@

   // create a listener for the attached position if it exists
   if (attachPos)
   {

- positionListener = (csPtr<psEffectMovableListener>) new psEffectMovableListener;
+ positionListener.AttachNew(new psEffectMovableListener);

       attachPos->GetMovable()->AddListener(positionListener);
       attachPos->GetMovable()->UpdateMove();
   }

@@ -254,7 +254,7 @@

   // create a listener for the attached target if it exists
   if (attachTarget)
   {

- targetListener = (csPtr<psEffectMovableListener>) new psEffectMovableListener;
+ targetListener.AttachNew(new psEffectMovableListener);

       attachTarget->GetMovable()->AddListener(targetListener);
       attachTarget->GetMovable()->UpdateMove();
   }

@@ -371,7 +371,7 @@

   // create a listener for the attached position if it exists
   if (attachPos)
   {

- positionListener = (csPtr<psEffectMovableListener>) new psEffectMovableListener;
+ positionListener.AttachNew(new psEffectMovableListener);

       attachPos->GetMovable()->AddListener(positionListener);
       attachPos->GetMovable()->UpdateMove();
   }

@@ -379,7 +379,7 @@

   // create a listener for the attached target if it exists
   if (attachTarget)
   {

- targetListener = (csPtr<psEffectMovableListener>) new psEffectMovableListener;
+ targetListener.AttachNew(new psEffectMovableListener);

       attachTarget->GetMovable()->AddListener(targetListener);
       attachTarget->GetMovable()->UpdateMove();
   }

Index: src/common/net/messages.cpp

— src/common/net/messages.cpp (revision 8702)
+++ src/common/net/messages.cpp (working copy)
@@ -8086,7 +8086,7 @@

   char *ptr = (char *)me->GetBufferPointerUnsafe(size);
   if (ptr)
   {

- databuf = csPtr<iDataBuffer> (new csDataBuffer (ptr, size, false));
+ databuf.AttachNew(new csDataBuffer (ptr, size, false));

   }

}

Index: src/common/paws/pawsgenericview.cpp

— src/common/paws/pawsgenericview.cpp (revision 8702)
+++ src/common/paws/pawsgenericview.cpp (working copy)
@@ -118,7 +118,7 @@

            return false;
   }


- view = csPtr<iView> (new csView( engine, PawsManager::GetSingleton().GetGraphics3D() ));
+ view.AttachNew(new csView( engine, PawsManager::GetSingleton().GetGraphics3D() ));

   if (engine->GetCameraPositions()->GetCount() > 0)
   {
       iCameraPosition * cp = engine->GetCameraPositions()->Get(0);

Index: src/common/paws/pawslistbox.cpp

— src/common/paws/pawslistbox.cpp (revision 8702)
+++ src/common/paws/pawslistbox.cpp (working copy)
@@ -969,7 +969,8 @@

void pawsListBox::SetColumnDef( int col, int width, int height, const char* widgetDesc )
{
- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc= xml->CreateDocument();
   doc->Parse( widgetDesc );

@@ -1515,7 +1516,8 @@

   widget->SetParent( this );
   //widget->Load( def[column].widgetNode );

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   csRef<iDocumentNode> node = doc->CreateRoot();
   node = node->CreateNodeBefore(CS_NODE_ELEMENT);

Index: src/common/paws/pawsmainwidget.cpp

— src/common/paws/pawsmainwidget.cpp (revision 8702)
+++ src/common/paws/pawsmainwidget.cpp (working copy)
@@ -106,7 +106,8 @@

   csRef<iVFS> vfs =  csQueryRegistry<iVFS > ( PawsManager::GetSingleton().GetObjectRegistry());
   csRef<iDataBuffer> buf = vfs->ReadFile( guiKeyFile );

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem> ( new csTinyDocumentSystem );
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   if ( !buf || !buf->GetSize() )
   {

Index: src/common/paws/pawsmanager.cpp

— src/common/paws/pawsmanager.cpp (revision 8702)
+++ src/common/paws/pawsmanager.cpp (working copy)
@@ -119,7 +119,7 @@

   KeyboardUp = csevKeyboardUp(objectReg);
   vfs =  csQueryRegistry<iVFS > (objectReg);

- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iConfigManager> cfg =  csQueryRegistry<iConfigManager> (objectReg);
   // Getting sound manager

Index: src/common/paws/pawsobjectview.cpp

— src/common/paws/pawsobjectview.cpp (revision 8702)
+++ src/common/paws/pawsobjectview.cpp (working copy)
@@ -203,7 +203,8 @@

bool pawsObjectView::LoadMap( const char* map, const char* sector )
{
- csRef<iStringArray> zone = csPtr<iStringArray>(new scfStringArray());
+ csRef<iStringArray> zone;
+ zone.AttachNew(new scfStringArray());

   zone->Push(map);
   if(!loader->LoadPriorityZones(zone))
   {

@@ -220,12 +221,12 @@

   static uint sectorCount = 0;
   meshSector = engine->CreateSector(csString(sector).AppendFmt("%u", sectorCount++));


- meshView = csPtr<iView>(new csView(engine, PawsManager::GetSingleton().GetGraphics3D()));
+ meshView.AttachNew(new csView(engine, PawsManager::GetSingleton().GetGraphics3D()));

   meshView->SetAutoResize(false);
   meshView->GetCamera()->SetSector(meshSector);
   meshView->GetCamera()->GetTransform().SetOrigin(csVector3(0, 1, -distance));


- view = csPtr<iView>(new csView(engine, PawsManager::GetSingleton().GetGraphics3D()));
+ view.AttachNew(new csView(engine, PawsManager::GetSingleton().GetGraphics3D()));

   view->SetAutoResize(false);
   view->GetCamera()->SetSector(stage);
   view->GetCamera()->GetTransform().SetOrigin(csVector3(0, 1, -distance));

Index: src/common/paws/pawsprefmanager.cpp

— src/common/paws/pawsprefmanager.cpp (revision 8702)
+++ src/common/paws/pawsprefmanager.cpp (working copy)
@@ -46,7 +46,7 @@

   objectReg = PawsManager::GetSingleton().GetObjectRegistry();
   vfs =  csQueryRegistry<iVFS > ( objectReg);

- xml = csPtr<iDocumentSystem> ( new csTinyDocumentSystem );
+ xml.AttachNew(new csTinyDocumentSystem);

   graphics2D =  csQueryRegistry<iGraphics2D > ( objectReg);
   defaultFont = defaultScaledFont = NULL;

Index: src/common/paws/pawsstyles.cpp

— src/common/paws/pawsstyles.cpp (revision 8702)
+++ src/common/paws/pawsstyles.cpp (working copy)
@@ -38,7 +38,8 @@

       Error2("Could not find file: %s", fileName.GetData());
       return false;
   }

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   assert(xml);
   csRef<iDocument> doc = xml->CreateDocument();
   assert(doc);

Index: src/common/paws/pawstexturemanager.cpp

— src/common/paws/pawstexturemanager.cpp (revision 8702)
+++ src/common/paws/pawstexturemanager.cpp (working copy)
@@ -49,7 +49,7 @@

   objectReg = object;
   vfs =  csQueryRegistry<iVFS > ( objectReg);

- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);
}

pawsTextureManager::~pawsTextureManager()
Index: src/common/paws/pawswidget.cpp

— src/common/paws/pawswidget.cpp (revision 8702)
+++ src/common/paws/pawswidget.cpp (working copy)
@@ -2687,7 +2687,8 @@

bool pawsWidget::SelfPopulateXML( const char *xmlstr )
{
- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc= xml->CreateDocument();
   const char *error = doc->Parse( xmlstr );

Index: src/common/paws/psmousebinds.cpp

— src/common/paws/psmousebinds.cpp (revision 8702)
+++ src/common/paws/psmousebinds.cpp (working copy)
@@ -161,7 +161,7 @@

       Error2("Could not find file: %s", filename.GetData());
       return false;
   }

- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);

   assert(xml);
   doc = xml->CreateDocument();
   assert(doc);

Index: src/common/sound/data.cpp

— src/common/sound/data.cpp (revision 8702)
+++ src/common/sound/data.cpp (working copy)
@@ -266,7 +266,7 @@

   SoundFile                      *snd;        ///< soundfile
   if (!(xml = csQueryRegistry<iDocumentSystem> (objectReg)))

- xml = csPtr<iDocumentSystem> (new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);

   buff = vfs->ReadFile(filename);


Index: src/common/util/namegenerator.cpp

— src/common/util/namegenerator.cpp (revision 8702)
+++ src/common/util/namegenerator.cpp (working copy)
@@ -261,7 +261,8 @@
bool NameGenerationSystem::LoadDatabase( iObjectRegistry* objectReg )
{

   csRef<iVFS> vfs =  csQueryRegistry<iVFS > ( objectReg);

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   
   csRef<iDataBuffer> buff = vfs->ReadFile( PHONICS_LIST );


Index: src/common/util/psxmlparser.cpp

— src/common/util/psxmlparser.cpp (revision 8702)
+++ src/common/util/psxmlparser.cpp (working copy)
@@ -283,8 +283,8 @@

       return NULL;
   }
   xml =  csQueryRegistry<iDocumentSystem> (object_reg);

- if (!xml)
- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ if (!xml.IsValid())
+ xml.AttachNew(new csTinyDocumentSystem);

   assert(xml);
   doc = xml->CreateDocument();
   assert(doc);

@@ -300,7 +300,7 @@
csRef<iDocument> ParseString(const csString & str, bool notify)
{

   csRef<iDocumentSystem> xml;

- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);

   CS_ASSERT(xml != NULL);
   csRef<iDocument> doc  = xml->CreateDocument();
   const char* error = doc->Parse(str);

Index: src/common/util/texfactory.cpp

— src/common/util/texfactory.cpp (revision 8702)
+++ src/common/util/texfactory.cpp (working copy)
@@ -43,7 +43,7 @@

   csRef<iVFS> vfs =  csQueryRegistry<iVFS> (object_reg);
   csRef<iDocumentSystem> xml =  csQueryRegistry<iDocumentSystem> (object_reg);
   if (!xml)

- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);

   if (!vfs || !xml)
       return false;


@@ -142,7 +142,7 @@

   csRef<iDocumentNode> node;
   csRef<iDocumentSystem> xmlDoc =  csQueryRegistry<iDocumentSystem> (object_reg);
   if (!xmlDoc)

- xmlDoc = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xmlDoc.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> xml = xmlDoc->CreateDocument();
   xml->Parse(xmlspec);


Index: src/eedit/eeditapp.cpp

— src/eedit/eeditapp.cpp (revision 8702)
+++ src/eedit/eeditapp.cpp (working copy)
@@ -267,7 +267,7 @@

   editWindow =     (pawsEEdit *)          paws->FindWidget("eedit");
   // Register our event handler

- event_handler = csPtr<EventHandler> (new EventHandler (this));
+ event_handler.AttachNew(new EventHandler (this));

   csEventID esub[] = {

csevFrame (object_reg),
csevMouseEvent (object_reg),
Index: src/eedit/eeditpartlisttoolbox.cpp

— src/eedit/eeditpartlisttoolbox.cpp (revision 8702)
+++ src/eedit/eeditpartlisttoolbox.cpp (working copy)
@@ -2047,7 +2047,8 @@
if (wnd)
{
EEditRequestCombo* rc = static_cast<EEditRequestCombo*> (wnd);
- csRef<CreateEmitCB> cb = csPtr<CreateEmitCB> (new CreateEmitCB(this));
+ csRef<CreateEmitCB> cb;
+ cb.AttachNew(new CreateEmitCB(this));
rc→SetCallback(cb);
rc→ClearChoices();
rc→AddChoice(”Sphere”);
@@ -2064,7 +2065,8 @@
if (wnd)
{
EEditRequestCombo* rc = static_cast<EEditRequestCombo*> (wnd);
- csRef<CreateEffectCB> cb = csPtr<CreateEffectCB> (new CreateEffectCB(this));
+ csRef<CreateEffectCB> cb;
+ cb.AttachNew(new CreateEffectCB(this));
rc→SetCallback(cb);
rc→ClearChoices();
rc→AddChoice(”Force”);
Index: src/npcclient/npcbehave.cpp

— src/npcclient/npcbehave.cpp (revision 8702)
+++ src/npcclient/npcbehave.cpp (working copy)
@@ -151,7 +151,8 @@

   inBoundsPerception    = row.GetString("in_bounds");
   fallingPerception     = row.GetString("falling");


- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   const char* error = doc->Parse(row.GetString("script"));
   if(error)

Index: src/npcclient/npcclient.cpp

— src/npcclient/npcclient.cpp (revision 8702)
+++ src/npcclient/npcclient.cpp (working copy)
@@ -388,7 +388,8 @@

csRef<iDocumentNode> psNPCClient::GetRootNode(const char* xmlfile)
{
- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDataBuffer> buff = vfs->ReadFile(xmlfile);


@@ -427,7 +428,8 @@

bool psNPCClient::AddNPCType(csString newType)
{
- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument>       doc = xml->CreateDocument();
   const char*            error = doc->Parse(newType);
   if(error)

@@ -2193,7 +2195,8 @@

void psNPCClient::AttachObject(iObject* object, gemNPCObject* gobject)
{
- csRef<psNpcMeshAttach> attacher = csPtr<psNpcMeshAttach>(new psNpcMeshAttach(gobject));
+ csRef<psNpcMeshAttach> attacher;
+ attacher.AttachNew(new psNpcMeshAttach(gobject));

   attacher->SetName(object->GetName());
   csRef<iObject> attacher_obj(scfQueryInterface<iObject>(attacher));


Index: src/npcclient/npcgui.cpp

— src/npcclient/npcgui.cpp (revision 8702)
+++ src/npcclient/npcgui.cpp (working copy)
@@ -122,7 +122,7 @@

 paws->GetMouse()->ChangeImage("Standard Mouse Pointer");
 // Register our event handler

- event_handler = csPtr<EventHandler> (new EventHandler (this));
+ event_handler.AttachNew(new EventHandler (this));

 csEventID esub[] = 
 {
   csevFrame (object_reg),

Index: src/plugins/common/soundmanager/data.cpp

— src/plugins/common/soundmanager/data.cpp (revision 8702)
+++ src/plugins/common/soundmanager/data.cpp (working copy)
@@ -244,7 +244,7 @@

   }
   if(!(xml = csQueryRegistry<iDocumentSystem>(objectReg)))

- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);

   buff = vfs->ReadFile(fileName);


Index: src/pslaunch/pslaunch.cpp

— src/pslaunch/pslaunch.cpp (revision 8702)
+++ src/pslaunch/pslaunch.cpp (working copy)
@@ -180,7 +180,7 @@

   paws->GetMouse()->ChangeImage("Standard Mouse Pointer");
   // Register our event handler

- event_handler = csPtr<EventHandler> (new EventHandler (this));
+ event_handler.AttachNew(new EventHandler (this));

   csEventID esub[] = 
   {
           csevFrame (object_reg),

Index: src/pslaunch/updaterengine.cpp

— src/pslaunch/updaterengine.cpp (revision 8702)
+++ src/pslaunch/updaterengine.cpp (working copy)
@@ -515,7 +515,8 @@
csRef<iDocumentNode> UpdaterEngine::GetRootNode(const char* nodeName, csRef<iDocument>* document)
{

   // Load xml.

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem> (new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   if (!xml)
   {
       PrintOutput("Could not load the XML Document System\n");

Index: src/server/bulkobjects/dictionary.cpp

— src/server/bulkobjects/dictionary.cpp (revision 8702)
+++ src/server/bulkobjects/dictionary.cpp (working copy)
@@ -1286,7 +1286,8 @@

   }
   int where=0;

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   const char* error = doc->Parse( xmlstr );
   if ( error )

Index: src/server/bulkobjects/pscharacter.cpp

— src/server/bulkobjects/pscharacter.cpp (revision 8702)
+++ src/server/bulkobjects/pscharacter.cpp (working copy)
@@ -604,7 +604,8 @@

       psserver->GetLogCSV()->Write(CSV_STATUS, status);
   }
   // Load merchant info

- csRef<psMerchantInfo> merchant = csPtr<psMerchantInfo>(new psMerchantInfo());
+ csRef<psMerchantInfo> merchant;
+ merchant.AttachNew(new psMerchantInfo());

   if (merchant->Load(use_id))
   {
       merchantInfo = merchant;

@@ -618,7 +619,8 @@

       psserver->GetLogCSV()->Write(CSV_STATUS, status);
   }
   // Load trainer info

- csRef<psTrainerInfo> trainer = csPtr<psTrainerInfo>(new psTrainerInfo());
+ csRef<psTrainerInfo> trainer;
+ trainer.AttachNew(new psTrainerInfo());

   if (trainer->Load(use_id))
   {
       trainerInfo = trainer;

Index: src/server/bulkobjects/psnpcloader.cpp

— src/server/bulkobjects/psnpcloader.cpp (revision 8702)
+++ src/server/bulkobjects/psnpcloader.cpp (working copy)
@@ -73,7 +73,8 @@

       return false;
   }


- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   const char* error = doc->Parse(data);
   if ( error )

@@ -164,7 +165,8 @@

       return false;
   }


- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   const char* error = doc->Parse(data);
   if ( error )

@@ -846,7 +848,8 @@

   npcID = id;
   area  = npc->GetCharName();


- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   csRef<iDocumentNode> root = doc->CreateRoot ();
   npcRoot = root->CreateNodeBefore(CS_NODE_ELEMENT);

@@ -886,7 +889,8 @@
{

   filename.Insert(0,"/this/");


- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   csRef<iDocumentNode> root = doc->CreateRoot ();


Index: src/server/bulkobjects/psquest.cpp

— src/server/bulkobjects/psquest.cpp (revision 8702)
+++ src/server/bulkobjects/psquest.cpp (working copy)
@@ -548,7 +548,8 @@

bool LoadPrerequisiteXML(csRef<psQuestPrereqOp>& prerequisite, psQuest * self, csString script)
{
- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   const char* error = doc->Parse( script );
   if ( error )

Index: src/server/client.cpp

— src/server/client.cpp (revision 8702)
+++ src/server/client.cpp (working copy)
@@ -95,8 +95,7 @@

   Client::clientnum=clientnum;
   Client::valid=true;


- outqueue = csPtr<NetPacketQueueRefCount>
- (new NetPacketQueueRefCount (MAXCLIENTQUEUESIZE));
+ outqueue.AttachNew(new NetPacketQueueRefCount (MAXCLIENTQUEUESIZE));

   if (!outqueue)
       ERRORHALT("No Memory!");


Index: src/server/economymanager.cpp

— src/server/economymanager.cpp (revision 8702)
+++ src/server/economymanager.cpp (working copy)
@@ -108,7 +108,8 @@

   if (!supplyDemandInfo.Contains(trans->item))
   {

- csRef<ItemSupplyDemandInfo> newInfo = csPtr<ItemSupplyDemandInfo>(new ItemSupplyDemandInfo);
+ csRef<ItemSupplyDemandInfo> newInfo;
+ newInfo.AttachNew(new ItemSupplyDemandInfo);

       supplyDemandInfo.Put(trans->item, newInfo);
   }


@@ -190,7 +191,8 @@
{

   if (!supplyDemandInfo.Contains(itemId))
   {

- csRef<ItemSupplyDemandInfo> newInfo = csPtr<ItemSupplyDemandInfo> (new ItemSupplyDemandInfo);
+ csRef<ItemSupplyDemandInfo> newInfo;
+ newInfo.AttachNew(new ItemSupplyDemandInfo);

       supplyDemandInfo.Put(itemId, newInfo);
   }
   return *supplyDemandInfo[itemId];

Index: src/server/gem.cpp

— src/server/gem.cpp (revision 8702)
+++ src/server/gem.cpp (working copy)
@@ -519,7 +519,8 @@

void GEMSupervisor::AttachObject( iObject* object, gemObject* gobject )
{
- csRef<psGemServerMeshAttach> attacher = csPtr<psGemServerMeshAttach>(new psGemServerMeshAttach(gobject));
+ csRef<psGemServerMeshAttach> attacher;
+ attacher.AttachNew(new psGemServerMeshAttach(gobject));

   attacher->SetName( object->GetName() );
   csRef<iObject> attacher_obj(scfQueryInterface<iObject>(attacher));


Index: src/server/groupmanager.cpp

— src/server/groupmanager.cpp (revision 8702)
+++ src/server/groupmanager.cpp (working copy)
@@ -730,7 +730,8 @@

csPtr<PlayerGroup> GroupManager::NewGroup(gemActor * leader)
{
- csRef<PlayerGroup> group = csPtr<PlayerGroup>(new PlayerGroup(this,leader));
+ csRef<PlayerGroup> group;
+ group.AttachNew(new PlayerGroup(this,leader));

   groups.Push(group);


Index: src/server/guildmanager.cpp

— src/server/guildmanager.cpp (revision 8702)
+++ src/server/guildmanager.cpp (working copy)
@@ -189,7 +189,7 @@

   clients    = cs;
   chatserver = chat;  // Needed to GUILDSAY things.


- xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ xml.AttachNew(new csTinyDocumentSystem);

   CS_ASSERT( xml );
   Subscribe(&GuildManager::HandleCmdMessage,MSGTYPE_GUILDCMD,REQUIRE_READY_CLIENT);

Index: src/server/npcmanager.cpp

— src/server/npcmanager.cpp (revision 8702)
+++ src/server/npcmanager.cpp (working copy)
@@ -881,7 +881,8 @@

               psDRMessage drmsg(data,len,psserver->GetNetManager()->GetAccessPointers()); // alternate method of cracking
               // copy the DR data into an iDataBuffer

- csRef<iDataBuffer> databuf = csPtr<iDataBuffer> (new csDataBuffer(len));
+ csRef<iDataBuffer> databuf;
+ databuf.AttachNew(new csDataBuffer(len));

               memcpy(databuf->GetData(), data, len);
               // find the entity and Set the DR data for it
               gemActor* actor = dynamic_cast<gemActor*>(gemSupervisor->FindObject(drmsg.entityid));

@@ -3456,7 +3457,8 @@

       }
       case psPetSkillMessage::SKILL_SELECTED:
       {

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

           CS_ASSERT(xml);


Index: src/server/progressionmanager.cpp

— src/server/progressionmanager.cpp (revision 8702)
+++ src/server/progressionmanager.cpp (working copy)
@@ -269,7 +269,8 @@

       }
       case psGUISkillMessage::SKILL_SELECTED:
       {

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

           CS_ASSERT( xml );


@@ -361,7 +362,8 @@

       case psGUISkillMessage::BUY_SKILL:
       {
           Debug1(LOG_SKILLXP, client->GetClientNum(),"---------------Buying Skill-------------\n");

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

           CS_ASSERT( xml );


Index: src/server/psserver.cpp

— src/server/psserver.cpp (revision 8702)
+++ src/server/psserver.cpp (working copy)
@@ -496,19 +496,19 @@

   if(!questmanager->Initialize())
       return false;


- chatmanager = csPtr<ChatManager> (new ChatManager);
+ chatmanager.AttachNew(new ChatManager);

   Debug1(LOG_STARTUP,0,"Started Chat Manager");


- guildmanager = csPtr<GuildManager>(new GuildManager(GetConnections(), chatmanager));
+ guildmanager.AttachNew(new GuildManager(GetConnections(), chatmanager));

   Debug1(LOG_STARTUP,0,"Started Guild Manager");


- questionmanager = csPtr<QuestionManager>(new QuestionManager());
+ questionmanager.AttachNew(new QuestionManager());

   Debug1(LOG_STARTUP,0,"Started Question Manager");


- advicemanager = csPtr<AdviceManager>(new AdviceManager(database));
+ advicemanager.AttachNew(new AdviceManager(database));

   Debug1(LOG_STARTUP,0,"Started Advice Manager");


- groupmanager = csPtr<GroupManager>(new GroupManager(GetConnections(), chatmanager));
+ groupmanager.AttachNew(new GroupManager(GetConnections(), chatmanager));

   Debug1(LOG_STARTUP,0,"Started Group Manager");
   charmanager = new ServerCharManager(cachemanager, entitymanager->GetGEM());

@@ -524,10 +524,10 @@

   tutorialmanager = new TutorialManager(GetConnections());


- actionmanager = csPtr<ActionManager>(new ActionManager(database));
+ actionmanager.AttachNew(new ActionManager(database));

   Debug1(LOG_STARTUP,0,"Started Action Manager");


- authserver = csPtr<AuthenticationServer>(new AuthenticationServer(GetConnections(), usermanager, guildmanager));
+ authserver.AttachNew(new AuthenticationServer(GetConnections(), usermanager, guildmanager));

   Debug1(LOG_STARTUP,0,"Started Authentication Server");
   exchangemanager = new ExchangeManager(GetConnections());

Index: src/server/scripting.cpp

— src/server/scripting.cpp (revision 8702)
+++ src/server/scripting.cpp (working copy)
@@ -854,7 +854,8 @@

ApplicativeScript* ApplicativeScript::Create(EntityManager* entitymanager, CacheManager* cachemanager, const char* script)
{
- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   const char* error = doc->Parse(script);
   if (error)

@@ -2194,7 +2195,8 @@

       //     <category attribute="Type|Lifecycle|AttackTool|AttackType|..." name="" value="" />
       //     ...
       //     <category attribute="Type|Lifecycle|AttackTool|AttackType|..." name="" value="" />

- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

       CS_ASSERT(xml != NULL);
       csRef<iDocument> xmlDoc = xml->CreateDocument();
       const char* error = xmlDoc->Parse(chr->GetAnimalAffinity());

@@ -2718,7 +2720,8 @@

ProgressionScript* ProgressionScript::Create(EntityManager* entitymanager,CacheManager* cachemanager, const char* name, const char* script)
{
- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   csRef<iDocument> doc = xml->CreateDocument();
   const char* error = doc->Parse(script);
   if (error)

Index: src/server/serverstatus.cpp

— src/server/serverstatus.cpp (revision 8702)
+++ src/server/serverstatus.cpp (working copy)
@@ -75,7 +75,8 @@

   csString reportString;
   csString timeString;
   

- csRef<iDocumentSystem> docSystem = csPtr<iDocumentSystem> (new csTinyDocumentSystem ());
+ csRef<iDocumentSystem> docSystem;
+ docSystem.AttachNew(new csTinyDocumentSystem ());

   csRef<iDocument> doc = docSystem->CreateDocument();
   csRef<iDocumentNode> rootNode = doc->CreateRoot();


Index: src/server/spawnmanager.cpp

— src/server/spawnmanager.cpp (revision 8702)
+++ src/server/spawnmanager.cpp (working copy)
@@ -264,7 +264,8 @@
#if 0
bool SpawnManager::LoadWaypointsAsSpawnRanges()
{
- csRef<iDocumentSystem> xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem);
+ csRef<iDocumentSystem> xml;
+ xml.AttachNew(new csTinyDocumentSystem);

   const char *xmlfile = "/planeshift/data/npcdefs.xml";
   csRef<iDataBuffer> buff = vfs->ReadFile(xmlfile);

Index: src/tools/pawseditor/pawseditorapp.cpp

— src/tools/pawseditor/pawseditorapp.cpp (revision 8702)
+++ src/tools/pawseditor/pawseditorapp.cpp (working copy)
@@ -202,7 +202,7 @@

   skinSelector = (peSkinSelector *) paws->FindWidget( "peSkinSelector" );
   // Register our event handler

- event_handler = csPtr<EventHandler> (new EventHandler (this));
+ event_handler.AttachNew(new EventHandler (this));

   csEventID esub[] = {

csevFrame (object_reg),
csevMouseEvent (object_reg),
Index: src/worldeditor/worldeditor.cpp

— src/worldeditor/worldeditor.cpp (revision 8702)
+++ src/worldeditor/worldeditor.cpp (working copy)
@@ -196,7 +196,8 @@

   paws->GetMouse()->ChangeImage("Standard Mouse Pointer");
   // Register our event handler

- csRef<EventHandler> event_handler = csPtr<EventHandler> (new EventHandler (this));
+ csRef<EventHandler> event_handler;
+ event_handler.AttachNew(new EventHandler (this));

   csEventID esub[] = 
   {
       csevFrame (objectReg),
 6015 Medium02.06.2013Ralph CampbellVenalan Could not load image /planeshift/jewelry/powder_jar01_n ...19.12.2016No6 Task Description

I see this message when crossing into Hydlaa from East Hydlaa.

Could not load image /planeshift/jewelry/powder_jar01_n.dds!

I think the database needs to change the “jewelry” to “materials”.

Also:

Unable to find material /planeshift/materials/ring_01c.dds for item Ring of Xiosia (factory jewelry#ring01)!

Perhaps it should be “/planeshift/materials/ring01c.dds”.

 6000 Medium21.05.2013Ralph CampbellDavide Vescovini Tinga Tea is not consumable 05.08.2013No2 Task Description

Tinga Tea from Herbal Remedies can be made but when I try to consume it by drag-and-drop onto the doll figure, it just “bounces” back to the original box in inventory. I don’t see any error messages in the Main Tab.

 5961 Medium30.03.2013Ralph CampbellAnders Reggestad false returned instead of NULL 03.04.2013No Task Description

Fix compiler warnings that a pointer is not being returned.

Index: src/common/paws/pawstree.cpp

— src/common/paws/pawstree.cpp (revision 8649)
+++ src/common/paws/pawstree.cpp (working copy)
@@ -676,7 +676,7 @@

   csRect frame;
   if (parent->IsCollapsed())

- return false;
+ return NULL;

   child = parent->GetFirstChild();
   while (child != NULL)

Index: src/plugins/common/recast/celhpf.cpp

— src/plugins/common/recast/celhpf.cpp (revision 8649)
+++ src/plugins/common/recast/celhpf.cpp (working copy)
@@ -1423,7 +1423,7 @@

 csHash<csRef<iSector>, const char*> sectors;
 if(!ParseMeshes(meshesNode, sectors, navStruct, vfs, params))
 {

- return false;
+ return NULL;

 }
 // Read high level graph

@@ -1431,7 +1431,7 @@

 csRef<iCelGraph> graph = scfCreateInstance<iCelGraph>("cel.celgraph");
 if(!ParseGraph(graphNode, graph, sectors))
 {

- return false;
+ return NULL;

 }
 navStruct->SetHighLevelGraph(graph);


Index: src/server/bulkobjects/psnpcdialog.cpp

— src/server/bulkobjects/psnpcdialog.cpp (revision 8649)
+++ src/server/bulkobjects/psnpcdialog.cpp (working copy)
@@ -96,7 +96,7 @@
const char* NpcTriggerSentence::GeneralizeTerm(NPCDialogDict *dict,size_t which, size_t depth)
{

   if (which >= terms.GetSize())

- return false;
+ return NULL;

   
   str.Clear();


Index: src/server/psproxlist.cpp

— src/server/psproxlist.cpp (revision 8649)
+++ src/server/psproxlist.cpp (working copy)
@@ -285,7 +285,7 @@

           return objectsThatIWatch[x];
       }
   }

- return false;
+ return NULL;
}

void ProximityList::UpdatePublishDestRange(PublishDestination *pd, gemObject *myself, gemObject *object,

5923Medium03.03.2013Ralph CampbellDavide Vescovinimagical protection spells ineffective30.05.2020No5 Task Description

My character was attacking a Rogue in fully defensive mode with the following spells active and the damage was not noticeably reduced.

Animate Vegetation
Armoured Skin
Defensive Wind
Dome of Perfection
Lesser Future Sight
Rock Armor
Water Barrier

This is ridiculous.
One of these spells should have some protective effect and all of them active at the same time should have some additive effect.
Character was wearing no armor at the time.

 5921 Medium03.03.2013Ralph CampbellAnders Reggestad UpdaterEngine::UpdateFile is missing a return statement 29.03.2013No1 Task Description

The function UpdaterEngine::UpdateFile() is missing a return statement at the end.
Found with compiler warnings turned on.

Index: src/pslaunch/updaterengine.cpp

— src/pslaunch/updaterengine.cpp (revision 8625)
+++ src/pslaunch/updaterengine.cpp (working copy)
@@ -1382,6 +1382,7 @@

       }
   }
   PrintOutput(" Success!\n");

+ return true;
}

void UpdaterEngine::CheckAndUpdate(iDocumentNode* md5sums, csString baseurl, bool accepted)

 5913 Medium27.02.2013Ralph CampbellAnders Reggestad loot_modifiers_restrains.sql is missing a DROP TABLE co ...27.02.2013No Task Description

The mysql file to create the loot_modifiers_restrains.sql is missing a line to delete the table if it exists.
The ‘DROP TABLE’ line should be added so the database is created cleanly similar to the other sql files.
Also, the create table shouldn’t specify the planeshift database name so it is similar to the other sql files.

svn diff src/server/database/mysql/loot_modifiers_restrains.sql
Index: src/server/database/mysql/loot_modifiers_restrains.sql

— src/server/database/mysql/loot_modifiers_restrains.sql (revision 8612)
+++ src/server/database/mysql/loot_modifiers_restrains.sql (working copy)
@@ -2,7 +2,8 @@
# Table structure for table loot_modifiers_restrains
#

-CREATE TABLE `planeshift`.`loot_modifiers_restrains` (
+DROP TABLE IF EXISTS `loot_modifiers_restrains`;
+CREATE TABLE `loot_modifiers_restrains` (

 `loot_modifier_id` INTEGER  NOT NULL COMMENT 'The id of the loot modifier rule',
 `item_id` INTEGER  NOT NULL COMMENT 'The id of the item included in the loot modifier rule',
 PRIMARY KEY (`loot_modifier_id`, `item_id`)
 5912 Medium27.02.2013Ralph CampbellAnders Reggestad command_access.sql has minor syntax error 27.02.2013No Task Description

The mysql database file command_access.sql is missing a ‘;’ on two lines thus causing a SQL syntax error when loading.

svn diff src/server/database/mysql/command_access.sql
Index: src/server/database/mysql/command_access.sql

— src/server/database/mysql/command_access.sql (revision 8612)
+++ src/server/database/mysql/command_access.sql (working copy)
@@ -70,8 +70,8 @@
INSERT INTO command_group_assignment VALUES( “/key”, 30 );
INSERT INTO command_group_assignment VALUES( “full modify”, 30 );
INSERT INTO command_group_assignment VALUES( “spawn all”, 30 );
-INSERT INTO command_group_assignment VALUES( “variables list”, 30)
-INSERT INTO command_group_assignment VALUES( “variables modify”, 30)
+INSERT INTO command_group_assignment VALUES( “variables list”, 30);
+INSERT INTO command_group_assignment VALUES( “variables modify”, 30);

# GM5 and above
INSERT INTO command_group_assignment VALUES( “/disablequest”, 30 );

 5870 Medium16.01.2013Ralph Campbell adding an item to a nearly full glyph sack caused item  ...24.01.2014No1 Task Description

I tried adding a Guildhouse key to a glyph sack that only had 2 empty slots (capacity .92/1) and the key disappeared.
It was not on the ground or nearby (I tried “/target key”).
The drag and drop was a single key from a stack of 4 keys and now I only have 3 keys.
I tried logout/login but that didn’t seem to change the inventory contents.

 5864 Medium31.12.2012Ralph Campbell problem with completing "A Wife's Dilemma" 11.02.2013No2 Task Description

It looks like the quest “A Wife’s Dilemma” is broken. After talking to Gayla and Jayose, I selected the dialog option for the ribbon and entered “blue”. But then talking to Tilavi doesn’t get the book back. There are 5 dialog options for Moren still enabled and repeating them doesn’t activate Tilavi.

 5761 Medium15.09.2012Ralph Campbell quest: Remembrance of Love broken 20.09.2012No1 Task Description

After the 9/12/2012 quest updates, this quest won’t start because Fholen doesn’t understand “Ok, I’ll see what I can do.”.

 5740 Medium19.08.2012Ralph Campbell Gardr needs a quench tank 02.09.2012No1 Task Description

It would be very handy if there was a Quench Tank at Gardr’s smithy.
Otherwise, you can’t make blades, quench heated ingots, etc.

 5730 Medium07.08.2012Ralph Campbell crossing a sector stops character movement 20.11.2013No9 Task Description

In the latest commit #8414, it looks like the ability to change the character’s movement velocity was added but it is set to zero.
This has the effect of making the character stop at all sector crossings and one has to “jump” to move over it.

I worked around the problem by commenting out the following line in ZoneHandler::MovePlayerTo() in file src/client/zonehandler.cpp:

  //celclient->GetMainPlayer()->SetVelocity(csVector3(0.0,0.0,newVel));
Showing tasks 1 - 50 of 70 Page 1 of 21 - 2 -

Available keyboard shortcuts

Tasklist

Task Details

Task Editing