I might have found the problem. I used m_OwnerName == "" instead of m_OwnerName != ""
It works
Aww I get deadlocks when logging out ;(
It works
Aww I get deadlocks when logging out ;(
Random Chitchat 2012-2016
|
I might have found the problem. I used m_OwnerName == "" instead of m_OwnerName != ""
It works Aww I get deadlocks when logging out ;(
11-12-2013, 06:25 AM
Deadlocks are easy. They mostly get detected in the cDeadlockDetect class, which breaks into the debugger, and then you can examine each thread whether it's waiting for a critical section (has EnterCriticalSection in its call stack); then you can switch to that stack level and examine the critical section, you can then see which other thread currently owns the critical section, through cCriticalSection's m_OwningThreadID. This way you can trace what is holding what.
Your problem is that you're calling m_OwnerObject->IsDestroyed() although you haven't checked if it's not NULL - if the name is (non-)empty but the object is NULL, the function is called on a NULL object.
I'm currently using
if (IsTame()) { if (m_OwnerName != "" && m_OwnerObject == NULL) { class cCallback : public cPlayerListCallback { virtual bool Item(cPlayer * Player) override { OwnerObject = Player; return false; } public: cPlayer * OwnerObject; } Callback; m_World->DoWithPlayer(m_OwnerName, Callback); if (Callback.OwnerObject != NULL) { m_OwnerObject = Callback.OwnerObject; m_OwnerName = m_OwnerObject->GetName(); } } else { if (m_OwnerObject->IsDestroyed()) { m_OwnerObject = NULL; return; } Vector3f OwnerCoords = Vector3f(m_OwnerObject->GetPosition()); double Distance = (OwnerCoords - GetPosition()).Length(); if (Distance < 3) { m_bMovingToDestination = false; } else if ((Distance > 30) && (!IsSitting())) { TeleportToCoords(OwnerCoords.x, OwnerCoords.y, OwnerCoords.z); } else { m_Destination = OwnerCoords; } } }This should fix it right?
I think you don't need the IsDestroyed() check; it is unreliable (another thread can destroy the cPlayer object anywhere in the middle of this entire function - if the player is in another world). Your code is more or less breaking the very purpose of callbacks - not to have objects stored outside of the safety of the callbacks.
To be safe now, I'd use the scenario of remembering only the player name and using the DoWithPlayer() callback to directly set the destination, rather than remembering the player object: if (IsTame()) { class cCallback : public cPlayerListCallback { virtual bool Item(cPlayer * a_Player) override { OwnerPos = a_Player->GetPosition(); return false; } public: Vector3f OwnerPos; } Callback; if (m_World->DoWithPlayer(m_OwnerName, Callback)) { // The player is present in the world, follow them: double Distance = (Callback.OwnerCoords - GetPosition()).Length(); if (Distance < 3) { m_bMovingToDestination = false; } else if ((Distance > 30) && (!IsSitting())) { TeleportToCoords(Callback.OwnerCoords.x, Callback.OwnerCoords.y, Callback.OwnerCoords.z); } else { m_Destination = Callback.OwnerCoords; } } } // if (IsTame())Also, consider moving this entire piece of code to a separate function, TickFollowPlayer() for example; that way the code for Tick() will be more readable and it will be easier to split and extract it once we start implementing AI behaviors.
Thats basicly the code there is now. Maybe we can even create an cPet class?
11-12-2013, 07:14 AM
No need to, these will be moved out of the individual mob classes into behavior classes that the AI will use.
11-14-2013, 12:10 AM
Creeper World 3 has been released, and therefore I haven't had much time for the last week
http://knucklecracker.com/
11-14-2013, 08:11 AM
I have (hopefully) set up a loop at Tip4Commit, so that all the BTC that I receive for my commits go back to the project as donations. Hopefully this can motivate a few people to keep committing
11-14-2013, 05:33 PM
Cool!
|
« Next Oldest | Next Newest »
|