Updated Jasperre's AI

Updated Jasperre's AI to 1.4, fixed a few other coding bugs & fully compiled module.
This commit is contained in:
Jaysyn904
2021-08-30 17:31:44 -04:00
parent 2e0b5b615b
commit 1c1c90e986
404 changed files with 11239 additions and 7881 deletions

View File

@@ -1,6 +1,6 @@
/************************ [On Blocked] *****************************************
Filename: j_ai_onblocked or nw_c2_defaulte
************************* [On Blocked] *****************************************
/*/////////////////////// [On Blocked] /////////////////////////////////////////
Filename: J_AI_OnBlocked or nw_c2_defaulte
///////////////////////// [On Blocked] /////////////////////////////////////////
Added in user defined constant - won't open any doors.
0 = Default (even if not set) opens as appropriate
1 = Always bashes the door.
@@ -16,14 +16,20 @@
Note: This also fires for blocking via. creatures. It is optimised, and
works by re-targeting and doing a few small things to do with blocking.
************************* [History] ********************************************
///////////////////////// [History] ////////////////////////////////////////////
1.0 - Opens with Knock. Unlocks door. Ignores trapped doors.
1.3 - Debug messages.
- New events, even if the change of using them is small!
- No ClearAllactions so any previous movings will carry on once the door is gone.
- Removed debug messages
1.3 - Added Creature reaction code
************************* [Workings] *******************************************
- Added Creature reaction code
1.4 - Need to add a "hands" check (done on spawn, to set a setting to not
open doors at all, IE: We do NOT have hands, do not open doors), so
its a little more realistic "out of the box"
- Fixed an instance of GetObjectSeen being repeated.
- Fixed the variable AI_DOOR_INTELLIGENCE not being got via GetAIInteger().
- Removed unneeded else statement.
///////////////////////// [Workings] ///////////////////////////////////////////
Uses simple code to deal with a door in the best way possible.
Uses DoDoorAction, which is added to the top of an action queue and doesn't,
@@ -31,10 +37,10 @@
is like this)
Creatures are reacted by with ClearAllActions usually.
************************* [Arguments] ******************************************
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetBlockingDoor, GetIsDoorActionPossible, GetLocked, GetLockKeyRequired
GetLockKeyTag, GetLockUnlockDC, GetPlotFlag, DoDoorAction
************************* [On Blocked] ****************************************/
///////////////////////// [On Blocked] ///////////////////////////////////////*/
#include "J_INC_OTHER_AI"
@@ -45,10 +51,8 @@ int RangedAttack(object oTarget = OBJECT_INVALID);
void main()
{
// Pre-blocked-event
if(FireUserEvent(AI_FLAG_UDE_ON_BLOCKED_PRE_EVENT, EVENT_ON_BLOCKED_PRE_EVENT))
// We may exit if it fires
if(ExitFromUDE(EVENT_ON_BLOCKED_PRE_EVENT)) return;
// Pre-on blocked-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_ON_BLOCKED_PRE_EVENT, EVENT_ON_BLOCKED_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
@@ -74,19 +78,20 @@ void main()
if(GetLocalTimer(AI_TIMER_BLOCKED)) return;
// Set the timer for 1 second
SetLocalTimer(AI_TIMER_BLOCKED, f1);
SetLocalTimer(AI_TIMER_BLOCKED, 1.0);
// Is it an enemy?
if(GetIsEnemy(oBlocker))
{
// Check if seen or heard
if(GetObjectSeen(oBlocker) || GetObjectSeen(oBlocker))
if(GetObjectSeen(oBlocker) || GetObjectHeard(oBlocker))
{
// Enemy :-) We can re-target (as know of thier presence), using
// them as a target.
// - This overrides even casting a spell - basically, as we should
// be moving, this will re-cast it at someone or something in range
SetAIObject(AI_ATTACK_SPECIFIC_OBJECT, oBlocker);
// Check if we can do combat - if we cannot, we can re-do combat
// next time
if(!GetIsBusyWithAction())
@@ -106,6 +111,9 @@ void main()
{
SetAIObject(AI_LAST_TO_GO_INVISIBLE, oBlocker);
}
// Shout to allies
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// Check if we can do combat
if(!GetIsBusyWithAction())
{
@@ -125,42 +133,62 @@ void main()
// Were we attacking in combat?
object oPrevious = GetAttackTarget();
// Check action
if(GetCurrentAction() == ACTION_ATTACKOBJECT)
{
// Action attack, normally means melee attack. If we can, we
// attack our previous target if seen, ELSE we will re-initate
// combat.
AISpeakString(I_WAS_ATTACKED);
// This gets set to FALSE if we can cutthrough attack,
// or whatever.
int bPreviousAttackFailed = FALSE;
// Check if we can see our previous target
if(GetObjectSeen(oPrevious) ||
(GetObjectHeard(oPrevious) && LineOfSightObject(OBJECT_SELF, oPrevious)))
{
// We can! see if we can re-attack with ranged weapon, else
// doesn't matter we can see them
if(RangedAttack(oPrevious)) return;
bPreviousAttackFailed = RangedAttack(oPrevious);
}
else
// We have not stopped the script - so determine combat
// round against nearest seen or heard enemy!
if(RangedAttack()) return;
// Else normal round to try and get a new target
ClearAllActions();
DetermineCombatRound();
// If we havn't added an action yet...
if(bPreviousAttackFailed == FALSE)
{
// We have not stopped the script - so determine combat
// round against nearest seen or heard enemy!
if(!RangedAttack())
{
// Else normal round to try and get a new target
ClearAllActions();
DetermineCombatRound();
}
}
// Action attack, normally means melee attack. If we can, we
// attack our previous target if seen, ELSE we will re-initate
// combat.
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
// Fire the On blocked event as normal
FireBlockedEvent();
return;
}
else // if(iAction == ACTION_CASTSPELL and others)
else // if(nAction == ACTION_CASTSPELL and others)
{
// Reinitate combat
// Reinitate combat, but don't attack oPrevious
ClearAllActions();
DetermineCombatRound();
// Action attack, normally means melee attack. If we can, we
// attack our previous target if seen, ELSE we will re-initate
// combat.
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
// Fire the On blocked event as normal
FireBlockedEvent();
return;
}
}
}
// Placeable - Not sure it can be returned, however, we can add it to the
// type if/else check.
// Placeable - Currently not returned, however, added just in case!
else if(nBlockerType == OBJECT_TYPE_PLACEABLE)
{
// Check for plot, and therefore attack it to bring it down.
@@ -171,26 +199,29 @@ void main()
{
// Do placeable action
DoPlaceableObjectAction(oBlocker, PLACEABLE_ACTION_BASH);
FireBlockedEvent();
return;
}
return;
}
// Door behaviour
else if(nBlockerType == OBJECT_TYPE_DOOR)
{
int iDoorIntelligence = GetLocalInt(OBJECT_SELF, AI_DOOR_INTELLIGENCE);
int iInt = GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE);
if(iDoorIntelligence == i1)// 1 = Always bashes the doors, plot, locked or anything.
int nDoorIntelligence = GetAIInteger(AI_DOOR_INTELLIGENCE);
int nInt = GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE);
if(nDoorIntelligence == 1)// 1 = Always bashes the doors, plot, locked or anything.
{
DoDoorAction(oBlocker, DOOR_ACTION_BASH);
// We re-initiate combat.
FireBlockedEvent();
return;
}
else if(iDoorIntelligence == i2)// 2 = Never open anything, bashing or not.
else if(nDoorIntelligence == 2)// 2 = Never open anything, bashing or not.
{
FireBlockedEvent();
return;
}
else if(iDoorIntelligence == i3)// 3 = Never tries anything against plot doors.
else if(nDoorIntelligence == 3)// 3 = Never tries anything against plot doors.
{
if(GetPlotFlag(oBlocker))
{
@@ -198,10 +229,10 @@ void main()
return;
}
}
if(iInt >= i5)
if(nInt >= 5)
{
// Need some intelligence :-)
if(iInt >= i7)
if(nInt >= 7)
{
// Right, first, we may...shock...open it!!!
// Checks Key, lock, trap and if the action is possible.
@@ -221,17 +252,17 @@ void main()
!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER) &&
!GetLockKeyRequired(oBlocker) && GetHasSkill(SKILL_OPEN_LOCK) &&
GetIsDoorActionPossible(oBlocker, DOOR_ACTION_UNLOCK) && !GetIsTrapped(oBlocker) &&
(GetSkillRank(SKILL_OPEN_LOCK) >= (GetLockLockDC(oBlocker) - i20)))
(GetSkillRank(SKILL_OPEN_LOCK) >= (GetLockLockDC(oBlocker) - 20)))
{
DoDoorAction(oBlocker, DOOR_ACTION_UNLOCK);
FireBlockedEvent();
return;
}
// Specilist thing - knock
if(iInt >= i10)
if(nInt >= 10)
{
if((GetIsDoorActionPossible(oBlocker, DOOR_ACTION_KNOCK)) &&
GetLockUnlockDC(oBlocker) <= i25 &&
GetLockUnlockDC(oBlocker) <= 25 &&
!GetLockKeyRequired(oBlocker) && GetHasSpell(SPELL_KNOCK))
{
DoDoorAction(oBlocker, DOOR_ACTION_KNOCK);
@@ -239,16 +270,16 @@ void main()
return;
}
}
// If Our Int is over 5, we will bash after everything else.
if(GetIsDoorActionPossible(oBlocker, DOOR_ACTION_BASH) && !GetPlotFlag(oBlocker))
}
// If Our Int is over 5, we will bash after everything else.
if(GetIsDoorActionPossible(oBlocker, DOOR_ACTION_BASH) && !GetPlotFlag(oBlocker))
{
if(GetAttackTarget() != oBlocker)
{
if(GetAttackTarget() != oBlocker)
{
DoDoorAction(oBlocker, DOOR_ACTION_BASH);
}
FireBlockedEvent();
return;
DoDoorAction(oBlocker, DOOR_ACTION_BASH);
}
FireBlockedEvent();
return;
}
}
}
@@ -284,11 +315,13 @@ int RangedAttack(object oTarget)
// Ranged weapon attack against oTarget
// doesn't matter we can see them
object oRanged = GetAIObject(AI_WEAPON_RANGED);
int iAmmo = GetAIInteger(AI_WEAPON_RANGED_AMMOSLOT);
int nAmmo = GetAIInteger(AI_WEAPON_RANGED_AMMOSLOT);
// Check ammo and validness
if(GetIsObjectValid(oRanged) && (iAmmo == INVENTORY_SLOT_RIGHTHAND ||
GetIsObjectValid(GetItemInSlot(iAmmo))))
if(GetIsObjectValid(oRanged) && (nAmmo == INVENTORY_SLOT_RIGHTHAND ||
GetIsObjectValid(GetItemInSlot(nAmmo))))
{
// Attack with it
ClearAllActions();
ActionEquipItem(oRanged, INVENTORY_SLOT_RIGHTHAND);
ActionAttack(oRangedTarget);