From 77f5a7770d7eca78aa0ff1c7512575e397440df9 Mon Sep 17 00:00:00 2001 From: Sevenfm Date: Mon, 20 Jan 2020 18:01:18 +0000 Subject: [PATCH] l_SetMercProfiles: allow serting zero values for sSectorX and sSectorY. Added more restriction for using grenades in CalcBestThrow: - blinded soldier can only attack recently seen/heard opponents - limit explosives type when attacking zombies - limit smoke grenade use - limit explosives type when attacking robots, vehicles and tanks - don't use grenades against dying enemies - limit explosives type when attacking collapsed enemies - don't use flare if soldier is in light - don't use flares against opponents on roof git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8736 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/LuaInitNPCs.cpp | 12 +++--- TacticalAI/Attacks.cpp | 88 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 8 deletions(-) diff --git a/Strategic/LuaInitNPCs.cpp b/Strategic/LuaInitNPCs.cpp index e90eb816..56fe6a37 100644 --- a/Strategic/LuaInitNPCs.cpp +++ b/Strategic/LuaInitNPCs.cpp @@ -2338,9 +2338,9 @@ static int l_SetMercProfiles(lua_State *L) { MERCPROFILESTRUCT * pProfile; UINT8 idNPC; - UINT16 x = 0; - UINT16 y = 0; - UINT8 z = 255; + UINT16 x = -1; + UINT16 y = -1; + UINT8 z = -1; UINT32 Orders = -1; UINT16 usEyesX = -1; UINT16 usEyesY = -1; @@ -2375,13 +2375,13 @@ static int l_SetMercProfiles(lua_State *L) sSalary = lh_getIntegerFromTable(L, "Salary"); ubBodyType = lh_getIntegerFromTable(L, "BodyType"); - if (x >= 1 && x <= 16) + if (x != -1 && x >= 0 && x <= 16) pProfile->sSectorX = x; - if (y >= 1 && y <= 16) + if (y != -1 && y >= 0 && y <= 16) pProfile->sSectorY = y; - if (z <= 3) + if (z != -1 && z <= 3) pProfile->bSectorZ = z; if (usEyesX != -1) diff --git a/TacticalAI/Attacks.cpp b/TacticalAI/Attacks.cpp index e8d923ec..8860a8de 100644 --- a/TacticalAI/Attacks.cpp +++ b/TacticalAI/Attacks.cpp @@ -979,6 +979,15 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) continue; // next soldier */ + bPersOL = pSoldier->aiData.bOppList[pOpponent->ubID]; + bPublOL = gbPublicOpplist[pSoldier->bTeam][pOpponent->ubID]; + + // we know nothing about this opponent + if (bPersOL == NOT_HEARD_OR_SEEN && bPublOL == NOT_HEARD_OR_SEEN) + { + continue; + } + // if this man is neutral / on the same side, he's not an opponent if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide)) { @@ -995,12 +1004,87 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) continue; // next opponent } + // sevenfm: additional restrictions - bPersOL = pSoldier->aiData.bOppList[pOpponent->ubID]; + // blinded soldier can only attack recently seen/heard opponents + if (pSoldier->bBlindedCounter > 0 && + bPersOL != SEEN_CURRENTLY && + bPersOL != SEEN_THIS_TURN && + bPersOL != HEARD_THIS_TURN) + { + continue; + } + // limit explosives type when attacking zombies + if (usGrenade != NOTHING && + !Item[usGrenade].flare && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_NORMAL && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_CREATUREGAS && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_BURNABLEGAS && + pOpponent->IsZombie()) + { + continue; + } + + // limit smoke grenade use + if (usGrenade != NOTHING && + Explosive[Item[usGrenade].ubClassIndex].ubType == EXPLOSV_SMOKE && + (FindAIUsableObjClass(pOpponent, IC_GUN) == NO_SLOT || + (pSoldier->usAnimState == COWERING || pSoldier->usAnimState == COWERING_PRONE) || + CoweringShockLevel(pOpponent) > 50 || + EffectiveMarksmanship(pOpponent) < 90 && !IsScoped(&pOpponent->inv[HANDPOS]) && !pOpponent->aiData.bLastAttackHit)) + { + continue; + } + + // limit explosives type when attacking robots, vehicles and tanks + if (usGrenade != NOTHING && + !Item[usGrenade].flare && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_NORMAL && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_CREATUREGAS && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_BURNABLEGAS && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_SMOKE && + (ARMED_VEHICLE(pOpponent) || pOpponent->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT(pOpponent))) + { + continue; + } + + // don't use grenades against dying enemies + if (pOpponent->stats.bLife < OKLIFE && !pOpponent->IsZombie()) + { + continue; + } + + // limit explosives type when attacking collapsed enemies + if (usGrenade != NOTHING && + !Item[usGrenade].flare && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_NORMAL && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_CREATUREGAS && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_BURNABLEGAS && + Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_MUSTGAS && + (pOpponent->bCollapsed || pOpponent->bBreathCollapsed)) + { + continue; + } + + // don't use flare if soldier is in light + if (usGrenade != NOTHING && + Item[usGrenade].flare && + InLightAtNight(pOpponent->sGridNo, pOpponent->pathing.bLevel)) + { + continue; + } + + // don't use flares against opponents on roof + if (usGrenade != NOTHING && + Item[usGrenade].flare && + pOpponent->pathing.bLevel > 0) + { + continue; + } + if ((Item[usInHand].mortar ) || (Item[usInHand].grenadelauncher ) || (Item[usInHand].cannon ) ) { - bPublOL = gbPublicOpplist[pSoldier->bTeam][pOpponent->ubID]; // allow long range firing, where target doesn't PERSONALLY see opponent if ((bPersOL != SEEN_CURRENTLY) && (bPublOL != SEEN_CURRENTLY)) {