X operations(XOPS)に非常に近いFPSゲームを制作・リメイクし、成果物をオープンソースとして公開することを目的としたプロジェクトです。
| Revision | 179 (tree) |
|---|---|
| Time | 2017-06-18 16:46:47 |
| Author | |
AIが攻撃を受けた方向を向くよう改良、死亡した際に倒れる方向を制御するように
| @@ -45,6 +45,8 @@ | ||
| 45 | 45 | battlemode = AI_NORMAL; |
| 46 | 46 | cautionback_posx = 0.0f; |
| 47 | 47 | cautionback_posz = 0.0f; |
| 48 | + FaceCaution_flag = false; | |
| 49 | + FaceCaution_rx = 0.0f; | |
| 48 | 50 | total_move = 0.0f; |
| 49 | 51 | waitcnt = 0; |
| 50 | 52 | movejumpcnt = 1*((int)GAMEFPS); |
| @@ -380,6 +382,31 @@ | ||
| 380 | 382 | int pointmode; |
| 381 | 383 | MoveNavi->GetTargetPos(NULL, NULL, &target_rx, NULL, &pointmode); |
| 382 | 384 | |
| 385 | + //撃たれて警戒したなら、撃たれた方向を向く | |
| 386 | + if( (battlemode == AI_CAUTION)&&(FaceCaution_flag == true) ){ | |
| 387 | + float tr; | |
| 388 | + | |
| 389 | + //方向を計算 | |
| 390 | + tr = FaceCaution_rx - rx; | |
| 391 | + for(; tr > (float)M_PI; tr -= (float)M_PI*2){} | |
| 392 | + for(; tr < (float)M_PI*-1; tr += (float)M_PI*2){} | |
| 393 | + | |
| 394 | + //旋回 | |
| 395 | + if( tr > DegreeToRadian(2.5f) ){ | |
| 396 | + ObjDriver->SetModeFlag(AI_CTRL_TURNRIGHT); | |
| 397 | + } | |
| 398 | + if( tr < DegreeToRadian(-2.5f) ){ | |
| 399 | + ObjDriver->SetModeFlag(AI_CTRL_TURNLEFT); | |
| 400 | + } | |
| 401 | + | |
| 402 | + //特定方向に向き終われば、普通の警戒に移行する | |
| 403 | + if( fabs(tr) <= DegreeToRadian(2.5f) ){ | |
| 404 | + FaceCaution_flag = false; | |
| 405 | + } | |
| 406 | + | |
| 407 | + return; | |
| 408 | + } | |
| 409 | + | |
| 383 | 410 | //回転の開始・終了確率を設定 |
| 384 | 411 | if( battlemode == AI_ACTION ){ |
| 385 | 412 | return; |
| @@ -1475,6 +1502,8 @@ | ||
| 1475 | 1502 | else{ |
| 1476 | 1503 | newbattlemode = AI_CAUTION; |
| 1477 | 1504 | cautioncnt = 160; |
| 1505 | + FaceCaution_flag = false; | |
| 1506 | + FaceCaution_rx = 0.0f; | |
| 1478 | 1507 | } |
| 1479 | 1508 | } |
| 1480 | 1509 |
| @@ -1491,6 +1520,7 @@ | ||
| 1491 | 1520 | bool AIcontrol::CautionMain() |
| 1492 | 1521 | { |
| 1493 | 1522 | int newbattlemode = AI_CAUTION; |
| 1523 | + float caution_rx; | |
| 1494 | 1524 | |
| 1495 | 1525 | //座標とチーム番号を取得 |
| 1496 | 1526 | int teamid; |
| @@ -1497,7 +1527,7 @@ | ||
| 1497 | 1527 | ctrlhuman->GetParamData(NULL, NULL, NULL, &teamid); |
| 1498 | 1528 | |
| 1499 | 1529 | //被弾と音の状況を取得 |
| 1500 | - bool HitFlag = ctrlhuman->CheckHit(); | |
| 1530 | + bool HitFlag = ctrlhuman->CheckHit(&caution_rx); | |
| 1501 | 1531 | soundlist soundlist[MAX_SOUNDMGR_LIST]; |
| 1502 | 1532 | int soundlists = GameSound->GetWorldSound(posx, posy + VIEW_HEIGHT, posz, teamid, soundlist); |
| 1503 | 1533 |
| @@ -1511,13 +1541,18 @@ | ||
| 1511 | 1541 | newbattlemode = AI_ACTION; |
| 1512 | 1542 | actioncnt = 0; |
| 1513 | 1543 | } |
| 1514 | - else if( SearchEnemy() != 0 ){ //敵が見つかれば | |
| 1544 | + else if( SearchEnemy() != 0 ){ //敵が見つかれば | |
| 1515 | 1545 | newbattlemode = AI_ACTION; |
| 1516 | 1546 | actioncnt = 0; |
| 1517 | 1547 | } |
| 1518 | - else if( (HitFlag == true)||(soundlists > 0) ){ //被弾したか音が聞こえた | |
| 1519 | - cautioncnt = 160; //警戒を再開 | |
| 1548 | + else if( HitFlag == true ){ //被弾した | |
| 1549 | + cautioncnt = 160; //警戒を再開 | |
| 1550 | + FaceCaution_flag = true; | |
| 1551 | + FaceCaution_rx = caution_rx; | |
| 1520 | 1552 | } |
| 1553 | + else if( soundlists > 0 ){ //音が聞こえた | |
| 1554 | + cautioncnt = 160; //警戒を再開 | |
| 1555 | + } | |
| 1521 | 1556 | else if( cautioncnt == 0 ){ //警戒を終了するなら |
| 1522 | 1557 | if( CheckTargetPos(true) == false ){ //警戒開始地点より離れているか |
| 1523 | 1558 | MoveTarget(true); //警戒開始地点に近づく |
| @@ -1524,6 +1559,8 @@ | ||
| 1524 | 1559 | } |
| 1525 | 1560 | else{ |
| 1526 | 1561 | newbattlemode = AI_NORMAL; |
| 1562 | + FaceCaution_flag = false; | |
| 1563 | + FaceCaution_rx = 0.0f; | |
| 1527 | 1564 | |
| 1528 | 1565 | //警戒待ちパスなら次へ進める |
| 1529 | 1566 | pointdata pdata; |
| @@ -1534,7 +1571,7 @@ | ||
| 1534 | 1571 | } |
| 1535 | 1572 | } |
| 1536 | 1573 | } |
| 1537 | - else if( cautioncnt < 100 ){ //100フレームを切ったら、ランダムに警戒終了(カウント:0に) | |
| 1574 | + else if( (cautioncnt < 100)&&(FaceCaution_flag == false) ){ //100フレームを切ったら、ランダムに警戒終了(カウント:0に) | |
| 1538 | 1575 | if( GetRand(50) == 0 ){ cautioncnt = 0; } |
| 1539 | 1576 | } |
| 1540 | 1577 | else{ cautioncnt -= 1; } |
| @@ -1569,6 +1606,7 @@ | ||
| 1569 | 1606 | bool AIcontrol::NormalMain() |
| 1570 | 1607 | { |
| 1571 | 1608 | int newbattlemode = AI_NORMAL; |
| 1609 | + float caution_rx; | |
| 1572 | 1610 | |
| 1573 | 1611 | MoveNavi->MovePathNowState(); |
| 1574 | 1612 | enemyhuman = NULL; |
| @@ -1578,7 +1616,7 @@ | ||
| 1578 | 1616 | ctrlhuman->GetParamData(NULL, NULL, NULL, &teamid); |
| 1579 | 1617 | |
| 1580 | 1618 | //被弾と音の状況を取得 |
| 1581 | - bool HitFlag = ctrlhuman->CheckHit(); | |
| 1619 | + bool HitFlag = ctrlhuman->CheckHit(&caution_rx); | |
| 1582 | 1620 | soundlist soundlist[MAX_SOUNDMGR_LIST]; |
| 1583 | 1621 | int soundlists = GameSound->GetWorldSound(posx, posy + VIEW_HEIGHT, posz, teamid, soundlist); |
| 1584 | 1622 |
| @@ -1614,9 +1652,17 @@ | ||
| 1614 | 1652 | } |
| 1615 | 1653 | else{ //優先的な走り以外の処理 |
| 1616 | 1654 | //警戒判定に入る処理 |
| 1617 | - if( | |
| 1618 | - (SearchEnemy() != 0)|| //敵を見つけた | |
| 1619 | - (HitFlag == true)||(soundlists > 0)|| //被弾したか音が聞こえた | |
| 1655 | + if( HitFlag == true ){ //被弾した | |
| 1656 | + newbattlemode = AI_CAUTION; | |
| 1657 | + cautioncnt = 160; | |
| 1658 | + cautionback_posx = posx; | |
| 1659 | + cautionback_posz = posz; | |
| 1660 | + FaceCaution_flag = true; | |
| 1661 | + FaceCaution_rx = caution_rx; | |
| 1662 | + } | |
| 1663 | + else if( | |
| 1664 | + (SearchEnemy() != 0)|| //敵を見つけた | |
| 1665 | + (soundlists > 0)|| //音が聞こえた | |
| 1620 | 1666 | (CheckCorpse( GetRand(MAX_HUMAN) ) == true) //死体を見つけた |
| 1621 | 1667 | ){ |
| 1622 | 1668 | newbattlemode = AI_CAUTION; |
| @@ -1623,6 +1669,8 @@ | ||
| 1623 | 1669 | cautioncnt = 160; |
| 1624 | 1670 | cautionback_posx = posx; |
| 1625 | 1671 | cautionback_posz = posz; |
| 1672 | + FaceCaution_flag = false; | |
| 1673 | + FaceCaution_rx = 0.0f; | |
| 1626 | 1674 | } |
| 1627 | 1675 | else{ |
| 1628 | 1676 | MovePath(); //移動実行 |
| @@ -1657,6 +1705,8 @@ | ||
| 1657 | 1705 | NoFight = false; |
| 1658 | 1706 | battlemode = AI_NORMAL; |
| 1659 | 1707 | enemyhuman = NULL; |
| 1708 | + FaceCaution_flag = false; | |
| 1709 | + FaceCaution_rx = 0.0f; | |
| 1660 | 1710 | waitcnt = 0; |
| 1661 | 1711 | gotocnt = 0; |
| 1662 | 1712 | cautioncnt = 0; |
| @@ -1710,6 +1760,8 @@ | ||
| 1710 | 1760 | } |
| 1711 | 1761 | battlemode = AI_CAUTION; |
| 1712 | 1762 | cautioncnt = 160; |
| 1763 | + FaceCaution_flag = false; | |
| 1764 | + FaceCaution_rx = 0.0f; | |
| 1713 | 1765 | } |
| 1714 | 1766 | |
| 1715 | 1767 | //! @brief 非戦闘化フラグを設定 |
| @@ -75,6 +75,8 @@ | ||
| 75 | 75 | float ry; //!< Y軸回転角度 |
| 76 | 76 | float cautionback_posx; //!< 警戒後に戻るX座標 |
| 77 | 77 | float cautionback_posz; //!< 警戒後に戻るZ座標 |
| 78 | + bool FaceCaution_flag; //!< 警戒中に特定の報告を向くフラグ | |
| 79 | + float FaceCaution_rx; //!< 警戒中に向く方向 | |
| 78 | 80 | float total_move; //!< 合計移動量 |
| 79 | 81 | int waitcnt; //!< 時間待ちカウント |
| 80 | 82 | int movejumpcnt; //!< ジャンプ判定カウント |
| @@ -1965,7 +1965,7 @@ | ||
| 1965 | 1965 | } |
| 1966 | 1966 | |
| 1967 | 1967 | //ダメージを受けていれば、レッドフラッシュを描画する |
| 1968 | - redflash_flag = myHuman->CheckHit(); | |
| 1968 | + redflash_flag = myHuman->CheckHit(NULL); | |
| 1969 | 1969 | |
| 1970 | 1970 | //----------------------------------- |
| 1971 | 1971 |
| @@ -201,6 +201,7 @@ | ||
| 201 | 201 | MoveFlag_lt = MoveFlag; |
| 202 | 202 | scopemode = 0; |
| 203 | 203 | HitFlag = false; |
| 204 | + Hit_rx = 0.0f; | |
| 204 | 205 | totalmove = 0.0f; |
| 205 | 206 | StateGunsightErrorRange = 0; |
| 206 | 207 | ReactionGunsightErrorRange = 0; |
| @@ -265,6 +266,7 @@ | ||
| 265 | 266 | MoveFlag_lt = MoveFlag; |
| 266 | 267 | scopemode = 0; |
| 267 | 268 | HitFlag = false; |
| 269 | + Hit_rx = 0.0f; | |
| 268 | 270 | totalmove = 0.0f; |
| 269 | 271 | Invincible = false; |
| 270 | 272 |
| @@ -884,18 +886,23 @@ | ||
| 884 | 886 | } |
| 885 | 887 | |
| 886 | 888 | //! @brief 被弾フラグをセット |
| 887 | -void human::SetHitFlag() | |
| 889 | +//! @param rx 被弾した方向 | |
| 890 | +void human::SetHitFlag(float rx) | |
| 888 | 891 | { |
| 889 | 892 | HitFlag = true; |
| 893 | + Hit_rx = rx; | |
| 890 | 894 | } |
| 891 | 895 | |
| 892 | 896 | //! @brief 被弾したかチェックする |
| 897 | +//! @param rx 被弾した方向を受け取るポインタ(NULL可) | |
| 893 | 898 | //! @return 被弾した:true 被弾してない:false |
| 894 | 899 | //! @attention 実行すると、フラグは false に初期化されます。 |
| 895 | -bool human::CheckHit() | |
| 900 | +bool human::CheckHit(float *rx) | |
| 896 | 901 | { |
| 897 | 902 | bool returnflag = HitFlag; |
| 903 | + if( rx != NULL ){ *rx = Hit_rx; } | |
| 898 | 904 | HitFlag = false; |
| 905 | + //Hit_rx = 0.0f; | |
| 899 | 906 | return returnflag; |
| 900 | 907 | } |
| 901 | 908 |
| @@ -985,8 +992,15 @@ | ||
| 985 | 992 | |
| 986 | 993 | if( deadstate == 0 ){ |
| 987 | 994 | if( hp <= 0 ){ //HPが 0 以下になった(死亡した)瞬間なら、倒し始める |
| 995 | + float tr; | |
| 996 | + | |
| 997 | + //最後に攻撃を受けた方向を計算 | |
| 998 | + tr = Hit_rx - rotation_x; | |
| 999 | + for(; tr > (float)M_PI; tr -= (float)M_PI*2){} | |
| 1000 | + for(; tr < (float)M_PI*-1; tr += (float)M_PI*2){} | |
| 1001 | + | |
| 988 | 1002 | //体の角度 |
| 989 | - if( GetRand(2) == 0 ){ | |
| 1003 | + if( ((float)M_PI/2*-1 < tr)&&(tr < (float)M_PI/2) ){ | |
| 990 | 1004 | add_ry = HUMAN_DEADADDRY; |
| 991 | 1005 | } |
| 992 | 1006 | else{ |
| @@ -149,6 +149,7 @@ | ||
| 149 | 149 | int MoveFlag_lt; //!< (前回の)移動方向を表すフラグ |
| 150 | 150 | int scopemode; //!< スコープ使用モード |
| 151 | 151 | bool HitFlag; //!< 被弾を表すフラグ |
| 152 | + float Hit_rx; //!< 被弾した方向 | |
| 152 | 153 | float totalmove; //!< 合計移動量 |
| 153 | 154 | int StateGunsightErrorRange; //!< 照準の状態誤差 |
| 154 | 155 | int ReactionGunsightErrorRange; //!< 照準の反動誤差 |
| @@ -205,8 +206,8 @@ | ||
| 205 | 206 | virtual void HitBulletLeg(int attacks); |
| 206 | 207 | virtual void HitZombieAttack(); |
| 207 | 208 | virtual void HitGrenadeExplosion(int attacks); |
| 208 | - virtual void SetHitFlag(); | |
| 209 | - virtual bool CheckHit(); | |
| 209 | + virtual void SetHitFlag(float rx); | |
| 210 | + virtual bool CheckHit(float *rx); | |
| 210 | 211 | virtual float GetTotalMove(); |
| 211 | 212 | virtual int RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata, bool AddCollisionFlag, bool player, bool F5mode); |
| 212 | 213 | virtual int GetGunsightErrorRange(); |
| @@ -950,10 +950,10 @@ | ||
| 950 | 950 | } |
| 951 | 951 | |
| 952 | 952 | if( flag == true ){ |
| 953 | - HumanIndex[HitHuman_id].SetHitFlag(); | |
| 953 | + HumanIndex[HitHuman_id].SetHitFlag(brx*-1 - (float)M_PI/2); | |
| 954 | 954 | } |
| 955 | 955 | #else |
| 956 | - HumanIndex[HitHuman_id].SetHitFlag(); | |
| 956 | + HumanIndex[HitHuman_id].SetHitFlag(brx*-1 - (float)M_PI/2); | |
| 957 | 957 | #endif |
| 958 | 958 | |
| 959 | 959 | //ロボットかどうか判定 |
| @@ -1099,23 +1099,6 @@ | ||
| 1099 | 1099 | |
| 1100 | 1100 | HumanIndex[i].GetParamData(NULL, NULL, NULL, &HitHuman_TeamID); |
| 1101 | 1101 | |
| 1102 | -#ifdef ENABLE_BUG_TEAMID | |
| 1103 | - bool flag = true; | |
| 1104 | - | |
| 1105 | - //チーム番号が負数、かつチーム番号が大きいなら、フラグ無効 | |
| 1106 | - if( (HitHuman_TeamID < 0)&&(teamid < 0) ){ | |
| 1107 | - if( HitHuman_TeamID < teamid ){ | |
| 1108 | - flag = false; | |
| 1109 | - } | |
| 1110 | - } | |
| 1111 | - | |
| 1112 | - if( flag == true ){ | |
| 1113 | - HumanIndex[i].SetHitFlag(); | |
| 1114 | - } | |
| 1115 | -#else | |
| 1116 | - HumanIndex[i].SetHitFlag(); | |
| 1117 | -#endif | |
| 1118 | - | |
| 1119 | 1102 | float y2; |
| 1120 | 1103 | float arx, ary; |
| 1121 | 1104 |
| @@ -1143,6 +1126,23 @@ | ||
| 1143 | 1126 | ary = 0.0f; |
| 1144 | 1127 | } |
| 1145 | 1128 | |
| 1129 | +#ifdef ENABLE_BUG_TEAMID | |
| 1130 | + bool flag = true; | |
| 1131 | + | |
| 1132 | + //チーム番号が負数、かつチーム番号が大きいなら、フラグ無効 | |
| 1133 | + if( (HitHuman_TeamID < 0)&&(teamid < 0) ){ | |
| 1134 | + if( HitHuman_TeamID < teamid ){ | |
| 1135 | + flag = false; | |
| 1136 | + } | |
| 1137 | + } | |
| 1138 | + | |
| 1139 | + if( flag == true ){ | |
| 1140 | + HumanIndex[i].SetHitFlag(arx*-1 + (float)M_PI/2); | |
| 1141 | + } | |
| 1142 | +#else | |
| 1143 | + HumanIndex[i].SetHitFlag(arx*-1 + (float)M_PI/2); | |
| 1144 | +#endif | |
| 1145 | + | |
| 1146 | 1146 | //爆風による風圧 |
| 1147 | 1147 | HumanIndex[i].AddPosOrder(arx, ary, 2.2f/MAX_DAMAGE_GRENADE_DISTANCE * (MAX_DAMAGE_GRENADE_DISTANCE - sqrt(x*x + y*y + z*z))); |
| 1148 | 1148 |
| @@ -2254,7 +2254,9 @@ | ||
| 2254 | 2254 | |
| 2255 | 2255 | int MyHuman_dataID, MyHuman_TeamID; |
| 2256 | 2256 | int EnemyHuman_dataID, EnemyHuman_TeamID; |
| 2257 | + float mx, my, mz; | |
| 2257 | 2258 | float tx, ty, tz; |
| 2259 | + float arx; | |
| 2258 | 2260 | int paramid; |
| 2259 | 2261 | HumanParameter Paraminfo; |
| 2260 | 2262 | bool NotRobot; |
| @@ -2263,9 +2265,13 @@ | ||
| 2263 | 2265 | MyHuman->GetParamData(NULL, &MyHuman_dataID, NULL, &MyHuman_TeamID); |
| 2264 | 2266 | EnemyHuman->GetParamData(NULL, &EnemyHuman_dataID, NULL, &EnemyHuman_TeamID); |
| 2265 | 2267 | |
| 2268 | + MyHuman->GetPosData(&mx, &my, &mz, NULL); | |
| 2266 | 2269 | EnemyHuman->GetPosData(&tx, &ty, &tz, NULL); |
| 2267 | 2270 | ty += VIEW_HEIGHT; |
| 2268 | 2271 | |
| 2272 | + //敵が攻撃を受けた角度を求める | |
| 2273 | + arx = atan2(mz - tz, mx - tx); | |
| 2274 | + | |
| 2269 | 2275 | //ロボットかどうか判定 |
| 2270 | 2276 | EnemyHuman->GetParamData(¶mid, NULL, NULL, NULL); |
| 2271 | 2277 | GameParamInfo->GetHuman(paramid, &Paraminfo); |
| @@ -2290,10 +2296,10 @@ | ||
| 2290 | 2296 | } |
| 2291 | 2297 | |
| 2292 | 2298 | if( flag == true ){ |
| 2293 | - EnemyHuman->SetHitFlag(); | |
| 2299 | + EnemyHuman->SetHitFlag(arx*-1 + (float)M_PI/2); | |
| 2294 | 2300 | } |
| 2295 | 2301 | #else |
| 2296 | - EnemyHuman->SetHitFlag(); | |
| 2302 | + EnemyHuman->SetHitFlag(arx*-1 + (float)M_PI/2); | |
| 2297 | 2303 | #endif |
| 2298 | 2304 | |
| 2299 | 2305 | //エフェクト(血)を描画 |