Feature fixes & enhancements.

*Adds LOG_FEATURE (--debug feature) so we can keep track of features.

*Disallow VTOLs from being able to poach features.

*Changes feature spawning from instant to a variable time period.

*When feature can't be placed, break out of routine instead of sending invalid data.

*Actually remove features, and notify others that the feature was removed. (AKA, actually sync between machines.)

ASSERT() when numNaybors is invalid.
Fix a spamming debug line mistakenly changed in r6677


git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@6737 4a71c877-e1ca-e34f-864e-861f7616d084
master
Buginator 2009-02-28 03:36:26 +00:00
parent df0ada9a50
commit fc8bbc5bd9
7 changed files with 70 additions and 19 deletions

View File

@ -74,6 +74,7 @@ static const char *code_part_names[] = {
"gateway",
"message",
"terrain",
"feature",
"last"
};

View File

@ -139,6 +139,7 @@ typedef enum {
LOG_GATEWAY,
LOG_MSG,
LOG_TERRAIN,
LOG_FEATURE,
LOG_LAST /**< _must_ be last! */
} code_part;

View File

@ -254,6 +254,7 @@ FEATURE * buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y,BOOL FromSave)
FEATURE* psFeature = createFeature();
if (psFeature == NULL)
{
debug(LOG_WARNING, "Feature couldn't be built.");
return NULL;
}
// features are not in the cluster system

View File

@ -2912,7 +2912,11 @@ static void checkLocalFeatures(DROID *psDroid)
{
SDWORD i;
BASE_OBJECT *psObj;
static int oilTimer = 0;
static bool GenerateDrum = false;
static uint8_t drumCount = 0;
// NOTE: Why not do this for AI units also?
// only do for players droids.
if(psDroid->player != selectedPlayer)
{
@ -2920,7 +2924,7 @@ static void checkLocalFeatures(DROID *psDroid)
}
droidGetNaybors(psDroid);// update naybor list.
ASSERT( numNaybors <= MAX_NAYBORS, "numNaybors is %d, out of range of %d!", numNaybors, MAX_NAYBORS);
// scan the neighbours
for(i=0; i<(SDWORD)numNaybors; i++)
{
@ -2928,26 +2932,43 @@ static void checkLocalFeatures(DROID *psDroid)
psObj = asDroidNaybors[i].psObj;
if ( psObj->type != OBJ_FEATURE
|| ((FEATURE *)psObj)->psStats->subType != FEAT_OIL_DRUM
|| asDroidNaybors[i].distSqr >= DROIDDIST )
|| asDroidNaybors[i].distSqr >= DROIDDIST
|| isVtolDroid(psDroid)) // VTOLs can't pick up features!
{
// object too far away to worry about
continue;
}
if(bMultiPlayer && (psObj->player == ANYPLAYER))
{
giftPower(ANYPLAYER,selectedPlayer,true); // give power and tell everyone.
addOilDrum(1);
// when player finds oil, we init the timer, and flag that we need a drum
if (!oilTimer)
{
oilTimer = gameTime2;
GenerateDrum = true;
}
// if player finds more than one drum (before timer expires), then we tack on ~50 sec to timer.
if(drumCount++)
{
oilTimer += GAME_TICKS_PER_SEC * 50;
}
}
else
{
addPower(selectedPlayer,OILDRUM_POWER);
CONPRINTF(ConsoleString,(ConsoleString,_("You found %u power in an oil drum"),OILDRUM_POWER));
CONPRINTF(ConsoleString,(ConsoleString,_("You found %u power in an oil drum."),OILDRUM_POWER));
}
removeFeature((FEATURE*)psObj); // remove artifact+ send multiplay info.
}
// once they found a oil drum, we then wait ~600 secs before we pop up new one(s).
if( ((oilTimer + GAME_TICKS_PER_SEC * 600) < gameTime2 ) && GenerateDrum )
{
addOilDrum(drumCount);
oilTimer = 0;
drumCount = 0;
GenerateDrum = false;
}
}

View File

