Step one towards vector based projectiles
git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@5106 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
974b5aacaa
commit
202ebc32fb
55
src/combat.c
55
src/combat.c
|
@ -98,16 +98,12 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
|
|||
WEAPON_STATS *psStats;
|
||||
UDWORD xDiff, yDiff, distSquared;
|
||||
UDWORD dice, damLevel;
|
||||
SDWORD missDir, missDist, missX,missY;
|
||||
SDWORD resultHitChance=0,baseHitChance=0,fireChance;
|
||||
UDWORD firePause;
|
||||
SDWORD targetDir,dirDiff;
|
||||
SDWORD longRange;
|
||||
DROID *psDroid = NULL;
|
||||
int minOffset = 5;
|
||||
//Watermelon:predicted X,Y offset per sec
|
||||
SDWORD predictX;
|
||||
SDWORD predictY;
|
||||
SDWORD dist;
|
||||
|
||||
CHECK_OBJECT(psAttacker);
|
||||
|
@ -351,29 +347,35 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
|
|||
// see if we were lucky to hit the target
|
||||
if (dice <= resultHitChance)
|
||||
{
|
||||
//Watermelon:predicted X,Y offset per sec
|
||||
Vector3i predict;
|
||||
|
||||
/* Kerrrbaaang !!!!! a hit */
|
||||
//Watermelon:Target prediction
|
||||
if(psTarget->type == OBJ_DROID)
|
||||
{
|
||||
predictX = (SDWORD)(trigSin( ((DROID *)psTarget)->sMove.moveDir ) * ((DROID *)psTarget)->sMove.speed * dist / psStats->flightSpeed );
|
||||
predictX += psTarget->pos.x;
|
||||
predictY = (SDWORD)(trigCos( ((DROID *)psTarget)->sMove.moveDir ) * ((DROID *)psTarget)->sMove.speed * dist / psStats->flightSpeed );
|
||||
predictY += psTarget->pos.y;
|
||||
predict.x = trigSin( ((DROID *)psTarget)->sMove.moveDir ) * ((DROID *)psTarget)->sMove.speed * dist / psStats->flightSpeed;
|
||||
predict.x += psTarget->pos.x;
|
||||
predict.y = trigCos( ((DROID *)psTarget)->sMove.moveDir ) * ((DROID *)psTarget)->sMove.speed * dist / psStats->flightSpeed;
|
||||
predict.y += psTarget->pos.y;
|
||||
|
||||
// Make sure we don't pass any negative or out of bounds numbers to proj_SendProjectile
|
||||
predictX = MAX(predictX, 0);
|
||||
predictX = MIN(predictX, world_coord(mapWidth - 1));
|
||||
predictY = MAX(predictY, 0);
|
||||
predictY = MIN(predictY, world_coord(mapHeight - 1));
|
||||
predict.x = MAX(predict.x, 0);
|
||||
predict.x = MIN(predict.x, world_coord(mapWidth - 1));
|
||||
predict.y = MAX(predict.y, 0);
|
||||
predict.y = MIN(predict.y, world_coord(mapHeight - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
predictX = psTarget->pos.x;
|
||||
predictY = psTarget->pos.y;
|
||||
predict.x = psTarget->pos.x;
|
||||
predict.y = psTarget->pos.y;
|
||||
}
|
||||
|
||||
predict.z = psTarget->pos.z;
|
||||
|
||||
debug(LOG_SENSOR, "combFire: Accurate prediction range (%d)", dice);
|
||||
if (!proj_SendProjectile(psWeap, psAttacker, psAttacker->player,
|
||||
predictX, predictY, psTarget->pos.z, psTarget, false, false, weapon_slot))
|
||||
predict, psTarget, false, false, weapon_slot))
|
||||
{
|
||||
/* Out of memory - we can safely ignore this */
|
||||
debug(LOG_ERROR, "Out of memory");
|
||||
|
@ -392,19 +394,20 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in
|
|||
|
||||
missed:
|
||||
/* Deal with a missed shot */
|
||||
{
|
||||
int missDir = rand() % BUL_MAXSCATTERDIR, missDist = 2 * (100 - resultHitChance);
|
||||
Vector3i miss = {
|
||||
aScatterDir[missDir].x * missDist + psTarget->pos.x + minOffset,
|
||||
aScatterDir[missDir].y * missDist + psTarget->pos.y + minOffset,
|
||||
psTarget->pos.z
|
||||
};
|
||||
|
||||
missDist = 2 * (100 - resultHitChance);
|
||||
missDir = rand() % BUL_MAXSCATTERDIR;
|
||||
missX = aScatterDir[missDir].x * missDist + psTarget->pos.x + minOffset;
|
||||
missY = aScatterDir[missDir].y * missDist + psTarget->pos.y + minOffset;
|
||||
|
||||
debug(LOG_NEVER, "combFire: Missed shot (%d) ended up at (%4d,%4d)", dice, missX, missY);
|
||||
|
||||
/* 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, missX,missY, psTarget->pos.z, NULL,
|
||||
psTarget->player == selectedPlayer, false, weapon_slot);
|
||||
debug(LOG_NEVER, "combFire: Missed shot (%d) ended up at (%4d,%4d)", dice, miss.x, miss.y);
|
||||
|
||||
/* 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, false, weapon_slot);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,26 +55,26 @@
|
|||
BOOL sendBuildStarted(STRUCTURE *psStruct, DROID *psDroid)
|
||||
{
|
||||
NETbeginEncode(NET_BUILD, NET_ALL_PLAYERS);
|
||||
|
||||
|
||||
// Who is building it
|
||||
NETuint8_t(&psDroid->player);
|
||||
|
||||
|
||||
// What they are building
|
||||
NETuint32_t(&psDroid->psTarStats->ref);
|
||||
|
||||
|
||||
// Where it is being built
|
||||
NETuint16_t(&psDroid->orderX);
|
||||
NETuint16_t(&psDroid->orderY);
|
||||
|
||||
|
||||
// The droid building it
|
||||
NETuint32_t(&psDroid->id);
|
||||
|
||||
|
||||
// The ID assigned to the structure being built
|
||||
NETuint32_t(&psStruct->id);
|
||||
|
||||
|
||||
// The droids order
|
||||
NETint32_t(&psDroid->order);
|
||||
|
||||
|
||||
if (psDroid->psTarget
|
||||
&& psDroid->psTarget->type == OBJ_STRUCTURE)
|
||||
{
|
||||
|
@ -85,7 +85,7 @@ BOOL sendBuildStarted(STRUCTURE *psStruct, DROID *psDroid)
|
|||
{
|
||||
NETnull();
|
||||
}
|
||||
|
||||
|
||||
// Z coord
|
||||
NETuint16_t(&psStruct->pos.z);
|
||||
|
||||
|
@ -129,16 +129,16 @@ BOOL recvBuildStarted()
|
|||
if (getDroidDestination((BASE_STATS *) psStats, x, y, &actionX, &actionY))
|
||||
{
|
||||
psDroid->order = order;
|
||||
|
||||
|
||||
if (psDroid->order == DORDER_LINEBUILD)
|
||||
{
|
||||
psDroid->order = DORDER_BUILD;
|
||||
}
|
||||
|
||||
|
||||
psDroid->orderX = x;
|
||||
psDroid->orderY = y;
|
||||
psDroid->psTarStats = (BASE_STATS *) psStats;
|
||||
|
||||
|
||||
if (targetId)
|
||||
{
|
||||
setDroidTarget(psDroid, IdToPointer(targetId, ANYPLAYER));
|
||||
|
@ -165,18 +165,18 @@ BOOL recvBuildStarted()
|
|||
((STRUCTURE *) psDroid->psTarget)->id = structId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// INFORM others that a building has been completed.
|
||||
BOOL SendBuildFinished(STRUCTURE *psStruct)
|
||||
{
|
||||
{
|
||||
NETbeginEncode(NET_BUILDFINISHED, NET_ALL_PLAYERS);
|
||||
// ID of building
|
||||
NETuint32_t(&psStruct->id);
|
||||
|
||||
|
||||
// Along with enough info to build it (if needed)
|
||||
NETuint32_t(&psStruct->pStructureType->ref);
|
||||
NETuint16_t(&psStruct->pos.x);
|
||||
|
@ -244,7 +244,7 @@ BOOL recvBuildFinished()
|
|||
}
|
||||
// Build the structure
|
||||
psStruct = buildStructure(&(asStructureStats[typeindex]), x, y, player, true);
|
||||
|
||||
|
||||
if (psStruct)
|
||||
{
|
||||
psStruct->id = structId;
|
||||
|
@ -257,7 +257,7 @@ BOOL recvBuildFinished()
|
|||
{
|
||||
NETlogEntry("had to plonk down a building, BUT FAILED OH S**T." ,0,player);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -266,8 +266,8 @@ BOOL recvBuildFinished()
|
|||
// demolish message.
|
||||
BOOL SendDemolishFinished(STRUCTURE *psStruct, DROID *psDroid)
|
||||
{
|
||||
NETbeginEncode(NET_DEMOLISH, NET_ALL_PLAYERS);
|
||||
|
||||
NETbeginEncode(NET_DEMOLISH, NET_ALL_PLAYERS);
|
||||
|
||||
// Send what is being demolish and who is doing it
|
||||
NETuint32_t(&psStruct->id);
|
||||
NETuint32_t(&psDroid->id);
|
||||
|
@ -303,7 +303,7 @@ BOOL recvDemolishFinished()
|
|||
psDroid->psTarStats = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,7 @@ BOOL recvDestroyStructure()
|
|||
NETbeginDecode(NET_STRUCTDEST);
|
||||
NETuint32_t(&structID);
|
||||
NETend();
|
||||
|
||||
|
||||
// Struct to destory
|
||||
psStruct = IdToStruct(structID,ANYPLAYER);
|
||||
|
||||
|
@ -344,7 +344,7 @@ BOOL recvDestroyStructure()
|
|||
// NOTE: I do not think this should be here!
|
||||
technologyGiveAway(psStruct);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -370,7 +370,7 @@ BOOL recvLasSat()
|
|||
UBYTE player,targetplayer;
|
||||
STRUCTURE *psStruct;
|
||||
uint32_t id,targetid;
|
||||
|
||||
|
||||
NETbeginDecode(NET_LASSAT);
|
||||
NETuint8_t(&player);
|
||||
NETuint32_t(&id);
|
||||
|
@ -378,18 +378,24 @@ BOOL recvLasSat()
|
|||
NETuint8_t(&targetplayer);
|
||||
NETend();
|
||||
|
||||
psStruct = IdToStruct (id, player);
|
||||
psObj = IdToPointer(targetid, targetplayer);
|
||||
|
||||
if( psStruct && psObj)
|
||||
{
|
||||
// Give enemy no quarter, unleash the lasat
|
||||
proj_SendProjectile(&psStruct->asWeaps[0], NULL, player, psObj->pos.x,
|
||||
psObj->pos.y, psObj->pos.z, psObj, true, false, 0);
|
||||
// Play 5 second countdown message
|
||||
audio_QueueTrackPos( ID_SOUND_LAS_SAT_COUNTDOWN, psObj->pos.x, psObj->pos.y,
|
||||
psObj->pos.z);
|
||||
}
|
||||
psStruct = IdToStruct (id, player);
|
||||
psObj = IdToPointer(targetid, targetplayer);
|
||||
|
||||
if( psStruct && psObj)
|
||||
{
|
||||
Vector3i pos;
|
||||
|
||||
// FIXME HACK Needed since we got those ugly Vector3uw floating around in BASE_OBJECT...
|
||||
Vector3i_Set(&pos, psObj->pos.x, psObj->pos.y, psObj->pos.z);
|
||||
|
||||
|
||||
// Give enemy no quarter, unleash the lasat
|
||||
proj_SendProjectile(&psStruct->asWeaps[0], NULL, player, pos, psObj, true, false, 0);
|
||||
|
||||
// Play 5 second countdown message
|
||||
audio_QueueTrackPos( ID_SOUND_LAS_SAT_COUNTDOWN, psObj->pos.x, psObj->pos.y,
|
||||
psObj->pos.z);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
55
src/order.c
55
src/order.c
|
@ -4183,34 +4183,39 @@ BOOL getFactoryState(STRUCTURE *psStruct, SECONDARY_ORDER sec, SECONDARY_STATE *
|
|||
//lasSat structure can select a target
|
||||
void orderStructureObj(UDWORD player, BASE_OBJECT *psObj)
|
||||
{
|
||||
STRUCTURE *psStruct;
|
||||
UDWORD firePause, damLevel;
|
||||
STRUCTURE *psStruct;
|
||||
|
||||
for (psStruct = apsStructLists[player]; psStruct; psStruct = psStruct->psNext)
|
||||
{
|
||||
if (lasSatStructSelected(psStruct))
|
||||
{
|
||||
//there will only be the one!
|
||||
firePause = weaponFirePause(&asWeaponStats[psStruct->asWeaps[0].
|
||||
nStat], (UBYTE)player);
|
||||
damLevel = PERCENT(psStruct->body, structureBody(psStruct));
|
||||
if (damLevel < HEAVY_DAMAGE_LEVEL)
|
||||
{
|
||||
firePause += firePause;
|
||||
}
|
||||
if (isHumanPlayer(player)
|
||||
for (psStruct = apsStructLists[player]; psStruct; psStruct = psStruct->psNext)
|
||||
{
|
||||
if (lasSatStructSelected(psStruct))
|
||||
{
|
||||
Vector3i pos;
|
||||
//there will only be the one!
|
||||
unsigned int firePause = weaponFirePause(&asWeaponStats[psStruct->asWeaps[0].nStat], (UBYTE)player);
|
||||
unsigned int damLevel = PERCENT(psStruct->body, structureBody(psStruct));
|
||||
|
||||
// FIXME HACK Needed since we got those ugly Vector3uw floating around in BASE_OBJECT...
|
||||
Vector3i_Set(&pos, psObj->pos.x, psObj->pos.y, psObj->pos.z);
|
||||
|
||||
if (damLevel < HEAVY_DAMAGE_LEVEL)
|
||||
{
|
||||
firePause += firePause;
|
||||
}
|
||||
|
||||
if (isHumanPlayer(player)
|
||||
&& (gameTime - psStruct->asWeaps[0].lastFired <= firePause) )
|
||||
{
|
||||
/* Too soon to fire again */
|
||||
break;
|
||||
/* Too soon to fire again */
|
||||
break;
|
||||
}
|
||||
//ok to fire - so fire away
|
||||
proj_SendProjectile(&psStruct->asWeaps[0], NULL,
|
||||
player, psObj->pos.x, psObj->pos.y, psObj->pos.z, psObj, true, false, 0);
|
||||
//set up last fires time
|
||||
psStruct->asWeaps[0].lastFired = gameTime;
|
||||
|
||||
//play 5 second countdown message
|
||||
//ok to fire - so fire away
|
||||
proj_SendProjectile(&psStruct->asWeaps[0], NULL,
|
||||
player, pos, psObj, true, false, 0);
|
||||
//set up last fires time
|
||||
psStruct->asWeaps[0].lastFired = gameTime;
|
||||
|
||||
//play 5 second countdown message
|
||||
audio_QueueTrackPos( ID_SOUND_LAS_SAT_COUNTDOWN,
|
||||
psObj->pos.x, psObj->pos.y, psObj->pos.z );
|
||||
|
||||
|
@ -4222,8 +4227,8 @@ void orderStructureObj(UDWORD player, BASE_OBJECT *psObj)
|
|||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* getDroidOrderName(DROID_ORDER order)
|
||||
|
|
|
@ -338,8 +338,7 @@ static void proj_UpdateKills(PROJECTILE *psObj, float experienceInc)
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
BOOL proj_SendProjectile(WEAPON *psWeap, BASE_OBJECT *psAttacker, int player, int tarX, int tarY, int tarZ,
|
||||
BASE_OBJECT *psTarget, BOOL bVisible, BOOL bPenetrate, int weapon_slot)
|
||||
BOOL proj_SendProjectile(WEAPON *psWeap, BASE_OBJECT *psAttacker, int player, Vector3i target, BASE_OBJECT *psTarget, BOOL bVisible, BOOL bPenetrate, int weapon_slot)
|
||||
{
|
||||
PROJECTILE *psObj = malloc(sizeof(PROJECTILE));
|
||||
SDWORD tarHeight, srcHeight, iMinSq;
|
||||
|
@ -358,9 +357,7 @@ BOOL proj_SendProjectile(WEAPON *psWeap, BASE_OBJECT *psAttacker, int player, in
|
|||
{
|
||||
// if there isn't an attacker just start at the target position
|
||||
// NB this is for the script function to fire the las sats
|
||||
muzzle.x = (SDWORD)tarX;
|
||||
muzzle.y = (SDWORD)tarY;
|
||||
muzzle.z = (SDWORD)tarZ;
|
||||
muzzle = target;
|
||||
}
|
||||
else if (psAttacker->type == OBJ_DROID && weapon_slot >= 0)
|
||||
{
|
||||
|
@ -383,13 +380,11 @@ BOOL proj_SendProjectile(WEAPON *psWeap, BASE_OBJECT *psAttacker, int player, in
|
|||
psObj->type = OBJ_PROJECTILE;
|
||||
psObj->state = PROJ_INFLIGHT;
|
||||
psObj->psWStats = asWeaponStats + psWeap->nStat;
|
||||
psObj->pos.x = (UWORD)muzzle.x;
|
||||
psObj->pos.y = (UWORD)muzzle.y;
|
||||
psObj->pos.z = (UWORD)muzzle.z;
|
||||
Vector3uw_Set(&psObj->pos, muzzle.x, muzzle.y, muzzle.z);
|
||||
psObj->startX = muzzle.x;
|
||||
psObj->startY = muzzle.y;
|
||||
psObj->tarX = tarX;
|
||||
psObj->tarY = tarY;
|
||||
psObj->tarX = target.x;
|
||||
psObj->tarY = target.y;
|
||||
psObj->targetRadius = (psTarget ? establishTargetRadius(psTarget) : 0); // needed to backtrack FX
|
||||
psObj->born = gameTime;
|
||||
psObj->player = (UBYTE)player;
|
||||
|
@ -405,7 +400,7 @@ BOOL proj_SendProjectile(WEAPON *psWeap, BASE_OBJECT *psAttacker, int player, in
|
|||
|
||||
/* If target is a VTOL or higher than ground, it is an air target. */
|
||||
if ((psTarget != NULL && psTarget->type == OBJ_DROID && vtolDroid((DROID*)psTarget))
|
||||
|| (psTarget == NULL && (SDWORD)tarZ > map_Height(tarX,tarY)))
|
||||
|| (psTarget == NULL && target.z > map_Height(target.x, target.y)))
|
||||
{
|
||||
psObj->airTarget = true;
|
||||
}
|
||||
|
@ -472,7 +467,7 @@ BOOL proj_SendProjectile(WEAPON *psWeap, BASE_OBJECT *psAttacker, int player, in
|
|||
}
|
||||
else
|
||||
{
|
||||
tarHeight = (SDWORD)tarZ;
|
||||
tarHeight = target.z;
|
||||
scoreUpdateVar(WD_SHOTS_OFF_TARGET);
|
||||
}
|
||||
|
||||
|
@ -872,20 +867,22 @@ static void proj_InFlightDirectFunc( PROJECTILE *psObj )
|
|||
|
||||
if (bPenetrate)
|
||||
{
|
||||
SDWORD TargetX, TargetY;
|
||||
// Determine position to fire a missile at
|
||||
// (must be at least 0 because we don't use signed integers
|
||||
// this shouldn't be larger than the height and width of the map either)
|
||||
Vector3i target = {
|
||||
psObj->startX + extendRad * dx / rad,
|
||||
psObj->startY + extendRad * dy / rad,
|
||||
psObj->pos.z
|
||||
};
|
||||
target.x = clip(target.x, 0, world_coord(mapWidth - 1));
|
||||
target.y = clip(target.y, 0, world_coord(mapHeight - 1));
|
||||
|
||||
asWeap.nStat = psObj->psWStats - asWeaponStats;
|
||||
//Watermelon:just assume we damaged the chosen target
|
||||
setProjectileDamaged(psObj, psNewTarget);
|
||||
|
||||
// Determine position to fire a missile at
|
||||
// (must be at least 0 because we don't use signed integers
|
||||
// this shouldn't be larger than the height and width of the map either)
|
||||
TargetX = psObj->startX + extendRad * dx / rad;
|
||||
TargetY = psObj->startY + extendRad * dy / rad;
|
||||
CLIP(TargetX, 0, world_coord(mapWidth - 1));
|
||||
CLIP(TargetY, 0, world_coord(mapHeight - 1));
|
||||
proj_SendProjectile( &asWeap, (BASE_OBJECT*)psObj, psObj->player, TargetX, TargetY, psObj->pos.z, NULL, true, bPenetrate, -1 );
|
||||
proj_SendProjectile( &asWeap, (BASE_OBJECT*)psObj, psObj->player, target, NULL, true, bPenetrate, -1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1120,20 +1117,22 @@ static void proj_InFlightIndirectFunc( PROJECTILE *psObj )
|
|||
|
||||
if (bPenetrate)
|
||||
{
|
||||
SDWORD TargetX, TargetY;
|
||||
// Determine position to fire a missile at
|
||||
// (must be at least 0 because we don't use signed integers
|
||||
// this shouldn't be larger than the height and width of the map either)
|
||||
Vector3i target = {
|
||||
psObj->startX + extendRad * dx / iRad,
|
||||
psObj->startY + extendRad * dy / iRad,
|
||||
psObj->pos.z
|
||||
};
|
||||
target.x = clip(target.x, 0, world_coord(mapWidth - 1));
|
||||
target.y = clip(target.y, 0, world_coord(mapHeight - 1));
|
||||
|
||||
asWeap.nStat = psObj->psWStats - asWeaponStats;
|
||||
//Watermelon:just assume we damaged the chosen target
|
||||
setProjectileDamaged(psObj, psNewTarget);
|
||||
|
||||
// Determine position to fire a missile at
|
||||
// (must be at least 0 because we don't use signed integers
|
||||
// this shouldn't be larger than the height and width of the map either)
|
||||
TargetX = MAX(psObj->startX + extendRad * dx / iRad, 0);
|
||||
TargetX = MIN(TargetX, world_coord(mapWidth - 1));
|
||||
TargetY = MAX(psObj->startY + extendRad * dy / iRad, 0);
|
||||
TargetY = MIN(TargetY, world_coord(mapHeight - 1));
|
||||
proj_SendProjectile( &asWeap, (BASE_OBJECT*)psObj, psObj->player, TargetX, TargetY, psObj->pos.z, NULL, true, bPenetrate, -1 );
|
||||
proj_SendProjectile( &asWeap, (BASE_OBJECT*)psObj, psObj->player, target, NULL, true, bPenetrate, -1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1965,7 +1964,7 @@ UDWORD calcDamage(UDWORD baseDamage, WEAPON_EFFECT weaponEffect, BASE_OBJECT *ps
|
|||
{
|
||||
damage = baseDamage;
|
||||
}
|
||||
|
||||
|
||||
// A little fail safe!
|
||||
if (damage == 0 && baseDamage != 0)
|
||||
{
|
||||
|
|
|
@ -56,8 +56,7 @@ PROJECTILE *proj_GetNext(void); ///< Get next projectile in the list.
|
|||
void proj_FreeAllProjectiles(void); ///< Free all projectiles in the list.
|
||||
|
||||
/** Send a single projectile against the given target. */
|
||||
BOOL proj_SendProjectile(WEAPON *psWeap, BASE_OBJECT *psAttacker, int player, int tarX, int tarY, int tarZ,
|
||||
BASE_OBJECT *psTarget, BOOL bVisible, BOOL bPenetrate, int weapon_slot);
|
||||
BOOL proj_SendProjectile(WEAPON *psWeap, BASE_OBJECT *psAttacker, int player, Vector3i target, BASE_OBJECT *psTarget, BOOL bVisible, BOOL bPenetrate, int weapon_slot);
|
||||
|
||||
/** Return whether a weapon is direct or indirect. */
|
||||
bool proj_Direct(const WEAPON_STATS* psStats);
|
||||
|
|
|
@ -6359,11 +6359,11 @@ BOOL scrGetDroidCount(void)
|
|||
// fire a weapon stat at an object
|
||||
BOOL scrFireWeaponAtObj(void)
|
||||
{
|
||||
SDWORD wIndex;
|
||||
BASE_OBJECT *psTarget;
|
||||
WEAPON sWeapon;
|
||||
Vector3i target;
|
||||
BASE_OBJECT *psTarget;
|
||||
WEAPON sWeapon = {0, 0, 0, 0, 0};
|
||||
|
||||
if (!stackPopParams(2, ST_WEAPON, &wIndex, ST_BASEOBJECT, &psTarget))
|
||||
if (!stackPopParams(2, ST_WEAPON, &sWeapon.nStat, ST_BASEOBJECT, &psTarget))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -6374,11 +6374,11 @@ BOOL scrFireWeaponAtObj(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
memset(&sWeapon, 0, sizeof(WEAPON));
|
||||
sWeapon.nStat = wIndex;
|
||||
// FIXME HACK Needed since we got those ugly Vector3uw floating around in BASE_OBJECT...
|
||||
Vector3i_Set(&target, psTarget->pos.x, psTarget->pos.y, psTarget->pos.z);
|
||||
|
||||
// send the projectile using the selectedPlayer so that it can always be seen
|
||||
proj_SendProjectile(&sWeapon, NULL, selectedPlayer, psTarget->pos.x,psTarget->pos.y,psTarget->pos.z, psTarget, true, false, 0);
|
||||
proj_SendProjectile(&sWeapon, NULL, selectedPlayer, target, psTarget, true, false, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -6386,19 +6386,18 @@ BOOL scrFireWeaponAtObj(void)
|
|||
// fire a weapon stat at a location
|
||||
BOOL scrFireWeaponAtLoc(void)
|
||||
{
|
||||
SDWORD wIndex, x,y;
|
||||
WEAPON sWeapon;
|
||||
Vector3i target;
|
||||
WEAPON sWeapon = {0, 0, 0, 0, 0};
|
||||
|
||||
if (!stackPopParams(3, ST_WEAPON, &wIndex, VAL_INT, &x, VAL_INT, &y))
|
||||
if (!stackPopParams(3, ST_WEAPON, &sWeapon.nStat, VAL_INT, &target.x, VAL_INT, &target.y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(&sWeapon, 0, sizeof(WEAPON));
|
||||
sWeapon.nStat = wIndex;
|
||||
target.z = map_Height(target.x, target.y);
|
||||
|
||||
// send the projectile using the selectedPlayer so that it can always be seen
|
||||
proj_SendProjectile(&sWeapon, NULL, selectedPlayer, x,y,map_Height(x,y), NULL, true, false, 0);
|
||||
proj_SendProjectile(&sWeapon, NULL, selectedPlayer, target, NULL, true, false, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -11512,7 +11511,7 @@ BOOL scrAssembleWeaponTemplate(void)
|
|||
// add template to player template list
|
||||
pNewTemplate->psNext = apsDroidTemplates[player];
|
||||
apsDroidTemplates[player] = pNewTemplate; //apsTemplateList?
|
||||
|
||||
|
||||
if (bMultiPlayer)
|
||||
{
|
||||
sendTemplate(pNewTemplate);
|
||||
|
|
Loading…
Reference in New Issue