Synchronise barrel and artefact placement.
Artefacts are now dropped by factories, again. Even if the structure was destroyed without using debug mode.master
parent
ea243df7c0
commit
29966c5da2
|
@ -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";
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
syncDebug("Adding %d oil drums.", count);
|
||||
|
||||
// ///////////////////////////////////////////////////////////////
|
||||
// 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);
|
||||
|
||||
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;
|
||||
debug(LOG_WARNING, "No oil drum feature!");
|
||||
return false; // Return value ignored.
|
||||
}
|
||||
|
||||
NETuint32_t(&tx);
|
||||
NETuint32_t(&ty);
|
||||
NETuint32_t(&ref);
|
||||
NETuint8_t(&player);
|
||||
|
||||
if (tx == INVALID_XY)
|
||||
for (unsigned n = 0; n < count; ++n)
|
||||
{
|
||||
uint32_t x, y;
|
||||
for (int i = 0; i < 3; ++i) // try three times
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
if (x == INVALID_XY)
|
||||
{
|
||||
syncDebug("Did not find location for oil drum.");
|
||||
debug(LOG_FEATURE, "Unable to find a free location.");
|
||||
continue;
|
||||
}
|
||||
else if (!tileOnMap(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, "Already something at (%u,%u)!", tx, ty);
|
||||
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;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
||||
|
|
|
@ -718,9 +718,6 @@ bool recvMessage(void)
|
|||
startMultiplayerGame();
|
||||
}
|
||||
break;
|
||||
case GAME_ARTIFACTS:
|
||||
recvMultiPlayerRandomArtifacts(queue);
|
||||
break;
|
||||
case GAME_ALLIANCE:
|
||||
recvAlliance(queue, true);
|
||||
break;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue