Example #1
0
/**
 * Unknown function 0543.
 *
 * Stack: 1 - A distance.
 *
 * @param script The script engine to operate on.
 * @return The number of moving units.
 */
uint16 Script_Team_Unknown0543(ScriptEngine *script)
{
	Team *t;
	uint16 count = 0;
	uint16 distance;
	PoolFindStruct find;

	t = g_scriptCurrentTeam;
	distance = STACK_PEEK(1);

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

	while (true) {
		Unit *u;
		tile32 tile;
		uint16 distanceUnitDest;
		uint16 distanceUnitTeam;
		uint16 distanceTeamDest;

		u = Unit_Find(&find);
		if (u == NULL) break;
		if (t->index != u->team - 1) continue;

		tile = Tools_Index_GetTile(u->targetMove);
		distanceUnitTeam = Tile_GetDistanceRoundedUp(u->o.position, t->position);

		if (u->targetMove != 0) {
			distanceUnitDest = Tile_GetDistanceRoundedUp(u->o.position, tile);
			distanceTeamDest = Tile_GetDistanceRoundedUp(t->position, tile);
		} else {
			distanceUnitDest = 64;
			distanceTeamDest = 64;
		}

		if ((distanceUnitDest < distanceTeamDest && (distance + 2) < distanceUnitTeam) || (distanceUnitDest >= distanceTeamDest && distanceUnitTeam > distance)) {
			Unit_SetAction(u, ACTION_MOVE);

			tile = Tile_MoveByRandom(t->position, distance << 4, true);

			Unit_SetDestination(u, Tools_Index_Encode(Tile_PackTile(tile), IT_TILE));
			count++;
			continue;
		}

		Unit_SetAction(u, ACTION_GUARD);
	}

	return count;
}
Example #2
0
File: tile.c Project: l0b0/OpenDUNE
/**
 * Remove fog in the radius around the given tile.
 *
 * @param tile The tile to remove fog around.
 * @param radius The radius to remove fog around.
 */
void Tile_RemoveFogInRadius(tile32 tile, uint16 radius)
{
    uint16 packed;
    uint16 x, y;
    int16 i, j;

    packed = Tile_PackTile(tile);

    if (!Map_IsValidPosition(packed)) return;

    x = Tile_GetPackedX(packed);
    y = Tile_GetPackedY(packed);
    tile = Tile_MakeXY(x, y);

    for (i = -radius; i <= radius; i++) {
        for (j = -radius; j <= radius; j++) {
            tile32 t;

            if ((x + i) < 0 || (x + i) >= 64) continue;
            if ((y + j) < 0 || (y + j) >= 64) continue;

            packed = Tile_PackXY(x + i, y + j);
            t = Tile_MakeXY(x + i, y + j);

            if (Tile_GetDistanceRoundedUp(tile, t) > radius) continue;

            Map_UnveilTile(packed, g_playerHouseID);
        }
    }
}
Example #3
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;
}
Example #4
0
/**
 * Makes the current unit to go to the closest structure of the given type.
 *
 * Stack: 1 - The type of the structure.
 *
 * @param script The script engine to operate on.
 * @return The value 1 if and only if a structure has been found.
 */
uint16 Script_Unit_GoToClosestStructure(ScriptEngine *script)
{
	Unit *u;
	Structure *s = NULL;
	PoolFindStruct find;
	uint16 distanceMin =0;

	u = g_scriptCurrentUnit;

	find.houseID = Unit_GetHouseID(u);
	find.index   = 0xFFFF;
	find.type    = STACK_PEEK(1);

	while (true) {
		Structure *s2;
		uint16 distance;

		s2 = Structure_Find(&find);

		if (s2 == NULL) break;
		if (s2->state != STRUCTURE_STATE_IDLE) continue;
		if (s2->o.linkedID != 0xFF) continue;
		if (s2->o.script.variables[4] != 0) continue;

		distance = Tile_GetDistanceRoundedUp(s2->o.position, u->o.position);

		if (distance >= distanceMin && distanceMin != 0) continue;

		distanceMin = distance;
		s = s2;
	}

	if (s == NULL) return 0;

	Unit_SetAction(u, ACTION_MOVE);
	Unit_SetDestination(u, Tools_Index_Encode(s->o.index, IT_STRUCTURE));

	return 1;
}
Example #5
0
/**
 * Pickup a unit (either from structure or on the map). The unit that does the
 *  picking up returns the unit to his last position.
 *
 * Stack: *none*.
 *
 * @param script The script engine to operate on.
 * @return The value 0. Always.
 */
