Exemple #1
0
void Vehicle::ApplyAllImmunities()
{
    // This couldn't be done in DB, because some spells have MECHANIC_NONE

    // Vehicles should be immune on Knockback ...
    _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
    _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);

    // Mechanical units & vehicles ( which are not Bosses, they have own immunities in DB ) should be also immune on healing ( exceptions in switch below )
    if (_me->ToCreature() && _me->ToCreature()->GetCreatureTemplate()->type == CREATURE_TYPE_MECHANICAL && !_me->ToCreature()->isWorldBoss())
    {
        // Heal & dispel ...
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_DISPEL, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);

        // ... Shield & Immunity grant spells ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_IMMUNITY, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_UNATTACKABLE, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_ABSORB, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_IMMUNE_SHIELD, true);

        // ... Resistance, Split damage, Change stats ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_DAMAGE_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SPLIT_DAMAGE_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_RESISTANCE, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STAT, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, true);
    }

    // If vehicle flag for fixed position set (cannons), or if the following hardcoded units, then set state rooted
    //  30236 | Argent Cannon
    //  39759 | Tankbuster Cannon
    if ((GetVehicleInfo()->m_flags & VEHICLE_FLAG_FIXED_POSITION) || GetBase()->GetEntry() == 30236 || GetBase()->GetEntry() == 39759)
        _me->SetControlled(true, UNIT_STATE_ROOT);


    // Different immunities for vehicles goes below
    switch (GetVehicleInfo()->m_ID)
    {
        // code below prevents a bug with movable cannons
        case 160: // Strand of the Ancients
        case 244: // Wintergrasp
        case 510: // Isle of Conquest
        case 452: // Isle of Conquest
        case 543: // Isle of Conquest
            _me->SetControlled(true, UNIT_STATE_ROOT);
            // why we need to apply this? we can simple add immunities to slow mechanic in DB
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
            break;
        default:
            break;
    }
}
Exemple #2
0
PSpawnedVehicle* PVehicles::SpawnVehicle( u32 nVehicleId, u32 nLocation, PVhcCoordinates const* nVhcPos )
{
  PSpawnedVehicle* newVhc = NULL;
  PWorld* cWorld;
  PVehicleInformation nVhcInfo;

  if (( nLocation != PWorlds::mNcSubwayWorldId ) && IsValidVehicle( nVehicleId ) && !IsSpawned( nVehicleId ) )
  {
    cWorld = Worlds->LeaseWorld( nLocation );

    if ( cWorld && GetVehicleInfo( nVehicleId, &nVhcInfo ) )
    {
      newVhc = cWorld->GetSpawnedVehicules()->SpawnVehicle( &nVhcInfo, nVhcPos );
      if ( newVhc )
      {
        if ( !RegisterSpawnedVehicle( newVhc ) )
        {
          Console->Print( RED, BLACK, "[Error] PVehicles::SpawnVehicle : Could not register spawned vhc" );
        }
        if( gDevDebug )
          Console->Print( "%d Spawned vhc %d (local 0x%04x) type %d (requested: %d)", Console->ColorText( CYAN, BLACK, "[DEBUG]" ), newVhc->GetVehicleId(), newVhc->GetLocalId(), newVhc->GetInformation().GetVehicleType(), nVhcInfo.GetVehicleType() );
      }
      else
        Console->Print( RED, BLACK, "[Error] PVehicles::SpawnVehicle : Could not create vhc" );
    }

    Worlds->ReleaseWorld( nLocation );
  }

  return newVhc;
}
Exemple #3
0
PVhcInfoList* PVehicles::GetCharVehicles( u32 nCharId, u16 nMaxCount, u16 nStartIndex )
{
  PVhcInfoList* Entries = new PVhcInfoList();
  PVehicleInformation* InfoEntry;
  // Tmp implementation
  u16 LimitIndex = nStartIndex + nMaxCount;
  if ( !nMaxCount || ( VhcTypesNum < LimitIndex ) )
  {
    LimitIndex = VhcTypesNum;
  }

  for ( u16 i = nStartIndex; ( i < LimitIndex ) ; ++i )
  {
    InfoEntry = new PVehicleInformation();
    if ( GetVehicleInfo( nCharId * 100 + VhcTypes[i], InfoEntry ) )
    {
      Entries->push( InfoEntry );
    }
    else
    {
      delete InfoEntry;
    }
  }

  return Entries;
}
Exemple #4
0
Vehicle::Vehicle(Unit *unit, VehicleEntry const *vehInfo) : me(unit), m_vehicleInfo(vehInfo), m_usableSeatNum(0), m_bonusHP(0)
{
    for (uint32 i = 0; i < MAX_VEHICLE_SEATS; ++i)
    {
        if (uint32 seatId = m_vehicleInfo->m_seatID[i])
            if (VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId))
            {
                m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
                if (veSeat->IsUsable())
                    ++m_usableSeatNum;
            }
    }

    // HACKY WAY, We must found a more generic way to handle this
    // Set inmunities since db ones are rewritten with player's ones
    switch (GetVehicleInfo()->m_ID)
    {
        case 160:
            me->SetControlled(true, UNIT_STAT_ROOT);
            me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
            me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
        case 158:
            me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_FEAR, true);
            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);
            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STUN, true);
            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_ROOT, true);
            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_CONFUSE, true);
            me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip jump effect
            break;
        default:
            break;
    }
}
Exemple #5
0
/*
================
idBotAI::Vehicle_Ram_Attack_Movement
================
*/
bool idBotAI::Vehicle_Ram_Attack_Movement() {
	proxyInfo_t enemyVehicleInfo;
	idBox enemyBox;

	if ( enemyInfo.enemyDist < 700.0f && botVehicleInfo->forwardSpeed < 100.0f && botVehicleInfo->type != HOG ) { //mal: somethings holding us up, we can't ram at this speed/dist!
		VEHICLE_COMBAT_MOVEMENT_STATE = NULL; 
		return false;
	}

	if ( !Bot_VehicleCanRamClient( enemy ) ) {
		VEHICLE_COMBAT_MOVEMENT_STATE = NULL;
		return false;
	}

	if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {
		GetVehicleInfo( botWorld->clientInfo[ enemy ].proxyInfo.entNum, enemyVehicleInfo );
		enemyBox = idBox( enemyVehicleInfo.bbox, enemyVehicleInfo.origin, enemyVehicleInfo.axis );
	} else {
		enemyBox = idBox( botWorld->clientInfo[ enemy ].localBounds, botWorld->clientInfo[ enemy ].origin, botWorld->clientInfo[ enemy ].bodyAxis );
	}

	if ( !InFrontOfVehicle( botVehicleInfo->entNum, enemyBox.GetCenter(), false ) ) {
		VEHICLE_COMBAT_MOVEMENT_STATE = NULL;
		return false;
	}

	Bot_MoveToGoal( enemyBox.GetCenter(), vec3_zero, SPRINT_ATTACK, NULLMOVETYPE ); //mal: Prepare for ramming speed! Ram them until they're dead, or we are....
	Bot_LookAtLocation( enemyBox.GetCenter(), SMOOTH_TURN );

    return true;
}
Exemple #6
0
/*
==================
idBotAI::VehicleHasGunnerSeatOpen
==================
*/
bool idBotAI::VehicleHasGunnerSeatOpen( int entNum ) {
	bool hasSeat = true;
	int i;
	int j = 0;
	int numSeats = 1;
	proxyInfo_t vehicleInfo;
	botVehicleWeaponInfo_t weaponType = MINIGUN;
	GetVehicleInfo( entNum, vehicleInfo );

	if ( !vehicleInfo.hasFreeSeat ) { //mal: that was fast....
		return false;
	}

	if ( vehicleInfo.type == MCP ) {
		return true;
	}

	if ( vehicleInfo.type == BUFFALO ) { //mal: buffalo actually has 2 gunner seats, where most vehicles only have 1.
		numSeats = 3;
	}

	if ( vehicleInfo.type == TROJAN ) {
		weaponType = LAW;
	}

	for( i = 0; i < MAX_CLIENTS; i++ ) {

		if ( i == botNum && botVehicleInfo == NULL ) {
			continue;
		}

		if ( !ClientIsValid( i, -1 ) ) {
			continue;
		}

		const clientInfo_t &playerInfo = botWorld->clientInfo[ i ];

		if ( playerInfo.team != botInfo->team ) {
			continue;
		}

		if ( playerInfo.proxyInfo.entNum != entNum ) {
			continue;
		}

		if ( playerInfo.proxyInfo.weapon != weaponType ) {
			continue;
		}

		j++;

		if ( j >= numSeats ) {
            hasSeat = false;
			break;
		}
	}

	return hasSeat;
}
Exemple #7
0
void Vehicle::ApplyAllImmunities()
{
    // This couldn't be done in DB, because some spells have MECHANIC_NONE

    // Vehicles should be immune on Knockback ...
    _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
    _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);

    // Mechanical units & vehicles ( which are not Bosses, they have own immunities in DB ) should be also immune on healing ( exceptions in switch below )
    if (_me->ToCreature() && _me->ToCreature()->GetCreatureTemplate()->type == CREATURE_TYPE_MECHANICAL && !_me->ToCreature()->isWorldBoss())
    {
        // Heal & dispel ...
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_DISPEL, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);

        // ... Shield & Immunity grant spells ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_IMMUNITY, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_UNATTACKABLE, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_ABSORB, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_IMMUNE_SHIELD, true);

        // ... Resistance, Split damage, Change stats ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_DAMAGE_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SPLIT_DAMAGE_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_RESISTANCE, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STAT, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, true);
    }

	// Honour non movement flag (4)
    if (_me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
        _me->SetControlled(true, UNIT_STATE_ROOT);
	
    // Different immunities for vehicles goes below
    switch (GetVehicleInfo()->m_ID)
    {
        // code below prevents a bug with movable cannons
        case 160: // Strand of the Ancients
        case 244: // Wintergrasp
        case 510: // Isle of Conquest
        case 452: // Isle of Conquest
        case 543: // Isle of Conquest
            _me->SetControlled(true, UNIT_STATE_ROOT);
            // why we need to apply this? we can simple add immunities to slow mechanic in DB
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
            break;
		case 321: // Pilgrims Bount: Chair
            _me->SetControlled(true, UNIT_STATE_ROOT);
            break;
        default:
            break;
    }
}
Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) :
UsableSeatNum(0), _me(unit), _vehicleInfo(vehInfo), _creatureEntry(creatureEntry), _status(STATUS_NONE)
{
    for (uint32 i = 0; i < MAX_VEHICLE_SEATS; ++i)
    {
        if (uint32 seatId = _vehicleInfo->m_seatID[i])
            if (VehicleSeatEntry const* veSeat = sVehicleSeatStore.LookupEntry(seatId))
            {
                Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
                if (veSeat->CanEnterOrExit())
                    ++UsableSeatNum;
            }
    }

    // Vehicle Immunities
    switch (GetVehicleInfo()->m_ID)
    {
        case 160:
        case 116:
            _me->SetControlled(true, UNIT_STATE_ROOT);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
        case 117:
        case 324:
        case 158:
        case 79:
        case 106:
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_DISPEL, true);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_FEAR, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STUN, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_ROOT, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_CONFUSE, true);
            _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);
            _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13810, true); // Frost Trap
            _me->ApplySpellImmune(0, IMMUNITY_ID, 55741, true); // Desecration Rank 1
            _me->ApplySpellImmune(0, IMMUNITY_ID, 68766, true); // Desecration Rank 2
            break;
        default:
            break;
    }

    // Set or remove correct flags based on available seats. Will overwrite db data (if wrong).
    if (UsableSeatNum)
        _me->SetFlag(UNIT_NPC_FLAGS, (_me->GetTypeId() == TYPEID_PLAYER ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK));
    else
        _me->RemoveFlag(UNIT_NPC_FLAGS, (_me->GetTypeId() == TYPEID_PLAYER ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK));

    InitMovementInfoForBase();
}
Exemple #9
0
void Vehicle::ApplyAllImmunities()
{
    // This couldn't be done in DB, because Vehicle's immunities are overriden by Player's ones

    // Vehicles should be immune on Knockback, Deathgrip ...
    me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
    me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
    me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);

    // ... Fear, Snare, Root, Stun ...
    me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR, true);
    me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true);
    me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);
    me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);
    me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STUN, true);
    me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, true);
    me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_CONFUSE, true);

    // Mechanical units & vehicles ( which are not Bosses, they have own immunities in DB ) should be also immune on healing ( exceptions in switch below )
    if (me->ToCreature() && me->ToCreature()->GetCreatureInfo()->type == CREATURE_TYPE_MECHANICAL && !me->ToCreature()->isWorldBoss())
    {
        // Heal & dispel ...
        me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);

        // ... Shield & Immunity grant spells ...
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_IMMUNITY, true);
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_UNATTACKABLE, true);
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_ABSORB, true);
        me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
        me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_IMMUNE_SHIELD , true);

        // ... Resistance, Split damage, Speed Increase, ...
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_DAMAGE_SHIELD, true);
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SPLIT_DAMAGE_PCT, true);
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_RESISTANCE, true);
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STAT, true);
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, true);
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_INCREASE_SPEED, true);
    }

    // Different immunities for vehicles goes below
    switch (GetVehicleInfo()->m_ID)
    {
    case 160:
        me->SetControlled(true, UNIT_STAT_ROOT);
        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
        break;
    default:
        break;
    }
}
Exemple #10
0
Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : _me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntry)
{
    for (uint32 i = 0; i < MAX_VEHICLE_SEATS; ++i)
    {
        if (uint32 seatId = _vehicleInfo->m_seatID[i])
            if (VehicleSeatEntry const* veSeat = sVehicleSeatStore.LookupEntry(seatId))
            {
                Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
                if (veSeat->CanEnterOrExit())
                    ++_usableSeatNum;
            }
    }

    // HACKY WAY, We must found a more generic way to handle this
    // Set inmunities since db ones are rewritten with player's ones
    switch (GetVehicleInfo()->m_ID)
    {
        case 160:
        case 116:
        case 452:
        case 453:
        case 510:
            _me->SetControlled(true, UNIT_STATE_ROOT);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
       case 117:
       case 324:
       case 158:
       case 79:
       case 106:
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_DISPEL, true);
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_FEAR, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STUN, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_ROOT, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_CONFUSE, true);
            _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);
            _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13810, true); // Frost Trap
            _me->ApplySpellImmune(0, IMMUNITY_ID, 55741, true); // Desecration Rank 1
            _me->ApplySpellImmune(0, IMMUNITY_ID, 68766, true); // Desecration Rank 2
            break;
        default:
            break;
    }

    InitMovementInfoForBase();
}
Exemple #11
0
void Vehicle::InitMovementInfoForBase()
{
    uint32 vehicleFlags = GetVehicleInfo()->m_flags;

    if (vehicleFlags & VEHICLE_FLAG_NO_STRAFE)
        _me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_NO_STRAFE);
    if (vehicleFlags & VEHICLE_FLAG_NO_JUMPING)
        _me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_NO_JUMPING);
    if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDTURNING)
        _me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_TURNING);
    if (vehicleFlags & VEHICLE_FLAG_ALLOW_PITCHING)
        _me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING);
    if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDPITCHING)
        _me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_PITCHING);
}
Exemple #12
0
/*
================
idBotAI::Enter_Vehicle_Air_Movement
================
*/
bool idBotAI::Enter_Vehicle_Air_Movement() {
	proxyInfo_t enemyVehicleInfo;
 
	combatMoveType = VEHICLE_AIR_MOVEMENT;
	combatMoveActionGoal = ACTION_NULL;
	combatMoveTooCloseRange = 0.0f;

	if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE  ) {
		GetVehicleInfo( botWorld->clientInfo[ enemy ].proxyInfo.entNum, enemyVehicleInfo );
		if ( enemyVehicleInfo.isAirborneVehicle ) {
			if ( botVehicleInfo->type == BUFFALO ) {
				VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Buffalo_Air_To_Air_Movement;
				lastMoveNode = "Buffalo Air To Air Combat";
				combatMoveTime = botWorld->gameLocalInfo.time + 500;
			} else {
				VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Vehicle_Air_To_Air_Movement;
				lastMoveNode = "Vehicle Air To Air Combat";
			}
		} else {
			if ( botVehicleInfo->type == BUFFALO ) {
				VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Buffalo_Air_To_Ground_Movement;
				lastMoveNode = "Buffalo Air To Ground Combat";
				combatMoveTime = botWorld->gameLocalInfo.time + 500;
			} else {
				combatKeepMovingTime = 0;
				VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Vehicle_Air_To_Ground_Movement;
				lastMoveNode = "Vehicle Air To Ground Combat";
			}
		}
	} else {
		if ( botVehicleInfo->type == BUFFALO ) {
			VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Buffalo_Air_To_Ground_Movement;
			lastMoveNode = "Buffalo Air To Ground Combat";
			combatMoveTime = botWorld->gameLocalInfo.time + 500;
		} else {
			combatKeepMovingTime = 0;
			VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Vehicle_Air_To_Ground_Movement;
			lastMoveNode = "Vehicle Air To Ground Combat";
		}
	}

	rocketTime = 0;

	return true;
}
Exemple #13
0
void Vehicle::ApplyAllImmunities()
{
    // This couldn't be done in DB, because some spells have MECHANIC_NONE

    // Vehicles should be immune on Knockback ...
    _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
    _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);

    // Mechanical units & vehicles ( which are not Bosses, they have own immunities in DB ) should be also immune on healing ( exceptions in switch below )
    if (_me->ToCreature() && _me->ToCreature()->GetCreatureInfo()->type == CREATURE_TYPE_MECHANICAL && !_me->ToCreature()->isWorldBoss())
    {
        // Heal & dispel ...
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_DISPEL, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);

        // ... Shield & Immunity grant spells ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_IMMUNITY, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_UNATTACKABLE, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_ABSORB, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_IMMUNE_SHIELD , true);

        // ... Resistance, Split damage, Change stats ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_DAMAGE_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SPLIT_DAMAGE_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_RESISTANCE, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STAT, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, true);
    }

    // Different immunities for vehicles goes below
    switch (GetVehicleInfo()->m_ID)
    {
        case 160:
            _me->SetControlled(true, UNIT_STAT_ROOT);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
            break;
        default:
            break;
    }
}
Exemple #14
0
uint16 Vehicle::GetExtraMovementFlagsForBase() const
{
    uint16 movementMask = MOVEMENTFLAG2_NONE;
    uint32 vehicleFlags = GetVehicleInfo()->m_flags;

    if (vehicleFlags & VEHICLE_FLAG_NO_STRAFE)
        movementMask |= MOVEMENTFLAG2_NO_STRAFE;
    if (vehicleFlags & VEHICLE_FLAG_NO_JUMPING)
        movementMask |= MOVEMENTFLAG2_NO_JUMPING;
    if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDTURNING)
        movementMask |= MOVEMENTFLAG2_FULL_SPEED_TURNING;
    if (vehicleFlags & VEHICLE_FLAG_ALLOW_PITCHING)
        movementMask |= MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING;
    if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDPITCHING)
        movementMask |= MOVEMENTFLAG2_FULL_SPEED_PITCHING;

    sLog->outDebug("Vehicle::GetExtraMovementFlagsForBase() returned %u", movementMask);
    return movementMask;
}
Exemple #15
0
/*
================
idBotAI::Bot_FindBestVehicleCombatMovement

Finds the best combat movement for the bot while in a vehicle.
================
*/
bool idBotAI::Bot_FindBestVehicleCombatMovement() {
	bool vehicleCanRamClient; //mal: sounds a bit... dirty, doesn't it?
	bool vehicleGunnerSeatOpen;
	bool hasAttackedCriticalMate = false;
	bool enemyReachable = false;
	bool enemyHasVehicle = false;
	proxyInfo_t enemyVehicleInfo;

	const clientInfo_t& enemyPlayerInfo = botWorld->clientInfo[ enemy ];

	if ( enemyPlayerInfo.proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {
		GetVehicleInfo( enemyPlayerInfo.proxyInfo.entNum, enemyVehicleInfo );
		enemyHasVehicle = true;
	}

	combatMoveFailedCount = 0;
	combatMoveTime = -1;

	if ( botInfo->proxyInfo.weapon == NULL_VEHICLE_WEAPON && botVehicleInfo->driverEntNum != botNum ) {
		return false;
	} //mal: this shouldn't really ever happen, but may if the bot is moving between positions in a vehicle. Or if a human entered/exited a vehicle at just the right/wrong time.

	if ( ( botInfo->proxyInfo.weapon == MINIGUN || botInfo->proxyInfo.weapon == LAW || botInfo->proxyInfo.weapon == PERSONAL_WEAPON ) && botVehicleInfo->driverEntNum != botNum ) {
		VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_NULL_Movement; //mal: just sit there, and shoot the enemy.
		return true;
	}

	if ( botVehicleInfo->type > ICARUS ) {
		VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Air_Movement;
		return true;
	}

	//mal: this more often then not causes issues
/*
	if ( enemyHasVehicle ) {
		if ( enemyVehicleInfo.type == HOG && enemyInfo.enemyDist < 3000.0f && botVehicleInfo->driverEntNum == botNum ) { //mal: never stand around if a hog has us in his sights.
			VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Random_Movement;
			return true;
		}
	}
*/

	vehicleGunnerSeatOpen = VehicleHasGunnerSeatOpen( botInfo->proxyInfo.entNum );

	if ( enemyPlayerInfo.lastAttackClient > - 1 && enemyPlayerInfo.lastAttackClient < MAX_CLIENTS ) {
		if ( botWorld->clientInfo[ enemyPlayerInfo.lastAttackClient ].team == botInfo->team && enemyPlayerInfo.lastAttackClientTime + 3000 > botWorld->gameLocalInfo.time ) {
			if ( Client_IsCriticalForCurrentObj( enemyPlayerInfo.lastAttackClient, 2000.0f ) || ClientHasObj( enemyPlayerInfo.lastAttackClient ) ) {
				hasAttackedCriticalMate = true;
			}
		}
	}

	Bot_SetupVehicleMove( vec3_zero, enemy, ACTION_NULL );

    if ( botAAS.hasPath && botAAS.path.travelTime < Bot_ApproxTravelTimeToLocation( botInfo->origin, enemyPlayerInfo.origin, true ) * TRAVEL_TIME_MULTIPLY ) {
		enemyReachable = true;
	}

	if ( botInfo->proxyInfo.weapon == NULL_VEHICLE_WEAPON && botVehicleInfo->driverEntNum == botNum ) {

		vehicleCanRamClient = Bot_VehicleCanRamClient( enemy );

		if ( botVehicleInfo->type == HOG ) {
			if ( vehicleCanRamClient && InFrontOfVehicle( botVehicleInfo->entNum, enemyPlayerInfo.origin, true ) ) {
				VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Ram_Attack_Movement; //mal: ram them! Thats our only weapon.
				return true;
			}

			if ( enemyReachable && enemyHasVehicle ) {
				if ( enemyVehicleInfo.type != HUSKY ) {
					VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Chase_Movement; //mal: move in for a closer kill, THEN ram them.
					return true;
				}
			}
		}

		if ( botVehicleInfo->type == BADGER && enemyInfo.enemyDist < 1500.0f && vehicleCanRamClient && enemyPlayerInfo.proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE && botVehicleInfo->driverEntNum == botNum ) {
			VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Ram_Attack_Movement; //mal: 10 points! Fun for the whole family.
			return true;
		}

		if ( !vehicleGunnerSeatOpen ) {
			if ( enemyInfo.enemyDist < 2500.0f ) {
				VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Stand_Ground_Movement; //mal: just sit there, let our gunner get a chance to kill the enemy.
			} else {
				if ( enemyReachable || enemyInfo.enemyDist > 1500.0f ) {
                    VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Chase_Movement; //mal: move in for a closer kill.
				} else {
					VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Stand_Ground_Movement; //mal: just sit there, let our gunner get a chance to kill the enemy.
				}
			}

			return true;
		} else {
			if ( enemyPlayerInfo.proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE ) {
				if ( enemyInfo.enemyDist < 6000.0f && ( vehicleCanRamClient || hasAttackedCriticalMate ) ) { //mal: if an important mate is under attack, we'll fight to the end, even if its just to draw the enemies fire.
					VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Ram_Attack_Movement; //mal: ram them! Thats our only weapon.
					return true;
				}
			} else {
				Bot_IgnoreEnemy( enemy, 15000 );
				return false;
			} //mal: if all else fails, we have no choice but to ignore this enemy.
		}
	}

	if ( ( botInfo->proxyInfo.weapon == MINIGUN || botInfo->proxyInfo.weapon == LAW || botInfo->proxyInfo.weapon == PERSONAL_WEAPON ) && botVehicleInfo->driverEntNum != botNum ) {
		VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_NULL_Movement; //mal: just sit there, and shoot the enemy.
		return true;
	}

	if ( ( botInfo->proxyInfo.weapon == MINIGUN || botInfo->proxyInfo.weapon == LAW || botInfo->proxyInfo.weapon == PERSONAL_WEAPON ) && botVehicleInfo->driverEntNum == botNum ) {

		if ( botThreadData.random.RandomInt( 100 ) > 50 && enemyInfo.enemyDist < 1500.0f ) {
   			VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Stand_Ground_Movement; 
		} else {
			VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Chase_Movement; //mal: move around a bit to make ourselves harder to hit.
		}
		return true;
	}

	if ( botVehicleInfo->type == GOLIATH && botVehicleInfo->driverEntNum == botNum ) {
		VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Stand_Ground_Movement;
		return true;
	}

	if ( botInfo->proxyInfo.weapon == TANK_GUN && botVehicleInfo->driverEntNum == botNum ) {
		if ( !enemyReachable && enemyInfo.enemyDist < 3000.0f ) { //mal: dont do chase movement of our enemy, if we cant reach him.
           VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Stand_Ground_Movement; 
		} else {
			if ( enemyAcquireTime + 10000 < botWorld->gameLocalInfo.time && botInfo->lastAttackClientTime + 10000 < botWorld->gameLocalInfo.time ) {
				proxyInfo_t enemyVehicleInfo;
				GetVehicleInfo( enemyPlayerInfo.proxyInfo.entNum, enemyVehicleInfo );

				if ( enemyVehicleInfo.entNum != 0 && enemyVehicleInfo.type >= ICARUS ) { //mal: dont chase air vehicles around - this looks retarded.
					VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Stand_Ground_Movement;
				} else {
					VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Chase_Movement; //mal: haven't had much success hitting our enemy - so chase him for a better shot.
				}
			} else {
//				if ( botThreadData.random.RandomInt( 100 ) > 40 ) {
					VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Stand_Ground_Movement;
//				} else {
//					VEHICLE_COMBAT_MOVEMENT_STATE = &idBotAI::Enter_Vehicle_Chase_Movement;  //mal: move around a bit to make ourselves harder to hit.
//				}
			}
		}

		return true;
	}


	//mal_TODO: add support for air vehicles too......

	botThreadData.Warning( "Can't find a move that suits bot %i and his vehicle!", botNum );

	return false;
}
Exemple #16
0
bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
{
    if (unit->GetVehicle() != this)
        return false;
	// don't allow vehicles in arena
	if (unit->GetTypeId() == TYPEID_PLAYER && unit->GetMap()->IsBattleArena())
        return false;


    SeatMap::iterator seat;
    if (seatId < 0) // no specific seat requirement
    {
        for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
            if (!seat->second.passenger && seat->second.seatInfo->IsUsable())
                break;

        if (seat == m_Seats.end()) // no available seat
            return false;
    }
    else
    {
        seat = m_Seats.find(seatId);
        if (seat == m_Seats.end())
            return false;

        if (seat->second.passenger)
            seat->second.passenger->ExitVehicle();

        ASSERT(!seat->second.passenger);
    }

    sLog.outDebug("Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), me->GetEntry(), m_vehicleInfo->m_ID, me->GetGUIDLow(), (int32)seat->first);

    seat->second.passenger = unit;
    if (seat->second.seatInfo->IsUsable())
    {
        ASSERT(m_usableSeatNum);
        --m_usableSeatNum;
        if (!m_usableSeatNum)
        {
            if (me->GetTypeId() == TYPEID_PLAYER)
                me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
            else
                me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
        }
    }

    if (seat->second.seatInfo->m_flags && !(seat->second.seatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK11))
    {
        switch (GetVehicleInfo()->m_ID)
        {
            case 342: //Ignis
            case 335: //XT-002
            case 380: //Kologarn's Right Arm
                break;
            default:
        unit->addUnitState(UNIT_STAT_ONVEHICLE);
                break;
        }
    }
    unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
    VehicleSeatEntry const *veSeat = seat->second.seatInfo;
    unit->m_movementInfo.t_pos.m_positionX = veSeat->m_attachmentOffsetX;
    unit->m_movementInfo.t_pos.m_positionY = veSeat->m_attachmentOffsetY;
    unit->m_movementInfo.t_pos.m_positionZ = veSeat->m_attachmentOffsetZ;
    unit->m_movementInfo.t_pos.m_orientation = 0;
    unit->m_movementInfo.t_time = 0; // 1 for player
    unit->m_movementInfo.t_seat = seat->first;

    if (me->GetTypeId() == TYPEID_UNIT
        && unit->GetTypeId() == TYPEID_PLAYER
        && seat->first == 0 && seat->second.seatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
    {
        if (!me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE))
            ASSERT(false);

        if (VehicleScalingInfo const *scalingInfo = sObjectMgr.GetVehicleScalingInfo(m_vehicleInfo->m_ID))
        {
            Player *plr = unit->ToPlayer();
            float averageItemLevel = plr->GetAverageItemLevel();
            if (averageItemLevel < scalingInfo->baseItemLevel)
                averageItemLevel = scalingInfo->baseItemLevel;
            averageItemLevel -= scalingInfo->baseItemLevel;

            m_bonusHP = uint32(me->GetMaxHealth() * (averageItemLevel * scalingInfo->scalingFactor));
            me->SetMaxHealth(me->GetMaxHealth() + m_bonusHP);
            me->SetHealth(me->GetHealth() + m_bonusHP);
        }
    }

    if (me->IsInWorld())
    {
        unit->SendMonsterMoveTransport(me);

        if (me->GetTypeId() == TYPEID_UNIT)
        {
            if (me->ToCreature()->IsAIEnabled)
                me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true);

            // update all passenger's positions
            RelocatePassengers(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
        }
    }

    if (GetBase()->GetTypeId() == TYPEID_UNIT)
        sScriptMgr.OnAddPassenger(this, unit, seatId);

    return true;
}
Exemple #17
0
/*
==================
idBotAI::Bot_PickBestVehicleWeapon

See what the best weapon is that we have at our disposal - we'll change our position in this vehicle if need be to get access to a ( better ) weapon.
==================
*/
void idBotAI::Bot_PickBestVehicleWeapon() {

	bool enemyInAirborneVehicle = false;
	bool enemyInGroundVehicle = false;
	bool needMovementUpdate = false;
	bool enemyOnFoot = false;
	bool hasGunnerSeatOpen;
	bool enemyReachable = false;

	if ( weapSwitchTime > botWorld->gameLocalInfo.time ) {
		return;
	}

	if ( botVehicleInfo->type == ICARUS ) {
		return;
	}

	proxyInfo_t enemyVehicleInfo;

	idVec3 vec = botWorld->clientInfo[ enemy ].origin - botInfo->origin;

	float dist = vec.LengthSqr();

	hasGunnerSeatOpen = VehicleHasGunnerSeatOpen( botInfo->proxyInfo.entNum );

	if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {
        GetVehicleInfo( botWorld->clientInfo[ enemy ].proxyInfo.entNum, enemyVehicleInfo );

		if ( enemyVehicleInfo.isAirborneVehicle ) {
			enemyInAirborneVehicle = true;
		} else {
			enemyInGroundVehicle = true;
		}
	} else {
		enemyOnFoot = true;
	}

	Bot_SetupVehicleMove( vec3_zero, enemy, ACTION_NULL );

    if ( botAAS.hasPath && botAAS.path.travelTime < Bot_ApproxTravelTimeToLocation( botInfo->origin, botWorld->clientInfo[ enemy ].origin, true ) * TRAVEL_TIME_MULTIPLY ) {
		enemyReachable = true;
	}

	switch( botVehicleInfo->type ) {

		case TITAN:
			if ( botVehicleInfo->driverEntNum == botNum ) {
				if ( enemyInAirborneVehicle && enemyInfo.enemyDist <= TANK_MINIGUN_RANGE && hasGunnerSeatOpen ) {
					botUcmd->botCmds.becomeGunner = true; 
					needMovementUpdate = true;
					break;
				}
			} else {
				if ( ( enemyInAirborneVehicle && enemyInfo.enemyDist > TANK_MINIGUN_RANGE && botVehicleInfo->driverEntNum == -1 ) || !enemyInAirborneVehicle ) {
					botUcmd->botCmds.becomeDriver = true;
					needMovementUpdate = true;
					break;
				}
			}

			break;

		case TROJAN:
			if ( botInfo->proxyInfo.weapon == LAW ) {
				if ( botVehicleInfo->driverEntNum == -1 ) {
					if ( ( !enemyInAirborneVehicle && !enemyInGroundVehicle ) || enemyInfo.enemyDist < 700.0f || enemyInfo.enemyDist > WEAPON_LOCK_DIST ) {
                        botUcmd->botCmds.becomeDriver = true; //mal: using the LAW to lock onto our vehicle enemy makes sense ( the drivers MG is a joke in this case ).
						needMovementUpdate = true;
						break;
					}
				}
			}

			if ( botVehicleInfo->driverEntNum == botNum ) {
				if ( ( enemyInAirborneVehicle || enemyInGroundVehicle ) && hasGunnerSeatOpen && dist < Square( WEAPON_LOCK_DIST ) ) {
					botUcmd->botCmds.becomeGunner = true; //mal: using the LAW to lock onto our airborne enemy makes sense ( the drivers MG is a joke in this case ).
					needMovementUpdate = true;
					break;
				}
			}

			if ( botInfo->proxyInfo.weapon == NULL_VEHICLE_WEAPON ) {
				if ( botVehicleInfo->driverEntNum == -1 ) {
					botUcmd->botCmds.becomeDriver = true;
					needMovementUpdate = true;
				} else if ( VehicleHasGunnerSeatOpen( botVehicleInfo->entNum ) ) {
					botUcmd->botCmds.becomeGunner = true;
					needMovementUpdate = true;
				}
				break;
			}//mal: if we're the driver, stay as the driver!

			break;

		case BADGER:
			if ( botVehicleInfo->driverEntNum == botNum ) { //mal: we're the driver, if the turret is available, we may jump into it to fight enemies.
				if ( hasGunnerSeatOpen && vehicleDriverTime < botWorld->gameLocalInfo.time && enemyReachable && enemyInfo.enemyDist > 700.0f && enemyVehicleInfo.type != HOG ) {
                    if ( botThreadData.random.RandomInt( 100 ) > 50 ) {
						vehicleDriverTime = botWorld->gameLocalInfo.time + 15000;
						break;
					}
					
					if ( ( enemyInAirborneVehicle || ( enemyInfo.enemyDist < 3000.0f && enemyInfo.enemyDist > 700.0f ) ) && vehicleGunnerTime + 30000 < botWorld->gameLocalInfo.time && enemyInfo.enemyVisible ) { //mal: dont do this if enemy too far away, or its been too soon since we last did this.
						botUcmd->botCmds.becomeGunner = true;
						vehicleGunnerTime = botWorld->gameLocalInfo.time + 15000;
						needMovementUpdate = true;
						break;
					}
				}
			}

			if ( botInfo->proxyInfo.weapon == PERSONAL_WEAPON ) {
				if ( hasGunnerSeatOpen && botVehicleInfo->driverEntNum != -1 ) {
					botUcmd->botCmds.becomeGunner = true;
					needMovementUpdate = true;
					break;
				} //mal: our gunner may have been killed, or maybe he jumped out some time ago - take his place.

				if ( botVehicleInfo->driverEntNum == -1 ) {
                    botUcmd->botCmds.becomeDriver = true;
					needMovementUpdate = true;
					break;
				}
			}

			if ( botInfo->proxyInfo.weapon == MINIGUN ) {
				if ( botVehicleInfo->driverEntNum == -1 ) {
					if ( vehicleGunnerTime < botWorld->gameLocalInfo.time || !enemyInfo.enemyVisible ) { //mal: even if we had a driver and he bailed, become the driver for a better shot, then can go back to the gun.
						botUcmd->botCmds.becomeDriver = true;
						needMovementUpdate = true;
						break;
					}
				}
			}

			if ( botInfo->proxyInfo.weapon == NULL_VEHICLE_WEAPON && botVehicleInfo->driverEntNum != botNum ) {
				if ( botVehicleInfo->driverEntNum == -1 ) {
					botUcmd->botCmds.becomeDriver = true;
					needMovementUpdate = true;
				} else if ( VehicleHasGunnerSeatOpen( botVehicleInfo->entNum ) ) {
					botUcmd->botCmds.becomeGunner = true;
					needMovementUpdate = true;
				} else if ( botVehicleInfo->hasFreeSeat ) {
					needMovementUpdate = true;
					botUcmd->botCmds.activate = true; //mal: rotate to one of the back seats.
				}
			}//mal: if we're the driver, stay as the driver!

			break;

		case PLATYPUS:
			if ( botVehicleInfo->driverEntNum == botNum ) { //mal: we're the driver, if the turret is available, we may jump into it to fight enemies.
				if ( hasGunnerSeatOpen ) {
					if ( enemyInfo.enemyDist < 1500.0f && vehicleGunnerTime + 30000 < botWorld->gameLocalInfo.time && enemyInfo.enemyVisible ) { //mal: dont do this if enemy too far away, or its been too soon since we last did this.
						botUcmd->botCmds.becomeGunner = true;
						vehicleGunnerTime = botWorld->gameLocalInfo.time + 10000;
						needMovementUpdate = true;
					}
				} //mal: if we have a gunner, we'll try to get a better shot for him, so that he can cut down our enemies.
			}

			if ( botInfo->proxyInfo.weapon == MINIGUN ) {
				if ( botVehicleInfo->driverEntNum == -1 ) {
					if ( vehicleGunnerTime < botWorld->gameLocalInfo.time || !enemyInfo.enemyVisible ) { //mal: even if we had a driver and he bailed, become the driver for a better shot, then can go back to the gun.
						botUcmd->botCmds.becomeDriver = true;
						needMovementUpdate = true;
					}
				}
			}

			break;

		case DESECRATOR:
			if ( botVehicleInfo->driverEntNum == botNum ) {
				if ( enemyInAirborneVehicle && enemyInfo.enemyDist <= TANK_MINIGUN_RANGE && hasGunnerSeatOpen ) {
					botUcmd->botCmds.becomeGunner = true; 
					needMovementUpdate = true;
					break;
				}
			} else {
				if ( ( enemyInAirborneVehicle && enemyInfo.enemyDist > TANK_MINIGUN_RANGE && botVehicleInfo->driverEntNum == -1 ) || !enemyInAirborneVehicle ) {
					botUcmd->botCmds.becomeDriver = true;
					needMovementUpdate = true;
					break;
				}
			}

			break;

		case HOG:
			if ( botInfo->proxyInfo.weapon == MINIGUN ) {
				if ( botVehicleInfo->driverEntNum == -1 ) {
					if ( vehicleGunnerTime < botWorld->gameLocalInfo.time || !enemyInfo.enemyVisible || botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE && !enemyInAirborneVehicle ) { //mal: even if we had a driver and he bailed, become the driver for a better shot, then can go back to the gun.
						botUcmd->botCmds.becomeDriver = true;
						needMovementUpdate = true;
					} //mal: we'll prefer to ram our enemies who are in vehicles
				}
			}

			if ( botVehicleInfo->driverEntNum == botNum && ( !Bot_VehicleCanRamClient( enemy ) || VEHICLE_COMBAT_MOVEMENT_STATE == NULL || combatMoveType != VEHICLE_RAM_ATTACK_MOVEMENT ) ) {
				if ( ( enemyInAirborneVehicle || ( enemyInfo.enemyDist < 3000.0f && enemyInfo.enemyDist > 700.0f ) ) && vehicleGunnerTime + 30000 < botWorld->gameLocalInfo.time && enemyInfo.enemyVisible ) {
					botUcmd->botCmds.becomeGunner = true;
					vehicleGunnerTime = botWorld->gameLocalInfo.time + 10000;
					needMovementUpdate = true;
				}
			}

			break;

		case ANANSI:
		case HORNET:
			if ( botInfo->proxyInfo.weapon == MINIGUN ) {
				if ( botVehicleInfo->driverEntNum == -1 ) {
					botUcmd->botCmds.becomeDriver = true; //mal: our coward of a pilot bailed on us... take the controls!
					needMovementUpdate = true;
				}
			}

			if ( botVehicleInfo->driverEntNum == botNum ) {
				if ( botInfo->proxyInfo.weapon == LAW ) { //mal: law is better against other vehicles
					if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE ) {
						botUcmd->botCmds.switchVehicleWeap = true;
					} else {
						if ( botInfo->proxyInfo.weaponIsReady == false && rocketTime < botWorld->gameLocalInfo.time && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) { //mal: use rockets if LAW outta charge
							rocketTime = botWorld->gameLocalInfo.time + 2000;
							botUcmd->botCmds.switchVehicleWeap = true;
						}
					}
				}

				if ( botInfo->proxyInfo.weapon == ROCKETS ) { //mal: rockets are nice against slow moving ground targets.
					if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE && rocketTime < botWorld->gameLocalInfo.time ) {
						botUcmd->botCmds.switchVehicleWeap = true;
					}
				}
			}

			break;		
	}

	if ( needMovementUpdate ) {
		COMBAT_MOVEMENT_STATE = NULL;
		VEHICLE_COMBAT_MOVEMENT_STATE = NULL;
		vehicleUpdateTime = botWorld->gameLocalInfo.time + 500;
	}

	weapSwitchTime = botWorld->gameLocalInfo.time + 1500;
}
Exemple #18
0
/*
==================
idBotAI::Bot_VehicleCanRamClient

See if the vehicle can ram the client in question, in the vehicle the bot is in.
==================
*/
bool idBotAI::Bot_VehicleCanRamClient( int clientNum ) {
	int areaNum;
	proxyInfo_t enemyVehicleInfo;
	idVec3 vec;
	idVec3 enemyOrg;

	if ( botVehicleInfo->type != HOG && botVehicleInfo->health < ( botVehicleInfo->maxHealth / 4 ) && botWorld->clientInfo[ clientNum ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {
		return false;
	} //mal: most vehicles can't handle ramming other vehicles while damaged - clients on foot are ALWAYS ok tho! >:-D

	if ( botVehicleInfo->flags & WATER || botVehicleInfo->inWater || botVehicleInfo->type == GOLIATH || botVehicleInfo->type == DESECRATOR || botVehicleInfo->flags & PERSONAL || botVehicleInfo->flags & AIR ) {
		return false;
	}

	if ( botVehicleInfo->type != HOG && botVehicleInfo->forwardSpeed < 100.0f && enemyInfo.enemyDist < 700.0f ) {
		return false;
	}

	if ( botWorld->clientInfo[ clientNum ].proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE ) {

		enemyOrg = botWorld->clientInfo[ clientNum ].origin;
		areaNum = botWorld->clientInfo[ clientNum ].areaNumVehicle;

		if ( botWorld->clientInfo[ clientNum ].inWater || !botWorld->clientInfo[ enemy ].inPlayZone ) {
			return false;
		}

		if ( !botWorld->clientInfo[ clientNum ].hasGroundContact ) {
			return false;
		}
	} else {
		GetVehicleInfo( botWorld->clientInfo[ clientNum ].proxyInfo.entNum, enemyVehicleInfo );

		enemyOrg = enemyVehicleInfo.origin;
		areaNum = enemyVehicleInfo.areaNumVehicle;

		if ( enemyVehicleInfo.isAirborneVehicle ) {
			return false;
		}

		if ( enemyVehicleInfo.isEmpty ) {
			return false;
		}

		if ( !enemyVehicleInfo.inPlayZone ) {
			return false;
		}

		if ( enemyVehicleInfo.inWater ) {
			return false;
		}
	}

	bool canReach = botThreadData.Nav_IsDirectPath( AAS_VEHICLE, botInfo->team, botInfo->areaNumVehicle, botVehicleInfo->origin, enemyOrg );

	if ( !canReach ) {
		return false;
	}

	return true;
}
Exemple #19
0
/*
================
idBotAI::Bot_ShouldVehicleChaseHiddenEnemy
================
*/
bool idBotAI::Bot_ShouldVehicleChaseHiddenEnemy() {

	proxyInfo_t enemyVehicleInfo;
	idVec3 vec;
	chasingEnemy = false;

	if ( ClientHasObj( botNum ) || Client_IsCriticalForCurrentObj( botNum, -1.0f ) ) { //mal: never chase if we are important!
		return false;
	}

	if ( botVehicleInfo->driverEntNum != botNum ) { //mal: we dont get the choice to chase someone if we're not the driver!
		return false;
	}

	if ( botVehicleInfo->health <= ( botVehicleInfo->maxHealth / 4 ) && !ClientHasObj( enemy ) ) { //mal: if we're in pretty bad shape, randomly decide to sometimes give up the fight....
		if ( botThreadData.random.RandomInt( 100 ) > 50 ) {
            return false;
		}
	}

	if ( ( botVehicleInfo->flags & PERSONAL ) || botInfo->proxyInfo.weapon == NULL_VEHICLE_WEAPON && !ClientHasObj( enemy ) ) {
		return false;
	} //mal: if we dont have a vehicle weapon to fight with, or we're in a personal transport, dont go chasing ppl.

	if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {

		GetVehicleInfo( botWorld->clientInfo[ enemy ].proxyInfo.entNum, enemyVehicleInfo );

		if ( enemyVehicleInfo.inWater && !botVehicleInfo->isAirborneVehicle || !( botVehicleInfo->flags & WATER ) ) {
			return false;
		} //mal: hes in the water, but we can't chase him, so forget him!

		if ( !ClientHasObj( enemy ) && !Client_IsCriticalForCurrentObj( enemy, 2000.0f ) ) {
            if ( botThreadData.random.RandomInt( 100 ) > 50 ) {
				return false;
			}
		}
	}

	if ( AIStack.STACK_AI_NODE != NULL && AIStack.isPriority != false && !ClientHasObj( enemy ) ) {
		return false;
	} // we have something important on our mind, and cant chase ATM - UNLESS they have the obj! Always chase them!

	vec = enemyInfo.enemy_LS_Pos - botInfo->origin;
	
	if ( vec.LengthSqr() > Square( ENEMY_CHASE_DIST ) ) {
		return false;
	} // too far away to chase

	vec = enemyInfo.enemy_LS_Pos - botWorld->clientInfo[ enemy ].origin;

	if ( vec.LengthSqr() > Square( 900.0f ) && !ClientHasObj( enemy ) && !Client_IsCriticalForCurrentObj( enemy, 1500.0f ) ) { // unless he's REALLY close or a threat, sometimes we'll stop the chase, just because....
		if ( botThreadData.random.RandomInt( 100 ) > 50 ) {
            return false;
		}
	}

	chasingEnemy = true;

	if ( ClientHasObj( enemy ) ) {
		chaseEnemyTime = botWorld->gameLocalInfo.time + 30000;
	} else if ( Client_IsCriticalForCurrentObj( enemy, 1500.0f ) ) {
		chaseEnemyTime = botWorld->gameLocalInfo.time + 15000;
	} else {
		chaseEnemyTime = botWorld->gameLocalInfo.time + 7000;
	}

	return true;
}
Exemple #20
0
/*
================
idBotAI::Bot_VehicleFindBetterEnemy
================
*/
bool idBotAI::Bot_VehicleFindBetterEnemy() {
	int i;
	int entClientNum = enemy;
	float dist;
	float entDist;
	proxyInfo_t vehicleInfo;
	proxyInfo_t enemyVehicleInfo;
	idVec3 vec;

	if ( enemy == -1 ) { //mal: we lost our enemy for some reason, so just skip finding a new one til next frame.
		return false;
	}

	if ( ignoreNewEnemiesWhileInVehicleTime > botWorld->gameLocalInfo.time ) {
		return false;
	}

	if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) { //mal: if we're attacking the MCP, its the priority.
		if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum == botWorld->botGoalInfo.botGoal_MCP_VehicleNum ) {
			return false;
		}
	}

	GetVehicleInfo( botWorld->clientInfo[ enemy ].proxyInfo.entNum, enemyVehicleInfo );

	if ( enemyVehicleInfo.entNum > 0 && ( enemyVehicleInfo.type == ANANSI || enemyVehicleInfo.type == HORNET ) ) { //mal: stay in dogfights!
		return false;
	}

	const clientInfo_t& enemyPlayerInfo = botWorld->clientInfo[ enemy ];

    vec = enemyPlayerInfo.origin - botInfo->origin;
	entDist = vec.LengthSqr();

	if ( !enemyInfo.enemyVisible ) { //mal: if we can't see our current enemy, more likely to attack a visible enemy.
		entDist = idMath::INFINITY;
	}

	if ( botWorld->gameLocalInfo.botSkill == BOT_SKILL_DEMO && !botWorld->botGoalInfo.gameIsOnFinalObjective && ( !enemyPlayerInfo.isBot || enemyPlayerInfo.isActor ) ) { //mal: dont worry about keeping our human target in training mode, unless its the final obj...
		entDist += Square( TRAINING_MODE_RANGE_ADDITION );
	}

	bool curEnemyNotInVehicle = false;

	if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE && !ClientIsDefusingOurTeamCharge( enemy ) && !vehicleEnemyWasInheritedFromFootCombat ) { //mal: if our current enemy is on foot, more likely to pick a better target. Unless they're defusing our charge, or an enemy we jumped in this vehicle for, then we artificially raise their importance.
		curEnemyNotInVehicle = true;
	}
	
	numVisEnemies = 1; //mal: our current enemy is always visible to us

	for ( i = 0; i < MAX_CLIENTS; i++ ) {

		if ( !ClientIsValid( i, -1 ) ) {
			continue; //mal: no valid client in this client slot!
		}

		if ( i == botNum ) {
			continue; //mal: dont try to fight ourselves!
		}

		if ( i == enemy ) { //mal: ignore an enemy we already have
			continue;
		}

		if ( EnemyIsIgnored( i ) ) {
			continue; //mal: dont try to fight someone we've flagged to ignore for whatever reason!
		}

//mal: if we're in the middle of a critical obj, dont go looking for trouble, unless they're shooting us!
		if ( Client_IsCriticalForCurrentObj( botNum, -1.0f ) && ( botInfo->lastAttacker != i || botInfo->lastAttackerTime + 3000 < botWorld->gameLocalInfo.time ) && !ClientIsDefusingOurTeamCharge( i ) ) {
			continue;
		}

		const clientInfo_t& playerInfo = botWorld->clientInfo[ i ];

		if ( playerInfo.isNoTarget ) {
			continue;
		} //mal: dont target clients that have notarget set - this is useful for debugging, etc.

		if ( playerInfo.isDisguised && playerInfo.disguisedClient != botNum ) {
			continue; //mal: won't "see" disguised clients, unless they look like us!
		}

		if ( playerInfo.inLimbo ) {
			continue;
		}

		if ( playerInfo.isActor ) {
			continue;
		}

		if ( playerInfo.invulnerableEndTime > botWorld->gameLocalInfo.time ) {
			continue; //mal: ignore revived/just spawned in clients - get the ppl around them!
		}

		if ( playerInfo.health <= 0 ) {
			continue;
		}

		if ( playerInfo.team == botInfo->team ) {
			continue;
		}

		if ( botWorld->gameLocalInfo.botSkill == BOT_SKILL_DEMO && !botWorld->botGoalInfo.gameIsOnFinalObjective && !playerInfo.isBot && enemyPlayerInfo.isBot ) { //mal: dont worry about human targets in training mode if we have a bot one, unless its the final obj...
			continue;
		}

		if ( botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) { //mal: st00pid bot - your not smart enough to pick your targets wisely
			if ( enemyVehicleInfo.entNum > 0 && enemyInfo.enemyVisible ) {

				if ( !( enemyVehicleInfo.flags & PERSONAL ) && !( enemyVehicleInfo.flags & WATER ) && ( enemyVehicleInfo.isAirborneVehicle && enemyVehicleInfo.xyspeed > 900.0f && entDist > Square( 2000.0f ) ) ) {
                    if ( playerInfo.proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE && !Client_IsCriticalForCurrentObj( i, 1500.0f ) && !ClientHasObj( i ) ) {
						continue;
					} //mal: dont worry about an enemy in a vehicle if the vehicle is far away, moving too fast, is not a real threat
				}
			}
		} //mal: if our current enemy is in a vehicle, and this guy isn't, and this guy doesn't have an obj, or isn't important, hes not worth fighting.

		bool enemyIsInAirAttackVehicle = false;

		if ( playerInfo.proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) { //mal: pick the driver of a vehicle as the target, NOT passengers, unless there is no driver - then kill whoever.
			
			GetVehicleInfo( playerInfo.proxyInfo.entNum, vehicleInfo );

			if ( vehicleInfo.driverEntNum != i && vehicleInfo.driverEntNum != -1 ) {
				continue;
			}

			if ( vehicleInfo.type == ANANSI || vehicleInfo.type == HORNET ) {
				enemyIsInAirAttackVehicle = true;
			} else {
				vec = vehicleInfo.origin - botInfo->origin;				

				if ( vehicleInfo.xyspeed > 600.0f && vec.LengthSqr() > Square( 1900.0f ) && !InFrontOfVehicle( vehicleInfo.entNum, botInfo->origin ) ) { //mal: if they're in a mad dash away from us, forget about them!
					continue;
				}
			}
		}

		vec = playerInfo.origin - botInfo->origin;
		dist = vec.LengthSqr();

		if ( !enemyIsInAirAttackVehicle ) {
			if ( dist > Square( ENEMY_SIGHT_BUSY_DIST * 2.0f ) ) {
				continue;
			}
		}

		float tempDist = entDist;

		if ( curEnemyNotInVehicle && playerInfo.proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {
			tempDist += Square( 3000.0f );
		}

		if ( !enemyIsInAirAttackVehicle ) {
			if ( dist > tempDist ) {
				continue;
			}
		} else {
			if ( dist > Square( AIRCRAFT_ATTACK_DIST ) ) {
				continue;
			}
		}

		if ( !ClientIsVisibleToBot ( i, true, false ) ) {
			continue;
		}

		if ( Client_IsCriticalForCurrentObj( i, 1500.0f ) && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) { //mal: if a critical class, get high priority
			dist = Square( 600.0f );
			ignoreNewEnemiesWhileInVehicleTime = botWorld->gameLocalInfo.time + IGNORE_NEW_ENEMIES_TIME;
		}

		if ( ClientHasObj( i ) && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) { //mal: if have docs, get HIGHER priority.
			dist = Square( 500.0f );
			ignoreNewEnemiesWhileInVehicleTime = botWorld->gameLocalInfo.time + IGNORE_NEW_ENEMIES_TIME;
		}

		if ( ClientIsDefusingOurTeamCharge( i ) && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) { //mal: if defusing our charge, get HIGHER priority.
			dist = Square( 100.0f );
			ignoreNewEnemiesWhileInVehicleTime = botWorld->gameLocalInfo.time + IGNORE_NEW_ENEMIES_TIME;
		}

		if ( botWorld->botGoalInfo.mapHasMCPGoal && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) {
			if ( playerInfo.proxyInfo.entNum == botWorld->botGoalInfo.botGoal_MCP_VehicleNum ) {
				dist = Square( 400.0f );
				ignoreNewEnemiesWhileInVehicleTime = botWorld->gameLocalInfo.time + IGNORE_NEW_ENEMIES_TIME;
			}
		}

		if ( enemyIsInAirAttackVehicle && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) { //mal: dont ignore a chance to dogfight!
			dist = Square( 100.0f );
			ignoreNewEnemiesWhileInVehicleTime = botWorld->gameLocalInfo.time + IGNORE_NEW_ENEMIES_TIME;
		}

		numVisEnemies++;
		entClientNum = i;
		entDist = dist;
	}

	if ( entClientNum != enemy ) {
		enemy = entClientNum;
		enemySpawnID = botWorld->clientInfo[ entClientNum ].spawnID;

		enemyInfo.enemy_FS_Pos = botWorld->clientInfo[ entClientNum ].origin;
		enemyInfo.enemy_LS_Pos = enemyInfo.enemy_FS_Pos;

		enemyInfo.enemyLastVisTime = botWorld->gameLocalInfo.time;

		enemyAcquireTime = botWorld->gameLocalInfo.time;

		bot_FS_Enemy_Pos = botInfo->origin;
		bot_LS_Enemy_Pos = bot_FS_Enemy_Pos;

		VEHICLE_COMBAT_AI_SUB_NODE = NULL; //mal: reset the bot's combat AI node and movement state.
		COMBAT_MOVEMENT_STATE = NULL;
		return true;
	}

	return false;
}
Exemple #21
0
/*
================
idBotAI::Bot_CheckVehicleAttack
================
*/
void idBotAI::Bot_CheckVehicleAttack() {
	float minFOV = ( botInfo->proxyInfo.weapon == TANK_GUN ) ? 0.95f : 0.60f;
	idVec3 dir;

	if ( botVehicleInfo->type == ICARUS ) {
		botUcmd->botCmds.attack = true;
		return;
	}

	if ( botInfo->proxyInfo.weapon == NULL_VEHICLE_WEAPON ) {
		return;
	}

	if ( gunTargetEntNum > -1 && gunTargetEntNum < MAX_CLIENTS ) {
		if ( botWorld->clientInfo[ gunTargetEntNum ].team == botInfo->team && !botWorld->gameLocalInfo.inWarmup ) { 
			return;
		}
	} //mal: hold your fire! have a friendly in the way.

	if ( timeOnTarget > botWorld->gameLocalInfo.time ) { //mal: haven't had time enough to "react" to this threat...
		return;
	}

	if ( !botInfo->proxyInfo.weaponIsReady && botInfo->proxyInfo.weapon == TANK_GUN ) { //mal: strogg hyperblaster will report not ready between shots, which can confuse the bots
		return;
	}

	if ( botInfo->proxyInfo.weapon == PERSONAL_WEAPON ) {
		if ( enemyInfo.enemyInfont ) {
			if ( botInfo->weapInfo.weapon == ROCKET ) {
				if ( botInfo->targetLocked ) { 
                    botUcmd->botCmds.attack = true;
				}
			} else {
				botUcmd->botCmds.attack = true;
			}
		}
		return;
	}

	if ( botInfo->proxyInfo.weapon == LAW ) {
 		if ( botVehicleInfo->type == TROJAN ) {
			if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {
				proxyInfo_t enemyVehicle;
				GetVehicleInfo( botWorld->clientInfo[ enemy ].proxyInfo.entNum, enemyVehicle );

				if ( enemyVehicle.type >= ICARUS ) {
					if ( botInfo->targetLocked ) {
						botUcmd->botCmds.attack = true;
					}
				} else {
					botUcmd->botCmds.attack = true;
				}
			} else {
				botUcmd->botCmds.attack = true;
			}
		} else {
			if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {
				if ( botInfo->targetLocked ) {
					botUcmd->botCmds.attack = true;
				}
			}
		}
		return;
	}

	if ( botInfo->proxyInfo.weapon == ROCKETS ) {
		if ( botVehicleInfo->isAirborneVehicle ) {
			minFOV = 0.95f;
		}

		dir = botWorld->clientInfo[ enemy ].origin - botVehicleInfo->origin;
        dir.NormalizeFast(); 
		if ( dir * botVehicleInfo->axis[ 0 ] > minFOV ) { //mal: we have them in our sights - FIRE!
			botUcmd->botCmds.attack = true;
		}
		return;
	}

	if ( botInfo->proxyInfo.hasTurretWeapon ) {
		if ( botVehicleInfo->type > ICARUS && botInfo->proxyInfo.weapon == MINIGUN ) {
			botUcmd->botCmds.attack = true;
		} else {
			dir = botWorld->clientInfo[ enemy ].origin - botInfo->proxyInfo.weaponOrigin;
			dir.NormalizeFast(); 
			if ( dir * botInfo->proxyInfo.weaponAxis[0] > minFOV ) { //mal: we have them in our sights - FIRE!
				botUcmd->botCmds.attack = true;
			}
		}
	} else {
		if ( InFrontOfVehicle( botInfo->proxyInfo.entNum, botWorld->clientInfo[ enemy ].origin ) ) {
			botUcmd->botCmds.attack = true; //mal: they're in front of us - FIRE!
		}
	}

	if ( botWorld->gameLocalInfo.botSkill == BOT_SKILL_EASY && botVehicleInfo->driverEntNum == botNum && botInfo->proxyInfo.weapon != MINIGUN ) { //mal: have a delay between shots for low skill bots.
		if ( botUcmd->botCmds.attack == true ) {
			timeOnTarget = botWorld->gameLocalInfo.time + ( ( botVehicleInfo->isAirborneVehicle ) ? 9500 : 5500 );
		}
	}
}
Exemple #22
0
/*
================
idBotAI::Bot_VehicleFindEnemy

We'll sort thru the clients, and ignore certain clients if we're too busy
to be buggered (carrying obj, planting/hacking, etc) or they're not valid enemies
(in disguise, hidden by smoke, etc).
================
*/
bool idBotAI::Bot_VehicleFindEnemy() {
	bool hasAttackedMate;
	bool hasAttackedCriticalMate;
	bool hasObj;
	bool isDefusingOurBomb;
	bool inFront;
	bool botGotShotRecently;
	bool botIsBigShot;
	bool audible;
	bool isVisible;
	bool isFacingUs;
	bool isFiringWeapon;
	bool isNearOurObj;
	bool isAttackingDeployable = false;
	bool inAttackAirCraft = false;
	int i;
	int entClientNum = -1;
	float dist;
	float botSightDist;
	float tempSightDist;
	float entDist = idMath::INFINITY;
	proxyInfo_t enemyVehicleInfo;
	enemyVehicleInfo.entNum = 0;
	idVec3 vec;

	numVisEnemies = 0;

	vehicleEnemyWasInheritedFromFootCombat = false;

	botSightDist = Square( ENEMY_VEHICLE_SIGHT_DIST ); //mal_FIXME: break this out into a script cmd!

/*
	if ( botSightDist > Square( 8000.0f ) ) {
		botSightDist = Square( 8000.0f );
	} else if ( botSightDist < Square( 3000.0f ) ) {
		botSightDist = Square( 3000.0f );
	}
*/

//mal: some debugging stuff....
	if ( botWorld->gameLocalInfo.botIgnoreEnemies == 1 ) {
			return false;
	} else if ( botWorld->gameLocalInfo.botIgnoreEnemies == 2 ) {
			if ( botInfo->team == GDF ) {
				return false;
			}
	} else if ( botWorld->gameLocalInfo.botIgnoreEnemies == 3 ) {
			if ( botInfo->team == STROGG ) {
				return false;
			}
		}

	if ( botVehicleInfo->type != BUFFALO && Bot_VehicleIsUnderAVTAttack() != -1 && ( ( botVehicleInfo->flags & ARMOR ) || botVehicleInfo->type > ICARUS ) ) {
		return false;
	}

	if ( botVehicleInfo->type > ICARUS ) {
		botSightDist = Square( 6000.0f );
	}

	if ( botVehicleInfo->type == BUFFALO ) {
		botSightDist = Square( 3500.0f );
	}

	if ( botVehicleInfo->type == GOLIATH || botVehicleInfo->type == DESECRATOR ) { //mal: these 2 are really limited
		botSightDist = Square( PLASMA_CANNON_RANGE - 1000.0f );
	}

	if ( botVehicleInfo->type == HUSKY ) { //mal: we're no match for anybody!
		return false;
	}

#ifdef _XENON
	if ( botVehicleInfo->type == MCP && botVehicleInfo->driverEntNum == botNum ) {
		return false;
	}

	if ( botVehicleInfo->type == PLATYPUS && botVehicleInfo->driverEntNum == botNum ) {
		return false;
	}
#endif

	if ( botVehicleInfo->type > ICARUS && Client_IsCriticalForCurrentObj( botNum, -1.0f ) ) {
		return false;
	}

	botIsBigShot = Client_IsCriticalForCurrentObj( botNum, 3500.0f );

	if ( aiState == VLTG && vLTGType == V_DESTROY_DEPLOYABLE ) {
		deployableInfo_t deployable;
		if ( GetDeployableInfo( false, vLTGTarget, deployable ) ) {
			if ( deployable.type == APT || deployable.type == AVT || deployable.type == AIT ) { //mal: these are the priorities
				isAttackingDeployable = true;
			}
		}
	}

	for ( i = 0; i < MAX_CLIENTS; i++ ) {

		if ( !ClientIsValid( i, -1 ) ) {
			continue; //mal: no valid client in this client slot!
		}

		if ( i == botNum ) {
			continue; //mal: dont try to fight ourselves!
		}

		if ( EnemyIsIgnored( i ) ) {
			continue; //mal: dont try to fight someone we've flagged to ignore for whatever reason!
		}

		if ( !Bot_VehicleCanAttackEnemy( i ) ) { //mal: check if the bot has access to a weapon in the vehicle, that can hit this client.
			continue;
		}

		const clientInfo_t& playerInfo = botWorld->clientInfo[ i ];

		if ( playerInfo.isNoTarget ) {
			continue;
		} //mal: dont target clients that have notarget set - this is useful for debugging, etc.

		bool enemyIsBigShot = Client_IsCriticalForCurrentObj( i, 2500.0f );

		if ( playerInfo.inLimbo ) {
			continue;
		}

		if ( playerInfo.invulnerableEndTime > botWorld->gameLocalInfo.time ) {
			continue; //mal: ignore revived/just spawned in clients - get the ppl around them!
		}

		if ( playerInfo.isActor ) {
			continue;
		}

		if ( playerInfo.health <= 0 ) {
			continue;
		}

		if ( playerInfo.team == botInfo->team ) {
			continue;
		}

		if ( botVehicleInfo->type == MCP && botVehicleInfo->driverEntNum == botNum ) {
			if ( !InFrontOfVehicle( botInfo->proxyInfo.entNum, playerInfo.origin ) ) {
				continue;
			}
		}

		if ( botWorld->gameLocalInfo.botSkill == BOT_SKILL_DEMO && botVehicleInfo->type > ICARUS && !playerInfo.isBot ) { //mal: don't attack human players in training mode when we're in flyers.
			continue;
		}

		hasAttackedCriticalMate = ClientHasAttackedTeammate( i, true, 3000 );
		hasAttackedMate = ClientHasAttackedTeammate( i, false, 3000 );
		hasObj = ClientHasObj( i );
		isDefusingOurBomb = ClientIsDefusingOurTeamCharge( i );
		inFront = ( botInfo->proxyInfo.weapon == PERSONAL_WEAPON ) ? InFrontOfClient( botNum, playerInfo.origin) : InFrontOfVehicle( botInfo->proxyInfo.entNum, playerInfo.origin );
		isFacingUs = ( playerInfo.proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE ) ? InFrontOfClient( i, botInfo->origin ) : InFrontOfVehicle( playerInfo.proxyInfo.entNum, botInfo->origin );
		botGotShotRecently = ( botInfo->lastAttackerTime + 3000 < botWorld->gameLocalInfo.time ) ? false : true;
		isFiringWeapon = playerInfo.weapInfo.isFiringWeap;
		isNearOurObj = ( LocationDistFromCurrentObj( botInfo->team, playerInfo.origin ) < 2500.0f ) ? true : false;
		bool isCriticalEnemy = Client_IsCriticalForCurrentObj( i, 2500.0f );

		if ( playerInfo.proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) { 
			GetVehicleInfo( playerInfo.proxyInfo.entNum, enemyVehicleInfo );
		}

		if ( isAttackingDeployable ) {
			if ( botInfo->team == botWorld->botGoalInfo.attackingTeam ) {
				if ( playerInfo.proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE ) {
					if ( playerInfo.weapInfo.weapon != ROCKET && !isDefusingOurBomb ) {
						continue;
					}
				} else {
					if ( !( enemyVehicleInfo.flags & ARMOR ) && enemyVehicleInfo.type != ANANSI && enemyVehicleInfo.type != HORNET ) {
			continue;
		}
				}
			} else {
				if ( !isDefusingOurBomb && playerInfo.proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE && !hasObj && playerInfo.weapInfo.weapon != ROCKET && ( !isCriticalEnemy || !isNearOurObj ) ) {
					continue;
				}
			}
		}

		if ( botIsBigShot && !isFacingUs && ( !botGotShotRecently || botInfo->lastAttacker != i ) && !isFiringWeapon && !hasObj && !isNearOurObj ) {
			continue;
		} //mal: if we're trying to do an important obj, dont get into a fight with everyone.

		vec = playerInfo.origin - botInfo->origin;

		if ( botVehicleInfo->isAirborneVehicle ) {
			vec.z = 0.0f;
		}

		dist = vec.LengthSqr();

		if ( botIsBigShot && !inFront && dist > Square( 2500.0f ) && ( !botGotShotRecently || botInfo->lastAttacker != i ) && botVehicleInfo->driverEntNum == botNum ) {
			continue;
		}

		if ( playerInfo.proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) { //mal: pick the driver of a vehicle as the target, NOT passengers, unless there is no driver - then kill whoever.
			if ( enemyVehicleInfo.type == ANANSI || enemyVehicleInfo.type == HORNET ) {
				inAttackAirCraft = true;
			}

			if ( botIsBigShot && enemyVehicleInfo.type <= ICARUS ) {
				continue;
			}

			if ( enemyVehicleInfo.type == BUFFALO && botVehicleInfo->flags & ARMOR && playerInfo.isBot ) {
				continue;
			}

			if ( enemyVehicleInfo.type == MCP && enemyVehicleInfo.isImmobilized && enemyVehicleInfo.driverEntNum == i ) {
				continue;
			}

			if ( botVehicleInfo->type == ANANSI && enemyVehicleInfo.type == ICARUS ) { //mal: this is funny to watch, but is a waste of time. :-)
				continue;
			}

			if ( isAttackingDeployable ) {
				if ( botVehicleInfo->isAirborneVehicle && ( enemyVehicleInfo.type <= ICARUS || enemyVehicleInfo.type == BUFFALO ) ) { //mal: if attacking from the air, only worry about air vehicles.
					continue;
				}
			}

			if ( enemyVehicleInfo.driverEntNum != i && enemyVehicleInfo.driverEntNum != -1 ) {
				continue;
			}

			if ( inAttackAirCraft && enemyVehicleInfo.xyspeed > 500.0f && dist > Square( TANK_MINIGUN_RANGE ) && botVehicleInfo->flags & ARMOR ) { //mal: tanks won't attack fast moving aircraft that are too far away for their MGs
				continue;
			}

			if ( botVehicleInfo->type == BADGER ) {
				if ( botInfo->proxyInfo.weapon == NULL_VEHICLE_WEAPON && enemyVehicleInfo.flags & ARMOR || enemyVehicleInfo.inWater || ( enemyVehicleInfo.isAirborneVehicle && dist > Square( 3000.0f ) || enemyVehicleInfo.type == HOG ) ) {
                    continue;
				}
			}

			if ( botVehicleInfo->inWater && botInfo->proxyInfo.weapon == NULL_VEHICLE_WEAPON ) {
				continue;
			}

			if ( botVehicleInfo->type != ANANSI && botVehicleInfo->type != HORNET ) {
                if ( enemyVehicleInfo.xyspeed > 600.0f && dist > Square( 1900.0f ) && !InFrontOfVehicle( enemyVehicleInfo.entNum, botInfo->origin ) && !ClientHasObj( i ) && !enemyIsBigShot ) { //mal: if they're in a mad dash away from us, forget about them!
					continue;
				}
			}
		}

		if ( botVehicleInfo->type == BUFFALO && !inAttackAirCraft ) { //mal_TODO: need to make the buffalo a more effective fighting platform!
			continue;
		}

		tempSightDist = botSightDist;

		if ( !ClientHasObj( i ) && !enemyIsBigShot && playerInfo.proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE && !playerInfo.isCamper && playerInfo.killsSinceSpawn < KILLING_SPREE && botVehicleInfo->driverEntNum == botNum && !isDefusingOurBomb ) { //mal: vehicles will prefer to fight other vehicles, not some guy on foot a mile away....
			tempSightDist = Square( 3500.0f );
		}

		if ( inAttackAirCraft && ( botVehicleInfo->type == ANANSI || botVehicleInfo->type == HORNET ) && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) {
			tempSightDist = Square( AIRCRAFT_ATTACK_DIST );
		}

		if ( dist > tempSightDist ) {
            continue;
		}

		if ( playerInfo.isDisguised ) { //mal: when in a vehicle, bots are much less likely to notice or worry about coverts
			if ( botThreadData.GetBotSkill() == BOT_SKILL_EASY ) {
				continue;
			} else {
				if ( ( playerInfo.disguisedClient != botNum && !hasAttackedMate ) || dist > Square( 2500.0f ) ) {
                    continue;
				}
			}
		} 

 		if ( !ClientHasObj( i ) ) {
            audible = ClientIsAudibleToVehicle( i ); //mal: if we can hear you, we'll skip the FOV test in the vis check below
		} else {
            audible = true;
			dist = Square( 500.0f ); //mal: if you've got the docs, your our priority target, unless someone else is right on top of us!
		}

		isVisible = ClientIsVisibleToBot( i, !audible, false );

		if ( !isVisible && !ClientHasObj( i ) ) {
			continue;
		}

		if ( botWorld->gameLocalInfo.botSkill != BOT_SKILL_DEMO || botWorld->botGoalInfo.gameIsOnFinalObjective || botWorld->botGoalInfo.attackingTeam == botInfo->team ) {
			if ( isDefusingOurBomb ) {
				dist = Square( 100.0f );
			}

			if ( hasAttackedCriticalMate && inFront && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) {
				dist = Square( 600.0f ); //mal: will give higher priority to someone attacking a critical mate, if we can see it happening.
			}

			if ( botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) {
				if ( Client_IsCriticalForCurrentObj( i, 6000.0f ) ) {
					dist = Square( 700.0f ); //mal: if your a critical client, we're more likely to kill you.
				}
			}

			if ( botWorld->botGoalInfo.mapHasMCPGoal ) {
				if ( playerInfo.proxyInfo.entNum == botWorld->botGoalInfo.botGoal_MCP_VehicleNum ) {
					dist = 400.0f;
				}
			} //mal: if your in MCP, you get higher priority then a normal enemy. Especially when we're in a vehicle!

			if ( botVehicleInfo->type > ICARUS && botVehicleInfo->type != BUFFALO && ( playerInfo.isCamper || playerInfo.killsSinceSpawn >= KILLING_SPREE ) && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY && !playerInfo.isBot ) {
				dist = Square( 600.0f );
			} //mal: target trouble making humans!
		} else {
			if ( !playerInfo.isBot || playerInfo.isActor ) {
				dist += Square( TRAINING_MODE_RANGE_ADDITION );
			}
		}

		numVisEnemies++;

		if ( dist < entDist ) {
			entClientNum = i;
			entDist = dist;
		}
	}

	if ( entClientNum != -1 ) {
		enemy = entClientNum;
		enemySpawnID = botWorld->clientInfo[ entClientNum ].spawnID;

		enemyInfo.enemy_FS_Pos = botWorld->clientInfo[ entClientNum ].origin;
		enemyInfo.enemy_LS_Pos = enemyInfo.enemy_FS_Pos;

		bot_FS_Enemy_Pos = botInfo->origin;
		bot_LS_Enemy_Pos = bot_FS_Enemy_Pos;
		enemyInfo.enemyLastVisTime = botWorld->gameLocalInfo.time;
		enemyAcquireTime = botWorld->gameLocalInfo.time;

		Bot_SetAttackTimeDelay( inFront ); //mal: this sets a delay on how long the bot should take to see enemy, based on bot's state.

		VEHICLE_COMBAT_AI_SUB_NODE = NULL; //mal: reset the bot's combat AI node
		COMBAT_MOVEMENT_STATE = NULL;
		return true;
	}

	return false;
}
Exemple #23
0
/*
================
idBotAI::Vehicle_Air_To_Air_Movement

Air to Air specific attack case.
Special case: Air vehicles can't attack one way, while move in another. So they need to have their attack/move unified.
This is a bit of a hack, but theres no time to do anything else. :-(
================
*/
bool idBotAI::Vehicle_Air_To_Air_Movement() {
	bool overRideLook = false;
	bool enemyInFront;
	bool botInFrontOfEnemy;
	float desiredRange;
	float tooCloseDist;
	float dist;
	proxyInfo_t enemyVehicleInfo;
	idVec3 enemyOrg;
	idVec3 vec;

	if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE ) {
		Bot_ResetEnemy();
		return false;
	}

	GetVehicleInfo( botWorld->clientInfo[ enemy ].proxyInfo.entNum, enemyVehicleInfo );
	enemyOrg = enemyVehicleInfo.origin;

	vec = enemyOrg - botVehicleInfo->origin;
	vec.z = 0.0f;
	dist = vec.LengthSqr();
	float tempDist = vec.LengthFast();

	Bot_CheckVehicleAttack(); //mal: always see if we can get a shot off.

	if ( botInfo->enemyHasLockon && dist < Square( 6000.0f ) && botWorld->gameLocalInfo.botSkill == BOT_SKILL_EASY ) { //mal: OH NOES!1 Panic and run for it.
		Bot_IgnoreEnemy( enemy, 3000 );
		Bot_ResetEnemy();
		return false;
	}

	if ( botVehicleInfo->type == ANANSI ) {
		desiredRange = 5000.0f;
		tooCloseDist = 2500.0f;

		if ( Bot_CheckEnemyHasLockOn( enemy ) && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY && botWorld->gameLocalInfo.botSkill != BOT_SKILL_DEMO ) { //mal: they need a bit of an edge
			botUcmd->botCmds.launchDecoysNow = true;
		}

		if ( dist < Square( tooCloseDist ) && combatMoveTime < botWorld->gameLocalInfo.time && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) {
			combatMoveDir = BACK;
			combatMoveTime = botWorld->gameLocalInfo.time + 5000;
			botUcmd->botCmds.launchDecoys = true; //mal: we're exposing our flank, so fire some decoys to cover our move.
		}

		if ( combatMoveTime > botWorld->gameLocalInfo.time ) {
			if ( !InAirVehicleGunSights( enemyVehicleInfo.entNum, botInfo->origin ) ) { //mal: he can't see us anymore, so attack!
				combatMoveTime = 0;
				overRideLook = true;
			}
		}

		if ( combatMoveTime > 0 ) {
			vec = enemyOrg;
			vec += ( -desiredRange * enemyVehicleInfo.axis[ 0 ] ); 

			if ( !botThreadData.Nav_IsDirectPath( AAS_VEHICLE, botInfo->team, botInfo->areaNumVehicle, botInfo->aasVehicleOrigin, vec ) ) {
				combatMoveTime = 0;
				return true;
			}

			Bot_SetupVehicleMove( vec, -1, ACTION_NULL );

			if ( MoveIsInvalid() ) {
				combatMoveTime = 0;
				return true;
			}

			Bot_MoveToGoal( botAAS.path.moveGoal, vec3_zero, RUN, NULLMOVETYPE );
			Bot_LookAtLocation( botAAS.path.viewGoal, SMOOTH_TURN );
			return true;
		}
	} else { //must be in a hornet
		 desiredRange = 2500.0f; //mal: was 1500
		 tooCloseDist = 0.0f;

		if ( dist < Square( desiredRange ) && combatMoveTime < botWorld->gameLocalInfo.time && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) {
			int n = botThreadData.random.RandomInt( 3 ); //mal: we're too close, so manuever around our enemy and fire. low skill bots need not apply.

			if ( n == 0 ) {
				combatMoveDir = BACK;
			} else if ( n == 1 ) {
				combatMoveDir = RIGHT;
			} else {
				combatMoveDir = LEFT;
			}

			combatMoveTime = botWorld->gameLocalInfo.time + 5000;
			botUcmd->botCmds.launchDecoys = true; //mal: we're exposing our flank, so fire some decoys to cover our move.
		}

		if ( combatMoveTime > botWorld->gameLocalInfo.time ) {
			if ( !InAirVehicleGunSights( enemyVehicleInfo.entNum, botInfo->origin ) ) { //mal: he can't see us anymore, so attack!
				combatMoveTime = 0;
				overRideLook = true;
			}
		}

		if ( combatMoveTime > 0 ) {
			vec = enemyOrg;
			if ( combatMoveDir == BACK ) {
				vec += ( -desiredRange * botInfo->viewAxis[ 0 ] ); //mal: this seems wrong, but it works SO well.
			} else if ( combatMoveDir == RIGHT ) {
				vec += ( desiredRange * ( botInfo->viewAxis[ 1 ] * -1 ) );
			} else if ( combatMoveDir == LEFT ) {
				vec += ( -desiredRange * ( botInfo->viewAxis[ 1 ] * -1 ) );
			}

			if ( !botThreadData.Nav_IsDirectPath( AAS_VEHICLE, botInfo->team, botInfo->areaNumVehicle, botInfo->aasVehicleOrigin, vec ) ) {
				combatMoveTime = 0;
				return true;
			}

			Bot_SetupVehicleMove( vec, -1, ACTION_NULL );

			if ( MoveIsInvalid() ) {
				combatMoveTime = 0;
				return true;
			}

			Bot_MoveToGoal( botAAS.path.moveGoal, vec3_zero, RUN, NULLMOVETYPE );
			Bot_LookAtLocation( botAAS.path.viewGoal, SMOOTH_TURN );
			return true;
		}
	}

	enemyInFront = InFrontOfVehicle( botVehicleInfo->entNum, enemyOrg );
	botInFrontOfEnemy = InFrontOfVehicle( enemyVehicleInfo.entNum, botInfo->origin );

	if ( dist > Square( desiredRange ) )  {
		Bot_SetupVehicleMove( vec3_zero, enemy, ACTION_NULL );

		if ( MoveIsInvalid() ) {
			Bot_IgnoreEnemy( enemy, ENEMY_IGNORE_TIME ); //mal: no valid path to this client for some reason - ignore him for a while
			Bot_ResetEnemy();
			return false;
		}

//mal: if we're just moving into range of the target, we'll try to get a lock. If not ( or in danger ) we'll gun it. Fighter pilot mantra: speed is life.
		Bot_MoveToGoal( botAAS.path.moveGoal, vec3_zero, RUN, ( botInFrontOfEnemy && enemyInFront && dist > Square( 6000.0f ) && botVehicleInfo->forwardSpeed > 1500.0f && !botInfo->enemyHasLockon ) ? AIR_COAST : NULLMOVETYPE );

		if ( enemyInFront || overRideLook ) {
			Bot_LookAtEntity( enemy, SMOOTH_TURN );
		} else {
			Bot_LookAtLocation( botAAS.path.viewGoal, SMOOTH_TURN );
		}
	} else {
		Bot_SetupVehicleMove( vec3_zero, enemy, ACTION_NULL ); //mal: still want to take into account obstacles, so do a move check.

		if ( MoveIsInvalid() ) {
			Bot_IgnoreEnemy( enemy, ENEMY_IGNORE_TIME ); //mal: no valid path to this client for some reason - ignore him for a while
			Bot_ResetEnemy();
			return false;
		}

		Bot_MoveToGoal( botAAS.path.moveGoal, vec3_zero, RUN, ( botAAS.obstacleNum == -1 ) ? AIR_BRAKE : NULLMOVETYPE );
		Bot_LookAtEntity( enemy, SMOOTH_TURN );
	}

	return true;
}
Exemple #24
0
/*
================
idBotAI::Vehicle_Air_To_Ground_Movement

Ground Specific attack case.
Special case: Air vehicles can't attack one way, while move in another. So they need to have their attack/move unified.
This is a bit of a hack, but theres no time to do anything else. :-(
================
*/
bool idBotAI::Vehicle_Air_To_Ground_Movement() {
	bool overRideLook = false;
	bool inVehicle = false;
	float desiredRange = 5800.0f;
	float tooCloseRange = 2700.0f;
	float enemySpeed = 0.0f;
	float dist;
	proxyInfo_t enemyVehicleInfo;
	idVec3 enemyOrg;
	idVec3 vec;

	if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {
		GetVehicleInfo( botWorld->clientInfo[ enemy ].proxyInfo.entNum, enemyVehicleInfo );
		enemyOrg = enemyVehicleInfo.origin;
		inVehicle = true;
	} else {
		enemyOrg = botWorld->clientInfo[ enemy ].origin;
	}

	enemySpeed = botWorld->clientInfo[ enemy ].xySpeed;

	vec = enemyOrg - botVehicleInfo->origin;
	vec[ 2 ] = 0.0f;
	dist = vec.LengthSqr();

	Bot_CheckVehicleAttack(); //mal: always see if we can get a shot off.

	if ( botInfo->enemyHasLockon && dist < Square( 6000.0f ) && botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) { //mal: OH NOES! Panic and run for it. 
		Bot_IgnoreEnemy( enemy, 3000 );
		Bot_ResetEnemy();
		return false;
	}

//mal: we're too close, so manuever around our enemy and fire. 
	if ( dist < Square( tooCloseRange ) && combatMoveTime < botWorld->gameLocalInfo.time && enemySpeed < SPRINTING_SPEED ) { //mal: if they're moving fast, just let them move into our crosshairs..
		int actionNumber = ACTION_NULL;

		if ( botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY ) {
			actionNumber = Bot_FindNearbySafeActionToMoveToward( botInfo->origin, ( desiredRange ) );
		}

		if ( actionNumber != -1 ) {
			combatMoveActionGoal = actionNumber;
			combatMoveTime = botWorld->gameLocalInfo.time + 10000;
			combatMoveTooCloseRange = ( inVehicle ) ? 5000.0f : tooCloseRange + 1000.0f;
		} else {
			int n = botThreadData.random.RandomInt( 3 );

			if ( n == 0 ) {
				combatMoveDir = BACK;
			} else if ( n == 1 ) {
				combatMoveDir = RIGHT;
			} else {
				combatMoveDir = LEFT;
			}

			combatMoveTime = botWorld->gameLocalInfo.time + 5000;
			combatMoveTooCloseRange = tooCloseRange;
		}
	}

	if ( combatMoveTime > botWorld->gameLocalInfo.time ) {
		if ( dist > Square( combatMoveTooCloseRange ) ) { //mal: we're far enough away to get a shot - attack.
			combatMoveTime = 0;
			combatMoveActionGoal = ACTION_NULL;
			overRideLook = true;
		}
	}

	if ( combatMoveTime > botWorld->gameLocalInfo.time ) {
		if ( combatMoveActionGoal != ACTION_NULL ) {
			Bot_SetupVehicleMove( vec3_zero, -1, combatMoveActionGoal );
		} else {
			vec = enemyOrg;
			if ( combatMoveDir == BACK ) {
				vec += ( -tooCloseRange * botWorld->clientInfo[ enemy ].viewAxis[ 0 ] );
			} else if ( combatMoveDir == RIGHT ) {
				vec += ( tooCloseRange * ( botWorld->clientInfo[ enemy ].viewAxis[ 1 ] * -1 ) );
			} else if ( combatMoveDir == LEFT ) {
				vec += ( -tooCloseRange * ( botWorld->clientInfo[ enemy ].viewAxis[ 1 ] * -1 ) );
			}

			vec.z = botVehicleInfo->origin.z;

			if ( !botThreadData.Nav_IsDirectPath( AAS_VEHICLE, botInfo->team, botInfo->areaNumVehicle, botInfo->aasVehicleOrigin, vec ) ) {
				combatMoveTime = 0;
				return true;
			}

			Bot_SetupVehicleMove( vec, -1, ACTION_NULL );
		}

		if ( MoveIsInvalid() ) {
			combatMoveTime = 0;
			combatMoveActionGoal = ACTION_NULL;
			return true;
		}

		Bot_MoveToGoal( botAAS.path.moveGoal, vec3_zero, RUN, NULLMOVETYPE );
		Bot_LookAtLocation( botAAS.path.viewGoal, SMOOTH_TURN );
		return true;
	}

	if ( dist > Square( desiredRange ) )  {
		Bot_SetupVehicleMove( vec3_zero, enemy, ACTION_NULL );

		if ( MoveIsInvalid() ) {
			Bot_IgnoreEnemy( enemy, ENEMY_IGNORE_TIME ); //mal: no valid path to this client for some reason - ignore him for a while
			Bot_ResetEnemy();
			return false;
		}

		Bot_MoveToGoal( botAAS.path.moveGoal, vec3_zero, RUN, NULLMOVETYPE );

		if ( InFrontOfVehicle( botVehicleInfo->entNum, enemyOrg ) || overRideLook ) {
			Bot_LookAtEntity( enemy, SMOOTH_TURN );
		} else {
			Bot_LookAtLocation( botAAS.path.viewGoal, SMOOTH_TURN );
		}
	} else {
		Bot_SetupVehicleMove( vec3_zero, enemy, ACTION_NULL ); //mal: still want to take into account obstacles, so do a move check.

		if ( MoveIsInvalid() ) {
			Bot_IgnoreEnemy( enemy, ENEMY_IGNORE_TIME ); //mal: no valid path to this client for some reason - ignore him for a while
			Bot_ResetEnemy();
			return false;
		}

		botMoveTypes_t defaultMoveType = AIR_BRAKE;

		if ( botWorld->gameLocalInfo.botSkill > BOT_SKILL_EASY && Bot_VehicleIsUnderAVTAttack() != -1 || Bot_CheckIfEnemyHasUsInTheirSightsWhenInAirVehicle() || Bot_CheckEnemyHasLockOn( -1, true ) || combatKeepMovingTime > botWorld->gameLocalInfo.time ) { //mal: do a bombing run if someone is shooting at us!
			defaultMoveType = NULLMOVETYPE;

			if ( combatKeepMovingTime < botWorld->gameLocalInfo.time ) {
				combatKeepMovingTime = botWorld->gameLocalInfo.time + FLYER_AVOID_DANGER_TIME;
			}
		}

		Bot_MoveToGoal( botAAS.path.moveGoal, vec3_zero, RUN, ( botAAS.obstacleNum == -1 ) ? defaultMoveType : NULLMOVETYPE );
		Bot_LookAtEntity( enemy, SMOOTH_TURN );
	}

	return true;
}
Exemple #25
0
void Vehicle::ApplyAllImmunities()
{
    // This couldn't be done in DB, because some spells have MECHANIC_NONE

    // Vehicles should be immune on Knockback ...
    _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
    _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);

    // Mechanical units & vehicles ( which are not Bosses, they have own immunities in DB ) should be also immune on healing ( exceptions in switch below )
    if (_me->ToCreature() && _me->ToCreature()->GetCreatureInfo()->type == CREATURE_TYPE_MECHANICAL && !_me->ToCreature()->isWorldBoss())
    {
        // Heal & dispel ...
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_DISPEL, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);

        // ... Shield & Immunity grant spells ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_IMMUNITY, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_UNATTACKABLE, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_ABSORB, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_IMMUNE_SHIELD, true);

        // ... Resistance, Split damage, Change stats ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_DAMAGE_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SPLIT_DAMAGE_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_RESISTANCE, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STAT, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, true);
    }

    // Different immunities for vehicles goes below
    switch (GetVehicleInfo()->m_ID)
    {
        // code below prevents a bug with movable cannons
        case 160: // Strand of the Ancients
        case 244: // Wintergrasp
        case 510: // Isle of Conquest
            _me->SetControlled(true, UNIT_STATE_ROOT);
            // why we need to apply this? we can simple add immunities to slow mechanic in DB
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
            break;
        // Wintergrasp Siege Engine -- need to remove general knockback immunity here
        case 117:
        case 324:
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, false);
            _me->ApplySpellImmune(0, IMMUNITY_ID, 50652, true); // Ram - used by Wintergrasp Demolisher
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61391, true); // Typhoon - Rank 1 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61390, true); // Typhoon - Rank 2 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61388, true); // Typhoon - Rank 3 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61387, true); // Typhoon - Rank 4 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 53227, true); // Typhoon - Rank 5 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 51490, true); // Thunderstorm - Rank 1 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 59156, true); // Thunderstorm - Rank 2 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 59158, true); // Thunderstorm - Rank 3 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 59159, true); // Thunderstorm - Rank 4 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 11113, true); // Blast Wave - Rank 1 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13018, true); // Blast Wave - Rank 2 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13019, true); // Blast Wave - Rank 3 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13020, true); // Blast Wave - Rank 4 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13021, true); // Blast Wave - Rank 5 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 27133, true); // Blast Wave - Rank 6 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 33933, true); // Blast Wave - Rank 7 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 42944, true); // Blast Wave - Rank 8 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 42945, true); // Blast Wave - Rank 9 - Mage talent
            break;
        // Wintergrasp Demolisher -- need to remove general knockback immunity here
        case 106:
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, false);
            _me->ApplySpellImmune(0, IMMUNITY_ID, 51678, true); // Ram - used by Wintergrasp Siege Engine
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61391, true); // Typhoon - Rank 1 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61390, true); // Typhoon - Rank 2 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61388, true); // Typhoon - Rank 3 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61387, true); // Typhoon - Rank 4 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 53227, true); // Typhoon - Rank 5 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 51490, true); // Thunderstorm - Rank 1 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 59156, true); // Thunderstorm - Rank 2 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 59158, true); // Thunderstorm - Rank 3 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 59159, true); // Thunderstorm - Rank 4 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 11113, true); // Blast Wave - Rank 1 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13018, true); // Blast Wave - Rank 2 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13019, true); // Blast Wave - Rank 3 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13020, true); // Blast Wave - Rank 4 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13021, true); // Blast Wave - Rank 5 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 27133, true); // Blast Wave - Rank 6 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 33933, true); // Blast Wave - Rank 7 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 42944, true); // Blast Wave - Rank 8 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 42945, true); // Blast Wave - Rank 9 - Mage talent
            break;
        // Battleground Demolisher -- need to remove general knockback immunity here
        case 158:
            _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, false);
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61391, true); // Typhoon - Rank 1 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61390, true); // Typhoon - Rank 2 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61388, true); // Typhoon - Rank 3 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 61387, true); // Typhoon - Rank 4 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 53227, true); // Typhoon - Rank 5 - Druid talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 51490, true); // Thunderstorm - Rank 1 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 59156, true); // Thunderstorm - Rank 2 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 59158, true); // Thunderstorm - Rank 3 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 59159, true); // Thunderstorm - Rank 4 - Shaman talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 11113, true); // Blast Wave - Rank 1 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13018, true); // Blast Wave - Rank 2 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13019, true); // Blast Wave - Rank 3 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13020, true); // Blast Wave - Rank 4 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 13021, true); // Blast Wave - Rank 5 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 27133, true); // Blast Wave - Rank 6 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 33933, true); // Blast Wave - Rank 7 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 42944, true); // Blast Wave - Rank 8 - Mage talent
            _me->ApplySpellImmune(0, IMMUNITY_ID, 42945, true); // Blast Wave - Rank 9 - Mage talent
            break;
        default:
            break;
    }
}
Exemple #26
0
/*
================
idBotAI::Vehicle_Stand_Ground_Movement
================
*/
bool idBotAI::Vehicle_Stand_Ground_Movement() {

//	int result;
	bool enemyHasVehicle = false;
	float tooCloseDist = 750.0f;
	proxyInfo_t enemyVehicleInfo;
	idVec3 vec;

	if ( combatMoveFailedCount >= 10 ) {
		VEHICLE_COMBAT_MOVEMENT_STATE = NULL;
		return false;
	}

	if ( botWorld->clientInfo[ enemy ].proxyInfo.entNum != CLIENT_HAS_NO_VEHICLE ) {
		GetVehicleInfo( botWorld->clientInfo[ enemy ].proxyInfo.entNum, enemyVehicleInfo );
		enemyHasVehicle = true;
	}

	if ( combatDangerExists ) {
		Bot_SetupVehicleQuickMove( botInfo->origin, false ); //mal: just path to itself, if its in an obstacle, it will freak and avoid it.

		if ( MoveIsInvalid() ) {
			VEHICLE_COMBAT_MOVEMENT_STATE = NULL;
			return false;
		}

		vec = botAAS.path.moveGoal - botInfo->origin;

		if ( vec.LengthSqr() > Square( 25.0f ) ) {
			Bot_MoveToGoal( botAAS.path.moveGoal, vec3_zero, SPRINT, NULLMOVETYPE );
		}

		return true;
	}

	if ( botVehicleInfo->type == TROJAN && botVehicleInfo->driverEntNum == botNum ) {
		if ( !InFrontOfVehicle( botVehicleInfo->entNum, botWorld->clientInfo[ enemy ].origin ) ) {
			Bot_SetupVehicleMove( vec3_zero, enemy, ACTION_NULL );
            
			if ( MoveIsInvalid() ) {
				VEHICLE_COMBAT_MOVEMENT_STATE = NULL;
				return false;
			}

            Bot_MoveToGoal( botAAS.path.moveGoal, vec3_zero, RUN, NULLMOVETYPE );
			return true;
		}
	}


/*
	if ( ( !botInfo->proxyInfo.weaponIsReady && botInfo->proxyInfo.weapon == TANK_GUN ) || combatMoveTime < botWorld->gameLocalInfo.time && !vehicleInfo.inSiegeMode ) {

		if ( combatMoveDir == NULL_DIR ) {
            result = botThreadData.random.RandomInt( 4 );

			if ( result == 0 ) {
				combatMoveDir = FORWARD;
			} else if ( result == 1 ) {
				combatMoveDir = BACK;
			} else if ( result == 2 ) {
				combatMoveDir = RIGHT;
			} else {
				combatMoveDir = LEFT;
			}

			combatMoveTime = botWorld->gameLocalInfo.time + 2000;
		}

		if ( Bot_CanMove( combatMoveDir, 300.0f, true ) ) {
            Bot_MoveToGoal( botCanMoveGoal, vec3_zero, RUN, NULLMOVETYPE );
		} else {
			combatMoveDir = NULL_DIR;
			combatMoveFailedCount++;
		}

		return true;
	}
*/

	if ( enemyInfo.enemyDist < tooCloseDist ) {
		if ( botVehicleInfo->type == GOLIATH ) {
			const clientInfo_t& enemyPlayer = botWorld->clientInfo[ enemy ];
			botUcmd->botCmds.exitSiegeMode = true;
			if ( enemyPlayer.proxyInfo.entNum == CLIENT_HAS_NO_VEHICLE ) {
				Bot_MoveToGoal( vec3_zero, vec3_zero, NULLMOVEFLAG, TAUNT_MOVE );
				return true;
			}
		}

		if ( enemyInfo.enemyInfont ) {
            if ( Bot_VehicleCanMove( BACK, 100.0f, true )) {
  				Bot_MoveToGoal( botCanMoveGoal, vec3_zero, REVERSE, NULLMOVETYPE );
			} else if ( Bot_VehicleCanMove( RIGHT, 100.0f, true ) ) {
				Bot_MoveToGoal( botCanMoveGoal, vec3_zero, REVERSE, NULLMOVETYPE );
			} else if ( Bot_VehicleCanMove( LEFT, 100.0f, true ) ) {
				Bot_MoveToGoal( botCanMoveGoal, vec3_zero, REVERSE, NULLMOVETYPE );
			} else {
				combatMoveFailedCount++;
			}
		} else {
			if ( Bot_VehicleCanMove( FORWARD, 100.0f, true )) {
  				Bot_MoveToGoal( botCanMoveGoal, vec3_zero, RUN, NULLMOVETYPE );
			} else if ( Bot_VehicleCanMove( RIGHT, 100.0f, true ) ) {
				Bot_MoveToGoal( botCanMoveGoal, vec3_zero, RUN, NULLMOVETYPE );
			} else if ( Bot_VehicleCanMove( LEFT, 100.0f, true ) ) {
				Bot_MoveToGoal( botCanMoveGoal, vec3_zero, RUN, NULLMOVETYPE );
			} else {
				combatMoveFailedCount++;
			}
		}

		return true;
	}

	if ( botVehicleInfo->type == GOLIATH && !botVehicleInfo->inSiegeMode ) {
		idVec3 enemyOrg = botWorld->clientInfo[ enemy ].origin;
		trace_t trace;
		botThreadData.clip->TracePointExt( CLIP_DEBUG_PARMS trace, botVehicleInfo->origin, enemyOrg, BOT_VISIBILITY_TRACE_MASK, GetGameEntity( botNum ), GetGameEntity( botVehicleInfo->entNum ) );
		if ( enemyInfo.enemyDist > 1200.0f && trace.fraction == 1.0f ) {
            botUcmd->botCmds.enterSiegeMode = true;
		}
	} else if ( botVehicleInfo->type == DESECRATOR ) {
        if ( enemyHasVehicle && enemyVehicleInfo.type != TITAN ) {
			if ( enemyInfo.enemyDist > 1500.0f ) {
                botUcmd->botCmds.enterSiegeMode = true;
			}
		} /* else {												
			if ( combatMoveTime < botWorld->gameLocalInfo.time ) {		//mal_NOTE: this just caused more problems then its worth.
				if ( combatMoveDir == NULL_DIR ) {
                    if ( botThreadData.random.RandomInt( 100 ) > 50 ) {
						combatMoveDir = RIGHT;
					} else {
						combatMoveDir = LEFT;
					}
				} else {
                    if ( combatMoveDir == RIGHT ) {
						combatMoveDir = LEFT;
					} else {
						combatMoveDir = RIGHT;
					}
				}

				combatMoveTime = botWorld->gameLocalInfo.time + 5000;
			}

            if ( combatMoveDir == RIGHT ) {
				Bot_MoveToGoal( vec3_zero, vec3_zero, NULLMOVEFLAG, LEAN_RIGHT );
			} else {
				Bot_MoveToGoal( vec3_zero, vec3_zero, NULLMOVEFLAG, LEAN_LEFT );
			}
			return true;
		} */
	}

	Bot_MoveToGoal( vec3_zero, vec3_zero, NULLMOVEFLAG, FULL_STOP ); //mal: hit the brakes!

	return true;
}
Exemple #27
0
void Vehicle::ApplyAllImmunities()
{
    // This couldn't be done in DB, because some spells have MECHANIC_NONE

    // Vehicles should be immune on Knockback ...
    //_me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
    //_me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);

    // Mechanical units & vehicles ( which are not Bosses, they have own immunities in DB ) should be also immune on healing ( exceptions in switch below )
    if (_me->ToCreature() && _me->ToCreature()->GetCreatureTemplate()->type == CREATURE_TYPE_MECHANICAL && !_me->ToCreature()->isWorldBoss())
    {
        // Heal & dispel ...
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_MAX_HEALTH, true); // Xinef
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_DISPEL, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);

        // ... Shield & Immunity grant spells ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_IMMUNITY, true);
        //_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_UNATTACKABLE, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_IMMUNE_SHIELD, true);
        if (_me->GetZoneId() == BATTLEFIELD_WG_ZONEID || _me->ToCreature()->GetDBTableGUIDLow() || (_me->FindMap() && _me->FindMap()->Instanceable()))
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_ABSORB, true);

        // ... Resistance, Split damage, Change stats ...
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_DAMAGE_SHIELD, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SPLIT_DAMAGE_PCT, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_RESISTANCE, true);
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STAT, true);

        // Taunt
        _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
        _me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
    }

    // Different immunities for vehicles goes below
    switch (GetVehicleInfo()->m_ID)
    {
        case 160: //Isle of conquest turret
        case 244: //Wintergrasp turret
        case 510: // Isle of Conquest
        case 452: // Isle of Conquest
        case 543: // Isle of Conquest
            //_me->SetControlled(true, UNIT_STATE_ROOT);
            //me->AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
            //me->SetSpeed(MOVE_TURN_RATE, 0.7f);
            //me->SetSpeed(MOVE_PITCH_RATE, 0.7f);
            //me->m_movementInfo.flags2=59;
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
            break;
        // Ulduar vehicles, remove immunities used in flame leviathan spells
        case 335:
        case 336:
        case 338:
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, false);
            _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_ABSORB, false);
            break;
        default:
            break;
    }
}