I am trying to figure out how to get a 100% solid method to know a bot recieved damage due falling. This is to let bots learn from their mistakes in some nodes.
I tried using the DMG_FALL and DMG_CRUSS bits, but they gave me no luck! I saw in the SDK only bits gets sent that require a HUD drawing on the client, this stinks!
My code:
Code:
// This message gets sent when the bots are getting damaged.
void BotClient_Valve_Damage(void *p, int bot_index)
{
//DebugOut("bot_client: BotClient_Valve_Damage()\n");
static int state = 0; // current state machine state
static int damage_armor;
static int damage_taken;
static int damage_bits; // type of damage being done
static Vector damage_origin;
if (state == 0)
{
state++;
damage_armor = *(int *)p;
}
else if (state == 1)
{
state++;
damage_taken = *(int *)p;
}
else if (state == 2)
{
state++;
damage_bits = *(int *)p;
}
else if (state == 3)
{
state++;
damage_origin.x = *(float *)p;
}
else if (state == 4)
{
state++;
damage_origin.y = *(float *)p;
}
else if (state == 5)
{
state = 0;
damage_origin.z = *(float *)p;
if ((damage_armor > 0) || (damage_taken > 0))
{
// Damage recieved:
// - when the prev node was higher (so we are sure we do FIX the correct nodes!)
// we fix it (only when dist > 90)
cBot *pBot = &bots[bot_index];
if ((damage_bits & (DMG_FALL | DMG_CRUSH))
{
LOG_CONSOLE (PLID, "realbot - fixed connection with falling.");
LOG_MESSAGE (PLID, "realbot - fixed connection with falling.");
if (pBot->bot_pathid > 0)
{
int iNode = NodeMachine.NodeFromPath(pBot->iIndex, (pBot->bot_pathid-1));
float fDist = fabs(damage_origin.z - NodeMachine.node_vector(iNode).z);
if (fDist > 90)
{
// we know where we came from, and we know where we went to
int iNodeTo = NodeMachine.NodeFromPath(pBot->iIndex, pBot->bot_pathid);
// remove connection
NodeMachine.remove_neighbour_node(iNode, iNodeTo);
}
}
}
// ignore certain types of damage...
if (damage_bits & IGNORE_DAMAGE)
return;
// if the bot doesn't have an enemy and someone is shooting at it then
// turn in the attacker's direction...
if (bots[bot_index].pBotEnemy == NULL)
{
// face the attacker... (yeah yeah, cheating for now ;) )
// Face danger vector
pBot->vHead = damage_origin;
pBot->vBody = damage_origin;
// move to damage vector
pBot->f_camp_time = gpGlobals->time; // stop camping
pBot->iGoalNode = NodeMachine.close(damage_origin, 150, NULL);
pBot->bot_pathid = -1;
///////////// END STEFAN
}
}
}
}
Code from sdk (player.cpp, function "UpdateClientdata"),
Code:
if (pev->dmg_take || pev->dmg_save || m_bitsHUDDamage != m_bitsDamageType)
{
// Comes from inside me if not set
Vector damageOrigin = pev->origin;
// send "damage" message
// causes screen to flash, and pain compass to show direction of damage
edict_t *other = pev->dmg_inflictor;
if ( other )
{
CBaseEntity *pEntity = CBaseEntity::Instance(other);
if ( pEntity )
damageOrigin = pEntity->Center();
}
// only send down damage type that have hud art
int visibleDamageBits = m_bitsDamageType & DMG_SHOWNHUD;
MESSAGE_BEGIN( MSG_ONE, gmsgDamage, NULL, pev );
WRITE_BYTE( pev->dmg_save );
WRITE_BYTE( pev->dmg_take );
WRITE_LONG( visibleDamageBits );
WRITE_COORD( damageOrigin.x );
WRITE_COORD( damageOrigin.y );
WRITE_COORD( damageOrigin.z );
MESSAGE_END();
pev->dmg_take = 0;
pev->dmg_save = 0;
m_bitsHUDDamage = m_bitsDamageType;
// Clear off non-time-based damage indicators
m_bitsDamageType &= DMG_TIMEBASED;
}