@ -311,6 +311,7 @@ void giftPower(uint8_t from, uint8_t to, BOOL send)
if (from == ANYPLAYER)
{
gifval = OILDRUM_POWER;
CONPRINTF(ConsoleString,(ConsoleString,_("Player %u found %u power in an oil drum"), to, gifval));
}
else
{
@ -321,10 +322,6 @@ void giftPower(uint8_t from, uint8_t to, BOOL send)
addPower(to, gifval);
if (from == ANYPLAYER && to == selectedPlayer)
{
CONPRINTF(ConsoleString,(ConsoleString,_("You found %u power in an oil drum"),gifval));
}
if (send)
{
uint8_t giftType = POWER_GIFT;
@ -604,6 +601,23 @@ void recvMultiPlayerFeature()
}
}
}
// must match _feature_type in featuredef.h
static const char *feature_names[] =
{
"FEAT_BUILD_WRECK",
"FEAT_HOVER",
"FEAT_TANK",
"FEAT_GEN_ARTE",
"FEAT_OIL_RESOURCE",
"FEAT_BOULDER",
"FEAT_VEHICLE",
"FEAT_BUILDING",
"FEAT_DROID",
"FEAT_LOS_OBJ",
"FEAT_OIL_DRUM",
"FEAT_TREE",
"FEAT_SKYSCRAPER",
};
///////////////////////////////////////////////////////////////////////////////
// splatter artifact gifts randomly about.
void addMultiPlayerRandomArtifacts(uint8_t quantity, FEATURE_TYPE type)
@ -613,6 +627,7 @@ void addMultiPlayerRandomArtifacts(uint8_t quantity, FEATURE_TYPE type)
uint32_t x, y;
uint8_t player = ANYPLAYER;
debug(LOG_FEATURE, "Sending %u artifact(s) type: (%s)", quantity, feature_names[type]);
NETbeginEncode(NET_ARTIFACTS, NET_ALL_PLAYERS);
NETuint8_t(&quantity);
NETenum(&type);
@ -630,7 +645,8 @@ void addMultiPlayerRandomArtifacts(uint8_t quantity, FEATURE_TYPE type)
if (!pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT))
{
ASSERT(false, "addMultiPlayerRandomArtifacts: Unable to find a free location");
ASSERT(false, "Unable to find a free location");
break;
}
pF = buildFeature(asFeatureStats + i, world_coord(x), world_coord(y), false);
@ -671,6 +687,7 @@ void recvMultiPlayerRandomArtifacts()
NETuint8_t(&quantity);
NETenum(&type);
debug(LOG_FEATURE, "receiving %u artifact(s) type: (%s)", quantity, feature_names[type]);
for (i = 0; i < numFeatureStats && asFeatureStats[i].subType != type; i++);
for (count = 0; count < quantity; count++)
@ -684,13 +701,13 @@ void recvMultiPlayerRandomArtifacts()
if (!tileOnMap(tx, ty))
{
debug(LOG_ERROR, "recvMultiPlayerRandomArtifacts: Bad tile coordinates (%u,%u)", tx, ty);
debug(LOG_ERROR, "Bad tile coordinates (%u,%u)", tx, ty);
continue;
}
psTile = mapTile(tx, ty);
if (!psTile || psTile->psObject != NULL)
{
debug(LOG_ERROR, "recvMultiPlayerRandomArtifacts: Already something at (%u,%u)!", tx, ty);
debug(LOG_ERROR, "Already something at (%u,%u)!", tx, ty);
continue;
}
@ -700,6 +717,10 @@ void recvMultiPlayerRandomArtifacts()
pF->id = ref;
pF->player = player;
}
else
{
debug(LOG_ERROR, "Couldn't build feature %u for player %u ?", ref, player);
}
}
NETend();
}

View File

@ -849,7 +849,8 @@ static BOOL campInit(void)
// add free research gifts..
if(NetPlay.bHost)
{
addOilDrum( NetPlay.playercount*2 ); // add some free power.
// NOTE: you can set this safely to 50 for testing.
addOilDrum( NetPlay.playercount*2); // add some free power.
}
playerResponding(); // say howdy!

View File

@ -123,8 +123,8 @@ BOOL turnOffMultiMsg(BOOL bDoit)
{
if(bTemp == true)
{
// Surely, this should be a Assert?
debug(LOG_ERROR, "multiple calls to turn off");
// This is spammed multiple times.
debug(LOG_NEVER, "multiple calls to turn off");
}
if(bMultiPlayer)
{
@ -1479,10 +1479,13 @@ static BOOL recvDestroyTemplate()
// send a destruct feature message.
BOOL SendDestroyFeature(FEATURE *pF)
{
// Only send if it is our responsibility
if (myResponsibility(pF->player))
// Since ANYPLAYER is supposed to be controlled by host only, that creates a issue when
// a MP player gets a feature, and it is 'ANYPLAYER' it would never send the destroy msg.
if (!myResponsibility(pF->player) || !(pF->player == ANYPLAYER))
{
return true;
}
debug(LOG_FEATURE, "p%d feature id %d destroyed (%s)", pF->player, pF->id, pF->psStats->pName);
NETbeginEncode(NET_FEATUREDEST, NET_ALL_PLAYERS);
NETuint32_t(&pF->id);
return NETend();
@ -1502,9 +1505,11 @@ BOOL recvDestroyFeature()
if (pF == NULL)
{
debug(LOG_WARNING, "feature id %d not found? (sync error?)", id);
return false;
}
debug(LOG_FEATURE, "p%d feature id %d destroyed (%s)", pF->player, pF->id, pF->psStats->pName);
// Remove the feature locally
turnOffMultiMsg(true);
removeFeature(pF);