Ejemplo n.º 1
0
/**
 * Play a voice. Volume is based on distance to position.
 * @param voiceID Which voice to play.
 * @param position Which position to play it on.
 */
void Voice_PlayAtTile(int16 voiceID, tile32 position)
{
	uint16 index;
	uint16 volume;

	if (voiceID < 0 || voiceID >= 120) return;
	if (!g_gameConfig.sounds) return;

	volume = 255;
	if (position.x != 0 || position.y != 0) {
		volume = Tile_GetDistancePacked(g_minimapPosition, Tile_PackTile(position));
		if (volume > 64) volume = 64;

		volume = 255 - (volume * 255 / 80);
	}

	index = g_table_voiceMapping[voiceID];

	if (g_enableVoices != 0 && index != 0xFFFF && g_voiceData[index] != NULL && g_table_voices[index].priority >= s_currentVoicePriority) {
		s_currentVoicePriority = g_table_voices[index].priority;
		memmove(g_readBuffer, g_voiceData[index], g_voiceDataSize[index]);

		Driver_Voice_Play(g_readBuffer, s_currentVoicePriority);
	} else {
		Driver_Sound_Play(voiceID, volume);
	}
}
Ejemplo n.º 2
0
/**
 * Play a voice. Volume is based on distance to position.
 * @param voiceID Which voice to play.
 * @param position Which position to play it on.
 */
void Voice_PlayAtTile(int16 voiceID, tile32 position)
{
    uint16 index;
    uint16 volume;

    if (voiceID < 0 || voiceID >= 120) return;
    if (!g_gameConfig.sounds) return;

    volume = 255;
    if (position.tile != 0) {
        volume = Tile_GetDistancePacked(g_minimapPosition, Tile_PackTile(position));
        if (volume > 64) volume = 64;

        volume = 255 - (volume * 255 / 80);
    }

    index = g_table_voiceMapping[voiceID];

    if (g_enableVoices != 0 && index != 0xFFFF && g_variable_3E54[index] != NULL && g_table_voices[index].variable_04 >= s_variable_4060) {
        s_variable_4060 = g_table_voices[index].variable_04;
        memmove(g_readBuffer, g_variable_3E54[index], g_variable_3E54_size[index]);

        Driver_Voice_Play(g_readBuffer, s_variable_4060);
    } else {
        Driver_Sound_Play(voiceID, volume);
    }
}
Ejemplo n.º 3
0
Archivo: tile.c Proyecto: l0b0/OpenDUNE
/**
 * Get a tile in the direction of a destination, randomized a bit.
 *
 * @param packed_from The origin.
 * @param packed_to The destination.
 * @return A packed tile.
 */
uint16 Tile_GetTileInDirectionOf(uint16 packed_from, uint16 packed_to)
{
    int16 distance;
    uint8 direction;
    uint8 i;

    if (packed_from == 0 || packed_to == 0) return 0;

    distance = Tile_GetDistancePacked(packed_from, packed_to);
    direction = Tile_GetDirectionPacked(packed_to, packed_from);

    if (distance <= 10) return 0;

    for (i = 0; i < 4; i++) {
        int16 dir;
        tile32 position;
        uint16 packed;

        dir = 29 + (Tools_Random_256() & 0x3F);

        if ((Tools_Random_256() & 1) != 0) dir = -dir;

        position = Tile_UnpackTile(packed_to);
        position = Tile_MoveByDirection(position, direction + dir, min(distance, 20) << 8);
        packed = Tile_PackTile(position);

        if (Map_IsValidPosition(packed)) return packed;
    }

    return 0;
}
Ejemplo n.º 4
0
/**
 * Calculate the route to a tile.
 *
 * Stack: 1 - An encoded tile to calculate the route to.
 *
 * @param script The script engine to operate on.
 * @return 0 if we arrived on location, 1 otherwise.
 */
