Skip to content

Commit

Permalink
Deja'vu strikes -- sorry about the noise, wrong commit was reverted.
Browse files Browse the repository at this point in the history
Apply "Shots sometimes pass through the ground" patch by Corvuscorax, with formatting fixes.

refs ticket:2151
  • Loading branch information
buginator committed Oct 16, 2010
1 parent 3a37a47 commit 80b27a9
Show file tree
Hide file tree
Showing 15 changed files with 614 additions and 76 deletions.
30 changes: 15 additions & 15 deletions src/action.c
Expand Up @@ -676,29 +676,29 @@ BOOL actionVisibleTarget(DROID *psDroid, BASE_OBJECT *psTarget, int weapon_slot)
ASSERT_OR_RETURN( false, compIndex < numWeaponStats, "Invalid range referenced for numWeaponStats, %d > %d", compIndex, numWeaponStats);
psStats = asWeaponStats + compIndex;

if (proj_Direct(psStats))
if (lineOfFire((BASE_OBJECT*)psDroid, psTarget, weapon_slot, true))
{
if (visibleObject((BASE_OBJECT*)psDroid, psTarget, true))
if (proj_Direct(psStats))
{
return true;
}
}
else
{
// indirect can only attack things they can see unless attacking
// through a sensor droid - see DORDER_FIRESUPPORT
if (orderState(psDroid, DORDER_FIRESUPPORT))
else
{
if (psTarget->visible[psDroid->player])
// indirect can only attack things they can see unless attacking
// through a sensor droid - see DORDER_FIRESUPPORT
if (orderState(psDroid, DORDER_FIRESUPPORT))
{
return true;
if (psTarget->visible[psDroid->player])
{
return true;
}
}
}
else
{
if (visibleObject((BASE_OBJECT*)psDroid, psTarget, false))
else
{
return true;
if (visibleObject((BASE_OBJECT*)psDroid, psTarget, false))
{
return true;
}
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/ai.c
Expand Up @@ -66,9 +66,7 @@ static BOOL aiStructHasRange(STRUCTURE *psStruct, BASE_OBJECT *psTarget, int wea
longRange = proj_GetLongRange(psWStats);
if (xdiff*xdiff + ydiff*ydiff < longRange*longRange)
{
// in range
return true;

return (lineOfFire((BASE_OBJECT*)psStruct, psTarget, weapon_slot, true));
}

return false;
Expand Down
75 changes: 53 additions & 22 deletions src/combat.c
Expand Up @@ -93,7 +93,7 @@ BOOL combShutdown(void)

// Watermelon:real projectile
/* Fire a weapon at something */
void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, int weapon_slot)
BOOL combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, int weapon_slot)
{
WEAPON_STATS *psStats;
UDWORD xDiff, yDiff, distSquared;
Expand All @@ -106,6 +106,7 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
int minOffset = 5;
SDWORD dist;
int compIndex;
int min_angle;

CHECK_OBJECT(psAttacker);
CHECK_OBJECT(psTarget);
Expand All @@ -117,27 +118,27 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
if (((DROID *)psAttacker)->sMove.iAttackRuns[weapon_slot] >= getNumAttackRuns(((DROID *)psAttacker), weapon_slot))
{
objTrace(psAttacker->id, "VTOL slot %d is empty", weapon_slot);
return;
return false;
}
}

/* Get the stats for the weapon */
compIndex = psWeap->nStat;
ASSERT_OR_RETURN( , compIndex < numWeaponStats, "Invalid range referenced for numWeaponStats, %d > %d", compIndex, numWeaponStats);
ASSERT_OR_RETURN(false , compIndex < numWeaponStats, "Invalid range referenced for numWeaponStats, %d > %d", compIndex, numWeaponStats);
psStats = asWeaponStats + compIndex;

// check valid weapon/prop combination
if (!validTarget(psAttacker, psTarget, weapon_slot))
{
return;
return false;
}

/*see if reload-able weapon and out of ammo*/
if (psStats->reloadTime && !psWeap->ammo)
{
if (gameTime - psWeap->lastFired < weaponReloadTime(psStats, psAttacker->player))
{
return;
return false;
}
//reset the ammo level
psWeap->ammo = psStats->numRounds;
Expand Down Expand Up @@ -169,57 +170,57 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
if (gameTime - psWeap->lastFired <= firePause)
{
/* Too soon to fire again */
return;
return false;
}

// add a random delay to the fire
fireChance = gameTime - (psWeap->lastFired + firePause);
if (rand() % RANDOM_PAUSE > fireChance)
{
return;
return false;
}

if (!psTarget->visible[psAttacker->player])
{
// Can't see it - can't hit it
objTrace(psAttacker->id, "combFire(%u[%s]->%u): Object has no indirect sight of target", psAttacker->id, psStats->pName, psTarget->id);
return;
return false;
}

/* Check we can see the target */
if (psAttacker->type == OBJ_DROID && !isVtolDroid((DROID *)psAttacker)
&& (proj_Direct(psStats) || actionInsideMinRange(psDroid, psTarget, psStats)))
{
if(!lineOfFire(psAttacker, psTarget, true))
if(!lineOfFire(psAttacker, psTarget, weapon_slot, true))
{
// Can't see the target - can't hit it with direct fire
objTrace(psAttacker->id, "combFire(%u[%s]->%u): Droid has no direct line of sight to target",
psAttacker->id, ((DROID *)psAttacker)->aName, psTarget->id);
return;
return false;
}
}
else if ((psAttacker->type == OBJ_STRUCTURE) &&
(((STRUCTURE *)psAttacker)->pStructureType->height == 1) &&
proj_Direct(psStats))
{
// a bunker can't shoot through walls
if (!lineOfFire(psAttacker, psTarget, true))
if (!lineOfFire(psAttacker, psTarget, weapon_slot, true))
{
// Can't see the target - can't hit it with direct fire
objTrace(psAttacker->id, "combFire(%u[%s]->%u): Structure has no direct line of sight to target",
psAttacker->id, ((STRUCTURE *)psAttacker)->pStructureType->pName, psTarget->id);
return;
return false;
}
}
else if ( proj_Direct(psStats) )
{
// VTOL or tall building
if (!lineOfFire(psAttacker, psTarget, false))
if (!lineOfFire(psAttacker, psTarget, weapon_slot, false))
{
// Can't see the target - can't hit it with direct fire
objTrace(psAttacker->id, "combFire(%u[%s]->%u): Tall object has no direct line of sight to target",
psAttacker->id, psStats->pName, psTarget->id);
return;
return false;
}
}

Expand All @@ -230,7 +231,7 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
dirDiff = labs(targetDir - (SDWORD)psAttacker->direction);
if (dirDiff > FIXED_TURRET_DIR)
{
return;
return false;
}
}

Expand All @@ -245,6 +246,30 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
dist = sqrtf(distSquared);
longRange = proj_GetLongRange(psStats);

// calculate shooting angle
min_angle = 0;
// only calculate for indirect shots
if (!proj_Direct(psStats) && dist>0)
{
min_angle = arcOfFire(psAttacker,psTarget,weapon_slot,true);

// prevent extremely steep shots
if (min_angle > PROJ_ULTIMATE_PITCH)
{
min_angle = PROJ_ULTIMATE_PITCH;
}

// adjust maximum range of unit if forced to shoot very steep
if (min_angle > PROJ_MAX_PITCH)
{
//do not allow increase of max range though
if (trigSin(2*min_angle) < trigSin(2*PROJ_MAX_PITCH))
{
longRange = longRange * trigSin(2*min_angle) / trigSin(2*PROJ_MAX_PITCH);
}
}
}

if (distSquared <= (psStats->shortRange * psStats->shortRange) &&
distSquared >= (psStats->minRange * psStats->minRange))
{
Expand All @@ -259,12 +284,18 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
{
// get weapon chance to hit in the long range
baseHitChance = weaponLongHit(psStats,psAttacker->player);

// adapt for hight adjusted artillery shots
if (min_angle>PROJ_MAX_PITCH)
{
baseHitChance = baseHitChance * trigCos(min_angle) / trigCos(PROJ_MAX_PITCH);
}
}
else
{
/* Out of range */
objTrace(psAttacker->id, "combFire(%u[%s]->%u): Out of range", psAttacker->id, psStats->pName, psTarget->id);
return;
return false;
}

// apply experience accuracy modifiers to the base
Expand Down Expand Up @@ -298,7 +329,7 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
{
case FOM_NO:
// Can't fire while moving
return;
return false;
break;
case FOM_PARTIAL:
resultHitChance = FOM_PARTIAL_ACCURACY_PENALTY * resultHitChance / 100;
Expand Down Expand Up @@ -410,11 +441,11 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
predict.z = psTarget->pos.z;

debug(LOG_SENSOR, "combFire: Accurate prediction range (%d)", dice);
if (!proj_SendProjectile(psWeap, psAttacker, psAttacker->player, predict, psTarget, false, weapon_slot))
if (!proj_SendProjectileAngled(psWeap, psAttacker, psAttacker->player, predict, psTarget, false, weapon_slot, min_angle))
{
/* Out of memory - we can safely ignore this */
debug(LOG_ERROR, "Out of memory");
return;
return false;
}
}
else
Expand All @@ -425,7 +456,7 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
objTrace(psAttacker->id, "combFire: %u[%s]->%u: resultHitChance=%d, visibility=%hhu : ",
psAttacker->id, psStats->pName, psTarget->id, resultHitChance, psTarget->visible[psAttacker->player]);

return;
return true;

missed:
/* Deal with a missed shot */
Expand All @@ -441,9 +472,9 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in

/* Fire off the bullet to the miss location. The miss is only visible if the player owns
* the target. (Why? - Per) */
proj_SendProjectile(psWeap, psAttacker, psAttacker->player, miss, NULL, psTarget->player == selectedPlayer, weapon_slot);
proj_SendProjectileAngled(psWeap, psAttacker, psAttacker->player, miss, NULL, psTarget->player == selectedPlayer, weapon_slot, min_angle);
}
return;
return true;
}

/*checks through the target players list of structures and droids to see
Expand Down
2 changes: 1 addition & 1 deletion src/combat.h
Expand Up @@ -46,7 +46,7 @@ extern BOOL combInitialise(void);
extern BOOL combShutdown(void);

/* Fire a weapon at something added int weapon_slot*/
extern void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, int weapon_slot);
extern BOOL combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, int weapon_slot);

