Skip to content

Commit

Permalink
Synchronise barrel and artefact placement.
Browse files Browse the repository at this point in the history
Artefacts are now dropped by factories, again. Even if the structure was destroyed
without using debug mode.
  • Loading branch information
Cyp committed Mar 31, 2012
1 parent ea243df commit 29966c5
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 148 deletions.
1 change: 0 additions & 1 deletion lib/netplay/netplay.cpp
Expand Up @@ -3589,7 +3589,6 @@ const char *messageTypeToString(unsigned messageType_)
case GAME_TEMPLATEDEST: return "GAME_TEMPLATEDEST";
case GAME_ALLIANCE: return "GAME_ALLIANCE";
case GAME_GIFT: return "GAME_GIFT";
case GAME_ARTIFACTS: return "GAME_ARTIFACTS";
case GAME_LASSAT: return "GAME_LASSAT";
case GAME_GAME_TIME: return "GAME_GAME_TIME";
case GAME_PLAYER_LEFT: return "GAME_PLAYER_LEFT";
Expand Down
1 change: 0 additions & 1 deletion lib/netplay/netplay.h
Expand Up @@ -99,7 +99,6 @@ enum MESSAGE_TYPES
GAME_TEMPLATEDEST, ///< remove template
GAME_ALLIANCE, ///< alliance data.
GAME_GIFT, ///< a luvly gift between players.
GAME_ARTIFACTS, ///< artifacts randomly placed.
GAME_LASSAT, ///< lassat firing.
GAME_GAME_TIME, ///< Game time. Used for synchronising, so that all messages are executed at the same gameTime on all clients.
GAME_PLAYER_LEFT, ///< Player has left or dropped.
Expand Down
188 changes: 50 additions & 138 deletions src/multigifts.cpp
Expand Up @@ -517,41 +517,33 @@ bool recvAlliance(NETQUEUE queue, bool allowAudio)
// add an artifact on destruction if required.
void technologyGiveAway(const STRUCTURE *pS)
{
uint8_t count = 1;
FEATURE_TYPE type = FEAT_GEN_ARTE;
syncDebug("Adding artefact.");

// If a fully built factory (or with modules under construction) which is our responsibility got destroyed
if (pS->pStructureType->type == REF_FACTORY && (pS->status == SS_BUILT || pS->currentBuildPts >= pS->body)
&& myResponsibility(pS->player))
int featureIndex;
for (featureIndex = 0; featureIndex < numFeatureStats && asFeatureStats[featureIndex].subType != FEAT_GEN_ARTE; ++featureIndex) {}
if (featureIndex >= numFeatureStats)
{
uint32_t x = map_coord(pS->pos.x);
uint32_t y = map_coord(pS->pos.y);
uint32_t id = generateNewObjectId();

// Pick a tile to place the artifact
if (!pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT))
{
ASSERT(false, "technologyGiveAway: Unable to find a free location");
}

NETbeginEncode(NETgameQueue(selectedPlayer), GAME_ARTIFACTS);
{
/* Make sure that we don't have to violate the constness of pS.
* Since the nettype functions aren't const correct when sending
*/
uint8_t player = pS->player;

NETuint8_t(&count);
NETenum(&type);
NETuint32_t(&x);
NETuint32_t(&y);
NETuint32_t(&id);
NETuint8_t(&player);
}
NETend();
debug(LOG_WARNING, "No artefact feature!");
return;
}

return;
uint32_t x = map_coord(pS->pos.x), y = map_coord(pS->pos.y);
if (!pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT))
{
syncDebug("Did not find location for oil drum.");
debug(LOG_FEATURE, "Unable to find a free location.");
return;
}
FEATURE *pF = buildFeature(&asFeatureStats[featureIndex], world_coord(x), world_coord(y), false);
if (pF)
{
pF->player = pS->player;
syncDebugFeature(pF, '+');
}
else
{
debug(LOG_ERROR, "Couldn't build artefact?");
}
}

