mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-13 14:07:04 +03:00
Merge branch 'master' into NewTRMath
This commit is contained in:
commit
e1ff9ba698
15 changed files with 1093 additions and 848 deletions
|
@ -8,30 +8,151 @@
|
||||||
|
|
||||||
BITE_INFO apeBite = { 0, -19, 75, 15 };
|
BITE_INFO apeBite = { 0, -19, 75, 15 };
|
||||||
|
|
||||||
|
#define ATTACK_DAMAGE 200
|
||||||
|
|
||||||
|
#define TOUCH (0xFF00)
|
||||||
|
|
||||||
|
#define DIE_ANIM 7
|
||||||
|
#define VAULT_ANIM 19
|
||||||
|
|
||||||
|
#define RUN_TURN ANGLE(5)
|
||||||
|
|
||||||
|
#define DISPLAY_ANGLE ANGLE(45)
|
||||||
|
|
||||||
|
#define ATTACK_RANGE SQUARE(430)
|
||||||
|
#define PANIC_RANGE SQUARE(WALL_SIZE*2)
|
||||||
|
|
||||||
|
#define JUMP_CHANCE 0xa0
|
||||||
|
#define WARN1_CHANCE (JUMP_CHANCE + 0xA0)
|
||||||
|
#define WARN2_CHANCE (WARN1_CHANCE + 0xA0)
|
||||||
|
#define RUNLEFT_CHANCE (WARN2_CHANCE + 0x110)
|
||||||
|
|
||||||
|
#define ATTACK_FLAG 1
|
||||||
|
#define TURNL_FLAG 2
|
||||||
|
#define TURNR_FLAG 4
|
||||||
|
|
||||||
|
#define SHIFT 75
|
||||||
|
|
||||||
|
enum ape_anims {
|
||||||
|
APE_EMPTY,
|
||||||
|
APE_STOP,
|
||||||
|
APE_WALK,
|
||||||
|
APE_RUN,
|
||||||
|
APE_ATTACK1,
|
||||||
|
APE_DEATH,
|
||||||
|
APE_WARNING,
|
||||||
|
APE_WARNING2,
|
||||||
|
APE_RUNLEFT,
|
||||||
|
APE_RUNRIGHT,
|
||||||
|
APE_JUMP,
|
||||||
|
APE_VAULT
|
||||||
|
};
|
||||||
|
|
||||||
|
void ApeVault(short item_number, short angle)
|
||||||
|
{
|
||||||
|
ITEM_INFO *item;
|
||||||
|
CREATURE_INFO *ape;
|
||||||
|
long long y, xx, yy, x_floor, y_floor;
|
||||||
|
short room_number;
|
||||||
|
|
||||||
|
item = &g_Level.Items[item_number];
|
||||||
|
|
||||||
|
ape = (CREATURE_INFO *)item->data;
|
||||||
|
if (ape->flags & TURNL_FLAG)
|
||||||
|
{
|
||||||
|
item->pos.yRot -= 0x4000;
|
||||||
|
ape->flags -= TURNL_FLAG;
|
||||||
|
}
|
||||||
|
else if (item->flags & TURNR_FLAG)
|
||||||
|
{
|
||||||
|
item->pos.yRot += 0x4000;
|
||||||
|
ape->flags -= TURNR_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
xx = item->pos.zPos >> WALL_SHIFT;
|
||||||
|
yy = item->pos.xPos >> WALL_SHIFT;
|
||||||
|
y = item->pos.yPos;
|
||||||
|
room_number = item->roomNumber;
|
||||||
|
|
||||||
|
CreatureAnimation(item_number, angle, 0);
|
||||||
|
|
||||||
|
if (item->pos.yPos > y - STEP_SIZE * 3 / 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
x_floor = item->pos.zPos >> WALL_SHIFT;
|
||||||
|
y_floor = item->pos.xPos >> WALL_SHIFT;
|
||||||
|
if (xx == x_floor)
|
||||||
|
{
|
||||||
|
if (yy == y_floor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (yy < y_floor)
|
||||||
|
{
|
||||||
|
item->pos.xPos = (y_floor << WALL_SHIFT) - SHIFT;
|
||||||
|
item->pos.yRot = 0x4000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->pos.xPos = (yy << WALL_SHIFT) + SHIFT;
|
||||||
|
item->pos.yRot = -0x4000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (yy == y_floor)
|
||||||
|
{
|
||||||
|
if (xx < x_floor)
|
||||||
|
{
|
||||||
|
item->pos.zPos = (x_floor << WALL_SHIFT) - SHIFT;
|
||||||
|
item->pos.yRot = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->pos.zPos = (xx << WALL_SHIFT) + SHIFT;
|
||||||
|
item->pos.yRot = -0x8000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// diagonal
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (CreatureVault(item_number, angle, 2, 75))
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
// creature->maximumTurn = 0;
|
||||||
|
item->pos.yPos = y;
|
||||||
|
item->animNumber = Objects[ID_APE].animIndex + VAULT_ANIM;
|
||||||
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||||
|
item->currentAnimState = APE_VAULT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ApeControl(short itemNum)
|
void ApeControl(short itemNum)
|
||||||
{
|
{
|
||||||
|
short head, angle, random;
|
||||||
|
|
||||||
if (!CreatureActive(itemNum))
|
if (!CreatureActive(itemNum))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ITEM_INFO* item = &g_Level.Items[itemNum];
|
ITEM_INFO* item = &g_Level.Items[itemNum];
|
||||||
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
||||||
|
AI_INFO info;
|
||||||
short head = 0;
|
head = angle = 0;
|
||||||
short angle = 0;
|
|
||||||
short random = 0;
|
|
||||||
|
|
||||||
if (item->hitPoints <= 0)
|
if (item->hitPoints <= 0)
|
||||||
{
|
{
|
||||||
if (item->currentAnimState != 5)
|
if (item->currentAnimState != APE_DEATH)
|
||||||
{
|
{
|
||||||
item->animNumber = Objects[item->objectNumber].animIndex + 7 + (short)(GetRandomControl() / 0x4000);
|
item->animNumber = Objects[item->objectNumber].animIndex + DIE_ANIM + (short)(GetRandomControl() / 0x4000);
|
||||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||||
item->currentAnimState = 5;
|
item->currentAnimState = APE_DEATH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AI_INFO info;
|
|
||||||
CreatureAIInfo(item, &info);
|
CreatureAIInfo(item, &info);
|
||||||
|
|
||||||
if (info.ahead)
|
if (info.ahead)
|
||||||
|
@ -42,112 +163,112 @@ void ApeControl(short itemNum)
|
||||||
|
|
||||||
angle = CreatureTurn(item, creature->maximumTurn);
|
angle = CreatureTurn(item, creature->maximumTurn);
|
||||||
|
|
||||||
if (item->hitStatus || info.distance < SQUARE(2048))
|
if (item->hitStatus || info.distance < PANIC_RANGE)
|
||||||
creature->flags |= 1;
|
creature->flags |= ATTACK_FLAG;
|
||||||
|
|
||||||
switch (item->currentAnimState)
|
switch (item->currentAnimState)
|
||||||
{
|
{
|
||||||
case 1:
|
case APE_STOP:
|
||||||
if (creature->flags & 2)
|
if (creature->flags & TURNL_FLAG)
|
||||||
{
|
{
|
||||||
item->pos.yRot -= ANGLE(90);
|
item->pos.yRot -= ANGLE(90);
|
||||||
creature->flags -= 2;
|
creature->flags -= TURNL_FLAG;
|
||||||
}
|
}
|
||||||
else if (item->flags & 4)
|
else if (item->flags & TURNR_FLAG)
|
||||||
{
|
{
|
||||||
item->pos.yRot += ANGLE(90);
|
item->pos.yRot += ANGLE(90);
|
||||||
creature->flags -= 4;
|
creature->flags -= TURNR_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item->requiredAnimState)
|
if (item->requiredAnimState)
|
||||||
item->goalAnimState = item->requiredAnimState;
|
item->goalAnimState = item->requiredAnimState;
|
||||||
else if (info.bite && info.distance < SQUARE(430))
|
else if (info.bite && info.distance < ATTACK_RANGE)
|
||||||
item->goalAnimState = 4;
|
item->goalAnimState = APE_ATTACK1;
|
||||||
else if (!(creature->flags & 1) &&
|
else if (!(creature->flags & ATTACK_FLAG) &&
|
||||||
info.zoneNumber == info.enemyZone && info.ahead)
|
info.zoneNumber == info.enemyZone && info.ahead)
|
||||||
{
|
{
|
||||||
random = (short)(GetRandomControl() / 32);
|
random = (short)(GetRandomControl() / 32);
|
||||||
if (random < 0xA0)
|
if (random < JUMP_CHANCE)
|
||||||
item->goalAnimState = 10;
|
item->goalAnimState = APE_JUMP;
|
||||||
else if (random < 0x140)
|
else if (random < WARN1_CHANCE)
|
||||||
item->goalAnimState = 6;
|
item->goalAnimState = APE_WARNING;
|
||||||
else if (random < 0x1E0)
|
else if (random < WARN2_CHANCE)
|
||||||
item->goalAnimState = 7;
|
item->goalAnimState = APE_WARNING2;
|
||||||
else if (random < 0x2F0)
|
else if (random < RUNLEFT_CHANCE)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 8;
|
item->goalAnimState = APE_RUNLEFT;
|
||||||
creature->maximumTurn = 0;
|
creature->maximumTurn = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 9;
|
item->goalAnimState = APE_RUNRIGHT;
|
||||||
creature->maximumTurn = 0;
|
creature->maximumTurn = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = APE_RUN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case APE_RUN:
|
||||||
creature->maximumTurn = ANGLE(5);
|
creature->maximumTurn = RUN_TURN;
|
||||||
|
|
||||||
if (creature->flags == 0 && info.angle > -ANGLE(45) && info.angle < ANGLE(45))
|
if (creature->flags == 0 && info.angle > -DISPLAY_ANGLE && info.angle < DISPLAY_ANGLE)
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = APE_STOP;
|
||||||
else if (info.ahead && (item->touchBits & 0xFF00))
|
else if (info.ahead && (item->touchBits & TOUCH))
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 4;
|
item->requiredAnimState = APE_ATTACK1;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = APE_STOP;
|
||||||
}
|
}
|
||||||
else if (creature->mood != ESCAPE_MOOD)
|
else if (creature->mood != ESCAPE_MOOD)
|
||||||
{
|
{
|
||||||
random = (short)GetRandomControl();
|
random = (short)GetRandomControl();
|
||||||
if (random < 0xA0)
|
if (random < JUMP_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 10;
|
item->requiredAnimState = APE_JUMP;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = APE_STOP;
|
||||||
}
|
}
|
||||||
else if (random < 0x140)
|
else if (random < WARN1_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 6;
|
item->requiredAnimState = APE_WARNING;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = APE_STOP;
|
||||||
}
|
}
|
||||||
else if (random < 0x1E0)
|
else if (random < WARN2_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 7;
|
item->requiredAnimState = APE_WARNING2;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = APE_STOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case APE_RUNLEFT:
|
||||||
if (!(creature->flags & 4))
|
if (!(creature->flags & TURNR_FLAG))
|
||||||
{
|
{
|
||||||
item->pos.yRot -= ANGLE(90);
|
item->pos.yRot -= ANGLE(90);
|
||||||
creature->flags |= 4;
|
creature->flags |= TURNR_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = APE_STOP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case APE_RUNRIGHT:
|
||||||
if (!(creature->flags & 2))
|
if (!(creature->flags & TURNL_FLAG))
|
||||||
{
|
{
|
||||||
item->pos.yRot += ANGLE(90);
|
item->pos.yRot += ANGLE(90);
|
||||||
creature->flags |= 2;
|
creature->flags |= TURNL_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = APE_STOP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case APE_ATTACK1:
|
||||||
if (!item->requiredAnimState && (item->touchBits & 0xFF00))
|
if (!item->requiredAnimState && (item->touchBits & TOUCH))
|
||||||
{
|
{
|
||||||
CreatureEffect(item, &apeBite, DoBloodSplat);
|
CreatureEffect(item, &apeBite, DoBloodSplat);
|
||||||
|
|
||||||
LaraItem->hitPoints -= 200;
|
LaraItem->hitPoints -= ATTACK_DAMAGE;
|
||||||
LaraItem->hitStatus = true;
|
LaraItem->hitStatus = true;
|
||||||
|
|
||||||
item->requiredAnimState = 1;
|
item->requiredAnimState = APE_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -155,32 +276,10 @@ void ApeControl(short itemNum)
|
||||||
|
|
||||||
CreatureJoint(item, 0, head);
|
CreatureJoint(item, 0, head);
|
||||||
|
|
||||||
if (item->currentAnimState != 11)
|
if (item->currentAnimState != APE_VAULT)
|
||||||
{
|
{
|
||||||
if (creature->flags & 2)
|
ApeVault(itemNum, angle);
|
||||||
{
|
|
||||||
item->pos.yRot -= ANGLE(90);
|
|
||||||
creature->flags -= 2;
|
|
||||||
}
|
|
||||||
else if (item->flags & 4)
|
|
||||||
{
|
|
||||||
item->pos.yRot += ANGLE(90);
|
|
||||||
creature->flags -= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (CreatureVault(itemNum, angle, 2, 75))
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
creature->maximumTurn = 0;
|
|
||||||
item->animNumber = Objects[item->objectNumber].animIndex + 19;
|
|
||||||
item->currentAnimState = 11;
|
|
||||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CreatureAnimation(itemNum, angle, 0);
|
CreatureAnimation(itemNum, angle, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void ApeControl(short itemNum);
|
void ApeControl(short itemNum);
|
||||||
|
|
|
@ -8,6 +8,40 @@
|
||||||
|
|
||||||
BITE_INFO bearBite = { 0, 96, 335, 14 };
|
BITE_INFO bearBite = { 0, 96, 335, 14 };
|
||||||
|
|
||||||
|
enum bearStates{
|
||||||
|
BEAR_STROLL,
|
||||||
|
BEAR_STOP,
|
||||||
|
BEAR_WALK,
|
||||||
|
BEAR_RUN,
|
||||||
|
BEAR_REAR,
|
||||||
|
BEAR_ROAR,
|
||||||
|
BEAR_ATTACK1,
|
||||||
|
BEAR_ATTACK2,
|
||||||
|
BEAR_EAT,
|
||||||
|
BEAR_DEATH
|
||||||
|
};
|
||||||
|
#define TOUCH 0x2406C
|
||||||
|
|
||||||
|
|
||||||
|
#define ROAR_CHANCE 0x50
|
||||||
|
#define REAR_CHANCE 0x300
|
||||||
|
#define DROP_CHANCE 0x600
|
||||||
|
|
||||||
|
#define REAR_RANGE SQUARE(WALL_SIZE*2)
|
||||||
|
#define ATTACK_RANGE SQUARE(WALL_SIZE)
|
||||||
|
#define PAT_RANGE SQUARE(600)
|
||||||
|
|
||||||
|
#define RUN_TURN ANGLE(5)
|
||||||
|
#define WALK_TURN ANGLE(2)
|
||||||
|
|
||||||
|
#define EAT_RANGE SQUARE(WALL_SIZE*3/4)
|
||||||
|
|
||||||
|
|
||||||
|
#define CHARGE_DAMAGE 3
|
||||||
|
#define SLAM_DAMAGE 200
|
||||||
|
#define ATTACK_DAMAGE 200
|
||||||
|
#define PAT_DAMAGE 400
|
||||||
|
|
||||||
void BearControl(short itemNum)
|
void BearControl(short itemNum)
|
||||||
{
|
{
|
||||||
if (!CreatureActive(itemNum))
|
if (!CreatureActive(itemNum))
|
||||||
|
@ -17,48 +51,55 @@ void BearControl(short itemNum)
|
||||||
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
||||||
|
|
||||||
short head = 0;
|
short head = 0;
|
||||||
short angle = 0;
|
short angle;
|
||||||
|
|
||||||
if (item->hitPoints <= 0)
|
if (item->hitPoints <= 0)
|
||||||
{
|
{
|
||||||
if (item->currentAnimState != 9)
|
// if (item->currentAnimState != 9)
|
||||||
{
|
// {
|
||||||
angle = CreatureTurn(item, ANGLE(1));
|
angle = CreatureTurn(item, ANGLE(1));
|
||||||
|
|
||||||
switch (item->currentAnimState)
|
switch (item->currentAnimState)
|
||||||
{
|
{
|
||||||
case 2:
|
case BEAR_WALK:
|
||||||
item->goalAnimState = 4;
|
{
|
||||||
|
item->goalAnimState = BEAR_REAR;
|
||||||
break;
|
break;
|
||||||
case 3:
|
}
|
||||||
case 0:
|
case BEAR_RUN:
|
||||||
item->goalAnimState = 1;
|
case BEAR_STROLL:
|
||||||
|
{
|
||||||
|
item->goalAnimState = BEAR_STOP;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 4:
|
case BEAR_REAR:
|
||||||
|
{
|
||||||
creature->flags = 1;
|
creature->flags = 1;
|
||||||
item->goalAnimState = 9;
|
item->goalAnimState = BEAR_DEATH;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 1:
|
case BEAR_STOP:
|
||||||
|
{
|
||||||
creature->flags = 0;
|
creature->flags = 0;
|
||||||
item->goalAnimState = 9;
|
item->goalAnimState = BEAR_DEATH;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 9:
|
case BEAR_DEATH:
|
||||||
if (creature->flags && (item->touchBits & 0x2406C))
|
{
|
||||||
|
if (creature->flags && (item->touchBits & TOUCH))
|
||||||
{
|
{
|
||||||
LaraItem->hitPoints -= 200;
|
LaraItem->hitPoints -= SLAM_DAMAGE;
|
||||||
LaraItem->hitStatus = 1;
|
LaraItem->hitStatus = 1;
|
||||||
creature->flags = 0;
|
creature->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->animNumber = Objects[item->objectNumber].animIndex + 20;
|
// item->animNumber = Objects[item->objectNumber].animIndex + 20;
|
||||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
// item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||||
item->currentAnimState = 9;
|
// item->currentAnimState = 9;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -76,18 +117,20 @@ void BearControl(short itemNum)
|
||||||
if (item->hitStatus)
|
if (item->hitStatus)
|
||||||
creature->flags = 1;
|
creature->flags = 1;
|
||||||
|
|
||||||
|
const bool Laradead = (LaraItem->hitPoints <= 0);
|
||||||
|
|
||||||
switch (item->currentAnimState)
|
switch (item->currentAnimState)
|
||||||
{
|
{
|
||||||
case 1:
|
case BEAR_STOP:
|
||||||
if (LaraItem->hitPoints <= 0)
|
if (Laradead)
|
||||||
{
|
{
|
||||||
if (info.bite && info.distance < SQUARE(768))
|
if (info.bite && info.distance < EAT_RANGE)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 8;
|
item->goalAnimState = BEAR_EAT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 0;
|
item->goalAnimState = BEAR_STROLL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (item->requiredAnimState)
|
else if (item->requiredAnimState)
|
||||||
|
@ -96,70 +139,70 @@ void BearControl(short itemNum)
|
||||||
}
|
}
|
||||||
else if (creature->mood == BORED_MOOD)
|
else if (creature->mood == BORED_MOOD)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 0;
|
item->goalAnimState = BEAR_STROLL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = BEAR_RUN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case BEAR_STROLL:
|
||||||
creature->maximumTurn = ANGLE(2);
|
creature->maximumTurn = WALK_TURN;
|
||||||
|
|
||||||
if (LaraItem->hitPoints <= 0 && (item->touchBits & 0x2406C) && info.ahead)
|
if (Laradead && (item->touchBits & TOUCH) && info.ahead)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = BEAR_STOP;
|
||||||
}
|
}
|
||||||
else if (creature->mood != BORED_MOOD)
|
else if (creature->mood != BORED_MOOD)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = BEAR_STOP;
|
||||||
if (creature->mood == ESCAPE_MOOD)
|
if (creature->mood == ESCAPE_MOOD)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 0;
|
item->requiredAnimState = BEAR_STROLL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (GetRandomControl() < 0x50)
|
else if (GetRandomControl() < ROAR_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 5;
|
item->requiredAnimState = BEAR_ROAR;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = BEAR_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case BEAR_RUN:
|
||||||
creature->maximumTurn = ANGLE(5);
|
creature->maximumTurn = RUN_TURN;
|
||||||
|
|
||||||
// if the bear slams you it hurts
|
// if the bear slams you it hurts
|
||||||
if (item->touchBits & 0x2406C)
|
if (item->touchBits & TOUCH)
|
||||||
{
|
{
|
||||||
LaraItem->hitPoints -= 3;
|
LaraItem->hitPoints -= CHARGE_DAMAGE;
|
||||||
LaraItem->hitStatus = true;
|
LaraItem->hitStatus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (creature->mood == BORED_MOOD || LaraItem->hitPoints <= 0)
|
if (creature->mood == BORED_MOOD || Laradead)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = BEAR_STOP;
|
||||||
}
|
}
|
||||||
else if (info.ahead && !item->requiredAnimState)
|
else if (info.ahead && !item->requiredAnimState)
|
||||||
{
|
{
|
||||||
// bear may rear up, but not after he's taken some bullets!
|
// bear may rear up, but not after he's taken some bullets!
|
||||||
if (!creature->flags && info.distance < SQUARE(2048) && GetRandomControl() < 0x300)
|
if (!creature->flags && info.distance < REAR_RANGE && GetRandomControl() < REAR_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 4;
|
item->requiredAnimState = BEAR_REAR;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = BEAR_STOP;
|
||||||
}
|
}
|
||||||
else if (info.distance < SQUARE(1024))
|
else if (info.distance < ATTACK_RANGE)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 6;
|
item->goalAnimState = BEAR_ATTACK1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case BEAR_REAR:
|
||||||
if (creature->flags)
|
if (creature->flags)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 0;
|
item->requiredAnimState = BEAR_STROLL;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = BEAR_STOP;
|
||||||
}
|
}
|
||||||
else if (item->requiredAnimState)
|
else if (item->requiredAnimState)
|
||||||
{
|
{
|
||||||
|
@ -167,62 +210,62 @@ void BearControl(short itemNum)
|
||||||
}
|
}
|
||||||
else if (creature->mood == BORED_MOOD || creature->mood == ESCAPE_MOOD)
|
else if (creature->mood == BORED_MOOD || creature->mood == ESCAPE_MOOD)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = BEAR_STOP;
|
||||||
}
|
}
|
||||||
else if (info.bite && info.distance < SQUARE(600))
|
else if (info.bite && info.distance < PAT_RANGE)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 7;
|
item->goalAnimState = BEAR_ATTACK2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = BEAR_WALK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case BEAR_WALK:
|
||||||
if (creature->flags)
|
if (creature->flags)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 0;
|
item->requiredAnimState = BEAR_STROLL;
|
||||||
item->goalAnimState = 4;
|
item->goalAnimState = BEAR_REAR;
|
||||||
}
|
}
|
||||||
else if (info.ahead && (item->touchBits & 0x2406C))
|
else if (info.ahead && (item->touchBits & TOUCH))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 4;
|
item->goalAnimState = BEAR_REAR;
|
||||||
}
|
}
|
||||||
else if (creature->mood == ESCAPE_MOOD)
|
else if (creature->mood == ESCAPE_MOOD)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 4;
|
item->goalAnimState = BEAR_REAR;
|
||||||
item->requiredAnimState = 0;
|
item->requiredAnimState = BEAR_STROLL;
|
||||||
}
|
}
|
||||||
else if (creature->mood == BORED_MOOD || GetRandomControl() < 0x50)
|
else if (creature->mood == BORED_MOOD || GetRandomControl() < ROAR_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 5;
|
item->requiredAnimState = BEAR_ROAR;
|
||||||
item->goalAnimState = 4;
|
item->goalAnimState = BEAR_REAR;
|
||||||
}
|
}
|
||||||
else if (info.distance > SQUARE(2048) || GetRandomControl() < 0x600)
|
else if (info.distance > REAR_RANGE || GetRandomControl() < DROP_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 1;
|
item->requiredAnimState = BEAR_STOP;
|
||||||
item->goalAnimState = 4;
|
item->goalAnimState = BEAR_REAR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case BEAR_ATTACK2:
|
||||||
if (!item->requiredAnimState && (item->touchBits & 0x2406C))
|
if (!item->requiredAnimState && (item->touchBits & TOUCH))
|
||||||
{
|
{
|
||||||
LaraItem->hitPoints -= 400;
|
LaraItem->hitPoints -= PAT_DAMAGE;
|
||||||
LaraItem->hitStatus = true;
|
LaraItem->hitStatus = true;
|
||||||
item->requiredAnimState = 4;
|
item->requiredAnimState = BEAR_REAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case BEAR_ATTACK1:
|
||||||
if (!item->requiredAnimState && (item->touchBits & 0x2406C))
|
if (!item->requiredAnimState && (item->touchBits & TOUCH))
|
||||||
{
|
{
|
||||||
CreatureEffect(item, &bearBite, DoBloodSplat);
|
CreatureEffect(item, &bearBite, DoBloodSplat);
|
||||||
LaraItem->hitPoints -= 200;
|
LaraItem->hitPoints -= ATTACK_DAMAGE;
|
||||||
LaraItem->hitStatus = true;
|
LaraItem->hitStatus = true;
|
||||||
item->requiredAnimState = 1;
|
item->requiredAnimState = BEAR_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -231,4 +274,4 @@ void BearControl(short itemNum)
|
||||||
|
|
||||||
CreatureJoint(item, 0, head);
|
CreatureJoint(item, 0, head);
|
||||||
CreatureAnimation(itemNum, angle, 0);
|
CreatureAnimation(itemNum, angle, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void BearControl(short itemNum);
|
void BearControl(short itemNum);
|
||||||
|
|
|
@ -24,10 +24,14 @@ void InitialiseDoppelganger(short itemNum)
|
||||||
void DoppelgangerControl(short itemNum)
|
void DoppelgangerControl(short itemNum)
|
||||||
{
|
{
|
||||||
ITEM_INFO* item;
|
ITEM_INFO* item;
|
||||||
|
ITEM_INFO* ref;
|
||||||
FLOOR_INFO* floor;
|
FLOOR_INFO* floor;
|
||||||
int h, lh;
|
int h, lh;
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
short room_num;
|
short room_num;
|
||||||
|
short xRef, zRef;
|
||||||
|
|
||||||
|
ref = find_a_fucking_item(ID_BACON_REFERENCE);
|
||||||
|
|
||||||
item = &g_Level.Items[itemNum];
|
item = &g_Level.Items[itemNum];
|
||||||
|
|
||||||
|
@ -41,9 +45,11 @@ void DoppelgangerControl(short itemNum)
|
||||||
{
|
{
|
||||||
// TODO: fix evil lara moving.
|
// TODO: fix evil lara moving.
|
||||||
room_num = item->roomNumber;
|
room_num = item->roomNumber;
|
||||||
x = item->pos.xPos; // 2*36*WALL_SIZE - LaraItem->pos.xPos;
|
xRef = ref->pos.xPos;
|
||||||
y = item->pos.yPos; // LaraItem->pos.yPos;
|
zRef = ref->pos.zPos;
|
||||||
z = item->pos.zPos; // 2*60*WALL_SIZE - LaraItem->pos.zPos;
|
x = 2 * ref->pos.xPos - LaraItem->pos.xPos;
|
||||||
|
y = LaraItem->pos.yPos;
|
||||||
|
z = 2 * ref->pos.zPos - LaraItem->pos.zPos;
|
||||||
floor = GetFloor(x, y, z, &room_num);
|
floor = GetFloor(x, y, z, &room_num);
|
||||||
h = GetFloorHeight(floor, x, y, z);
|
h = GetFloorHeight(floor, x, y, z);
|
||||||
item->floor = h;
|
item->floor = h;
|
||||||
|
@ -52,9 +58,9 @@ void DoppelgangerControl(short itemNum)
|
||||||
lh = GetFloorHeight(floor, LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos);
|
lh = GetFloorHeight(floor, LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos);
|
||||||
item->frameNumber = LaraItem->frameNumber;
|
item->frameNumber = LaraItem->frameNumber;
|
||||||
item->animNumber = LaraItem->animNumber;
|
item->animNumber = LaraItem->animNumber;
|
||||||
//item->pos.xPos = x;
|
item->pos.xPos = x;
|
||||||
//item->pos.yPos = y;
|
item->pos.yPos = y;
|
||||||
//item->pos.zPos = z;
|
item->pos.zPos = z;
|
||||||
item->pos.xRot = LaraItem->pos.xRot;
|
item->pos.xRot = LaraItem->pos.xRot;
|
||||||
item->pos.yRot = LaraItem->pos.yRot - ANGLE(180);
|
item->pos.yRot = LaraItem->pos.yRot - ANGLE(180);
|
||||||
item->pos.zRot = LaraItem->pos.zRot;
|
item->pos.zRot = LaraItem->pos.zRot;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void InitialiseDoppelganger(short itemNum);
|
void InitialiseDoppelganger(short itemNum);
|
||||||
void DoppelgangerControl(short itemNum);
|
void DoppelgangerControl(short itemNum);
|
||||||
|
|
|
@ -9,11 +9,47 @@
|
||||||
|
|
||||||
BITE_INFO wolfBite = { 0, -14, 174, 6 };
|
BITE_INFO wolfBite = { 0, -14, 174, 6 };
|
||||||
|
|
||||||
|
enum wolfStates {
|
||||||
|
STATE_EMPTY,
|
||||||
|
STATE_STOP,
|
||||||
|
STATE_WALK,
|
||||||
|
STATE_RUN,
|
||||||
|
STATE_JUMP,
|
||||||
|
STATE_STALK,
|
||||||
|
STATE_ATTACK,
|
||||||
|
STATE_HOWL,
|
||||||
|
STATE_SLEEP,
|
||||||
|
STATE_CROUCH,
|
||||||
|
STATE_FASTTURN,
|
||||||
|
STATE_DEATH,
|
||||||
|
STATE_BITE
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TOUCH (0x774f)
|
||||||
|
|
||||||
|
#define SLEEP_FRAME 96
|
||||||
|
|
||||||
|
#define DIE_ANIM 20
|
||||||
|
|
||||||
|
#define ATTACK_RANGE SQUARE(WALL_SIZE*3/2)
|
||||||
|
#define STALK_RANGE SQUARE(WALL_SIZE*3)
|
||||||
|
|
||||||
|
#define BITE_DAMAGE 100
|
||||||
|
#define LUNGE_DAMAGE 50
|
||||||
|
|
||||||
|
#define WAKE_CHANCE 0x20
|
||||||
|
#define SLEEP_CHANCE 0x20
|
||||||
|
#define HOWL_CHANCE 0x180
|
||||||
|
|
||||||
|
#define WALK_TURN ANGLE(2)
|
||||||
|
#define RUN_TURN ANGLE(5)
|
||||||
|
#define STALK_TURN ANGLE(2)
|
||||||
|
|
||||||
void InitialiseWolf(short itemNum)
|
void InitialiseWolf(short itemNum)
|
||||||
{
|
{
|
||||||
ITEM_INFO* item = &g_Level.Items[itemNum];
|
ITEM_INFO* item = &g_Level.Items[itemNum];
|
||||||
ClearItem(itemNum);
|
ClearItem(itemNum);
|
||||||
item->frameNumber = 96;
|
item->frameNumber = SLEEP_FRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WolfControl(short itemNum)
|
void WolfControl(short itemNum)
|
||||||
|
@ -21,25 +57,26 @@ void WolfControl(short itemNum)
|
||||||
if (!CreatureActive(itemNum))
|
if (!CreatureActive(itemNum))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
short head;
|
||||||
|
short angle;
|
||||||
|
short tilt;
|
||||||
|
|
||||||
ITEM_INFO* item = &g_Level.Items[itemNum];
|
ITEM_INFO* item = &g_Level.Items[itemNum];
|
||||||
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
||||||
|
head = angle = tilt = 0;
|
||||||
short head = 0;
|
AI_INFO info;
|
||||||
short angle = 0;
|
|
||||||
short tilt = 0;
|
|
||||||
|
|
||||||
if (item->hitPoints <= 0)
|
if (item->hitPoints <= 0)
|
||||||
{
|
{
|
||||||
if (item->currentAnimState != 11)
|
if (item->currentAnimState != STATE_DEATH)
|
||||||
{
|
{
|
||||||
item->animNumber = Objects[item->objectNumber].animIndex + 20 + (short)(GetRandomControl() / 11000);
|
item->animNumber = Objects[ID_WOLF].animIndex + DIE_ANIM + (short)(GetRandomControl() / 11000);
|
||||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||||
item->currentAnimState = 11;
|
item->currentAnimState = STATE_DEATH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AI_INFO info;
|
|
||||||
CreatureAIInfo(item, &info);
|
CreatureAIInfo(item, &info);
|
||||||
|
|
||||||
if (info.ahead)
|
if (info.ahead)
|
||||||
|
@ -52,128 +89,128 @@ void WolfControl(short itemNum)
|
||||||
|
|
||||||
switch (item->currentAnimState)
|
switch (item->currentAnimState)
|
||||||
{
|
{
|
||||||
case 8:
|
case STATE_SLEEP:
|
||||||
head = 0;
|
head = 0;
|
||||||
|
|
||||||
if (creature->mood == ESCAPE_MOOD || info.zoneNumber == info.enemyZone)
|
if (creature->mood == ESCAPE_MOOD || info.zoneNumber == info.enemyZone)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 9;
|
item->requiredAnimState = STATE_CROUCH;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_STOP;
|
||||||
}
|
}
|
||||||
else if (GetRandomControl() < 0x20)
|
else if (GetRandomControl() < WAKE_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 2;
|
item->requiredAnimState = STATE_WALK;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case STATE_STOP:
|
||||||
if (item->requiredAnimState)
|
if (item->requiredAnimState)
|
||||||
item->goalAnimState = item->requiredAnimState;
|
item->goalAnimState = item->requiredAnimState;
|
||||||
else
|
else
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = STATE_WALK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case STATE_WALK:
|
||||||
creature->maximumTurn = ANGLE(2);
|
creature->maximumTurn = WALK_TURN;
|
||||||
|
|
||||||
if (creature->mood != BORED_MOOD)
|
if (creature->mood != BORED_MOOD)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 5;
|
item->goalAnimState = STATE_STALK;
|
||||||
item->requiredAnimState = 0;
|
item->requiredAnimState = STATE_EMPTY;
|
||||||
}
|
}
|
||||||
else if (GetRandomControl() < 0x20)
|
else if (GetRandomControl() < SLEEP_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 8;
|
item->requiredAnimState = STATE_SLEEP;
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case STATE_CROUCH:
|
||||||
if (item->requiredAnimState)
|
if (item->requiredAnimState)
|
||||||
item->goalAnimState = item->requiredAnimState;
|
item->goalAnimState = item->requiredAnimState;
|
||||||
else if (creature->mood == ESCAPE_MOOD)
|
else if (creature->mood == ESCAPE_MOOD)
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_RUN;
|
||||||
else if (info.distance < SQUARE(345) && info.bite)
|
else if (info.distance < SQUARE(345) && info.bite)
|
||||||
item->goalAnimState = 12;
|
item->goalAnimState = STATE_BITE;
|
||||||
else if (creature->mood == STALK_MOOD)
|
else if (creature->mood == STALK_MOOD)
|
||||||
item->goalAnimState = 5;
|
item->goalAnimState = STATE_STALK;
|
||||||
else if (creature->mood == BORED_MOOD)
|
else if (creature->mood == BORED_MOOD)
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_STOP;
|
||||||
else
|
else
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_RUN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case STATE_STALK:
|
||||||
creature->maximumTurn = ANGLE(2);
|
creature->maximumTurn = STALK_TURN;
|
||||||
|
|
||||||
if (creature->mood == ESCAPE_MOOD)
|
if (creature->mood == ESCAPE_MOOD)
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_RUN;
|
||||||
else if (info.distance < SQUARE(345) && info.bite)
|
else if (info.distance < SQUARE(345) && info.bite)
|
||||||
item->goalAnimState = 12;
|
item->goalAnimState = STATE_BITE;
|
||||||
else if (info.distance > SQUARE(3072))
|
else if (info.distance > SQUARE(3072))
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_RUN;
|
||||||
else if (creature->mood == ATTACK_MOOD)
|
else if (creature->mood == ATTACK_MOOD)
|
||||||
{
|
{
|
||||||
if (!info.ahead || info.distance > SQUARE(1536) ||
|
if (!info.ahead || info.distance > SQUARE(1536) ||
|
||||||
(info.enemyFacing < FRONT_ARC && info.enemyFacing > -FRONT_ARC))
|
(info.enemyFacing < FRONT_ARC && info.enemyFacing > -FRONT_ARC))
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_RUN;
|
||||||
}
|
}
|
||||||
else if (GetRandomControl() < 0x180)
|
else if (GetRandomControl() < HOWL_CHANCE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 7;
|
item->requiredAnimState = STATE_HOWL;
|
||||||
item->goalAnimState = 9;
|
item->goalAnimState = STATE_CROUCH;
|
||||||
}
|
}
|
||||||
else if (creature->mood == BORED_MOOD)
|
else if (creature->mood == BORED_MOOD)
|
||||||
item->goalAnimState = 9;
|
item->goalAnimState = STATE_CROUCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
creature->maximumTurn = ANGLE(5);
|
creature->maximumTurn = RUN_TURN;
|
||||||
tilt = angle;
|
tilt = angle;
|
||||||
|
|
||||||
if (info.ahead && info.distance < SQUARE(1536))
|
if (info.ahead && info.distance < ATTACK_RANGE)
|
||||||
{
|
{
|
||||||
if (info.distance > (SQUARE(1536) / 2) &&
|
if (info.distance > (ATTACK_RANGE / 2) &&
|
||||||
(info.enemyFacing > FRONT_ARC || info.enemyFacing < -FRONT_ARC))
|
(info.enemyFacing > FRONT_ARC || info.enemyFacing < -FRONT_ARC))
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 5;
|
item->requiredAnimState = STATE_STALK;
|
||||||
item->goalAnimState = 9;
|
item->goalAnimState = STATE_CROUCH;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 6;
|
item->goalAnimState = STATE_ATTACK;
|
||||||
item->requiredAnimState = 0;
|
item->requiredAnimState = STATE_EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (creature->mood == STALK_MOOD && info.distance < SQUARE(3072))
|
else if (creature->mood == STALK_MOOD && info.distance < STALK_RANGE)
|
||||||
{
|
{
|
||||||
item->requiredAnimState = 5;
|
item->requiredAnimState = STATE_STALK;
|
||||||
item->goalAnimState = 9;
|
item->goalAnimState = STATE_CROUCH;
|
||||||
}
|
}
|
||||||
else if (creature->mood == BORED_MOOD)
|
else if (creature->mood == BORED_MOOD)
|
||||||
item->goalAnimState = 9;
|
item->goalAnimState = STATE_CROUCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case STATE_ATTACK:
|
||||||
tilt = angle;
|
tilt = angle;
|
||||||
if (!item->requiredAnimState && (item->touchBits & 0x774F))
|
if (!item->requiredAnimState && (item->touchBits & TOUCH))
|
||||||
{
|
{
|
||||||
CreatureEffect(item, &wolfBite, DoBloodSplat);
|
CreatureEffect(item, &wolfBite, DoBloodSplat);
|
||||||
LaraItem->hitPoints -= 50;
|
LaraItem->hitPoints -= LUNGE_DAMAGE;
|
||||||
LaraItem->hitStatus = true;
|
LaraItem->hitStatus = true;
|
||||||
item->requiredAnimState = 3;
|
item->requiredAnimState = STATE_RUN;
|
||||||
}
|
}
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_RUN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 12:
|
case 12:
|
||||||
if (!item->requiredAnimState && (item->touchBits & 0x774F) && info.ahead)
|
if (!item->requiredAnimState && (item->touchBits & TOUCH) && info.ahead)
|
||||||
{
|
{
|
||||||
CreatureEffect(item, &wolfBite, DoBloodSplat);
|
CreatureEffect(item, &wolfBite, DoBloodSplat);
|
||||||
LaraItem->hitPoints -= 100;
|
LaraItem->hitPoints -= BITE_DAMAGE;
|
||||||
LaraItem->hitStatus = true;
|
LaraItem->hitStatus = true;
|
||||||
item->requiredAnimState = 9;
|
item->requiredAnimState = STATE_CROUCH;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -182,4 +219,4 @@ void WolfControl(short itemNum)
|
||||||
CreatureTilt(item, tilt);
|
CreatureTilt(item, tilt);
|
||||||
CreatureJoint(item, 0, head);
|
CreatureJoint(item, 0, head);
|
||||||
CreatureAnimation(itemNum, angle, tilt);
|
CreatureAnimation(itemNum, angle, tilt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void InitialiseWolf(short itemNum);
|
void InitialiseWolf(short itemNum);
|
||||||
void WolfControl(short itemNum);
|
void WolfControl(short itemNum);
|
||||||
|
|
|
@ -26,7 +26,7 @@ static void StartBaddy(OBJECT_INFO* obj)
|
||||||
obj->initialise = InitialiseWolf;
|
obj->initialise = InitialiseWolf;
|
||||||
obj->control = WolfControl;
|
obj->control = WolfControl;
|
||||||
obj->collision = CreatureCollision;
|
obj->collision = CreatureCollision;
|
||||||
obj->shadowSize = 128;
|
obj->shadowSize = UNIT_SHADOW / 2;
|
||||||
obj->hitPoints = 6;
|
obj->hitPoints = 6;
|
||||||
obj->pivotLength = 375;
|
obj->pivotLength = 375;
|
||||||
obj->radius = 340;
|
obj->radius = 340;
|
||||||
|
@ -152,7 +152,13 @@ static void StartBaddy(OBJECT_INFO* obj)
|
||||||
|
|
||||||
static void StartObject(OBJECT_INFO* obj)
|
static void StartObject(OBJECT_INFO* obj)
|
||||||
{
|
{
|
||||||
|
obj = &Objects[ID_BACON_REFERENCE];
|
||||||
|
if (obj->loaded)
|
||||||
|
{
|
||||||
|
obj->drawRoutine = nullptr;
|
||||||
|
obj->collision = AIPickupCollision;
|
||||||
|
obj->hitPoints = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StartTrap(OBJECT_INFO* obj)
|
static void StartTrap(OBJECT_INFO* obj)
|
||||||
|
|
|
@ -12,7 +12,18 @@
|
||||||
|
|
||||||
BITE_INFO TroopsBite1 = { 0, 300, 64, 7 };
|
BITE_INFO TroopsBite1 = { 0, 300, 64, 7 };
|
||||||
|
|
||||||
|
#define STATE_TROOPS_STOP 1
|
||||||
|
#define STATE_TROOPS_WALK 2
|
||||||
|
#define STATE_TROOPS_RUN 3
|
||||||
|
#define STATE_TROOPS_ATTACK1 5
|
||||||
|
#define STATE_TROOPS_ATTACK2 6
|
||||||
|
#define STATE_TROOPS_DEATH 7
|
||||||
|
#define STATE_TROOPS_AIM1 8
|
||||||
|
#define STATE_TROOPS_AIM2 9
|
||||||
|
#define STATE_TROOPS_AIM3 10
|
||||||
|
#define STATE_TROOPS_ATTACK3 11
|
||||||
|
#define STATE_TROOPS_KILLED_BY_SCORPION 15
|
||||||
|
#define STATE_TROOPS_ATTACKED_BY_SCORPION 16
|
||||||
|
|
||||||
void InitialiseTroops(short itemNumber)
|
void InitialiseTroops(short itemNumber)
|
||||||
{
|
{
|
||||||
|
@ -22,12 +33,12 @@ void InitialiseTroops(short itemNumber)
|
||||||
|
|
||||||
if (item->triggerFlags == 1)
|
if (item->triggerFlags == 1)
|
||||||
{
|
{
|
||||||
item->goalAnimState = item->currentAnimState = 16;
|
item->goalAnimState = item->currentAnimState = STATE_TROOPS_ATTACKED_BY_SCORPION;
|
||||||
item->animNumber = Objects[item->objectNumber].animIndex + 27;
|
item->animNumber = Objects[item->objectNumber].animIndex + 27;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = item->currentAnimState = 1;
|
item->goalAnimState = item->currentAnimState = STATE_TROOPS_STOP;
|
||||||
item->animNumber = Objects[item->objectNumber].animIndex + 12;
|
item->animNumber = Objects[item->objectNumber].animIndex + 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,18 +50,23 @@ void TroopsControl(short itemNumber)
|
||||||
if (!CreatureActive(itemNumber))
|
if (!CreatureActive(itemNumber))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
&g_Level.Items[32].currentAnimState;
|
||||||
|
|
||||||
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
||||||
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
||||||
OBJECT_INFO* obj = &Objects[item->objectNumber];
|
OBJECT_INFO* obj = &Objects[item->objectNumber];
|
||||||
|
|
||||||
short angle = 0;
|
short angle = 0;
|
||||||
short tilt = 0;
|
short tilt = 0;
|
||||||
short joint0 = 0;
|
short joint0 = 0;
|
||||||
short joint1 = 0;
|
short joint1 = 0;
|
||||||
short joint2 = 0;
|
short joint2 = 0;
|
||||||
short rot = 0;
|
short rot = 0;
|
||||||
|
|
||||||
int dx = 0;
|
int dx = 0;
|
||||||
int dy = 0;
|
int dy = 0;
|
||||||
int dz = 0;
|
int dz = 0;
|
||||||
|
|
||||||
int distance = 0;
|
int distance = 0;
|
||||||
|
|
||||||
if (item->firedWeapon)
|
if (item->firedWeapon)
|
||||||
|
@ -69,14 +85,17 @@ void TroopsControl(short itemNumber)
|
||||||
|
|
||||||
if (item->hitPoints <= 0)
|
if (item->hitPoints <= 0)
|
||||||
{
|
{
|
||||||
if (item->currentAnimState != 7 && item->currentAnimState != 15)
|
if (item->currentAnimState != STATE_TROOPS_DEATH
|
||||||
|
&& item->currentAnimState != STATE_TROOPS_KILLED_BY_SCORPION)
|
||||||
{
|
{
|
||||||
if (creature->enemy && creature->enemy->objectNumber == ID_BIG_SCORPION && (item->itemFlags[0] < 80))
|
if (creature->enemy
|
||||||
|
&& creature->enemy->objectNumber == ID_BIG_SCORPION
|
||||||
|
&& item->itemFlags[0] < 80)
|
||||||
{
|
{
|
||||||
if (creature->enemy->animNumber == Objects[ID_BIG_SCORPION].animIndex + 6)
|
if (creature->enemy->animNumber == Objects[ID_BIG_SCORPION].animIndex + 6)
|
||||||
{
|
{
|
||||||
item->animNumber = Objects[item->objectNumber].animIndex + 23;
|
item->animNumber = Objects[item->objectNumber].animIndex + 23;
|
||||||
if (item->currentAnimState == 16)
|
if (item->currentAnimState == STATE_TROOPS_ATTACKED_BY_SCORPION)
|
||||||
{
|
{
|
||||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase += 37;
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase += 37;
|
||||||
}
|
}
|
||||||
|
@ -84,8 +103,8 @@ void TroopsControl(short itemNumber)
|
||||||
{
|
{
|
||||||
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
||||||
}
|
}
|
||||||
item->goalAnimState = 15;
|
item->goalAnimState = STATE_TROOPS_KILLED_BY_SCORPION;
|
||||||
item->currentAnimState = 15;
|
item->currentAnimState = STATE_TROOPS_KILLED_BY_SCORPION;
|
||||||
|
|
||||||
angle = 0;
|
angle = 0;
|
||||||
|
|
||||||
|
@ -107,7 +126,7 @@ void TroopsControl(short itemNumber)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->animNumber = Objects[item->objectNumber].animIndex + 19;
|
item->animNumber = Objects[item->objectNumber].animIndex + 19;
|
||||||
item->currentAnimState = 7;
|
item->currentAnimState = STATE_TROOPS_DEATH;
|
||||||
item->frameNumber = g_Level.Anims[item->frameNumber].frameBase;
|
item->frameNumber = g_Level.Anims[item->frameNumber].frameBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +156,7 @@ void TroopsControl(short itemNumber)
|
||||||
dx = currentItem->pos.xPos - item->pos.xPos;
|
dx = currentItem->pos.xPos - item->pos.xPos;
|
||||||
dy = currentItem->pos.yPos - item->pos.yPos;
|
dy = currentItem->pos.yPos - item->pos.yPos;
|
||||||
dz = currentItem->pos.zPos - item->pos.zPos;
|
dz = currentItem->pos.zPos - item->pos.zPos;
|
||||||
distance = dx * dx + dy * dy + dz * dz;
|
distance = SQUARE(dx) + SQUARE(dy) + SQUARE(dz);
|
||||||
|
|
||||||
if (distance < minDistance)
|
if (distance < minDistance)
|
||||||
{
|
{
|
||||||
|
@ -149,11 +168,10 @@ void TroopsControl(short itemNumber)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (creature->hurtByLara && item->currentAnimState != 16)
|
if (creature->hurtByLara && item->currentAnimState != STATE_TROOPS_ATTACKED_BY_SCORPION)
|
||||||
creature->enemy = LaraItem;
|
creature->enemy = LaraItem;
|
||||||
|
|
||||||
AI_INFO info;
|
AI_INFO info;
|
||||||
|
|
||||||
CreatureAIInfo(item, &info);
|
CreatureAIInfo(item, &info);
|
||||||
|
|
||||||
int distance = 0;
|
int distance = 0;
|
||||||
|
@ -166,18 +184,20 @@ void TroopsControl(short itemNumber)
|
||||||
{
|
{
|
||||||
dx = LaraItem->pos.xPos - item->pos.xPos;
|
dx = LaraItem->pos.xPos - item->pos.xPos;
|
||||||
dz = LaraItem->pos.zPos - item->pos.zPos;
|
dz = LaraItem->pos.zPos - item->pos.zPos;
|
||||||
distance = dx * dx + dz * dz;
|
distance = SQUARE(dx) + SQUARE(dz);
|
||||||
rot = phd_atan(dz, dx) - item->pos.yRot;
|
rot = phd_atan(dz, dx) - item->pos.yRot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!creature->hurtByLara && creature->enemy == LaraItem)
|
||||||
|
creature->enemy = NULL;
|
||||||
|
|
||||||
GetCreatureMood(item, &info, TIMID);
|
GetCreatureMood(item, &info, TIMID);
|
||||||
|
CreatureMood(item, &info, TIMID);
|
||||||
|
|
||||||
// Vehicle handling
|
// Vehicle handling
|
||||||
if (Lara.Vehicle != NO_ITEM && info.bite)
|
if (Lara.Vehicle != NO_ITEM && info.bite)
|
||||||
creature->mood == ESCAPE_MOOD;
|
creature->mood == ESCAPE_MOOD;
|
||||||
|
|
||||||
CreatureMood(item, &info, TIMID);
|
|
||||||
|
|
||||||
angle = CreatureTurn(item, creature->maximumTurn);
|
angle = CreatureTurn(item, creature->maximumTurn);
|
||||||
|
|
||||||
if (item->hitStatus)
|
if (item->hitStatus)
|
||||||
|
@ -185,7 +205,7 @@ void TroopsControl(short itemNumber)
|
||||||
|
|
||||||
switch (item->currentAnimState)
|
switch (item->currentAnimState)
|
||||||
{
|
{
|
||||||
case 1:
|
case STATE_TROOPS_STOP:
|
||||||
creature->flags = 0;
|
creature->flags = 0;
|
||||||
creature->maximumTurn = 0;
|
creature->maximumTurn = 0;
|
||||||
joint2 = rot;
|
joint2 = rot;
|
||||||
|
@ -194,7 +214,7 @@ void TroopsControl(short itemNumber)
|
||||||
{
|
{
|
||||||
if (abs(info.angle) >= ANGLE(10))
|
if (abs(info.angle) >= ANGLE(10))
|
||||||
{
|
{
|
||||||
if ((info.angle & 0x8000u) == 0)
|
if (info.angle >= 0)
|
||||||
{
|
{
|
||||||
item->pos.yRot += ANGLE(10);
|
item->pos.yRot += ANGLE(10);
|
||||||
}
|
}
|
||||||
|
@ -214,22 +234,22 @@ void TroopsControl(short itemNumber)
|
||||||
joint2 = AIGuard(creature);
|
joint2 = AIGuard(creature);
|
||||||
if (!(byte)GetRandomControl())
|
if (!(byte)GetRandomControl())
|
||||||
{
|
{
|
||||||
if (item->currentAnimState == 1)
|
if (item->currentAnimState == STATE_TROOPS_STOP)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 4;
|
item->goalAnimState = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_TROOPS_STOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (item->aiBits & PATROL1)
|
else if (item->aiBits & PATROL1)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = STATE_TROOPS_WALK;
|
||||||
joint2 = 0;
|
joint2 = 0;
|
||||||
}
|
}
|
||||||
else if (creature->mood == ESCAPE_MOOD)
|
else if (creature->mood == ESCAPE_MOOD)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_TROOPS_RUN;
|
||||||
}
|
}
|
||||||
else if (Targetable(item, &info))
|
else if (Targetable(item, &info))
|
||||||
{
|
{
|
||||||
|
@ -237,16 +257,16 @@ void TroopsControl(short itemNumber)
|
||||||
{
|
{
|
||||||
if (GetRandomControl() >= 0x4000)
|
if (GetRandomControl() >= 0x4000)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 10;
|
item->goalAnimState = STATE_TROOPS_AIM3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 8;
|
item->goalAnimState = STATE_TROOPS_AIM1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = STATE_TROOPS_WALK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -256,66 +276,67 @@ void TroopsControl(short itemNumber)
|
||||||
{
|
{
|
||||||
if (!creature->mood || info.distance <= SQUARE(2048))
|
if (!creature->mood || info.distance <= SQUARE(2048))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = STATE_TROOPS_WALK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_TROOPS_RUN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_TROOPS_STOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case STATE_TROOPS_WALK:
|
||||||
creature->flags = 0;
|
creature->flags = 0;
|
||||||
joint2 = rot;
|
joint2 = rot;
|
||||||
creature->maximumTurn = ANGLE(5);
|
creature->maximumTurn = ANGLE(5);
|
||||||
|
|
||||||
if (item->aiBits & PATROL1)
|
if (item->aiBits & PATROL1)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = STATE_TROOPS_WALK;
|
||||||
}
|
}
|
||||||
else if (creature->mood == 2)
|
else if (creature->mood == ESCAPE_MOOD)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_TROOPS_RUN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((item->aiBits & GUARD) || (item->aiBits & GUARD) &&
|
if ((item->aiBits & GUARD) || (item->aiBits & FOLLOW) &&
|
||||||
(creature->reachedGoal || distance > SQUARE(2048)))
|
(creature->reachedGoal || distance > SQUARE(2048)))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_TROOPS_STOP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Targetable(item, &info))
|
if (Targetable(item, &info))
|
||||||
{
|
{
|
||||||
if (info.distance < SQUARE(3072) || info.enemyZone != info.zoneNumber)
|
if (info.distance < SQUARE(3072) || info.enemyZone != info.zoneNumber)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_TROOPS_STOP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
item->goalAnimState = 9;
|
item->goalAnimState = STATE_TROOPS_AIM2;
|
||||||
}
|
}
|
||||||
else if (creature->mood)
|
else if (creature->mood)
|
||||||
{
|
{
|
||||||
if (info.distance > SQUARE(2048))
|
if (info.distance > SQUARE(2048))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 3;
|
item->goalAnimState = STATE_TROOPS_RUN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (info.ahead)
|
else if (info.ahead)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_TROOPS_STOP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case STATE_TROOPS_RUN:
|
||||||
if (info.ahead)
|
if (info.ahead)
|
||||||
{
|
{
|
||||||
joint2 = info.angle;
|
joint2 = info.angle;
|
||||||
|
@ -326,20 +347,21 @@ void TroopsControl(short itemNumber)
|
||||||
if ((item->aiBits & GUARD) || (item->aiBits & FOLLOW) &&
|
if ((item->aiBits & GUARD) || (item->aiBits & FOLLOW) &&
|
||||||
(creature->reachedGoal || distance > SQUARE(2048)))
|
(creature->reachedGoal || distance > SQUARE(2048)))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = STATE_TROOPS_WALK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (creature->mood != ESCAPE_MOOD)
|
if (creature->mood != ESCAPE_MOOD)
|
||||||
{
|
{
|
||||||
if (Targetable(item, &info))
|
if (Targetable(item, &info))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = STATE_TROOPS_WALK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!creature->mood || creature->mood == STALK_MOOD &&
|
if (creature->mood == BORED_MOOD || creature->mood == STALK_MOOD &&
|
||||||
!(item->aiBits & FOLLOW) && info.distance < SQUARE(2048))
|
!(item->aiBits & FOLLOW) && info.distance < SQUARE(2048))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = STATE_TROOPS_WALK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,22 +377,22 @@ void TroopsControl(short itemNumber)
|
||||||
joint2 = AIGuard(creature);
|
joint2 = AIGuard(creature);
|
||||||
if (!(byte)GetRandomControl())
|
if (!(byte)GetRandomControl())
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_TROOPS_STOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Targetable(item, &info))
|
else if (Targetable(item, &info))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 5;
|
item->goalAnimState = STATE_TROOPS_ATTACK1;
|
||||||
}
|
}
|
||||||
else if (creature->mood || !info.ahead)
|
else if (creature->mood || !info.ahead)
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_TROOPS_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case STATE_TROOPS_ATTACK1:
|
||||||
case 6:
|
case STATE_TROOPS_ATTACK2:
|
||||||
if (info.ahead)
|
if (info.ahead)
|
||||||
{
|
{
|
||||||
joint0 = info.angle;
|
joint0 = info.angle;
|
||||||
|
@ -389,8 +411,8 @@ void TroopsControl(short itemNumber)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case STATE_TROOPS_AIM1:
|
||||||
case 10:
|
case STATE_TROOPS_AIM3:
|
||||||
creature->flags = 0;
|
creature->flags = 0;
|
||||||
|
|
||||||
if (info.ahead)
|
if (info.ahead)
|
||||||
|
@ -400,17 +422,17 @@ void TroopsControl(short itemNumber)
|
||||||
|
|
||||||
if (Targetable(item, &info))
|
if (Targetable(item, &info))
|
||||||
{
|
{
|
||||||
item->goalAnimState = item->currentAnimState != 8 ? 11 : 5;
|
item->goalAnimState = item->currentAnimState != STATE_TROOPS_AIM1 ? STATE_TROOPS_ATTACK1 : STATE_TROOPS_ATTACK3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_TROOPS_STOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case STATE_TROOPS_AIM2:
|
||||||
creature->flags = 0;
|
creature->flags = 0;
|
||||||
|
|
||||||
if (info.ahead)
|
if (info.ahead)
|
||||||
|
@ -420,23 +442,23 @@ void TroopsControl(short itemNumber)
|
||||||
|
|
||||||
if (Targetable(item, &info))
|
if (Targetable(item, &info))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 6;
|
item->goalAnimState = STATE_TROOPS_ATTACK2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->goalAnimState = 2;
|
item->goalAnimState = STATE_TROOPS_WALK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 11:
|
case STATE_TROOPS_ATTACK3:
|
||||||
if (item->goalAnimState != 1
|
if (item->goalAnimState != STATE_TROOPS_STOP
|
||||||
&& (creature->mood == ESCAPE_MOOD ||
|
&& (creature->mood == ESCAPE_MOOD ||
|
||||||
info.distance > SQUARE(3072) ||
|
info.distance > SQUARE(3072) ||
|
||||||
!Targetable(item, &info)))
|
!Targetable(item, &info)))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 1;
|
item->goalAnimState = STATE_TROOPS_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.ahead)
|
if (info.ahead)
|
||||||
|
@ -457,11 +479,11 @@ void TroopsControl(short itemNumber)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16:
|
case STATE_TROOPS_ATTACKED_BY_SCORPION:
|
||||||
creature->maximumTurn = 0;
|
creature->maximumTurn = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 17u:
|
case 17:
|
||||||
if (!WeaponEnemyTimer && !(GetRandomControl() & 0x7F))
|
if (!WeaponEnemyTimer && !(GetRandomControl() & 0x7F))
|
||||||
{
|
{
|
||||||
item->goalAnimState = 4;
|
item->goalAnimState = 4;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,6 +22,10 @@ void InitialiseRaisingBlock(short itemNumber)
|
||||||
AddActiveItem(itemNumber);
|
AddActiveItem(itemNumber);
|
||||||
item->status = ITEM_ACTIVE;
|
item->status = ITEM_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get height from animations
|
||||||
|
ANIM_FRAME* frame = &g_Level.Frames[g_Level.Anims[Objects[item->objectNumber].animIndex].framePtr];
|
||||||
|
item->itemFlags[7] = (short)abs(frame->boundingBox.Y1 - frame->boundingBox.Y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlRaisingBlock(short itemNumber)
|
void ControlRaisingBlock(short itemNumber)
|
||||||
|
@ -36,20 +40,20 @@ void ControlRaisingBlock(short itemNumber)
|
||||||
{
|
{
|
||||||
if (item->triggerFlags == -1)
|
if (item->triggerFlags == -1)
|
||||||
{
|
{
|
||||||
AlterFloorHeight(item, -255);
|
//AlterFloorHeight(item, -255);
|
||||||
}
|
}
|
||||||
else if (item->triggerFlags == -3)
|
else if (item->triggerFlags == -3)
|
||||||
{
|
{
|
||||||
AlterFloorHeight(item, -1023);
|
//AlterFloorHeight(item, -1023);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AlterFloorHeight(item, -1024);
|
//AlterFloorHeight(item, -item->itemFlags[7]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AlterFloorHeight(item, -2048);
|
//AlterFloorHeight(item, -item->itemFlags[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
item->itemFlags[2] = 1;
|
item->itemFlags[2] = 1;
|
||||||
|
@ -89,22 +93,22 @@ void ControlRaisingBlock(short itemNumber)
|
||||||
{
|
{
|
||||||
if (item->triggerFlags == -1)
|
if (item->triggerFlags == -1)
|
||||||
{
|
{
|
||||||
AlterFloorHeight(item, 255);
|
//AlterFloorHeight(item, 255);
|
||||||
item->itemFlags[2] = 0;
|
item->itemFlags[2] = 0;
|
||||||
}
|
}
|
||||||
else if (item->triggerFlags == -3)
|
else if (item->triggerFlags == -3)
|
||||||
{
|
{
|
||||||
AlterFloorHeight(item, 1023);
|
//AlterFloorHeight(item, 1023);
|
||||||
item->itemFlags[2] = 0;
|
item->itemFlags[2] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AlterFloorHeight(item, 1024);
|
//AlterFloorHeight(item, item->itemFlags[7]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AlterFloorHeight(item, 2048);
|
//AlterFloorHeight(item, item->itemFlags[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
item->itemFlags[2] = 0;
|
item->itemFlags[2] = 0;
|
||||||
|
@ -129,4 +133,26 @@ void ControlRaisingBlock(short itemNumber)
|
||||||
|
|
||||||
item->itemFlags[1] -= 64;
|
item->itemFlags[1] -= 64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<std::optional<int>, bool> RaisingBlockFloor(short itemNumber, int x, int y, int z)
|
||||||
|
{
|
||||||
|
const auto& item = g_Level.Items[itemNumber];
|
||||||
|
if (abs(item.pos.xPos - x) <= SECTOR(1) / 2 && abs(item.pos.zPos - z) <= SECTOR(1) / 2)
|
||||||
|
{
|
||||||
|
auto height = item.pos.yPos - item.itemFlags[7] * item.itemFlags[1] / 4096;
|
||||||
|
return std::make_tuple(std::optional{height}, y > height && y < item.pos.yPos);
|
||||||
|
}
|
||||||
|
return std::make_tuple(std::nullopt, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<std::optional<int>, bool> RaisingBlockCeiling(short itemNumber, int x, int y, int z)
|
||||||
|
{
|
||||||
|
const auto& item = g_Level.Items[itemNumber];
|
||||||
|
if (abs(item.pos.xPos - x) <= SECTOR(1) / 2 && abs(item.pos.zPos - z) <= SECTOR(1) / 2)
|
||||||
|
{
|
||||||
|
auto height = item.pos.yPos - item.itemFlags[7] * item.itemFlags[1] / 4096;
|
||||||
|
return std::make_tuple(std::optional{item.pos.yPos}, y > height && y < item.pos.yPos);
|
||||||
|
}
|
||||||
|
return std::make_tuple(std::nullopt, false);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void InitialiseRaisingBlock(short itemNumber);
|
void InitialiseRaisingBlock(short itemNumber);
|
||||||
void ControlRaisingBlock(short itemNumber);
|
void ControlRaisingBlock(short itemNumber);
|
||||||
|
std::tuple<std::optional<int>, bool> RaisingBlockFloor(short itemNumber, int x, int y, int z);
|
||||||
|
std::tuple<std::optional<int>, bool> RaisingBlockCeiling(short itemNumber, int x, int y, int z);
|
||||||
|
|
|
@ -903,6 +903,8 @@ static void StartObject(OBJECT_INFO *obj)
|
||||||
{
|
{
|
||||||
obj->initialise = InitialiseRaisingBlock;
|
obj->initialise = InitialiseRaisingBlock;
|
||||||
obj->control = ControlRaisingBlock;
|
obj->control = ControlRaisingBlock;
|
||||||
|
obj->floor = RaisingBlockFloor;
|
||||||
|
obj->ceiling = RaisingBlockCeiling;
|
||||||
obj->saveFlags = true;
|
obj->saveFlags = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -805,6 +805,7 @@ typedef enum GAME_OBJECT_ID
|
||||||
ID_WATERFALLSS1,
|
ID_WATERFALLSS1,
|
||||||
ID_WATERFALLSS2,
|
ID_WATERFALLSS2,
|
||||||
ID_FISHTANK,
|
ID_FISHTANK,
|
||||||
|
ID_BACON_REFERENCE,
|
||||||
|
|
||||||
ID_MESHSWAP1 = 1100,
|
ID_MESHSWAP1 = 1100,
|
||||||
ID_MESHSWAP2,
|
ID_MESHSWAP2,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue