Exemple #1
0
// add a droid to a command group
void cmdDroidAddDroid(DROID *psCommander, DROID *psDroid)
{
	DROID_GROUP	*psGroup;

	if (psCommander->psGroup == NULL)
	{
		if (!grpCreate(&psGroup))
		{
			return;
		}
		grpJoin(psGroup, psCommander);
		psDroid->group = UBYTE_MAX;
	}

	if (grpNumMembers(psCommander->psGroup) < cmdDroidMaxGroup(psCommander))
	{
		grpJoin(psCommander->psGroup, psDroid);
		psDroid->group = UBYTE_MAX;

		// set the secondary states for the unit
		secondarySetState(psDroid, DSO_ATTACK_RANGE, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_ARANGE_MASK));
		secondarySetState(psDroid, DSO_REPAIR_LEVEL, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_REPLEV_MASK));
		secondarySetState(psDroid, DSO_ATTACK_LEVEL, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_ALEV_MASK));
		secondarySetState(psDroid, DSO_HALTTYPE, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_HALT_MASK));

		orderDroidObj(psDroid, DORDER_GUARD, (BASE_OBJECT *)psCommander, ModeQueue);
	}
}
Exemple #2
0
/** This function adds the droid to the command group commanded by psCommander.
 * It creates a group if it doesn't exist.
 * If the group is not full, it adds the droid to it and sets all the droid's states and orders to the group's.
 */