/** Sends a build order for the given feature type to all players
Expand Down Expand Up @@ -604,132 +596,52 @@ void recvMultiPlayerFeature(NETQUEUE queue)
}
}
}
// must match _feature_type in featuredef.h
static const char *feature_names[] =
{
"FEAT_UNUSED",
"FEAT_HOVER",
"FEAT_TANK",
"FEAT_GEN_ARTE",
"FEAT_OIL_RESOURCE",
"FEAT_BOULDER",
"FEAT_VEHICLE",
"FEAT_BUILDING",
"FEAT_UNUSED",
"FEAT_LOS_OBJ",
"FEAT_OIL_DRUM",
"FEAT_TREE",
"FEAT_SKYSCRAPER",
};
///////////////////////////////////////////////////////////////////////////////
// splatter artifact gifts randomly about.
void addMultiPlayerRandomArtifacts(uint8_t quantity, FEATURE_TYPE type)
{
int i, count;
uint32_t x, y;
uint8_t player = ANYPLAYER;

debug(LOG_FEATURE, "Sending %u artifact(s) type: (%s)", quantity, feature_names[type]);
NETbeginEncode(NETgameQueue(selectedPlayer), GAME_ARTIFACTS);
NETuint8_t(&quantity);
NETenum(&type);

ASSERT(mapWidth > 20, "map not big enough");
ASSERT(mapHeight > 20, "map not big enough");

for (count = 0; count < quantity; count++)
{
uint32_t id = generateNewObjectId();

for (i = 0; i < 3; i++) // try three times
{
// Between 10 and mapwidth - 10
x = (rand()%(mapWidth - 20)) + 10;
y = (rand()%(mapHeight - 20)) + 10;

if (pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT))
{
break;
}
else if (i == 2)
{
debug(LOG_FEATURE, "Unable to find a free location after 3 tries; giving up.");
x = INVALID_XY;
}
}

NETuint32_t(&x);
NETuint32_t(&y);
NETuint32_t(&id);
NETuint8_t(&player);
}

NETend();
}

// ///////////////////////////////////////////////////////////////
bool addOilDrum(uint8_t count)
{
addMultiPlayerRandomArtifacts(count, FEAT_OIL_DRUM);
return true;
}

// ///////////////////////////////////////////////////////////////
// receive splattered artifacts
void recvMultiPlayerRandomArtifacts(NETQUEUE queue)
{
int count, i;
uint8_t quantity, player;
uint32_t tx,ty;
uint32_t ref;
FEATURE_TYPE type = FEAT_TREE; // Dummy initialisation.
FEATURE *pF;

NETbeginDecode(queue, GAME_ARTIFACTS);
NETuint8_t(&quantity);
NETenum(&type);
syncDebug("Adding %d oil drums.", count);

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++)
int featureIndex;
for (featureIndex = 0; featureIndex < numFeatureStats && asFeatureStats[featureIndex].subType != FEAT_OIL_DRUM; ++featureIndex) {}
if (featureIndex >= numFeatureStats)
{
MAPTILE *psTile;

NETuint32_t(&tx);
NETuint32_t(&ty);
NETuint32_t(&ref);
NETuint8_t(&player);
debug(LOG_WARNING, "No oil drum feature!");
return false; // Return value ignored.
}

if (tx == INVALID_XY)
{
continue;
}
else if (!tileOnMap(tx, ty))
for (unsigned n = 0; n < count; ++n)
{
uint32_t x, y;
for (int i = 0; i < 3; ++i) // try three times
{
debug(LOG_ERROR, "Bad tile coordinates (%u,%u)", tx, ty);
continue;
// Between 10 and mapwidth - 10
x = gameRand(mapWidth - 20) + 10;
y = gameRand(mapHeight - 20) + 10;

if (pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT))
{
break;
}
x = INVALID_XY;
}
psTile = mapTile(tx, ty);
if (!psTile || psTile->psObject != NULL)
if (x == INVALID_XY)
{
debug(LOG_ERROR, "Already something at (%u,%u)!", tx, ty);
syncDebug("Did not find location for oil drum.");
debug(LOG_FEATURE, "Unable to find a free location.");
continue;
}

pF = buildFeature((asFeatureStats + i), world_coord(tx), world_coord(ty), false);
FEATURE *pF = buildFeature(&asFeatureStats[featureIndex], world_coord(x), world_coord(y), false);
if (pF)
{
pF->id = ref;
pF->player = player;
pF->player = ANYPLAYER;
syncDebugFeature(pF, '+');
}
else
{
debug(LOG_ERROR, "Couldn't build feature %u for player %u ?", ref, player);
debug(LOG_ERROR, "Couldn't build oil drum?");
}
}
NETend();
return true;
}

// ///////////////////////////////////////////////////////////////
Expand Down
2 changes: 0 additions & 2 deletions src/multigifts.h
Expand Up @@ -35,8 +35,6 @@ extern bool sendGift (uint8_t type, uint8_t to);
extern bool recvGift (NETQUEUE queue);

extern void technologyGiveAway (const STRUCTURE* pS);
extern void recvMultiPlayerRandomArtifacts (NETQUEUE queue);
extern void addMultiPlayerRandomArtifacts (uint8_t quantity, FEATURE_TYPE type);
extern void recvMultiPlayerFeature (NETQUEUE queue);
extern void sendMultiPlayerFeature(FEATURE_TYPE type, uint32_t x, uint32_t y, uint32_t id);

Expand Down
6 changes: 4 additions & 2 deletions src/multiopt.cpp
Expand Up @@ -406,10 +406,12 @@ static bool gameInit(void)
game.skDiff[scavengerPlayer()] = DIFF_SLIDER_STOPS / 2;
}

if (NetPlay.isHost) // add oil drums
unsigned playerCount = 0;
for (int index = 0; index < game.maxPlayers; ++index)
{
addOilDrum(NetPlay.playercount * 2);
playerCount += NetPlay.players[index].ai >= 0 || NetPlay.players[index].allocated;
}
addOilDrum(playerCount * 2); // Calculating playerCount instead of using NetPlay.playercount, since the latter seems to be 0 for non-hosts.

playerResponding(); // say howdy!

Expand Down
3 changes: 0 additions & 3 deletions src/multiplay.cpp
Expand Up @@ -718,9 +718,6 @@ bool recvMessage(void)
startMultiplayerGame();
}
break;
case GAME_ARTIFACTS:
recvMultiPlayerRandomArtifacts(queue);
break;
case GAME_ALLIANCE:
recvAlliance(queue, true);
break;
Expand Down
1 change: 0 additions & 1 deletion src/multistruct.cpp
Expand Up @@ -163,7 +163,6 @@ bool recvBuildFinished(NETQUEUE queue)
// Inform others that a structure has been destroyed
bool SendDestroyStructure(STRUCTURE *s)
{
technologyGiveAway(s);
NETbeginEncode(NETgameQueue(selectedPlayer), GAME_DEBUG_REMOVE_STRUCTURE);

// Struct to destroy
Expand Down
2 changes: 2 additions & 0 deletions src/structure.cpp
Expand Up @@ -4642,6 +4642,8 @@ bool destroyStruct(STRUCTURE *psDel, unsigned impactTime)

CHECK_STRUCTURE(psDel);

technologyGiveAway(psDel); // Drop an artefact, if applicable.

/* Firstly, are we dealing with a wall section */
const bool bMinor = psDel->pStructureType->type == REF_WALL || psDel->pStructureType->type == REF_WALLCORNER;
const bool bDerrick = psDel->pStructureType->type == REF_RESOURCE_EXTRACTOR;
Expand Down

0 comments on commit 29966c5

Please sign in to comment.