/*checks through the target players list of structures and droids to see
if any support a counter battery sensor*/
Expand Down
40 changes: 40 additions & 0 deletions src/droid.c
Expand Up @@ -3372,6 +3372,46 @@ void setSelectedCommander(UDWORD commander)
selectedCommander = commander;
}

/**
* calculate muzzle base location in 3d world
*/
BOOL calcDroidMuzzleBaseLocation(DROID *psDroid, Vector3f *muzzle, int weapon_slot)
{
iIMDShape *psShape, *psWeaponImd;

CHECK_DROID(psDroid);

psShape = BODY_IMD(psDroid, psDroid->player);
psWeaponImd = (asWeaponStats[psDroid->asWeaps[weapon_slot].nStat]).pIMD;

if(psShape && psShape->nconnectors)
{
Vector3f barrel = {0.0f, 0.0f, 0.0f};

pie_MatBegin();
pie_TRANSLATE(psDroid->pos.x, -psDroid->pos.z, psDroid->pos.y);

//matrix = the center of droid
pie_MatRotY( DEG( psDroid->direction ) );
pie_MatRotX( DEG( psDroid->pitch ) );
pie_MatRotZ( DEG( -psDroid->roll ) );
pie_TRANSLATE( psShape->connectors[weapon_slot].x, -psShape->connectors[weapon_slot].z,
-psShape->connectors[weapon_slot].y);//note y and z flipped

pie_RotateTranslate3f(&barrel, muzzle);
muzzle->z = -muzzle->z;
pie_MatEnd();
}
else
{
*muzzle = Vector3f_Init(psDroid->pos.x, psDroid->pos.y, psDroid->pos.z + psDroid->sDisplay.imd->max.y);
}

CHECK_DROID(psDroid);

return true;
}

/**
* calculate muzzle tip location in 3d world
*/
Expand Down
2 changes: 2 additions & 0 deletions src/droid.h
Expand Up @@ -239,6 +239,8 @@ extern UDWORD getNumDroidsForLevel(UDWORD level);
extern BOOL activateGroupAndMove(UDWORD playerNumber, UDWORD groupNumber);
/* calculate muzzle tip location in 3d world added int weapon_slot to fix the always slot 0 hack*/
extern BOOL calcDroidMuzzleLocation(DROID *psDroid, Vector3f *muzzle, int weapon_slot);
/* calculate muzzle base location in 3d world added int weapon_slot to fix the always slot 0 hack*/
extern BOOL calcDroidMuzzleBaseLocation(DROID *psDroid, Vector3f *muzzle, int weapon_slot);

/* gets a template from its aName (when pName is unknown) */
extern DROID_TEMPLATE *GetHumanDroidTemplate(char *aName);
Expand Down

0 comments on commit 80b27a9

Please sign in to comment.