19 May 2018 Tagged: eulorac++

If you want to hang around, you’re going to have to pull you own weight. Foxybot is no different. And foxybot is in fact pulling her own weight. But lets not settle for merely that. Lets tune this bitch up.

Ok, so foxybot is chugging along, diggin' & buildin' and whatnot. But often, too often, she grabs the wrong stick. I mean, she’s making a sincere effort. If you watch her you’ll see that when there’s only one staff within reach she’s fine, she does her thing with it and then moves on. The problem is when you put her in a situation where she is just surrounded by wood she just ends up groping for the closest one.

Foxybot
Figure 1. Foxybot, overwhelmed. Last night.

Nothing 'bad' ends up happening, it’s just a missed opportunity. You’re not gonna wring anything more from a stick that’s been already drained. And the latest one you erected, well, if you couldn’t manage to get ahold of it the first time around, how are you expecting to get it later on?

So lets investigate what’s going through her mind.

src/client/foxybot/botactivity.cpp(169)
case MSGTYPE_PERSIST_ITEM:
{
        if (actionToDo == ACTION_BUILD)		//process only messages in sequence with the exploring done
        {
                psPersistItem incoming(message, psengine->GetNetManager()->GetConnection()->GetAccessPointers());
                message->Reset();

                if (incoming.name.EndsWith(EXP_MARKER))     (1)
                {
                        if (markerID == 0)		//retain first marker  (2)
                        {
                                markerID = incoming.eid;
                                markerPos = incoming.pos;
                        }
                        else
                        {
                                csVector3 newPos = incoming.pos;
                                csVector3 cPos = worldHandler::GetCurrentPos();
                                float d = csSquaredDist::PointPoint(cPos, markerPos);
                                float newd = csSquaredDist::PointPoint(cPos, newPos);

                                if (newd < d)	//update marker ID only if new marker is CLOSER to the character
                                {       (3)
                                        markerID = incoming.eid;
                                        markerPos = incoming.pos;
                                }
                        }
                }
        }
        break;
}
1 This will get called, and evaluate to true once for each marker in the area.
2 Her memory (i.e. markerID) is wiped between encounters, when she subsequently opens her eyes, she’s gonna grab the first shaft she sees.
3 Now if sees one that is closer, she’s going to grab on to that one instead.

I’ve got to take a second here and explain a little about how the game works. First you dig. Then, if successful, a stick with a little head on it appears somewhere within reach. Now, it looks like Foxybot had a sheltered childhood where the closest stick is always the correct stick. But that’s not the way it is in these parts. In fact, the more an area gets worked the more likely it is that the closest stick is the wrong stick.

I’m going to have her take note of each marker that’s already been processed. If she ever sees an old one again, she’s going to leave it alone.

src/client/foxybot/botactivity.h(332)
csHash<EID, EID> spentClaims;  (1)
1 add a new thing to the header thing

And then check to see if it has been used up before:

src/client/foxybot/botactivity.cpp(169)
case MSGTYPE_PERSIST_ITEM:
{
        if (actionToDo == ACTION_BUILD)		//process only messages in sequence with the exploring done
        {
                psPersistItem incoming(message, psengine->GetNetManager()->GetConnection()->GetAccessPointers());
                message->Reset();

                if (incoming.name.EndsWith(EXP_MARKER))
                {
+                       if (spentClaims.Contains(incoming.eid)) {  (1)
+                               break;
+                       }
                        if (markerID == 0)		//retain first marker
                        {
                                markerID = incoming.eid;
                                markerPos = incoming.pos;
                        }
                        else
                        {
                                csVector3 newPos = incoming.pos;
                                csVector3 cPos = worldHandler::GetCurrentPos();
                                float d = csSquaredDist::PointPoint(cPos, markerPos);
                                float newd = csSquaredDist::PointPoint(cPos, newPos);

                                if (newd < d)	//update marker ID only if new marker is CLOSER to the character
                                {
                                        markerID = incoming.eid;
                                        markerPos = incoming.pos;
                                }
                        }
                }
        }
        break;
}
1 Hey! Keep your damn hands off that one, jeez!

Now I need to actually save the claims in there.

src/client/foxybot/botactivity.cpp(668)
void ExploreActivity::DoUseCombine()
{
	worldHandler::TargetEID(markerID);
	if (claimType.CompareNoCase("Tiny"))
		worldHandler::UseTarget();
	else if (claimType.CompareNoCase("Small"))
		worldHandler::CombineContentsInTarget();
+	spentClaims.Put(markerID, markerID);
}
void ExploreActivity::DoTakeResult()
{
	worldHandler::TargetEID(markerID);
	worldHandler::TakeAllFromTarget();
+	spentClaims.Put(markerID, markerID);
}

Here I’m saving the claim marker after the combine and after taking the result. In a perfect world I could do it only after taking the result. But either of these could fail, and so I’m covering both cases.

And ba-da-bing ba-da-boom…​ efficiency! What can I say, I’m an architect. And I do imports and exports.


Add a Comment