uint16 Script_Unit_CalculateRoute(ScriptEngine *script)
{
	Unit *u;
	uint16 encoded;
	uint16 packedSrc;
	uint16 packedDst;

	u = g_scriptCurrentUnit;
	encoded = STACK_PEEK(1);

	if (u->currentDestination.tile != 0 || !Tools_Index_IsValid(encoded)) return 1;

	packedSrc = Tile_PackTile(u->o.position);
	packedDst = Tools_Index_GetPackedTile(encoded);

	if (packedDst == packedSrc) {
		u->route[0] = 0xFF;
		u->targetMove = 0;
		return 0;
	}

	if (u->route[0] == 0xFF) {
		Pathfinder_Data res;
		uint8 buffer[42];

		res = Script_Unit_Pathfinder(packedSrc, packedDst, buffer, 40);

		memcpy(u->route, res.buffer, min(res.routeSize, 14));

		if (u->route[0] == 0xFF) {
			u->targetMove = 0;
			if (u->o.type == UNIT_SANDWORM) {
				script->delay = 720;
			}
		}
	} else {
		uint16 distance;

		distance = Tile_GetDistancePacked(packedDst, packedSrc);
		if (distance < 14) u->route[distance] = 0xFF;
	}

	if (u->route[0] == 0xFF) return 1;

	if (u->orientation[0].current != (int8)(u->route[0] * 32)) {
		Unit_SetOrientation(u, (int8)(u->route[0] * 32), false, 0);
		return 1;
	}

	if (!Unit_StartMovement(u)) {
		u->route[0] = 0xFF;
		return 0;
	}

	memmove(&u->route[0], &u->route[1], 13);
	u->route[13] = 0xFF;
	return 1;
}
Ejemplo n.º 5
0
/**
 * Gets the average distance between current team members, and set the
 *  position of the team to the average position.
 *
 * Stack: *none*.
 *
 * @param script The script engine to operate on.
 * @return The average distance.
 */