void cmdDroidAddDroid(DROID *psCommander, DROID *psDroid)
{
	DROID_GROUP	*psGroup;

	if (psCommander->psGroup == NULL)
	{
		psGroup = grpCreate();
		psGroup->add(psCommander);
		psDroid->group = UBYTE_MAX;
	}

	if (psCommander->psGroup->getNumMembers() < cmdDroidMaxGroup(psCommander))
	{
		psCommander->psGroup->add(psDroid);
		psDroid->group = UBYTE_MAX;

		// set the secondary states for the unit
		secondarySetState(psDroid, DSO_REPAIR_LEVEL, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_REPLEV_MASK), ModeImmediate);
		secondarySetState(psDroid, DSO_ATTACK_LEVEL, (SECONDARY_STATE)(psCommander->secondaryOrder & DSS_ALEV_MASK), ModeImmediate);

		orderDroidObj(psDroid, DORDER_GUARD, (BASE_OBJECT *)psCommander, ModeImmediate);
	}
	else
	{
		audio_PlayTrack( ID_SOUND_BUILD_FAIL );
		addConsoleMessage(_("Commander needs a higher level to command more units"), DEFAULT_JUSTIFY,  SYSTEM_MESSAGE);
	}
}
Exemple #3
0
DROID_GROUP *grpFind(int id)
{
	DROID_GROUP *psGroup = grpGlobalManager.value(id, NULL);
	if (!psGroup)
	{
		psGroup = grpCreate(id);
	}
	return psGroup;
}
Exemple #4
0
// create a group structure for a ST_GROUP variable
bool scrvNewGroup(INTERP_VAL *psVal)
{
	DROID_GROUP		*psGroup;

	psGroup = grpCreate();

	// increment the refcount so the group doesn't get automatically freed when empty
	psGroup->add(NULL);

	psVal->v.oval = psGroup;

	return true;
}
Exemple #5
0
DROID_GROUP *grpFind(int id)
{
	DROID_GROUP *psGroup = nullptr;
	std::map<int, DROID_GROUP *>::iterator it = grpGlobalManager.find(id);
	if (it != grpGlobalManager.end())
	{
		psGroup = it->second;
	}
	if (!psGroup)
	{
		psGroup = grpCreate(id);
	}
	return psGroup;
}
Exemple #6
0
// create a group structure for a ST_GROUP variable
BOOL scrvNewGroup(INTERP_VAL *psVal)
{
	DROID_GROUP		*psGroup;

	if (!grpCreate(&psGroup))
	{
		return false;
	}

	// increment the refcount so the group doesn't get automatically freed when empty
	grpJoin(psGroup, NULL);

	psVal->v.oval = psGroup;

	return true;
}
static QScriptValue js_newGroup(QScriptContext *, QScriptEngine *)
{
	DROID_GROUP *newGrp = grpCreate();
	return QScriptValue(newGrp->id);
}
Exemple #8
0
/// default value load routine
bool scrValDefLoad(INTERP_VAL *psVal, WzConfig &ini)
{
	DROID			*psCDroid;
	SDWORD			index, members;
	UDWORD			id;
	LEVEL_DATASET	*psLevel;
	DROID_GROUP		*psGroup = NULL;

	switch ((unsigned)psVal->type)  // Unsigned cast to suppress compiler warnings due to enum abuse.
	{
	case ST_INTMESSAGE:
		if (ini.contains("data"))
		{
			psVal->v.oval = (void*)getViewData(ini.value("data").toString().toAscii().constData());
		}
		else
		{
			psVal->v.oval = NULL;
		}
		break;
	case ST_BASEOBJECT:
	case ST_DROID:
	case ST_STRUCTURE:
	case ST_FEATURE:
		if (ini.contains("data"))
		{
			psVal->v.oval = (void*)getBaseObjFromId(ini.value("data").toInt());
		}
		else
		{
			psVal->v.oval = NULL;
		}
		break;
	case ST_BASESTATS:
	case ST_COMPONENT:
		break;
	case ST_STRUCTURESTAT:
		index = 0;
		if (ini.contains("data"))
		{
			index = getStructStatFromName(ini.value("data").toString().toAscii().constData());
			if (index == -1)
			{
				debug( LOG_FATAL, "Could not find stat");
				index = 0;
			}
		}
		psVal->v.ival = index;
		break;
	case ST_FEATURESTAT:
		index = 0;
		if (ini.contains("data"))
		{
			index = getFeatureStatFromName(ini.value("data").toString().toAscii().constData());
			if (index == -1)
			{
				debug( LOG_FATAL, "Could not find stat");
				index = 0;
			}
		}
		psVal->v.ival = index;
		break;
	case ST_BODY:
		index = getCompFromResName(COMP_BODY, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find body component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_PROPULSION:
		index = getCompFromResName(COMP_PROPULSION, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find propulsion component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_ECM:
		index = getCompFromResName(COMP_ECM, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find ECM component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_SENSOR:
		index = getCompFromResName(COMP_SENSOR, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find sensor component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_CONSTRUCT:
		index = getCompFromResName(COMP_CONSTRUCT, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find constructor component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_WEAPON:
		index = getCompFromResName(COMP_WEAPON, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find weapon");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_REPAIR:
		index = getCompFromResName(COMP_REPAIRUNIT, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find repair component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_BRAIN:
		index = getCompFromResName(COMP_BRAIN, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find repair brain");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_TEMPLATE:
		psVal->v.oval = NULL;
		if (ini.contains("data"))
		{
			// FIXME: Ugh. Find a better way to show full template info
			psVal->v.oval = (void*)IdToTemplate(ini.value("data").toInt(), ANYPLAYER);
			if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL)
			{
				debug(LOG_FATAL, "Could not find template %d", ini.value("data").toInt());
			}
		}
		break;
	case ST_TEXTSTRING:
		psVal->v.sval = NULL;
		if (ini.contains("data"))
		{
			psVal->v.sval = strdup(ini.value("data").toString().toAscii().constData());
		}
		break;
	case ST_LEVEL:
		psVal->v.sval = NULL;
		if (ini.contains("data"))
		{
			psLevel = levFindDataSet(ini.value("data").toString().toAscii().constData());
			if (psLevel == NULL)
			{
				debug(LOG_FATAL, "Could not find level dataset");
			}
			psVal->v.sval = psLevel->pName;
		}
		break;
	case ST_RESEARCH:
		psVal->v.oval = NULL;
		if (ini.contains("data"))
		{
			QString research = ini.value("data").toString();
			if (!research.isEmpty())
			{
				psVal->v.oval = (void*)getResearch(research.toUtf8().constData());
				ASSERT_OR_RETURN(false, psVal->v.oval, "Could not find research %s", research.toUtf8().constData());
			}
		}
		break;
	case ST_GROUP:
		if (psVal->v.oval == NULL)
		{
			DROID_GROUP *tmp = grpCreate();
			tmp->add(NULL);
			psVal->v.oval = tmp;
		}
		psGroup = (DROID_GROUP *)(psVal->v.oval);
		members = ini.value("members", 0).toInt();
		if (psGroup && members > 0)
		{
			QStringList droids = ini.value("data").toStringList();

			// load the retreat data
			psGroup->sRunData.sPos = ini.vector2i("runpos");
			psGroup->sRunData.forceLevel = ini.value("forceLevel").toInt();
			psGroup->sRunData.leadership = ini.value("leadership").toInt();
			psGroup->sRunData.healthLevel = ini.value("healthLevel").toInt();

			// load the droids
			while (members > 0)
			{
				id = droids.takeLast().toInt();
				psCDroid = (DROID *)getBaseObjFromId(id);
				if (!psCDroid)
				{
					debug(LOG_ERROR, "Could not find object id %d", id);
				}
				else
				{
					((DROID_GROUP*)(psVal->v.oval))->add(psCDroid);
				}
				members--;
			}
		}
		break;
	case ST_SOUND:
		// find audio id

		// don't use sound if it's disabled
		if (audio_Disabled())
		{
			psVal->v.ival = NO_SOUND;
			break;
		}

		index = audio_GetTrackID(ini.value("data").toString().toAscii().constData());
		if (index == SAMPLE_NOT_FOUND)
		{
			// find empty id and set track vals
			QString soundname = ini.value("data").toString();
			index = audio_SetTrackVals(soundname.toAscii().constData(), false, 100, 1800);
			if (!index)			// this is a NON fatal error.
			{
				// We can't find filename of the sound for some reason.
				debug(LOG_ERROR, "Sound ID not available %s not found", soundname.toAscii().constData());
				break;
			}
		}
		psVal->v.ival = index;
		break;
	case ST_STRUCTUREID:
	case ST_DROIDID:
	default:
		// just set the contents directly
		psVal->v.ival = ini.value("data").toInt();
		break;
	}

	return true;
}
Exemple #9
0
/// default value load routine
bool scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size)
{
	char			*pPos;
	DROID			*psCDroid;
	SDWORD			index, members, savedMembers;
	UDWORD			id;
	LEVEL_DATASET	*psLevel;
	DROID_GROUP		*psGroup = NULL;
	const char              *pName;
	bool			bObjectDefined;

	switch ((unsigned)psVal->type)  // Unsigned cast to suppress compiler warnings due to enum abuse.
	{
	case ST_INTMESSAGE:
		if ((size == 1) &&
			(*pBuffer == 0))
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)getViewData(pBuffer);
			if (psVal->v.oval == NULL)
			{
				return false;
			}
		}
		break;
	case ST_BASEOBJECT:
	case ST_DROID:
	case ST_STRUCTURE:
	case ST_FEATURE:
		id = *((UDWORD *)pBuffer);
		endian_udword(&id);

		if (id == UDWORD_MAX)
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)getBaseObjFromId(id);
			if (!psVal->v.oval)
			{
				debug(LOG_ERROR, "Could not find object id %d", id);
			}
		}
		break;
	case ST_BASESTATS:
	case ST_COMPONENT:
		break;
	case ST_STRUCTURESTAT:
		index = getStructStatFromName(pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find structure stat %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_FEATURESTAT:
		index = getFeatureStatFromName(pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find feature stat %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_BODY:
		index = getCompFromResName(COMP_BODY, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find body component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_PROPULSION:
		index = getCompFromResName(COMP_PROPULSION, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find propulsion component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_ECM:
		index = getCompFromResName(COMP_ECM, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find ECM component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_SENSOR:
		index = getCompFromResName(COMP_SENSOR, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find sensor component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_CONSTRUCT:
		index = getCompFromResName(COMP_CONSTRUCT, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find constructor component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_WEAPON:
		index = getCompFromResName(COMP_WEAPON, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find weapon %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_REPAIR:
		index = getCompFromResName(COMP_REPAIRUNIT, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find repair component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_BRAIN:
		index = getCompFromResName(COMP_BRAIN, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find repair brain %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_TEMPLATE:
		id = *((UDWORD *)pBuffer);
		endian_udword(&id);

		if (id == UDWORD_MAX)
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)IdToTemplate(id, ANYPLAYER);
			if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL)
			{
				debug( LOG_FATAL, "scrValDefLoad: couldn't find template id %d", id );
				abort();
			}
		}
		break;
	case ST_TEXTSTRING:
		{
			const char* str;
			char* idStr;
			uint16_t len;

			if (size < sizeof(len))
			{
				debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len)), (unsigned int)size);
				return false;
			}

			len = *((uint16_t*)pBuffer);
			endian_uword(&len);

			if (size < sizeof(len) + len)
			{
				debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len) + len), (unsigned int)size);
				return false;
			}

			if (len == 0)
			{
				psVal->v.sval = NULL;
				return true;
			}

			idStr = (char *)malloc(len);
			if (!idStr)
			{
				debug(LOG_ERROR, "Out of memory (tried to allocate %u bytes)", (unsigned int)len);
				// Don't abort() here, as this might be the result from a bad "len" field in the data
				return false;
			}

			memcpy(idStr, pBuffer + sizeof(len), len);

			if (idStr[len - 1] != '\0')
			{
				debug(LOG_WARNING, "Non-NUL terminated string encountered!");
			}
			idStr[len - 1] = '\0';

			str = strresGetString(psStringRes, idStr);
			if (!str)
			{
				debug(LOG_ERROR, "Couldn't find string with id \"%s\"", idStr);
				free(idStr);
				return false;
			}
			free(idStr);

			psVal->v.sval = strdup(str);
			if (!psVal->v.sval)
			{
				debug(LOG_FATAL, "Out of memory");
				abort();
				return false;
			}
		}
		break;
	case ST_LEVEL:
		if ((size == 1) &&
			(*pBuffer == 0))
		{
			psVal->v.sval = '\0';
		}
		else
		{
			psLevel = levFindDataSet(pBuffer);
			if (psLevel == NULL)
			{
				debug( LOG_FATAL, "scrValDefLoad: couldn't find level dataset %s", pBuffer );
				abort();
			}
			psVal->v.sval = psLevel->pName;
		}
		break;
	case ST_RESEARCH:
		if ((size == 1) &&
			(*pBuffer == 0))
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)getResearch(pBuffer);
			if (psVal->v.oval == NULL)
			{
				debug( LOG_FATAL, "scrValDefLoad: couldn't find research %s", pBuffer );
				abort();
			}
		}
		break;
	case ST_GROUP:
		bObjectDefined = true;

		if (psVal->v.oval == NULL)
		{
			DROID_GROUP *tmp = grpCreate();
			tmp->add(NULL);
			psVal->v.oval = tmp;
		}

		pPos = pBuffer;

		if (version < 2)
		{
			members = size / sizeof(UDWORD);
		}
		else if (version < 3)
		{
			members = (size - sizeof(SDWORD)*4) / sizeof(UDWORD);
		}
		else
		{
			members = (size - sizeof(SDWORD)*6) / sizeof(UDWORD);

			// get saved group member count/nullpointer flag
			endian_sdword((SDWORD*)pPos);
			bObjectDefined = ( *((SDWORD *)pPos) != UNALLOCATED_OBJECT );

			if(bObjectDefined)
			{
				savedMembers = *((SDWORD *)pPos);	// get number of saved group members

				ASSERT(savedMembers == members, "scrValDefLoad: calculated and saved group member count did not match." );
			}
			pPos += sizeof(SDWORD);
		}

		// make sure group was allocated when it was saved (relevant starting from version 3)
		if( version < 3 || bObjectDefined )
		{
			if (version >= 2)
			{
				// load the retreat data
				psGroup = (DROID_GROUP*)(psVal->v.oval);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.sPos.x = *((SDWORD *)pPos);
				pPos += sizeof(SDWORD);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.sPos.y = *((SDWORD *)pPos);
				pPos += sizeof(SDWORD);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.forceLevel = (UBYTE)(*((SDWORD *)pPos));
				pPos += sizeof(SDWORD);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.leadership = (UBYTE)(*((SDWORD *)pPos));
				pPos += sizeof(SDWORD);
			}
			if (version >= 3)
			{
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.healthLevel = (UBYTE)(*((SDWORD *)pPos));
				pPos += sizeof(SDWORD);
			}

			// load the droids
			while (members > 0)
			{
				endian_udword((UDWORD*)pPos);
				id = *((UDWORD *) pPos);
				psCDroid = (DROID *)getBaseObjFromId(id);
				if (!psCDroid)
				{
					debug(LOG_ERROR, "Could not find object id %d", id);
				}
				else
				{
					((DROID_GROUP*)(psVal->v.oval))->add(psCDroid);
				}

				pPos += sizeof(UDWORD);
				members -= 1;
			}
		}
		else		// a group var was unallocated during saving
		{
			pPos += sizeof(UWORD);
		}
		break;
	case ST_SOUND:
		// find audio id

		// don't use sound if it's disabled
		if (audio_Disabled())
		{
			psVal->v.ival = NO_SOUND;
			break;
		}

		pName = pBuffer;
		index = audio_GetTrackID( pName );
		if (index == SAMPLE_NOT_FOUND)
		{
			// find empty id and set track vals
			index = audio_SetTrackVals(pName, false, 100, 1800);
			if (!index)			//this is a NON fatal error.
			{
				// We can't find filename of the sound for some reason.
				debug(LOG_ERROR, "Sound ID not available %s not found", pName);
				break;
			}
		}
		psVal->v.ival = index;
		break;
	case ST_STRUCTUREID:
	case ST_DROIDID:
	default:
		// just set the contents directly
		psVal->v.ival = *((SDWORD *)pBuffer);
		endian_sdword(&psVal->v.ival);
		break;
	}

	return true;
}