/////////////////////////////////////////////////////////////////////////////////
//  Returns a pointer to base object, given an id and optionally a player.
BASE_OBJECT *IdToPointer(UDWORD id,UDWORD player)
{
	DROID		*pD;
	STRUCTURE	*pS;
	FEATURE		*pF;
	// droids.

	pD = IdToDroid(id, player);
	if (pD)
	{
		return (BASE_OBJECT*)pD;
	}

	// structures
	pS = IdToStruct(id,player);
	if(pS)
	{
		return (BASE_OBJECT*)pS;
	}

	// features
	pF = IdToFeature(id,player);
	if(pF)
	{
		return (BASE_OBJECT*)pF;
	}

	return NULL;
}
Example #2
0
// recv lassat info on the receiving end.
BOOL recvLasSat(NETQUEUE queue)
{
	BASE_OBJECT	*psObj;
	UBYTE		player,targetplayer;
	STRUCTURE	*psStruct;
	uint32_t	id,targetid;

	// TODO Add some kind of checking, so that things don't get lasatted by bunkers.
	NETbeginDecode(queue, GAME_LASSAT);
		NETuint8_t(&player);
		NETuint32_t(&id);
		NETuint32_t(&targetid);
		NETuint8_t(&targetplayer);
	NETend();

	psStruct = IdToStruct (id, player);
	psObj	 = IdToPointer(targetid, targetplayer);

	if (psStruct && psObj)
	{
		// Give enemy no quarter, unleash the lasat
		proj_SendProjectile(&psStruct->asWeaps[0], NULL, player, psObj->pos, psObj, true, 0);
		psStruct->asWeaps[0].lastFired = gameTime;

		// Play 5 second countdown message
		audio_QueueTrackPos( ID_SOUND_LAS_SAT_COUNTDOWN, psObj->pos.x, psObj->pos.y, psObj->pos.z);
	}

	return true;
}
Example #3
0
BOOL recvDemolishFinished(NETQUEUE queue)
{
	STRUCTURE	*psStruct;
	DROID		*psDroid;
	uint32_t	structID, droidID;

	NETbeginDecode(queue, GAME_DEMOLISH);
		NETuint32_t(&structID);
		NETuint32_t(&droidID);
	NETend();

	psStruct = IdToStruct(structID, ANYPLAYER);
	if (!IdToDroid(droidID, ANYPLAYER, &psDroid))
	{
		debug(LOG_ERROR, "recvDemolishFinished: Packet with bad droid ID received. Discarding!");
		return false;
	}

	if (psStruct)
	{
		// Demolish it
		// Should never get here, if in synch.
		removeStruct(psStruct, true);
		if (psDroid && psDroid->psTarStats)
		{
			// Update droid if reqd
			psDroid->psTarStats = NULL;
		}
	}

	return true;
}
// recv lassat info on the receiving end.
BOOL recvLasSat()
{
    BASE_OBJECT	*psObj;
    UBYTE		player,targetplayer;
    STRUCTURE	*psStruct;
    uint32_t	id,targetid;

    NETbeginDecode(NET_LASSAT);
    NETuint8_t(&player);
    NETuint32_t(&id);
    NETuint32_t(&targetid);
    NETuint8_t(&targetplayer);
    NETend();

    psStruct = IdToStruct (id, player);
    psObj	 = IdToPointer(targetid, targetplayer);

    if (psStruct && psObj)
    {
        // Give enemy no quarter, unleash the lasat
        proj_SendProjectile(&psStruct->asWeaps[0], NULL, player, psObj->pos, psObj, true, 0);

        // Play 5 second countdown message
        audio_QueueTrackPos( ID_SOUND_LAS_SAT_COUNTDOWN, psObj->pos.x, psObj->pos.y, psObj->pos.z);
    }

    return true;
}
Example #5
0
// ////////////////////////////////////////////////////////////////////////////
// acknowledge the destruction of a structure, from another player.
bool recvDestroyStructure(NETQUEUE queue)
{
	uint32_t structID;
	STRUCTURE *psStruct;

	NETbeginDecode(queue, GAME_DEBUG_REMOVE_STRUCTURE);
	NETuint32_t(&structID);
	NETend();

	if (!getDebugMappingStatus() && bMultiPlayer)
	{
		debug(LOG_WARNING, "Failed to remove structure for player %u.", NetPlay.players[queue.index].position);
		return false;
	}

	// Struct to destory
	psStruct = IdToStruct(structID, ANYPLAYER);

	if (psStruct)
	{
		turnOffMultiMsg(true);
		// Remove the struct from remote players machine
		destroyStruct(psStruct, gameTime - deltaGameTime + 1);  // deltaGameTime is actually 0 here, since we're between updates. However, the value of gameTime - deltaGameTime + 1 will not change when we start the next tick.
		turnOffMultiMsg(false);
		// NOTE: I do not think this should be here!
		technologyGiveAway(psStruct);
	}

	return true;
}
Example #6
0
// recv lassat info on the receiving end.
BOOL recvLasSat(NETMSG *pMsg)
{
	BASE_OBJECT	*psObj;
	UBYTE		player,targetplayer;
	STRUCTURE	*psStruct;
	UDWORD		id,tid;

	NetGet(pMsg,0,player);
	NetGet(pMsg,1,id);
	NetGet(pMsg,5,tid);
	NetGet(pMsg,9,targetplayer);

	psStruct = IdToStruct (id ,player);
	psObj	 = IdToPointer(tid,targetplayer);

	if(psStruct && psObj)
	{
		proj_SendProjectile(&psStruct->asWeaps[0], NULL, player, psObj->x, 
            psObj->y, psObj->z, psObj, TRUE);
        //play 5 second countdown message
		audio_QueueTrackPos( ID_SOUND_LAS_SAT_COUNTDOWN, psObj->x, psObj->y, 
            psObj->z );
	}

	return TRUE;
}
Example #7
0
static QScriptValue js_structureIdle(QScriptContext *context, QScriptEngine *)
{
	QScriptValue structVal = context->argument(0);
	int id = structVal.property("id").toInt32();
	int player = structVal.property("player").toInt32();
	STRUCTURE *psStruct = IdToStruct(id, player);
	SCRIPT_ASSERT(context, psStruct, "No such structure id %d belonging to player %d", id, player);
	return QScriptValue(structureIdle(psStruct));
}
Example #8
0
// recv lassat info on the receiving end.
bool recvLasSat(NETQUEUE queue)
{
	BASE_OBJECT	*psObj;
	UBYTE		player, targetplayer;
	STRUCTURE	*psStruct;
	uint32_t	id, targetid;

	NETbeginDecode(queue, GAME_LASSAT);
	NETuint8_t(&player);
	NETuint32_t(&id);
	NETuint32_t(&targetid);
	NETuint8_t(&targetplayer);
	NETend();

	psStruct = IdToStruct(id, player);
	psObj	 = IdToPointer(targetid, targetplayer);
	if (psStruct && !canGiveOrdersFor(queue.index, psStruct->player))
	{
		syncDebug("Wrong player.");
		return false;
	}

	if (psStruct && psObj && psStruct->pStructureType->psWeapStat[0]->weaponSubClass == WSC_LAS_SAT)
	{
		// Lassats have just one weapon
		unsigned firePause = weaponFirePause(&asWeaponStats[psStruct->asWeaps[0].nStat], player);
		unsigned damLevel = PERCENT(psStruct->body, structureBody(psStruct));

		if (damLevel < HEAVY_DAMAGE_LEVEL)
		{
			firePause += firePause;
		}

		if (isHumanPlayer(player) && gameTime - psStruct->asWeaps[0].lastFired <= firePause)
		{
			/* Too soon to fire again */
			return true ^ false;  // Return value meaningless and ignored.
		}

		// Give enemy no quarter, unleash the lasat
		proj_SendProjectile(&psStruct->asWeaps[0], NULL, player, psObj->pos, psObj, true, 0);
		psStruct->asWeaps[0].lastFired = gameTime;
		psStruct->asWeaps[0].ammo = 1; // abducting this field for keeping track of triggers

		// Play 5 second countdown message
		audio_QueueTrackPos(ID_SOUND_LAS_SAT_COUNTDOWN, psObj->pos.x, psObj->pos.y, psObj->pos.z);
	}

	return true;
}
Example #9
0
// ////////////////////////////////////////////////////////////////////////////
// process droid order
static BASE_OBJECT *processDroidTarget(OBJECT_TYPE desttype, uint32_t destid)
{
	// Target is a location
	if (destid == 0 && desttype == 0)
	{
		return NULL;
	}
	// Target is an object
	else
	{
		BASE_OBJECT *psObj = NULL;
		DROID		*pD;

		switch (desttype)
		{
			case OBJ_DROID:
				if (IdToDroid(destid, ANYPLAYER, &pD))
				{
					psObj = (BASE_OBJECT*)pD;
				}
				break;
			case OBJ_STRUCTURE:
				psObj = (BASE_OBJECT*)IdToStruct(destid,ANYPLAYER);
				break;
			case OBJ_FEATURE:
				psObj = (BASE_OBJECT*)IdToFeature(destid,ANYPLAYER);
				break;

			// We should not get this!
			case OBJ_PROJECTILE:
				debug(LOG_ERROR, "ProcessDroidOrder: order specified destination as a bullet. what am i to do??");
				break;
			default:
				debug(LOG_ERROR, "ProcessDroidOrder: unknown object type");
				break;
		}

		// If we did not find anything, return
		if (!psObj)													// failed to find it;
		{
			syncDebug("Target missing");
			return TargetMissing;  // Can't return NULL, since then the order would still be attempted.
		}

		return psObj;
	}
}
Example #10
0
// NOTICE: the packet is already set-up for decoding via recvGift()
static void recvGiftStruct(uint8_t from, uint8_t to, uint32_t structID)
{
	STRUCTURE *psStruct = IdToStruct(structID, from);
	if (psStruct)
	{
		syncDebugStructure(psStruct, '<');
		giftSingleStructure(psStruct, to, false);
		syncDebugStructure(psStruct, '>');
		if (to == selectedPlayer)
		{
			CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives you a %s"), getPlayerName(from), objInfo(psStruct)));
		}
	}
	else
	{
		debug(LOG_ERROR, "Bad structure id %u, from %u to %u", structID, from, to);
	}
}
Example #11
0
/* Build a droid template in the specified factory */
static QScriptValue js_buildDroid(QScriptContext *context, QScriptEngine *)
{
	QScriptValue structVal = context->argument(1);
	int id = structVal.property("id").toInt32();
	int player = structVal.property("player").toInt32();
	QScriptValue templName = context->argument(0);
	DROID_TEMPLATE *psTemplate = getTemplateFromTranslatedNameNoPlayer(templName.toString().toUtf8().constData());
	STRUCTURE *psStruct = IdToStruct(id, player);

	SCRIPT_ASSERT(context, psStruct != NULL, "No factory object found for id %d, player %d", id, player);
	SCRIPT_ASSERT(context, psTemplate != NULL, "No template object found for %s sent to %s", templName.toString().toUtf8().constData(), objInfo(psStruct));
	SCRIPT_ASSERT(context, (psStruct->pStructureType->type == REF_FACTORY || psStruct->pStructureType->type == REF_CYBORG_FACTORY
		       || psStruct->pStructureType->type == REF_VTOL_FACTORY), "Structure %s is not a factory", objInfo(psStruct));
	SCRIPT_ASSERT(context, validTemplateForFactory(psTemplate, psStruct), "Invalid template - %s for factory - %s",
			 psTemplate->aName, psStruct->pStructureType->pName);

	return QScriptValue(structSetManufacture(psStruct, psTemplate, ModeQueue));
}
Example #12
0
// ////////////////////////////////////////////////////////////////////////////
// acknowledge the destruction of a structure, from another player.
BOOL recvDestroyStructure(NETMSG * m)
{
	UDWORD s;
	STRUCTURE *psStr;

	NetGet(m,0,s);								// struct to destory

	psStr = IdToStruct(s,ANYPLAYER);
	if (psStr)
	{
		turnOffMultiMsg(TRUE);
		destroyStruct(psStr);				// remove the struct from remote players machine.
		turnOffMultiMsg(FALSE);

		technologyGiveAway(psStr);

		return (TRUE);
	}
	return (TRUE);
}
Example #13
0
BOOL recvDemolishFinished(NETMSG *m)
{
	STRUCTURE	*psStruct;
	UDWORD		s,d;
	DROID		*psDroid;

	NetGet(m,0,s);					
	NetGet(m,4,d);							

	psStruct = IdToStruct(s,ANYPLAYER);
	IdToDroid(d,ANYPLAYER,&psDroid);

	if(psStruct)
	{
		removeStruct( psStruct, TRUE );				// demolish it.
		if(psDroid && psDroid->psTarStats)
		{
			psDroid->psTarStats = NULL;		// update droid if reqd.
		}
	}
	return TRUE;
}
Example #14
0
static QScriptValue js_label(QScriptContext *context, QScriptEngine *engine)
{
	QString label = context->argument(0).toString();
	QScriptValue ret = engine->newObject();
	if (labels.contains(label))
	{
		labeltype p = labels.value(label);
		if (p.type == AREA || p.type == POSITION)
		{
			ret.setProperty("x", map_coord(p.p1.x), QScriptValue::ReadOnly);
			ret.setProperty("y", map_coord(p.p1.y), QScriptValue::ReadOnly);
		}
		if (p.type == AREA)
		{
			ret.setProperty("x2", map_coord(p.p2.x), QScriptValue::ReadOnly);
			ret.setProperty("xy", map_coord(p.p2.y), QScriptValue::ReadOnly);
		}
		else if (p.type == OBJ_DROID)
		{
			DROID *psDroid = IdToDroid(p.id, p.player);
			if (psDroid) ret = convDroid(psDroid, engine);
		}
		else if (p.type == OBJ_STRUCTURE)
		{
			STRUCTURE *psStruct = IdToStruct(p.id, p.player);
			if (psStruct) ret = convStructure(psStruct, engine);
		}
		else if (p.type == OBJ_FEATURE)
		{
			FEATURE *psFeature = IdToFeature(p.id, p.player);
			if (psFeature) ret = convFeature(psFeature, engine);
		}
	}
	else debug(LOG_ERROR, "label %s not found!", label.toUtf8().constData());
	return ret;
}
Example #15
0
// ////////////////////////////////////////////////////////////////////////////
// acknowledge the destruction of a structure, from another player.
BOOL recvDestroyStructure(NETQUEUE queue)
{
	uint32_t structID;
	STRUCTURE *psStruct;

	NETbeginDecode(queue, GAME_STRUCTDEST);
		NETuint32_t(&structID);
	NETend();

	// Struct to destory
	psStruct = IdToStruct(structID,ANYPLAYER);

	if (psStruct)
	{
		turnOffMultiMsg(true);
		// Remove the struct from remote players machine
		destroyStruct(psStruct);
		turnOffMultiMsg(false);
		// NOTE: I do not think this should be here!
		technologyGiveAway(psStruct);
	}

	return true;
}
Example #16
0
// ////////////////////////////////////////////////////////////////////////////
// receive droid creation information from other players
bool recvDroid(NETQUEUE queue)
{
	DROID_TEMPLATE t, *pT = &t;
	DROID *psDroid;
	uint8_t player;
	uint32_t id;
	Position pos;
	bool haveInitialOrders;
	INITIAL_DROID_ORDERS initialOrders;

	NETbeginDecode(queue, GAME_DEBUG_ADD_DROID);
	{
		int32_t droidType;

		NETuint8_t(&player);
		NETuint32_t(&id);
		NETPosition(&pos);
		NETqstring(pT->name);
		pT->id = pT->name;
		NETint32_t(&droidType);
		NETuint8_t(&pT->asParts[COMP_BODY]);
		NETuint8_t(&pT->asParts[COMP_BRAIN]);
		NETuint8_t(&pT->asParts[COMP_PROPULSION]);
		NETuint8_t(&pT->asParts[COMP_REPAIRUNIT]);
		NETuint8_t(&pT->asParts[COMP_ECM]);
		NETuint8_t(&pT->asParts[COMP_SENSOR]);
		NETuint8_t(&pT->asParts[COMP_CONSTRUCT]);
		NETint8_t(&pT->numWeaps);
		for (int i = 0; i < pT->numWeaps; i++)
		{
			NETuint8_t(&pT->asWeaps[i]);
		}
		NETbool(&haveInitialOrders);
		if (haveInitialOrders)
		{
			NETuint32_t(&initialOrders.secondaryOrder);
			NETint32_t(&initialOrders.moveToX);
			NETint32_t(&initialOrders.moveToY);
			NETuint32_t(&initialOrders.factoryId);  // For making scripts happy.
		}
		pT->droidType = (DROID_TYPE)droidType;
	}
	NETend();

	if (!getDebugMappingStatus() && bMultiPlayer)
	{
		debug(LOG_WARNING, "Failed to add droid for player %u.", NetPlay.players[queue.index].position);
		return false;
	}

	ASSERT_OR_RETURN(false, player < MAX_PLAYERS, "invalid player %u", player);

	debug(LOG_LIFE, "<=== getting Droid from %u id of %u ", player, id);
	if ((pos.x == 0 && pos.y == 0) || pos.x > world_coord(mapWidth) || pos.y > world_coord(mapHeight))
	{
		debug(LOG_ERROR, "Received bad droid position (%d, %d) from %d about p%d (%s)", (int)pos.x, (int)pos.y,
		      queue.index, player, isHumanPlayer(player) ? "Human" : "AI");
		return false;
	}

	// Create that droid on this machine.
	psDroid = reallyBuildDroid(pT, pos, player, false);

	// If we were able to build the droid set it up
	if (psDroid)
	{
		psDroid->id = id;
		addDroid(psDroid, apsDroidLists);

		if (haveInitialOrders)
		{
			psDroid->secondaryOrder = initialOrders.secondaryOrder;
			psDroid->secondaryOrderPending = psDroid->secondaryOrder;
			orderDroidLoc(psDroid, DORDER_MOVE, initialOrders.moveToX, initialOrders.moveToY, ModeImmediate);
			cbNewDroid(IdToStruct(initialOrders.factoryId, ANYPLAYER), psDroid);
		}

		syncDebugDroid(psDroid, '+');
	}
	else
	{
		debug(LOG_ERROR, "Packet from %d cannot create droid for p%d (%s)!", queue.index,
		      player, isHumanPlayer(player) ? "Human" : "AI");
#ifdef DEBUG
		CONPRINTF(ConsoleString, (ConsoleString, "MULTIPLAYER: Couldn't build a remote droid, relying on checking to resync"));
#endif
		return false;
	}

	return true;
}
Example #17
0
void recvStructureInfo(NETQUEUE queue)
{
	uint8_t         player = 0;
	uint32_t        structId = 0;
	uint32_t        templateId = 0;
	uint8_t         structureInfo;
	STRUCTURE      *psStruct;
	DROID_TEMPLATE *psTempl = NULL;

	NETbeginDecode(queue, GAME_STRUCTUREINFO);
	NETuint8_t(&player);
	NETuint32_t(&structId);
	NETuint8_t(&structureInfo);
	if (structureInfo == STRUCTUREINFO_MANUFACTURE)
	{
		NETuint32_t(&templateId);
		if (templateId != 0)
		{
			// For autogames, where we want the AI to take us over, our templates are not setup... so let's use any AI's templates.
			if (!NetPlay.players[player].autoGame)
			{
				psTempl = IdToTemplate(templateId, player);
			}
			else
			{
				psTempl = IdToTemplate(templateId, ANYPLAYER);
			}
			if (psTempl == NULL)
			{
				debug(LOG_SYNC, "Synch error, don't have tempate id %u, so can't change production of factory %u!", templateId, structId);
			}
		}
	}
	NETend();

	psStruct = IdToStruct(structId, player);

	syncDebug("player%d,structId%u%c,structureInfo%u,templateId%u%c", player, structId, psStruct == NULL ? '^' : '*', structureInfo, templateId, psTempl == NULL ? '^' : '*');

	if (psStruct == NULL)
	{
		debug(LOG_SYNC, "Couldn't find structure %u to change production.", structId);
		return;
	}
	if (!canGiveOrdersFor(queue.index, psStruct->player))
	{
		syncDebug("Wrong player.");
		return;
	}

	CHECK_STRUCTURE(psStruct);

	if (StructIsFactory(psStruct))
	{
		popStatusPending(psStruct->pFunctionality->factory);
	}
	else if (psStruct->pStructureType->type == REF_RESEARCH)
	{
		popStatusPending(psStruct->pFunctionality->researchFacility);
	}

	syncDebugStructure(psStruct, '<');

	switch (structureInfo)
	{
	case STRUCTUREINFO_MANUFACTURE:       structSetManufacture(psStruct, psTempl, ModeImmediate); break;
	case STRUCTUREINFO_CANCELPRODUCTION:  cancelProduction(psStruct, ModeImmediate, false);       break;
	case STRUCTUREINFO_HOLDPRODUCTION:    holdProduction(psStruct, ModeImmediate);                break;
	case STRUCTUREINFO_RELEASEPRODUCTION: releaseProduction(psStruct, ModeImmediate);             break;
	case STRUCTUREINFO_HOLDRESEARCH:      holdResearch(psStruct, ModeImmediate);                  break;
	case STRUCTUREINFO_RELEASERESEARCH:   releaseResearch(psStruct, ModeImmediate);               break;
	default:
		debug(LOG_ERROR, "Invalid structureInfo %d", structureInfo);
	}

	syncDebugStructure(psStruct, '>');

	CHECK_STRUCTURE(psStruct);
}
Example #18
0
// ////////////////////////////////////////////////////////////////////////////
// receive droid creation information from other players
BOOL recvDroid(NETQUEUE queue)
{
	DROID_TEMPLATE* pT;
	DROID* psDroid;
	uint8_t player;
	uint32_t id;
	Position pos;
	uint32_t templateID;
	BOOL haveInitialOrders;
	INITIAL_DROID_ORDERS initialOrders;

	NETbeginDecode(queue, GAME_DROID);
	{
		NETuint8_t(&player);
		NETuint32_t(&id);
		NETPosition(&pos);
		NETuint32_t(&templateID);
		NETbool(&haveInitialOrders);
		if (haveInitialOrders)
		{
			NETuint32_t(&initialOrders.secondaryOrder);
			NETint32_t(&initialOrders.moveToX);
			NETint32_t(&initialOrders.moveToY);
			NETuint32_t(&initialOrders.factoryId);  // For making scripts happy.
		}

		pT = IdToTemplate(templateID, player);
	}
	NETend();

	ASSERT( player < MAX_PLAYERS, "invalid player %u", player);

	debug(LOG_LIFE, "<=== getting Droid from %u id of %u ",player,id);
	if ((pos.x == 0 && pos.y == 0) || pos.x > world_coord(mapWidth) || pos.y > world_coord(mapHeight))
	{
		debug(LOG_ERROR, "Received bad droid position (%d, %d) from %d about p%d (%s)", (int)pos.x, (int)pos.y,
				queue.index, player, isHumanPlayer(player) ? "Human" : "AI");
		return false;
	}

	// If we can not find the template ask for the entire droid instead
	if (!pT)
	{
		debug(LOG_ERROR, "Packet from %d refers to non-existent template %u, [%s : p%d]",
				queue.index, templateID, isHumanPlayer(player) ? "Human" : "AI", player);
		return false;
	}

	// Create that droid on this machine.
	psDroid = reallyBuildDroid(pT, pos.x, pos.y, player, false);

	// If we were able to build the droid set it up
	if (psDroid)
	{
		psDroid->id = id;
		addDroid(psDroid, apsDroidLists);

		if (haveInitialOrders)
		{
			psDroid->secondaryOrder = initialOrders.secondaryOrder;
			orderDroidLoc(psDroid, DORDER_MOVE, initialOrders.moveToX, initialOrders.moveToY, ModeImmediate);
			cbNewDroid(IdToStruct(initialOrders.factoryId, ANYPLAYER), psDroid);
		}
	}
	else
	{
		debug(LOG_ERROR, "Packet from %d cannot create droid for p%d (%s)!", queue.index,
			player, isHumanPlayer(player) ? "Human" : "AI");
#ifdef DEBUG
		CONPRINTF(ConsoleString, (ConsoleString, "MULTIPLAYER: Couldn't build a remote droid, relying on checking to resync"));
#endif
		return false;
	}

	return true;
}
Example #19
0
// ////////////////////////////////////////////////////////////////////////////
BOOL recvBuildFinished(NETQUEUE queue)
{
	uint32_t	structId;
	STRUCTURE	*psStruct;
	Position        pos;
	uint32_t	type,typeindex;
	uint8_t		player;

	NETbeginDecode(queue, GAME_BUILDFINISHED);
		NETuint32_t(&structId);	// get the struct id.
		NETuint32_t(&type); 	// Kind of building.
		NETPosition(&pos);      // pos
		NETuint8_t(&player);
	NETend();

	ASSERT( player < MAX_PLAYERS, "invalid player %u", player);

	psStruct = IdToStruct(structId,ANYPLAYER);

	if (psStruct)
	{												// make it complete.
		psStruct->currentBuildPts = psStruct->pStructureType->buildPoints+1;

		if (psStruct->status != SS_BUILT)
		{
			debug(LOG_SYNC, "Synch error, structure %u was not complete, and should have been.", structId);
			psStruct->status = SS_BUILT;
			buildingComplete(psStruct);
		}
		debug(LOG_SYNC, "Created normal building %u for player %u", psStruct->id, player);
		return true;
	}

	// The building wasn't started, so we'll have to just plonk it down in the map.

	// Find the structures stats
	for (typeindex=0;						// Find structure target
		(typeindex<numStructureStats ) && (asStructureStats[typeindex].ref != type);
		typeindex++);

	// Check for similar buildings, to avoid overlaps
	if (TileHasStructure(mapTile(map_coord(pos.x), map_coord(pos.y))))
	{
		// Get the current structure
		psStruct = getTileStructure(map_coord(pos.x), map_coord(pos.y));
		if (asStructureStats[typeindex].type == psStruct->pStructureType->type)
		{
			// Correct type, correct location, just rename the id's to sync it.. (urgh)
			psStruct->id = structId;
			psStruct->status = SS_BUILT;
			buildingComplete(psStruct);
			debug(LOG_SYNC, "Created modified building %u for player %u", psStruct->id, player);
#if defined (DEBUG)
			NETlogEntry("structure id modified", SYNC_FLAG, player);
#endif
			return true;
		}
	}
	// Build the structure
	psStruct = buildStructure(&(asStructureStats[typeindex]), pos.x, pos.y, player, true);

	if (psStruct)
	{
		psStruct->id		= structId;
		psStruct->status	= SS_BUILT;
		buildingComplete(psStruct);
		debug(LOG_SYNC, "Huge synch error, forced to create building %u for player %u", psStruct->id, player);
#if defined (DEBUG)
		NETlogEntry("had to plonk down a building", SYNC_FLAG, player);
#endif
	}
	else
	{
		debug(LOG_SYNC, "Gigantic synch error, unable to create building for player %u", player);
		NETlogEntry("had to plonk down a building, BUT FAILED!", SYNC_FLAG, player);
	}

	return false;
}
Example #20
0
void recvStructureInfo(NETQUEUE queue)
{
	uint8_t         player = 0;
	uint32_t        structId = 0;
	uint32_t        templateId = 0;
	uint8_t         structureInfo;
	STRUCTURE *     psStruct;
	DROID_TEMPLATE *psTempl = NULL;

	NETbeginDecode(queue, GAME_STRUCTUREINFO);
		NETuint8_t(&player);
		NETuint32_t(&structId);
		NETuint8_t(&structureInfo);
		if (structureInfo == STRUCTUREINFO_MANUFACTURE)
		{
			NETuint32_t(&templateId);
			if (templateId != 0)
			{
				psTempl = IdToTemplate(templateId, player);
				if (psTempl == NULL)
				{
					debug(LOG_SYNC, "Synch error, don't have tempate id %u, so can't change production of factory %u!", templateId, structId);
				}
			}
		}
	NETend();

	psStruct = IdToStruct(structId, player);

	syncDebug("player%d,structId%u%c,structureInfo%u,templateId%u%c", player, structId, psStruct == NULL? '^' : '*', structureInfo, templateId, psTempl == NULL? '^' : '*');

	if (psStruct == NULL)
	{
		debug(LOG_SYNC, "Couldn't find structure %u to change production.", structId);
		return;
	}

	CHECK_STRUCTURE(psStruct);

	if (StructIsFactory(psStruct))
	{
		if (psStruct->pFunctionality->factory.pendingCount == 0)
		{
			++psStruct->pFunctionality->factory.pendingCount;
		}
		if (--psStruct->pFunctionality->factory.pendingCount == 0)
		{
			// Subject is now synchronised, remove pending.
			psStruct->pFunctionality->factory.psSubjectPending = NULL;
			psStruct->pFunctionality->factory.statusPending = FACTORY_NOTHING_PENDING;
		}
	}

	syncDebugStructure(psStruct, '<');

	switch (structureInfo)
	{
		case STRUCTUREINFO_MANUFACTURE:       structSetManufacture(psStruct, psTempl, ModeImmediate); break;
		case STRUCTUREINFO_CANCELPRODUCTION:  cancelProduction(psStruct, ModeImmediate);              break;
		case STRUCTUREINFO_HOLDPRODUCTION:    holdProduction(psStruct, ModeImmediate);                break;
		case STRUCTUREINFO_RELEASEPRODUCTION: releaseProduction(psStruct, ModeImmediate);             break;
		case STRUCTUREINFO_HOLDRESEARCH:      holdResearch(psStruct, ModeImmediate);                  break;
		case STRUCTUREINFO_RELEASERESEARCH:   releaseResearch(psStruct, ModeImmediate);               break;
		default:
			debug(LOG_ERROR, "Invalid structureInfo %d", structureInfo);
	}

	syncDebugStructure(psStruct, '>');

	CHECK_STRUCTURE(psStruct);
}
// ////////////////////////////////////////////////////////////////////////////
BOOL recvBuildFinished()
{
    uint32_t	structId;
    STRUCTURE	*psStruct;
    int32_t		x,y,z;
    uint32_t	type,typeindex;
    uint8_t		player;
    uint32_t	power;

    NETbeginDecode(NET_BUILDFINISHED);
    NETuint32_t(&power);	// get the player's power level
    NETuint32_t(&structId);	// get the struct id.
    NETuint32_t(&type); 	// Kind of building.
    NETint32_t(&x);    	// x pos
    NETint32_t(&y);    	// y pos
    NETint32_t(&z);    	// z pos
    NETuint8_t(&player);
    NETend();

    ASSERT( player < MAX_PLAYERS, "invalid player %u", player);

    psStruct = IdToStruct(structId,ANYPLAYER);
    setPower( (uint32_t)player, power);		// we sync the power level as well

    if (psStruct)
    {   // make it complete.
        psStruct->currentBuildPts = psStruct->pStructureType->buildPoints+1;

        if (psStruct->status != SS_BUILT)
        {
            psStruct->status = SS_BUILT;
            buildingComplete(psStruct);
        }
        debug(LOG_SYNC, "Created normal building %u for player %u", psStruct->id, player);
        return true;
    }

    // The building wasn't started, so we'll have to just plonk it down in the map.

    // Find the structures stats
    for (typeindex=0;						// Find structure target
            (typeindex<numStructureStats ) && (asStructureStats[typeindex].ref != type);
            typeindex++);

    // Check for similar buildings, to avoid overlaps
    if (TileHasStructure(mapTile(map_coord(x), map_coord(y))))
    {
        // Get the current structure
        psStruct = getTileStructure(map_coord(x), map_coord(y));
        if (asStructureStats[typeindex].type == psStruct->pStructureType->type)
        {
            // Correct type, correct location, just rename the id's to sync it.. (urgh)
            psStruct->id = structId;
            psStruct->status = SS_BUILT;
            buildingComplete(psStruct);
            debug(LOG_SYNC, "Created modified building %u for player %u", psStruct->id, player);
#if defined (DEBUG)
            NETlogEntry("structure id modified", SYNC_FLAG, player);
#endif
            return true;
        }
    }
    // Build the structure
    psStruct = buildStructure(&(asStructureStats[typeindex]), x, y, player, true);

    if (psStruct)
    {
        psStruct->id		= structId;
        psStruct->status	= SS_BUILT;
        buildingComplete(psStruct);
        debug(LOG_SYNC, "Forced to create building %u for player %u", psStruct->id, player);
#if defined (DEBUG)
        NETlogEntry("had to plonk down a building" ,SYNC_FLAG, player);
#endif
    }
    else
    {
        debug(LOG_SYNC, "Unable to create building for player %u", player);
        NETlogEntry("had to plonk down a building, BUT FAILED!" , SYNC_FLAG, player);
    }

    return false;
}
Example #22
0
// receive checking info about a structure and update local world state
BOOL recvStructureCheck(NETQUEUE queue)
{
	uint32_t                synchTime;
	STRUCTURE		*pS;
	BOOL			hasCapacity = true;
	int                     j;
	Rotation                rot;
	uint8_t			player, ourCapacity;
	uint32_t		body;
	uint32_t                ref;
	uint32_t                type;

	NETbeginDecode(queue, GAME_CHECK_STRUCT);
		NETuint8_t(&player);
		NETuint32_t(&synchTime);
		NETuint32_t(&ref);
		NETuint32_t(&body);
		NETuint32_t(&type);
		NETRotation(&rot);

		if (player >= MAX_PLAYERS)
		{
			debug(LOG_ERROR, "Bad GAME_CHECK_STRUCT received!");
			NETend();
			return false;
		}

		if (structureCheckLastSent != synchTime)
		{
			debug(LOG_ERROR, "We got a structure synch at the wrong time.");
		}

		if (ref != structureCheckLastId[player])
		{
			debug(LOG_ERROR, "We got a structure %u synch, but had chosen %u instead.", ref, structureCheckLastId[player]);
			NETend();
			return false;
		}

		// If the structure exists our job is easy
		pS = IdToStruct(ref, player);
		if (pS)
		{
			syncDebugStructure(pS, '<');
			if (pS->pStructureType->type != structureCheckLastType[player] || type != structureCheckLastType[player])
			{
				debug(LOG_ERROR, "GAME_CHECK_STRUCT received, wrong structure type!");
				NETend();
				return false;
			}

			// Check its finished
			if (pS->status != SS_BUILT)
			{
				pS->rot = rot;
				pS->id = ref;
				pS->status = SS_BUILT;
				buildingComplete(pS);
			}

			// If the structure has a capacity
			switch (pS->pStructureType->type)
			{
				case REF_RESEARCH:
					ourCapacity = ((RESEARCH_FACILITY *) pS->pFunctionality)->capacity;
					j = researchModuleStat;
					break;
				case REF_FACTORY:
				case REF_VTOL_FACTORY:
					ourCapacity = ((FACTORY *) pS->pFunctionality)->capacity;
					j = factoryModuleStat;
					break;
				case REF_POWER_GEN:
					ourCapacity = ((POWER_GEN *) pS->pFunctionality)->capacity;
					j = powerModuleStat;
					break;
				default:
					hasCapacity = false;
					break;
			}

			// So long as the struct has a capacity fetch it from the packet
			if (hasCapacity)
			{
				uint8_t actualCapacity = 0;

				NETuint8_t(&actualCapacity);

				// If our capacity is different upgrade ourself
				for (; ourCapacity < actualCapacity; ourCapacity++)
				{
					debug(LOG_SYNC, "Structure %u out of synch, adding module.", ref);
					buildStructure(&asStructureStats[j], pS->pos.x, pS->pos.y, pS->player, false);

					// Check it is finished
					if (pS && pS->status != SS_BUILT)
					{
						pS->id = ref;
						pS->status = SS_BUILT;
						buildingComplete(pS);
					}
				}
			}

#define MERGEDELTA(x, y, ya, z) if (y != ya) { debug(LOG_SYNC, "Structure %u out of synch, changing "#x" from %"z" to %"z".", ref, x, x + y - ya); x += y - ya; }
			MERGEDELTA(pS->body, body, structureCheckLastBody[player], "u");
			MERGEDELTA(pS->rot.direction, rot.direction, structureCheckLastDirection[player].direction, "d");
			MERGEDELTA(pS->rot.pitch, rot.pitch, structureCheckLastDirection[player].pitch, "d");
			MERGEDELTA(pS->rot.roll, rot.roll, structureCheckLastDirection[player].roll, "d");
#undef MERGEDELTA

			syncDebugStructure(pS, '>');
		}
		else
		{
			debug(LOG_ERROR, "We got a structure %u synch, but can't find the structure.", ref);
		}

	NETend();
	return true;
}
Example #23
0
bool recvResearchStatus(NETQUEUE queue)
{
	STRUCTURE			*psBuilding;
	PLAYER_RESEARCH		*pPlayerRes;
	RESEARCH_FACILITY	*psResFacilty;
	RESEARCH			*pResearch;
	uint8_t				player;
	bool				bStart;
	uint32_t			index, structRef;

	NETbeginDecode(queue, GAME_RESEARCHSTATUS);
		NETuint8_t(&player);
		NETbool(&bStart);
		NETuint32_t(&structRef);
		NETuint32_t(&index);
	NETend();

	syncDebug("player%d, bStart%d, structRef%u, index%u", player, bStart, structRef, index);

	if (player >= MAX_PLAYERS || index >= asResearch.size())
	{
		debug(LOG_ERROR, "Bad GAME_RESEARCHSTATUS received, player is %d, index is %u", (int)player, index);
		return false;
	}
	if (!canGiveOrdersFor(queue.index, player))
	{
		debug(LOG_WARNING, "Droid order for wrong player.");
		syncDebug("Wrong player.");
		return false;
	}

	int prevResearchState = 0;
	if (aiCheckAlliances(selectedPlayer, player))
	{
		prevResearchState = intGetResearchState();
	}

	pPlayerRes = &asPlayerResList[player][index];

	// psBuilding may be null if finishing
	if (bStart)							// Starting research
	{
		psBuilding = IdToStruct(structRef, player);

		// Set that facility to research
		if (psBuilding && psBuilding->pFunctionality)
		{
			psResFacilty = (RESEARCH_FACILITY *) psBuilding->pFunctionality;

			popStatusPending(*psResFacilty);  // Research is no longer pending, as it's actually starting now.

			if (psResFacilty->psSubject)
			{
				cancelResearch(psBuilding, ModeImmediate);
			}

			// Set the subject up
			pResearch				= &asResearch[index];
			psResFacilty->psSubject = pResearch;

			// Start the research
			MakeResearchStarted(pPlayerRes);
			psResFacilty->timeStartHold		= 0;
		}

	}
	// Finished/cancelled research
	else
	{
		// If they completed the research, we're done
		if (IsResearchCompleted(pPlayerRes))
		{
			return true;
		}

		// If they did not say what facility it was, look it up orselves
		if (!structRef)
		{
			// Go through the structs to find the one doing this topic
			for (psBuilding = apsStructLists[player]; psBuilding; psBuilding = psBuilding->psNext)
			{
				if (psBuilding->pStructureType->type == REF_RESEARCH
				 && psBuilding->status == SS_BUILT
				 && ((RESEARCH_FACILITY *) psBuilding->pFunctionality)->psSubject
				 && ((RESEARCH_FACILITY *) psBuilding->pFunctionality)->psSubject->ref - REF_RESEARCH_START == index)
				{
					break;
				}
			}
		}
		else
		{
			psBuilding = IdToStruct(structRef, player);
		}

		// Stop the facility doing any research
		if (psBuilding)
		{
			cancelResearch(psBuilding, ModeImmediate);
			popStatusPending(*(RESEARCH_FACILITY *)psBuilding->pFunctionality);  // Research cancellation is no longer pending, as it's actually cancelling now.
		}
	}

	if (aiCheckAlliances(selectedPlayer, player))
	{
		intAlliedResearchChanged();
		intNotifyResearchButton(prevResearchState);
	}

	return true;
}
Example #24
0
// ////////////////////////////////////////////////////////////////////////////
BOOL recvBuildFinished(NETMSG *m)
{
	UDWORD strId;//,i;
	STRUCTURE *psStr;
	UWORD	x,y,z;
	UDWORD	type,typeindex;
	UBYTE	player;

	NetGet(m,0,strId);									// get the struct id.
	psStr = IdToStruct(strId,ANYPLAYER);
	
	if(psStr)
	{												// make it complete.
		psStr->currentBuildPts = psStr->pStructureType->buildPoints+1;
	
		if(psStr->status != SS_BUILT)
		{
			psStr->status = SS_BUILT;
			buildingComplete(psStr);
		}
		NETlogEntry("building finished ok." ,0,0);
		return TRUE;
	}
	
	// the building wasn't started, so we'll have to just plonk it down in the map.
	NetGet(m,4,type);									// kind of building.			
	NetGet(m,8,x);										// x pos
	NetGet(m,10,y);										// y pos
	NetGet(m,12,z);										// z pos

	player = m->body[14];								// player

	for(typeindex=0;														// find structure target
		(typeindex<numStructureStats ) && (asStructureStats[typeindex].ref != type);
		typeindex++);  
	psStr = 0;

	// check for similar buildings, to avoid overlaps
	if( TILE_HAS_STRUCTURE(mapTile(x>>TILE_SHIFT,y>>TILE_SHIFT))   )		
	{
		// get structure;
		psStr = getTileStructure(x>>TILE_SHIFT, y>>TILE_SHIFT);
		if(asStructureStats[typeindex].type == psStr->pStructureType->type)
		{
			// correct type, correct location, just rename the id's to sync it.. (urgh) 
			psStr->id = strId;	
			psStr->status = SS_BUILT;
			buildingComplete(psStr);
			NETlogEntry("structure id modified" ,0,player);
			return TRUE;
		}
	}

	psStr = buildStructure(&(asStructureStats[typeindex]),					// build the structure.
					x,y,
					player,TRUE);
	if (psStr)
	{
		psStr->id		= strId; 
		psStr->status	= SS_BUILT;
		buildingComplete(psStr);
	
		DBCONPRINTF(ConsoleString,(ConsoleString,"MultiPlayer: Struct not found on recvbuildcomplete :%d",strId ));
		NETlogEntry("had to plonk down a building" ,0,player);
	}
	else
	{
		DBCONPRINTF(ConsoleString,(ConsoleString,"MultiPlayer: Struct not found on recvbuildcomplete BUILDIT FAILED TOO!:%d",strId ));
		NETlogEntry("had to plonk down a building, BUT FAILED OH S**T." ,0,player);
	}
	return FALSE;
}