uint16 Script_Team_GetAverageDistance(ScriptEngine *script)
{
	uint16 averageX = 0;
	uint16 averageY = 0;
	uint16 count = 0;
	uint16 distance = 0;
	Team *t;
	PoolFindStruct find;

	VARIABLE_NOT_USED(script);

	t = g_scriptCurrentTeam;

	find.houseID = t->houseID;
	find.index   = 0xFFFF;
	find.type    = 0xFFFF;

	while (true) {
		Unit *u;

		u = Unit_Find(&find);
		if (u == NULL) break;
		if (t->index != u->team - 1) continue;
		count++;
		averageX += (u->o.position.x >> 8) & 0x3f;
		averageY += (u->o.position.y >> 8) & 0x3f;
	}

	if (count == 0) return 0;
	averageX /= count;
	averageY /= count;

	t->position = Tile_MakeXY(averageX, averageY);

	find.houseID = t->houseID;
	find.index   = 0xFFFF;
	find.type    = 0xFFFF;

	while (true) {
		Unit *u;

		u = Unit_Find(&find);
		if (u == NULL) break;
		if (t->index != u->team - 1) continue;
		distance += Tile_GetDistanceRoundedUp(u->o.position, t->position);
	}

	distance /= count;

	if (t->target == 0 || t->targetTile == 0) return distance;

	if (Tile_GetDistancePacked(Tile_PackXY(averageX, averageY), Tools_Index_GetPackedTile(t->target)) <= 10) t->targetTile = 2;

	return distance;
}
Ejemplo n.º 6
0
static void Skirmish_FindClosestStructures(HouseType houseID, uint16 packed, uint16* dist_ally, uint16* dist_enemy)
{
	PoolFindStruct find;
	Structure* s;

	find.houseID = HOUSE_INVALID;
	find.type = 0xFFFF;
	find.index = STRUCTURE_INDEX_INVALID;

	*dist_ally = 0xFFFF;
	*dist_enemy = 0xFFFF;
	while ((s = Structure_Find(&find)) != NULL)
	{
		if (s->o.type == STRUCTURE_SLAB_1x1 || s->o.type == STRUCTURE_SLAB_2x2 || s->o.type == STRUCTURE_WALL)
			continue;

		const uint16 dist = Tile_GetDistancePacked(Tile_PackTile(s->o.position), packed);
		if (House_AreAllied(houseID, s->o.houseID))
			*dist_ally = min(dist, *dist_ally);
		else
			*dist_enemy = min(dist, *dist_enemy);
	}
}
Ejemplo n.º 7
0
static bool Skirmish_GenUnitsHuman(HouseType houseID, SkirmishData* sd)
{
	const int delta[7] = {
		0, -4, 4,
		-MAP_SIZE_MAX * 3 - 2, -MAP_SIZE_MAX * 3 + 2,
		MAP_SIZE_MAX * 3 - 2, MAP_SIZE_MAX * 3 + 2,
	};

	const MapInfo* mi = &g_mapInfos[0];

	/* Pick a tile that is not too close to the edge, and not too
	 * close to the enemy.
	 */
	int r;
	for (int attempts = 0; attempts < 100; attempts++)
	{
		const int island = Skirmish_PickRandomIsland(sd);
		if (island < 0)
			return false;

		r = Tools_RandomLCG_Range(sd->island[island].start, sd->island[island].end - 1);
		if (!(mi->minX + 4 <= sd->buildable[r].x && sd->buildable[r].x < mi->minX + mi->sizeX - 4))
			continue;

		if (!(mi->minY + 3 <= sd->buildable[r].y && sd->buildable[r].y < mi->minY + mi->sizeY - 3))
			continue;

		PoolFindStruct find;
		find.houseID = HOUSE_INVALID;
		find.type = 0xFFFF;
		find.index = STRUCTURE_INDEX_INVALID;

		Structure* s = Structure_Find(&find);
		for (; s != NULL; s = Structure_Find(&find))
		{
			if (s->o.type == STRUCTURE_SLAB_1x1 || s->o.type == STRUCTURE_SLAB_2x2 || s->o.type == STRUCTURE_WALL)
				continue;

			if (House_AreAllied(g_playerHouseID, s->o.houseID))
				continue;

			const uint16 dist = Tile_GetDistancePacked(Tile_PackTile(s->o.position), sd->buildable[r].packed);
			if (dist < 24)
				break;
		}

		if (s == NULL)
		{
			break;
		}
		else
		{
			r = -1;
		}
	}

	if (r < 0)
		return false;

	bool mcvPlaced = false;

	for (int i = 0; i < 7; i++)
	{
		const uint16 packed = sd->buildable[r].packed + delta[i];
		const tile32 position = Tile_UnpackTile(packed);

		UnitType type;
		
		if (!mcvPlaced)
			type = UNIT_MCV;
		else if (i >= 0 && i < 3)
			type = UNIT_SIEGE_TANK;
		else if (i >= 3 && i < 4)
			type = House_GetIXVehicle(houseID);
		else if (i >= 4 && i < 5)
			type = House_GetMediumVehicle(houseID);
		else if (i >= 5 && i < 6)
			type = UNIT_QUAD;
		else if (i >= 6)
			type = House_GetInfantrySquad(houseID);
		
		const LandscapeType lst = (const LandscapeType)Map_GetLandscapeType(packed);

		/* If there's a structure or a bloom here, tough luck. */
		if (lst == LST_STRUCTURE || lst == LST_BLOOM_FIELD)
			continue;

		/* If there's a mountain here, build infantry instead. */
		if (lst == LST_ENTIRELY_MOUNTAIN || lst == LST_PARTIAL_MOUNTAIN)
			type = House_GetInfantrySquad(houseID);

		Scenario_Create_Unit(houseID, type, 256, position, 127, (UnitActionType)g_table_unitInfo[type].o.actionsPlayer[3]);

		if (type == UNIT_MCV)
			mcvPlaced = true;
	}

	return true;
}