Nvm I Figured It Out It Was An Properly Coded Animation
#3514 posted by
ranger on 2024/12/26 20:18:23
Regarding Monster AI
#3515 posted by
ranger on 2024/12/26 20:30:09
I was wondering how to improve it?
like even simple pathfinding? (funnily enough the Vore bomb has better cornering than the actual vore/monsters)
or being able to go up and down reasonable heights?
and how to change the angle before the monster can shoot? because seems grunt can shoot the player before his barrel is even pointed straight at the player?
and how to change the max & min "tilt" angles for monsters? because want some monsters to not be able to shoot at enemies at are at too steep angles
(this is what i have so far but honestly i don't really know what i am doing - very new at this)
---
float CheckMonsterJump(entity self)
{
vector start, end;
// Check ground below
start = self.origin;
end = start;
end_z = end_z - 64; // Adjust drop height check
traceline(start, end, TRUE, self);
if (trace_fraction == 1)
return FALSE; // Too high to drop
if (trace_fraction < 1)
{
// Safe to drop - within acceptable height
if ((start_z - trace_endpos_z) <= 64)
{
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.velocity_z = -300; // Adjust drop speed
return TRUE;
}
}
// Check for jumpable height
start = self.origin;
end = start;
end_z = end_z + 32; // Jump check height
traceline(start, end, TRUE, self);
if (trace_fraction == 1)
{
self.velocity_z = 300; // Jump velocity
return TRUE;
}
return FALSE;
}
float TryAlternativePath(entity self)
{
vector dir, right, left, start, end;
float right_clear, left_clear;
// Get perpendicular directions
dir = normalize(self.enemy.origin - self.origin);
right = '0 0 0';
right_x = dir_y;
right_y = -dir_x;
left = -right;
// Check right path
start = self.origin;
end = start + (right * 128); // Adjust side check distance
traceline(start, end, TRUE, self);
right_clear = trace_fraction;
// Check left path
end = start + (left * 128);
traceline(start, end, TRUE, self);
left_clear = trace_fraction;
if (right_clear > left_clear)
{
self.ideal_yaw = vectoyaw(right);
return TRUE;
}
else if (left_clear > right_clear)
{
self.ideal_yaw = vectoyaw(left);
return TRUE;
}
return FALSE;
}
AI Tutorials
#3516 posted by
Preach on 2024/12/26 23:11:18
The gold standard for quake AI tutorials are found at the “AI cafe”.
https://web.archive.org/web/20080603081043/http://minion.planetquake.gamespy.com:80/tutorial/main.htm
There are several tutorials about navigation. But bear in mind there’s no magic wand to switch perfect navigation on. Most modern games get better navigation by tagging their levels with lots of metadata. In Quake levels that don’t have any, you’ll never get the same results.
Also tutorials there about aiming. But bear in mind that the current aiming for grunts is
1 aim exactly at the player
2 “correct” the aim to slightly behind where they are now
The point I’m circling is that fun AI needs to be imperfect. Making them shoot the way they are facing is a simple change. The hard part is making them rotate in such a way that they are still fun to fight when they fire straight.
Example Of Grunt's Aiming Leeway
#3517 posted by
ranger on 2024/12/27 04:28:04
https://imgur.com/a/DMMkpxO
if you sneakup behind grunt and he shoots, seems there's a 60d arc where it's considered "pointing the gun at you"
This also applies to enforcers and such
trying to reduce this to 5d or less
^It's FacingIdeal In AI.qc
#3518 posted by
ranger on 2024/12/27 05:22:16
delta
Bug Where Monster Turns Into Solid BSP But Is Still Alive
#3519 posted by
ranger on 2024/12/27 09:30:35
I was following one of the tutorials to add strafing to monsters,and i think it might have caused this bug - but i am not familiar with
nothing looks wrong?
have any ideas?
if it helps i vaguely remember reading that if a fiend kills a nuclear box, it took becomes treated as BSP event though it's still alive?
Nvm I Found The Cuase, It's FoundTarget ... I Can't See What's Wrong?
#3520 posted by
ranger on 2024/12/27 10:12:06
void () FoundTarget = //causes invincible bug??
{
local entity head; //new
local float alertRadius; //new
if ( (self.enemy.flags & FL_MONSTER) || (self.enemy.classname == "player") || (self.enemy.classname == "hologram") || (self.enemy.classname == "cbot") || (self.enemy.classname == "CBot_Create")) //new
{
// let other monsters see this monster for a while
sight_entity = self;
sight_entity_time = time;
}
self.show_hostile = time + 2.00; // was 1 wake up other monsters
alertRadius = 512; // Large radius for alert spread (default was usually 1000)?
// Alert all monsters in radius
head = findradius(self.origin, alertRadius);
while(head)
{
if (head.flags & FL_MONSTER)
{
if (head != self) // Don't alert self
{
// Make other monsters aggressive
head.show_hostile = time + 2;
head.enemy = self.enemy;
head.think = head.th_run;
head.nextthink = time + random() * 0.5; // Stagger response times
// Chance to alert even more distant monsters
//if (random() < 0.3) // 30% chance
// {
// head.noise_time = time + 2; // Make noise to attract others
// }
}
}
head = head.chain;
}
//end new
SightSound ();
HuntTarget ();
};