// Free around structure, return the first cell that is free.
int cAbstractStructure::iFreeAround()
{
	int iStartX = iCellGiveX(iCell);
	int iStartY = iCellGiveY(iCell);

	int iEndX = (iStartX + iWidth) + 1;
	int iEndY = (iStartY + iHeight) + 1;

	iStartX--;
	iStartY--;

	int iCx=0;
	int iCy=0;

	for (int x = iStartX; x < iEndX; x++)
		for (int y = iStartY; y < iEndY; y++)
		{
			iCx=x;
			iCy=y;

			FIX_BORDER_POS(iCx, iCy);

			int cll = iCellMake(iCx, iCy);

			if (map.occupied(cll) == false) {
				return cll;
			}
		}

	return -1; // fail
}
Ejemplo n.º 2
0
void cRocketTurret::think() {
	int iMyIndex = -1;

	for (int i = 0; i < MAX_STRUCTURES; i++) {
		if (structure[i] == this) {
			iMyIndex = i;
			break;
		}
	}

	// this should not happen, but just in case
	if (iMyIndex < 0) {
		return;
	}

	if (player[getOwner()].bEnoughPower() == false) {
		return; // do not fire a thing now
	}

	// turning & shooting
	if (iTargetID > -1) {
		if (unit[iTargetID].isValid()) {
			// first make sure we face okay!
			int iCellX = iCellGiveX(getCell());
			int iCellY = iCellGiveY(getCell());

			int iTargetX = iCellGiveX(unit[iTargetID].iCell);
			int iTargetY = iCellGiveY(unit[iTargetID].iCell);

			int d = fDegrees(iCellX, iCellY, iTargetX, iTargetY);
			int f = face_angle(d); // get the angle

			// set facing
			iShouldHeadFacing = f;

			if (iShouldHeadFacing == iHeadFacing || (unit[iTargetID].iType == ORNITHOPTER)) {

				TIMER_fire++;

				int iDistance = 9999;
				int iSlowDown = 250;

				if (getType() == RTURRET)
					iSlowDown = 450;

				if (unit[iTargetID].isValid()) {
					// calculate distance
					iDistance = ABS_length(iCellX, iCellY, iTargetX, iTargetY);

					if (iDistance > structures[getType()].sight)
						iTargetID = -1;
				} else
					iTargetID = -1;

				if (iTargetID < 0)
					return;

				if (TIMER_fire > iSlowDown) {
					int iTargetCell = unit[iTargetID].iCell;

					int iBullet = BULLET_TURRET;

					if (getType() == RTURRET && iDistance > 3)
						iBullet = ROCKET_RTURRET;
					else {
						int iShootX = (iDrawX() + 16) + (mapCamera->getX() * 32);
						int iShootY = (iDrawY() + 16) + (mapCamera->getY() * 32);
						int bmp_head = convert_angle(iHeadFacing);

						PARTICLE_CREATE(iShootX, iShootY, OBJECT_TANKSHOOT, -1, bmp_head);

					}

					int iBull = create_bullet(iBullet, getCell(), iTargetCell, -1, iMyIndex);

					if (unit[iTargetID].iType == ORNITHOPTER) {
						// it is a homing missile!
						bullet[iBull].iHoming = iTargetID;
						bullet[iBull].TIMER_homing = 200;

					}

					TIMER_fire = 0;

				}

			} else {
				TIMER_turn++;

				int iSlowDown = 200;

				if (TIMER_turn > iSlowDown) {
					TIMER_turn = 0;

					int d = 1;

					int toleft = (iHeadFacing + 8) - iShouldHeadFacing;
					if (toleft > 7)
						toleft -= 8;

					int toright = abs(toleft - 8);

					if (toright == toleft)
						d = -1 + (rnd(2));
					if (toleft > toright)
						d = 1;
					if (toright > toleft)
						d = -1;

					iHeadFacing += d;

					if (iHeadFacing < 0)
						iHeadFacing = 7;

					if (iHeadFacing > 7)
						iHeadFacing = 0;
				} // turning

			}

		} else
			iTargetID = -1;
	}

	// think like base class
	cAbstractStructure::think();

}
Ejemplo n.º 3
0
void cRocketTurret::think_guard() {

	// no power = no defense
	if (player[getOwner()].bEnoughPower() == false) {
		return;
	}

	TIMER_guard++;

	if (TIMER_guard > 10) {
		int iCellX = iCellGiveX(getCell());
		int iCellY = iCellGiveY(getCell());

		int iDistance = 9999; // closest distance

		int iAir = -1; // aircraft (prioritized!)
		int iWorm = -1; // worm lowest priority
		int iDanger = -1; // danger id (unit to attack)

		iTargetID = -1; // no target

		// scan area for units
		for (int i = 0; i < MAX_UNITS; i++) {
			// is valid
			if (unit[i].isValid()) {
				bool bAlly = player[getOwner()].iTeam == player[unit[i].iPlayer].iTeam;

				// not ours and its visible
				if (unit[i].iPlayer != getOwner() && mapUtils->isCellVisibleForPlayerId(getOwner(), unit[i].iCell) && bAlly == false) {

					int distance = ABS_length(iCellX, iCellY, iCellGiveX(unit[i].iCell), iCellGiveY(unit[i].iCell));

					// when worm or ornithopter is in range, they are not limited to the iDistance (closest
					// unit) range.
					if (distance <= structures[getType()].sight) {
						if (unit[i].iType == ORNITHOPTER) {
							iAir = i;
						} else if (unit[i].iType == SANDWORM) {
							iWorm = i;
						}
					}

					// when distance < closest range so far, this one is the most dangerous.
					if (distance <= structures[getType()].sight && distance < iDistance) {
						// ATTACK
						iDistance = distance;
						iDanger = i;
					}
				}
			}
		}

		// set target
		if (iAir > -1) {
			iTargetID = iAir;
		} else if (iDanger > -1) {
			iTargetID = iDanger;
		} else if (iWorm > -1) {
			iTargetID = iWorm; // else pick worm
		}

		TIMER_guard = 0 - rnd(20); // redo

	}
}
// Y drawing position
int cAbstractStructure::iDrawY()
{
  return (( (( iCellGiveY(iCell) * 32 ) - (mapCamera->getY()*32)))+42);
}
// this structure dies
void cAbstractStructure::die()
{
    // find myself and set to zero
    int iIndex=-1;
	for (int i=0; i < MAX_STRUCTURES; i++) {
        if (structure[i] == this)
        {
            iIndex=i;
            break;
        }
	}

    if (iIndex < 0) {
        logbook("cAbstractStructure(): Could not die");
        return;
    }

    // selected structure
    if (game.selected_structure == iIndex) {
        game.selected_structure = -1;
    }

	// remove from array
    structure[iIndex]=NULL;

    // Destroy structure, take stuff in effect for the player
    player[iPlayer].iStructures[getType()]--; // remove from player building indexes

    // fix up power usage
    player[iPlayer].use_power -= structures[getType()].power_drain;

    // less power
    player[iPlayer].has_power -= structures[getType()].power_give;

	if (getType() == SILO) {
		player[iPlayer].max_credits -= 1000;
	}

	if (getType() == REFINERY) {
		player[iPlayer].max_credits -= 1500;
	}

    // UnitID > -1, means the unit inside will die too
    if (iUnitID > -1) {
        unit[iUnitID].init(iUnitID); // die here... softly
    }

	int iCll=iCell;
	int iCX=iCellGiveX(iCll);
	int iCY=iCellGiveY(iCll);

    // create destroy particles
    for (int w=0; w < iWidth; w++)
    {
        for (int h=0; h < iHeight; h++)
        {
			iCll=iCellMake(iCX+w, iCY+h);

			map.cell[iCll].type = TERRAIN_ROCK;
			mapEditor.smoothAroundCell(iCll);

			PARTICLE_CREATE(iDrawX() + (mapCamera->getX()*32) + (w*32) + 16,
				iDrawY() + (mapCamera->getY()*32) + (h*32) + 16, OBJECT_BOOM01, -1, -1);


            for (int i=0; i < 3; i++)
            {
				map.smudge_increase(SMUDGE_ROCK, iCll);

                // create particle
                PARTICLE_CREATE(iDrawX() + (mapCamera->getX()*32) + (w*32) + 16 + (-8 + rnd(16)),
                                iDrawY() + (mapCamera->getY()*32) + (h*32) + 16 + (-8 + rnd(16)), EXPLOSION_STRUCTURE01 + rnd(2), -1, -1);

                // create smoke
                if (rnd(100) < 7)
                    PARTICLE_CREATE(iDrawX() + (mapCamera->getX()*32) + (w*32) + 16 + (-8 + rnd(16)),
                                    iDrawY() + (mapCamera->getY()*32) + (h*32) + 16 + (-8 + rnd(16)), OBJECT_SMOKE, -1, -1);

                // create fire
                if (rnd(100) < 5)
                    PARTICLE_CREATE(iDrawX() + (mapCamera->getX()*32) + (w*32) + 16 + (-8 + rnd(16)),
                                    iDrawY() + (mapCamera->getY()*32) + (h*32) + 16 + (-8 + rnd(16)), EXPLOSION_FIRE, -1, -1);

            }
        }
    }

    // play sound
    play_sound_id(SOUND_CRUMBLE01 + rnd(2), iCellOnScreen(iCell));

    // remove from the playground
    map.remove_id(iIndex, MAPID_STRUCTURES);

    // screen shaking
    game.TIMER_shake = (iWidth * iHeight) * 20;

    // eventually die
    cStructureFactory::getInstance()->deleteStructureInstance(this);
}