- Changes for Enemy Target Changer

- Debris physics update

# Conflicts:
#	source/blood/src/actor.cpp
This commit is contained in:
Grind Core 2019-09-24 22:58:21 +03:00 committed by Christoph Oelckers
parent 623511021f
commit 05a1c94df4
4 changed files with 65 additions and 18 deletions

View file

@ -7125,8 +7125,9 @@ void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6,
actBurnSprite(actSpriteIdToOwnerId(nShooter), &xsprite[nXSprite], pVectorData->at11);
}
if (pSprite->index >= kThingBase && pSprite->index < kThingMax)
actPostSprite(pSprite->index, 4); // if it was a thing, return it's statnum back
if (pSprite->type >= kThingBase && pSprite->type < kThingMax)
changespritestat(pSprite->index, 4);
//actPostSprite(pSprite->index, 4); // if it was a thing, return it's statnum back
}
}
@ -7739,10 +7740,13 @@ void debrisConcuss(int nOwner, int listIndex, int x, int y, int z, int dmg) {
yvel[pSprite->xvel] += mulscale16(t, dy);
zvel[pSprite->xvel] += mulscale16(t, dz);
}
if (pSprite->type >= kThingBase && pSprite->type < kThingMax)
//actPostSprite(pSprite->index, 4); // !!! (does not working here) if it was a thing, return it's statnum back
changespritestat(pSprite->index, 4);
}
if (pSprite->index >= kThingBase && pSprite->index < kThingMax)
actPostSprite(pSprite->index, 4); // if it was a thing, return it's statnum back
actDamageSprite(nOwner, pSprite, DAMAGE_TYPE_3, dmg);
return;

View file

@ -137,6 +137,7 @@ void QuitGame(void);
#define kPhysFalling 0x0004 // currently in z-motion
// additional physics attributes for debris sprites
#define kPhysDebrisFly 0x0008 // *debris* affected by negative gravity (fly instead of falling, DO NOT mess with kHitagAutoAim)
#define kPhysDebrisSwim 0x0016 // *debris* can swim underwater (instead of drowning)
#define kPhysDebrisVector 0x0400 // *debris* can be affected by vector weapons
#define kPhysDebrisExplode 0x0800 // *debris* can be affected by explosions

View file

@ -979,6 +979,7 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT a3)
fallthrough__;
case COMMAND_ID_21:
if (pXSprite->txID <= 0 || !getDudesForTargetChg(pXSprite)) {
freeAllTargets(pXSprite);
evPost(nSprite, 3, 0, COMMAND_ID_0);
break;
} else {
@ -3039,15 +3040,28 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) {
/* 3: go to idle state if no targets in sight and ignore player(s) always - */
/* 4: follow player(s) when no targets in sight, attack targets if any in sight - */
if (type != 3 || !IsDudeSprite(&sprite[nDest]) || sprite[nDest].statnum != 6) return;
if (type != 3) return;
else if (!IsDudeSprite(&sprite[nDest]) && sprite[nDest].statnum != 6 && xsprite[sprite[nDest].extra].data3 != 0) {
switch (sprite[nDest].type) { // can be dead dude turned in gib
// make current target and all other dudes not attack this dude anymore
case 425:
case 426:
xsprite[sprite[nDest].extra].data3 = 0;
freeTargets(nDest);
return;
default:
return;
}
}
spritetype* pSprite = &sprite[nDest]; XSPRITE* pXSprite = &xsprite[pSprite->extra];
spritetype* pTarget = NULL; XSPRITE* pXTarget = NULL; int receiveHp = 33 + Random(33);
DUDEINFO* pDudeInfo = &dudeInfo[pSprite->type - kDudeBase]; int matesPerEnemy = 1;
// dude is burning?
if (pXSprite->burnTime > 0 && pXSprite->burnSource >= 0 && pXSprite->burnSource < kMaxSprites) {
if (!IsBurningDude(pSprite))
{
if (IsBurningDude(pSprite)) actKillDude(pSource->xvel, pSprite, DAMAGE_TYPE_0, 65535);
else {
spritetype* pBurnSource = &sprite[pXSprite->burnSource];
if (pBurnSource->extra >= 0) {
if (pXSource->data2 == 1 && isMateOf(pXSprite, &xsprite[pBurnSource->extra])) {
@ -3064,10 +3078,12 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) {
}
}
}
else {
actKillDude(pSource->xvel, pSprite, DAMAGE_TYPE_0, 65535);
return;
}
}
// dude is dead?
if (pXSprite->health <= 0) {
pSprite->type = 426; actPostSprite(pSprite->xvel, 4); // turn it in gib
return;
}
spritetype* pPlayer = targetIsPlayer(pXSprite);
@ -3411,9 +3427,9 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) {
/* - data4 = sector floor / sprite / wall cstat - */
int old = -1;
switch (type) {
// for sectors
case 6:
{
case 6: {
XSECTOR* pXSector = &xsector[sector[nDest].extra];
if (pXSource->data1 == 0) pXSector->Underwater = false;
@ -3431,8 +3447,9 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) {
if (valueIsBetween(pXSource->data4, -1, 65535))
sector[nDest].floorstat = pXSource->data4;
break;
}
break;
// for sprites
case 3: {
@ -3580,10 +3597,10 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) {
}
}
break;
break;
// for walls
case 0: {
walltype* pWall = &wall[nDest];
if (valueIsBetween(pXSource->data3, -1, 32767))
pWall->hitag = pXSource->data3;
@ -3609,9 +3626,9 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) {
}
}
}
break;
break;
}
}
}
@ -3755,6 +3772,29 @@ void activateDudes(int rx) {
}
}
// by NoOne: this function sets target to -1 for all dudes that hunting for nSprite
void freeTargets(int nSprite) {
for (int nTarget = headspritestat[6]; nTarget >= 0; nTarget = nextspritestat[nTarget]) {
if (!IsDudeSprite(&sprite[nTarget]) || sprite[nTarget].extra < 0) continue;
else if (xsprite[sprite[nTarget].extra].target == nSprite)
aiSetTarget(&xsprite[sprite[nTarget].extra], sprite[nTarget].x, sprite[nTarget].y, sprite[nTarget].z);
}
return;
}
// by NoOne: this function sets target to -1 for all targets that hunting for dudes affected by selected kModernDudeTargetChanger
void freeAllTargets(XSPRITE* pXSource) {
if (pXSource->txID <= 0) return;
for (int i = bucketHead[pXSource->txID]; i < bucketHead[pXSource->txID + 1]; i++) {
if (rxBucket[i].type == 3 && sprite[rxBucket[i].index].extra >= 0)
freeTargets(rxBucket[i].index);
}
return;
}
bool affectedByTargetChg(XSPRITE* pXDude) {
if (pXDude->rxID <= 0 || pXDude->locked == 1) return false;
for (int nSprite = headspritestat[kStatGDXDudeTargetChanger]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {

View file

@ -62,6 +62,8 @@ bool isAnnoyingUnit(spritetype* pDude);
bool unitCanFly(spritetype* pDude);
bool isMeleeUnit(spritetype* pDude);
void activateDudes(int rx);
void freeTargets(int nSprite);
void freeAllTargets(XSPRITE* pXSource);
bool affectedByTargetChg(XSPRITE* pXDude);
int getDataFieldOfObject(int objType, int objIndex, int dataIndex);
bool setDataValueOfObject(int objType, int objIndex, int dataIndex, int value);