Ejemplo n.º 1
0
/**
**	Repairable unit on screen map position.
**
**	@param x	X position on screen map, pixel-based.
**	@param y	Y position on screen map, pixel-based.
**
**	@return		Returns repairable unit found on screen map position.
*/
global Unit* RepairableOnScreenMapPosition(int x,int y)
{
    Unit* table[UnitMax];
    int tx;
    int ty;
    int n;
    int i;

    tx = x / TileSizeX;
    ty = y / TileSizeY;

    n = UnitCacheSelect(tx-2,ty-2, tx+2, ty+2, table);
    for( i=0; i<n; ++i ) {
	// FIXME: could use more or less for repair? Repair of ships/catapults.
	// Only repairable if target is a building or tansporter and it's HP is
	// not at max
	if( (table[i]->Type->Building || table[i]->Type->Transporter)
		&& table[i]->HP < table[i]->Stats->HitPoints ) {
	    if (InsideUnitSprite(table[i], x, y)) {
		return table[i];
	    }
	}
    }
    return NoUnitP;
}
Ejemplo n.º 2
0
/**
**	Searches for unit whose sprite is drawn at (x,y) pixel map position.
**
**	@param x	X position on screen map, pixel-based.
**	@param y	Y position on screen map, pixel-based.
**
**	@return		Returns unit found at this pixel map coordinates
*/
global Unit* UnitOnScreenMapPosition(int x,int y)
{
    Unit* table[UnitMax];
    int tx;
    int ty;
    int n;
    int i;

    //	this code runs quite often (e.g. upon each motion notify) so this
    //	little optimization could be appropriate

    tx = x / TileSizeX;
    ty = y / TileSizeY;

    //	fast path, should work most of the time
    n = SelectUnitsOnTile(tx, ty, table);
    for( i=0; i<n; ++i ) {
	if( !table[i]->Type->Vanishes && InsideUnitSprite(table[i], x, y)) {
	    return table[i];
	}
    }

    //	if we got here we have to search for our unit in the neighborhood

    //	ships and flyers could be 2 fields away
    n = UnitCacheSelect(tx-2,ty-2, tx+2, ty+2, table);
    for( i=0; i<n; ++i ) {
	if( !table[i]->Type->Vanishes && InsideUnitSprite(table[i], x, y)) {
	    return table[i];
	}
    }

    return NoUnitP;
}
Ejemplo n.º 3
0
/**
**	Select units in rectangle range.
**
**	@param x1	Left column of selection rectangle
**	@param y1	Top row of selection rectangle
**	@param x2	Right column of selection rectangle
**	@param y2	Bottom row of selection rectangle
**	@param table	All units in the selection rectangle
**
**	@return		Returns the number of units found
*/
global int SelectUnits(int x1,int y1,int x2,int y2,Unit** table)
{
    if ( x1 == x2 && y1 == y2 ) {
	return UnitCacheOnTile(x1,y1,table);
    } else {
	return UnitCacheSelect(x1,y1,x2,y2,table);
    }
}
Ejemplo n.º 4
0
/**
**  Change unit owner
**
**  @param l  Lua state.
*/
static int CclChangeUnitsOwner(lua_State *l)
{
	CUnit *table[UnitMax];
	int n;
	int oldp;
	int newp;
	int x1;
	int y1;
	int x2;
	int y2;

	LuaCheckArgs(l, 4);
	if (!lua_istable(l, 1) || !lua_istable(l, 2)) {
		LuaError(l, "incorrect argument");
	}
	if (luaL_getn(l, 1) != 2) {
		LuaError(l, "incorrect argument");
	}
	lua_rawgeti(l, 1, 1);
	x1 = LuaToNumber(l, -1);
	lua_pop(l, 1);
	lua_rawgeti(l, 1, 1);
	y1 = LuaToNumber(l, -1);
	lua_pop(l, 1);

	if (luaL_getn(l, 2) != 2) {
		LuaError(l, "incorrect argument");
	}
	lua_rawgeti(l, 2, 1);
	x2 = LuaToNumber(l, -1);
	lua_pop(l, 1);
	lua_rawgeti(l, 2, 1);
	y2 = LuaToNumber(l, -1);
	lua_pop(l, 1);

	n = UnitCacheSelect(x1, y1, x2 + 1, y2 + 1, table);
	oldp = LuaToNumber(l, 3);
	newp = LuaToNumber(l, 4);
	while (n) {
		if (table[n - 1]->Player->Index == oldp) {
			table[n - 1]->ChangeOwner(&Players[newp]);
		}
		--n;
	}

	return 0;
}
Ejemplo n.º 5
0
/**
**	Choose target at pixel map coordinates.
**
**	@param source	Unit which wants to attack.
**	@param x	X position on the display map, pixel-based.
**	@param y	Y position on the display map, pixel-based.
**
**	@return		Returns ideal target
*/
global Unit* TargetOnScreenMapPosition(const Unit* source,int x,int y)
{
    Unit* table[UnitMax];
    Unit* unit;
    Unit* best;
    int tx;
    int ty;
    int n;
    int i;

    //	this code runs upon right button action only so it can affort being a
    //	little inefficient.

    tx = x / TileSizeX;
    ty = y / TileSizeY;

    //	 ships and flyers could be 2 fields away
    n = UnitCacheSelect(tx-2,ty-2, tx+2, ty+2, table);
    best=NoUnitP;
    for( i=0; i<n; ++i ) {
	unit=table[i];
	// unusable unit ?
	// if( UnitUnusable(unit) ) can't attack constructions
	// FIXME: did SelectUnitsOnTile already filter this?
	// Invisible and not Visible
	if( unit->Removed || unit->Invisible
		|| !(unit->Visible&(1<<source->Player->Player))
		|| unit->Orders[0].Action==UnitActionDie ) {
	    continue;
	}
	if ( !InsideUnitSprite(table[i], x, y)) {
	    continue;
	}
	if( !CanTarget(source->Type,unit->Type) ) {
	    continue;
	}
	//
	//	Choose the best target.
	//
	if( !best || best->Type->Priority < unit->Type->Priority ) {
	    best=unit;
	}
    }
    return best;
}
Ejemplo n.º 6
0
/**
**	Transporter unit on screen map position.
**
**	@param x	X position on screen map, pixel-based.
**	@param y	Y position on screen map, pixel-based.
**
**	@return		Returns transporter unit found on tile.
*/
global Unit* TransporterOnScreenMapPosition(int x,int y)
{
    Unit* table[UnitMax];
    int tx;
    int ty;
    int n;
    int i;

    tx = x / TileSizeX;
    ty = y / TileSizeY;

//  n=SelectUnitsOnTile(tx,ty,table);
    n = UnitCacheSelect(tx-2,ty-2, tx+2, ty+2, table);
    for( i=0; i<n; ++i ) {
	if( table[i]->Type->Transporter && InsideUnitSprite(table[i], x, y)) {
	    return table[i];
	}
    }
    return NoUnitP;
}
Ejemplo n.º 7
0
/**
**  Find all units to draw in viewport.
**
**  @param vp     Viewport to be drawn.
**  @param table  Table of units to return in sorted order 
**
*/
int FindAndSortUnits(const CViewport *vp, CUnit **table)
{
	int i;
	int n;

	//
	//  Select all units touching the viewpoint.
	//
	n = UnitCacheSelect(vp->MapX - 1, vp->MapY - 1, vp->MapX + vp->MapWidth + 1,
		vp->MapY + vp->MapHeight + 1, table);

	for (i = 0; i < n; i++) {
		if (!table[i]->IsVisibleInViewport(vp)) {
			table[i--] = table[--n];
		}
	}

	if (n) {
		qsort((void *)table, n, sizeof(CUnit *), DrawLevelCompare);
	}

	return n;
}