uint16 Script_Unit_Pickup(ScriptEngine *script)
{
	Unit *u;

	VARIABLE_NOT_USED(script);

	u = g_scriptCurrentUnit;

	if (u->o.linkedID != 0xFF) return 0;

	switch (Tools_Index_GetType(u->targetMove)) {
		case IT_STRUCTURE: {
			Structure *s;
			Unit *u2;

			s = Tools_Index_GetStructure(u->targetMove);

			/* There was nothing to pickup here */
			if (s->state != STRUCTURE_STATE_READY) {
				Object_Script_Variable4_Clear(&u->o);
				u->targetMove = 0;
				return 0;
			}

			u->o.flags.s.inTransport = true;

			Object_Script_Variable4_Clear(&u->o);
			u->targetMove = 0;

			u2 = Unit_Get_ByIndex(s->o.linkedID);

			/* Pickup the unit */
			u->o.linkedID = u2->o.index & 0xFF;
			s->o.linkedID = u2->o.linkedID;
			u2->o.linkedID = 0xFF;

			if (s->o.linkedID == 0xFF) Structure_SetState(s, STRUCTURE_STATE_IDLE);

			/* Check if the unit has a return-to position or try to find spice in case of a harvester */
			if (u2->targetLast.tile != 0) {
				u->targetMove = Tools_Index_Encode(Tile_PackTile(u2->targetLast), IT_TILE);
			} else if (u2->o.type == UNIT_HARVESTER && Unit_GetHouseID(u2) != g_playerHouseID) {
				u->targetMove = Tools_Index_Encode(Map_SearchSpice(Tile_PackTile(u->o.position), 20), IT_TILE);
			}

			Unit_UpdateMap(2, u);

			return 1;
		}

		case IT_UNIT: {
			Unit *u2;
			Structure *s = NULL;
			PoolFindStruct find;
			int16 minDistance = 0;

			u2 = Tools_Index_GetUnit(u->targetMove);

			if (!u2->o.flags.s.allocated) return 0;

			find.houseID = Unit_GetHouseID(u);
			find.index   = 0xFFFF;
			find.type    = 0xFFFF;

			/* Find closest refinery / repair station */
			while (true) {
				Structure *s2;
				int16 distance;

				s2 = Structure_Find(&find);
				if (s2 == NULL) break;

				distance = Tile_GetDistanceRoundedUp(s2->o.position, u->o.position);

				if (u2->o.type == UNIT_HARVESTER) {
					if (s2->o.type != STRUCTURE_REFINERY || s2->state != STRUCTURE_STATE_IDLE || s2->o.script.variables[4] != 0) continue;
					if (minDistance != 0 && distance >= minDistance) break;
					minDistance = distance;
					s = s2;
					break;
				}

				if (s2->o.type != STRUCTURE_REPAIR || s2->state != STRUCTURE_STATE_IDLE || s2->o.script.variables[4] != 0) continue;

				if (minDistance != 0 && distance >= minDistance) continue;
				minDistance = distance;
				s = s2;
			}

			if (s == NULL) return 0;

			/* Deselect the unit as it is about to be picked up */
			if (u2 == g_unitSelected) Unit_Select(NULL);

			/* Pickup the unit */
			u->o.linkedID = u2->o.index & 0xFF;
			u->o.flags.s.inTransport = true;

			Unit_UpdateMap(0, u2);

			Unit_Hide(u2);

			/* Set where we are going to */
			Object_Script_Variable4_Link(Tools_Index_Encode(u->o.index, IT_UNIT), Tools_Index_Encode(s->o.index, IT_STRUCTURE));
			u->targetMove = u->o.script.variables[4];

			Unit_UpdateMap(2, u);

			if (u2->o.type != UNIT_HARVESTER) return 0;

			/* Check if we want to return to this spice field later */
			if (Map_SearchSpice(Tile_PackTile(u2->o.position), 2) == 0) {
				u2->targetPreLast.tile = 0;
				u2->targetLast.tile    = 0;
			}

			return 0;
		}

		default: return 0;
	}
}