Fix droid frustrated state. Make AI droids clip through each other when frustrated.

This should clear up the worst traffic jams.
master
Per Inge Mathisen 2012-10-27 18:50:10 +02:00
parent 647f5ed236
commit a19e41c15d
7 changed files with 27 additions and 11 deletions

View File

@ -34,8 +34,6 @@
#include "map.h"
#include "projectile.h"
#define FRUSTRATED_TIME (1000 * 5)
/* Weights used for target selection code,
* target distance is used as 'common currency'
*/
@ -634,11 +632,13 @@ int aiBestNearestTarget(DROID *psDroid, BASE_OBJECT **ppsObj, int weapon_slot, i
}
}
else if (targetInQuestion->type == OBJ_FEATURE
&& psDroid->lastFrustratedTime > 0
&& gameTime - psDroid->lastFrustratedTime < FRUSTRATED_TIME
&& ((FEATURE *)targetInQuestion)->psStats->damageable
&& psDroid->player != scavengerPlayer()) // hack to avoid scavs blowing up their nice feature walls
{
psTarget = targetInQuestion;
objTrace(psDroid->id, "considering shooting at %s in frustration", objInfo(targetInQuestion));
}
/* Check if our weapon is most effective against this object */

View File

@ -36,6 +36,9 @@
#define ALLIANCES 1
#define ALLIANCES_TEAMS 2 //locked teams
/// Amount of time to rage at the world when frustrated (10 seconds)
#define FRUSTRATED_TIME (1000 * 10)
// alliances
extern uint8_t alliances[MAX_PLAYER_SLOTS][MAX_PLAYER_SLOTS];
extern PlayerMask alliancebits[MAX_PLAYER_SLOTS];

View File

@ -1725,11 +1725,11 @@ static void dealWithLMBDroid(DROID* psDroid, SELECTION_TYPE selection)
if (getDebugMappingStatus()) // cheating on, so output debug info
{
CONPRINTF(ConsoleString, (ConsoleString,
"%s - Damage %d%% - ID %d - experience %f, %s - order %s - action %s - sensor range %hu - ECM %u - pitch %.0f",
"%s - Damage %d%% - ID %d - experience %f, %s - order %s - action %s - sensor range %hu - ECM %u - pitch %.0f - frust %u",
droidGetName(psDroid),
100 - clip(PERCENT(psDroid->body, psDroid->originalBody), 0, 100), psDroid->id,
psDroid->experience/65536.f, getDroidLevelName(psDroid), getDroidOrderName(psDroid->order.type), getDroidActionName(psDroid->action),
droidSensorRange(psDroid), droidConcealment(psDroid), UNDEG(psDroid->rot.pitch)));
droidSensorRange(psDroid), droidConcealment(psDroid), UNDEG(psDroid->rot.pitch), psDroid->lastFrustratedTime));
FeedbackOrderGiven();
}
else

View File

@ -307,6 +307,7 @@ DROID::DROID(uint32_t id, unsigned player)
sMove.asPath = NULL;
sMove.Status = MOVEINACTIVE;
lastFrustratedTime = 0; // make sure we do not start the game frustrated
}
/* DROID::~DROID: release all resources associated with a droid -
@ -1804,8 +1805,6 @@ DROID *reallyBuildDroid(DROID_TEMPLATE *pTemplate, Position pos, UDWORD player,
psGrp->add(psDroid);
}
psDroid->lastFrustratedTime = -UINT16_MAX; // make sure we do not start the game frustrated
psDroid->listSize = 0;
psDroid->listPendingBegin = 0;

View File

@ -152,7 +152,7 @@ struct DROID : public BASE_OBJECT
UDWORD originalBody; ///< the original body points
uint32_t experience;
int lastFrustratedTime; ///< Set when eg being stuck; used for eg firing indiscriminately at map features to clear the way (note: signed, so wrap arounds after 24.9 days)
UDWORD lastFrustratedTime; ///< Set when eg being stuck; used for eg firing indiscriminately at map features to clear the way
SWORD resistance; ///< used in Electronic Warfare

View File

@ -4257,6 +4257,7 @@ static bool loadSaveDroid(const char *pFileName, DROID **ppsCurrentDroidLists)
psDroid->actionStarted = ini.value("actionStarted", 0).toInt();
psDroid->actionPoints = ini.value("actionPoints", 0).toInt();
psDroid->resistance = ini.value("resistance", 0).toInt(); // zero resistance == no electronic damage
psDroid->lastFrustratedTime = ini.value("lastFrustratedTime", 0).toInt();
// copy the droid's weapon stats
for (int j = 0; j < psDroid->numWeaps; j++)

View File

@ -759,11 +759,18 @@ static bool moveBlocked(DROID *psDroid)
// Stopped long enough - blocked
psDroid->sMove.bumpTime = 0;
psDroid->sMove.lastBump = 0;
objTrace(psDroid->id, "BLOCKED");
if (!isHumanPlayer(psDroid->player) && bMultiPlayer)
{
psDroid->lastFrustratedTime = gameTime;
objTrace(psDroid->id, "FRUSTRATED");
}
else
{
objTrace(psDroid->id, "BLOCKED");
}
// if the unit cannot see the next way point - reroute it's got stuck
if ((bMultiPlayer || psDroid->player == selectedPlayer) &&
psDroid->sMove.pathIndex != psDroid->sMove.numPoints)
if ((bMultiPlayer || psDroid->player == selectedPlayer || psDroid->lastFrustratedTime == gameTime)
&& psDroid->sMove.pathIndex != psDroid->sMove.numPoints)
{
objTrace(psDroid->id, "Trying to reroute to (%d,%d)", psDroid->sMove.destination.x, psDroid->sMove.destination.y);
moveDroidTo(psDroid, psDroid->sMove.destination.x, psDroid->sMove.destination.y);
@ -1139,6 +1146,12 @@ static void moveCalcDroidSlide(DROID *psDroid, int *pmx, int *pmy)
// everything else doesn't avoid people
continue;
}
if (psObj->player == psDroid->player
&& psDroid->lastFrustratedTime > 0
&& gameTime - psDroid->lastFrustratedTime < FRUSTRATED_TIME)
{
continue; // clip straight through own units when sufficient frustrated -- using cheat codes!
}
}
else
{