mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-15 17:44:25 +02:00
#14 giant mutant AI (WIP)
This commit is contained in:
@@ -1107,8 +1107,10 @@ struct Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void update() {
|
virtual void update() {
|
||||||
updateAnimation(true);
|
if (explodeMask)
|
||||||
updateExplosion();
|
updateExplosion();
|
||||||
|
else
|
||||||
|
updateAnimation(true);
|
||||||
updateLights(true);
|
updateLights(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
158
src/enemy.h
158
src/enemy.h
@@ -1565,6 +1565,8 @@ struct Bat : Enemy {
|
|||||||
#define REX_TURN_FAST (DEG2RAD * 120)
|
#define REX_TURN_FAST (DEG2RAD * 120)
|
||||||
#define REX_TURN_SLOW (DEG2RAD * 60)
|
#define REX_TURN_SLOW (DEG2RAD * 60)
|
||||||
#define REX_DAMAGE 1000
|
#define REX_DAMAGE 1000
|
||||||
|
#define REX_DAMAGE_WALK 1
|
||||||
|
#define REX_DAMAGE_RUN 10
|
||||||
|
|
||||||
struct Rex : Enemy {
|
struct Rex : Enemy {
|
||||||
|
|
||||||
@@ -1620,7 +1622,7 @@ struct Rex : Enemy {
|
|||||||
if (mood == MOOD_SLEEP || walk) return STATE_WALK;
|
if (mood == MOOD_SLEEP || walk) return STATE_WALK;
|
||||||
return STATE_RUN;
|
return STATE_RUN;
|
||||||
case STATE_WALK :
|
case STATE_WALK :
|
||||||
if (mask) target->hit(1, this);
|
if (mask) target->hit(REX_DAMAGE_WALK, this);
|
||||||
if (mood != MOOD_SLEEP && !walk) return STATE_STOP;
|
if (mood != MOOD_SLEEP && !walk) return STATE_STOP;
|
||||||
if (targetInView && randf() < 0.015f) {
|
if (targetInView && randf() < 0.015f) {
|
||||||
nextState = STATE_BAWL;
|
nextState = STATE_BAWL;
|
||||||
@@ -1628,7 +1630,7 @@ struct Rex : Enemy {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_RUN :
|
case STATE_RUN :
|
||||||
if (mask) target->hit(10, this);
|
if (mask) target->hit(REX_DAMAGE_RUN, this);
|
||||||
if ((targetCanAttack && targetDist < REX_DIST_WALK) || walk)
|
if ((targetCanAttack && targetDist < REX_DIST_WALK) || walk)
|
||||||
return STATE_STOP;
|
return STATE_STOP;
|
||||||
if (targetInView && mood != MOOD_ESCAPE && randf() < 0.015f) {
|
if (targetInView && mood != MOOD_ESCAPE && randf() < 0.015f) {
|
||||||
@@ -1973,49 +1975,60 @@ struct Mutant : Enemy {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define GIANT_MUTANT_TURN_SLOW (DEG2RAD * 90)
|
||||||
|
#define GIANT_MUTANT_MAX_ANGLE (DEG2RAD * 45)
|
||||||
|
#define GIANT_MUTANT_DAMAGE 500
|
||||||
|
#define GIANT_MUTANT_DAMAGE_WALK 5
|
||||||
|
#define GIANT_MUTANT_DIST_ATTACK 2600
|
||||||
|
#define GIANT_MUTANT_DIST_FATAL 2250
|
||||||
|
|
||||||
struct GiantMutant : Enemy {
|
struct GiantMutant : Enemy {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
STATE_STOP = 1,
|
HIT_MASK_HAND = 0x3FF8000,
|
||||||
STATE_BORN = 8,
|
HIT_MASK_HANDS = 0x3FFFFF0,
|
||||||
STATE_FALL = 9,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GiantMutant(IGame *game, int entity) : Enemy(game, entity, 500, 341, 375.0f, 1.0f) {
|
enum {
|
||||||
hitSound = TR::SND_HIT_MUTANT;
|
ANIM_DEATH = 13,
|
||||||
stand = STAND_AIR;
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STATE_NONE,
|
||||||
|
STATE_STOP,
|
||||||
|
STATE_TURN_LEFT,
|
||||||
|
STATE_TURN_RIGHT,
|
||||||
|
STATE_ATTACK_1,
|
||||||
|
STATE_ATTACK_2,
|
||||||
|
STATE_ATTACK_3,
|
||||||
|
STATE_WALK,
|
||||||
|
STATE_BORN,
|
||||||
|
STATE_FALL,
|
||||||
|
STATE_UNUSED,
|
||||||
|
STATE_FATAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
GiantMutant(IGame *game, int entity) : Enemy(game, entity, 1/*500*/, 341, 375.0f, 1.0f) {
|
||||||
|
hitSound = TR::SND_HIT_MUTANT;
|
||||||
|
stand = STAND_AIR;
|
||||||
jointChest = -1;
|
jointChest = -1;
|
||||||
jointHead = 3;
|
jointHead = 3;
|
||||||
rangeHead = vec4(-0.5f, 0.5f, -0.5f, 0.5f) * PI;
|
rangeHead = vec4(-0.5f, 0.5f, -0.5f, 0.5f) * PI;
|
||||||
invertAim = true;
|
invertAim = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int getStateGround() {
|
|
||||||
if (!think(true))
|
|
||||||
return state;
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void update() {
|
void update() {
|
||||||
bool exploded = explodeMask != 0;
|
bool exploded = explodeMask != 0;
|
||||||
|
|
||||||
if (health <= 0.0f && !exploded) {
|
Enemy::update();
|
||||||
|
|
||||||
|
if (health <= 0.0f && !exploded && animation.index == ANIM_DEATH && flags.state == TR::Entity::asInactive) {
|
||||||
|
flags.state = TR::Entity::asActive;
|
||||||
game->playSound(TR::SND_MUTANT_DEATH, pos, 0);
|
game->playSound(TR::SND_MUTANT_DEATH, pos, 0);
|
||||||
explode(0xffffffff);
|
explode(0xffffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case STATE_BORN : animation.setState(STATE_FALL); break;
|
|
||||||
case STATE_FALL :
|
|
||||||
if (stand == STAND_GROUND) {
|
|
||||||
animation.setState(STATE_STOP);
|
|
||||||
game->shakeCamera(5.0f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Enemy::update();
|
|
||||||
|
|
||||||
setOverrides(true, jointChest, jointHead);
|
setOverrides(true, jointChest, jointHead);
|
||||||
lookAt(target);
|
lookAt(target);
|
||||||
|
|
||||||
@@ -2025,6 +2038,97 @@ struct GiantMutant : Enemy {
|
|||||||
flags.invisible = true;
|
flags.invisible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int getStateAir() {
|
||||||
|
if (state == STATE_BORN)
|
||||||
|
return STATE_FALL;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int getStateGround() {
|
||||||
|
if (health <= 0)
|
||||||
|
return state;
|
||||||
|
|
||||||
|
if (!think(true))
|
||||||
|
return state;
|
||||||
|
|
||||||
|
int mask = collide(target);
|
||||||
|
|
||||||
|
if (mask) target->hit(GIANT_MUTANT_DAMAGE_WALK, this);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case STATE_FALL :
|
||||||
|
animation.setState(STATE_STOP);
|
||||||
|
game->shakeCamera(5.0f);
|
||||||
|
break;
|
||||||
|
case STATE_STOP :
|
||||||
|
flags.unused = false;
|
||||||
|
//if (targetAngle > GIANT_MUTANT_MAX_ANGLE) return STATE_TURN_RIGHT;
|
||||||
|
//if (targetAngle < -GIANT_MUTANT_MAX_ANGLE) return STATE_TURN_LEFT;
|
||||||
|
if (targetDist < GIANT_MUTANT_DIST_ATTACK) {
|
||||||
|
if (target->health <= GIANT_MUTANT_DAMAGE) {
|
||||||
|
if (targetDist < GIANT_MUTANT_DIST_FATAL)
|
||||||
|
return STATE_ATTACK_3;
|
||||||
|
} else
|
||||||
|
return ((rand() % 2) ? STATE_ATTACK_1 : STATE_ATTACK_2);
|
||||||
|
}
|
||||||
|
return STATE_WALK;
|
||||||
|
case STATE_WALK :
|
||||||
|
if (targetDist < GIANT_MUTANT_DIST_ATTACK ||
|
||||||
|
targetAngle > GIANT_MUTANT_MAX_ANGLE ||
|
||||||
|
targetAngle < -GIANT_MUTANT_MAX_ANGLE)
|
||||||
|
return STATE_STOP;
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
case STATE_TURN_RIGHT :
|
||||||
|
if (targetAngle < GIANT_MUTANT_MAX_ANGLE)
|
||||||
|
return STATE_STOP;
|
||||||
|
break;
|
||||||
|
case STATE_TURN_LEFT :
|
||||||
|
if (targetAngle > -GIANT_MUTANT_MAX_ANGLE)
|
||||||
|
return STATE_STOP;
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case STATE_ATTACK_1 :
|
||||||
|
case STATE_ATTACK_2 :
|
||||||
|
if (!flags.unused && (
|
||||||
|
(state == STATE_ATTACK_1 && (mask & HIT_MASK_HAND)) ||
|
||||||
|
(state == STATE_ATTACK_2 && (mask & HIT_MASK_HANDS)))) {
|
||||||
|
target->hit(GIANT_MUTANT_DAMAGE, this);
|
||||||
|
flags.unused = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
case STATE_IDLE :
|
||||||
|
if (nextState == STATE_NONE && (collide(target) & HIT_MASK)) {
|
||||||
|
bite(5, vec3(50.0f, 30.0f, 0.0f), 200);
|
||||||
|
nextState = STATE_STOP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
default : ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int getStateDeath() {
|
||||||
|
if (animation.index != ANIM_DEATH)
|
||||||
|
return animation.setAnim(ANIM_DEATH);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void updatePosition() {
|
||||||
|
float angleY = 0.0f;
|
||||||
|
getTargetInfo(0, NULL, NULL, &angleY, NULL);
|
||||||
|
|
||||||
|
if (state == STATE_TURN_LEFT || state == STATE_TURN_RIGHT || state == STATE_WALK || state == STATE_STOP)
|
||||||
|
turn(angleY, GIANT_MUTANT_TURN_SLOW);
|
||||||
|
|
||||||
|
Enemy::updatePosition();
|
||||||
|
//setOverrides(true, jointChest, jointHead);
|
||||||
|
//lookAt(target);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CENTAUR_TURN_FAST (DEG2RAD * 120)
|
#define CENTAUR_TURN_FAST (DEG2RAD * 120)
|
||||||
|
Reference in New Issue
Block a user