| 2352 | } |
| 2353 | |
| 2354 | bool AiMelee(object *obj) { |
| 2355 | ai_frame *ai_info = obj->ai_info; |
| 2356 | vector f_vec; |
| 2357 | float dot; |
| 2358 | |
| 2359 | object *target = ObjGet(ai_info->target_handle); |
| 2360 | |
| 2361 | if (target == NULL) { |
| 2362 | ai_info->status_reg &= ~AISR_MELEE; |
| 2363 | return false; |
| 2364 | } |
| 2365 | |
| 2366 | if (((Gametime - ai_info->last_see_target_time) > 4.0 && ((Gametime - ai_info->last_hear_target_time) > 4.0)) || |
| 2367 | ai_info->awareness <= AWARE_BARELY) { |
| 2368 | ai_info->status_reg &= ~AISR_MELEE; |
| 2369 | return false; |
| 2370 | } |
| 2371 | |
| 2372 | if (ai_info->next_melee_time > Gametime) { |
| 2373 | ai_info->status_reg &= ~AISR_MELEE; |
| 2374 | return false; |
| 2375 | } |
| 2376 | |
| 2377 | if (ai_info->next_animation_type == AS_MELEE1 || ai_info->next_animation_type == AS_MELEE2) { |
| 2378 | ai_info->status_reg |= AISR_MELEE; |
| 2379 | return false; |
| 2380 | } |
| 2381 | |
| 2382 | if (!(ai_info->flags & (AIF_MELEE1 | AIF_MELEE2))) { |
| 2383 | ai_info->status_reg &= ~AISR_MELEE; |
| 2384 | return false; |
| 2385 | } |
| 2386 | |
| 2387 | // The AI wants to attack!!!!! |
| 2388 | ai_info->status_reg |= AISR_MELEE; |
| 2389 | |
| 2390 | // Determine if we are in melee range |
| 2391 | if (!MeleeHitOk(obj)) { |
| 2392 | return false; |
| 2393 | } |
| 2394 | |
| 2395 | f_vec = obj->orient.fvec; |
| 2396 | vm_NormalizeVector(&f_vec); |
| 2397 | |
| 2398 | dot = f_vec * ai_info->vec_to_target_perceived; |
| 2399 | |
| 2400 | if (dot >= 0.8f) { |
| 2401 | gi_fire attack_info; |
| 2402 | int attack_num; |
| 2403 | |
| 2404 | if (!(ai_info->flags & AIF_MELEE1) || ((ai_info->flags & AIF_MELEE2) && (ps_rand() > (D3_RAND_MAX >> 1)))) { |
| 2405 | attack_num = 1; |
| 2406 | } else { |
| 2407 | attack_num = 0; |
| 2408 | } |
| 2409 | |
| 2410 | // mprintf(0, "Melee attack now!!!!\n"); |
| 2411 |
no test coverage detected