//////////////////////////////////////////////////////////////////////////////// // // Olander's AI // nw_c2_default1 // by Don Anderson // dandersonru@msn.com // // OnHeartbeat // //////////////////////////////////////////////////////////////////////////////// #include "oai_inc_ai" void main() { object oNPC = OBJECT_SELF; // dk: 10-Dec-2005 skip if performing special action if(GetAIOff()) return; //Skip if in combat if(GetAttemptedAttackTarget() != OBJECT_INVALID || GetAttackTarget() != OBJECT_INVALID || GetAttemptedSpellTarget() != OBJECT_INVALID || GetIsObjectValid(GetNearestSeenEnemy())) return; //Guard Check int nGuard = GetLocalInt(oNPC,"OAI_GUARD"); if(nGuard == 1) { OAI_GuardCheck(oNPC); return; } /******************************************************************************/ //:: TAVERNS / INNS object oTavern = GetNearestObjectByTag("NW_TAVERN",oNPC,1); string sTag = GetTag(oNPC); //Cook Check int nCook = GetLocalInt(oNPC,"OAI_COOK"); if(GetIsObjectValid(oTavern) && nCook == 1) { OAI_Cooks(oNPC); return; } //Barmaid Check int nBarmaid = GetLocalInt(oNPC,"OAI_BARMAID"); if(GetIsObjectValid(oTavern) && nBarmaid == 1) { OAI_Barmaid(oNPC); return; } //Stripper Check int nStripper = GetLocalInt(oNPC,"OAI_STRIPPER"); if(GetIsObjectValid(oTavern) && nStripper == 1) { OAI_Stripper(oNPC); return; } //Bar Chatter Check if(GetIsObjectValid(oTavern) && sTag != "PackAnimal" && sTag != "Horse") { OAI_BarChatter(oNPC); return; } /******************************************************************************/ //:: CUSTOM HB SYSTEMS //Custom Scripts you Need to Execute ExecuteScript("oai_cust_hb", OBJECT_SELF); //:: CUSTOM HB SYSTEMS /******************************************************************************/ //Trolls if(GetBattleCondition(OAI_ROLE_TROLL)) TrollHB(); /******************************************************************************/ //:: SEARCHING // No regular hearbeat for a little while if we are searching // Searching values over 10 means we are running at the target // This section dontinues any search or chase operation we were performing that // may have been inturrupted somehow. int nSearch = GetLocalInt(OBJECT_SELF, "OAI_SEARCHING"); // If searching then we need to think about our search if(nSearch > 0) { location oLoc = GetLocalLocation(OBJECT_SELF, "OAI_SEARCH_LOC"); // Are we close enough to finish our search? if (!GetIsObjectValid(GetAreaFromLocation(oLoc)) || GetDistanceBetweenLocations(GetLocation(OBJECT_SELF), oLoc) < 2.0) { nSearch = 0; } //Decrement search count else nSearch--; //If last round of searching then cancel search if(nSearch < 1 || nSearch == 10) DeleteLocalInt(OBJECT_SELF, "OAI_SEARCHING"); //Falls through to normal hearbeat else { // Make sure we continue the search if not doing anything SetLocalInt(OBJECT_SELF, "OAI_SEARCHING", nSearch); if(GetCurrentAction() == ACTION_INVALID) { if(nSearch == 2 || nSearch == 12) { ActionForceMoveToLocation(oLoc, nSearch > 10, 4.0); } else { ActionMoveToLocation(oLoc, nSearch > 10); ActionDoCommand(OAI_DetermineCombatRound()); } } return; } } //:: SEARCHING /******************************************************************************/ /******************************************************************************/ //:: LIGHT SOURCES // Light sources will be wielded at night if all the conditions are met // - if we have one // - we are basically humanoid // - it is night or we are below ground // - the area we are in does not have the "NOTORCH" int set object oWeapon; int bCheckLightUser; switch (GetRacialType(OBJECT_SELF)) { case RACIAL_TYPE_DWARF: case RACIAL_TYPE_ELF: case RACIAL_TYPE_GNOME: case RACIAL_TYPE_HALFELF: case RACIAL_TYPE_HALFLING: case RACIAL_TYPE_HALFORC: case RACIAL_TYPE_HUMAN: case RACIAL_TYPE_HUMANOID_GOBLINOID: case RACIAL_TYPE_HUMANOID_ORC: case RACIAL_TYPE_HUMANOID_REPTILIAN: bCheckLightUser = TRUE; break; default: bCheckLightUser = FALSE; } if(bCheckLightUser) { int bWeildingLightSource = FALSE; oWeapon = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,OBJECT_SELF); //Are we wielding a light source right now if(GetIsObjectValid(oWeapon)) { bWeildingLightSource = GetModPropertyForItem(oWeapon, PROP_LIGHT, PROPV_LIGHT); } //If day (and in above ground setting), loose any wielded light source if(GetIsDay() && GetIsAreaAboveGround(GetArea(OBJECT_SELF))) { if(bWeildingLightSource) { ClearAllActions(); ActionUnequipItem(oWeapon); oWeapon = GetLocalObject(OBJECT_SELF, "OAI_LH_MELEE"); //Reweild any prior item if(GetIsObjectValid(oWeapon)) ActionEquipItem(oWeapon, INVENTORY_SLOT_LEFTHAND); return; } } //Try to wield a light source if we have one else if(!bWeildingLightSource && d4() == 1 && !GetLocalInt(GetArea(OBJECT_SELF),"NOTORCH")) { object oLight = GetModItemWithProperty(OBJECT_SELF, PROP_LIGHT, PROPV_LIGHT); //Found a Light Source if(GetIsObjectValid(oLight)) { ClearAllActions(); //Existing Something in Left Hand if(GetIsObjectValid(oWeapon)) ActionUnequipItem(oWeapon); ActionEquipItem(oLight, INVENTORY_SLOT_LEFTHAND); return; } } } //:: LIGHT SOURCES /******************************************************************************/ /******************************************************************************/ //:: WEAPONS //Sheath our weapons if weilded (based on chance to stop all NPCs doing at same time) if(d100() <= 50) { // Unweild weapons if not needed oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,OBJECT_SELF); if(IsWeapon(oWeapon)) OAI_UnequipWeapons(); } //:: WEAPONS /******************************************************************************/ /******************************************************************************/ //:: BEHAVIOR //Here we want to Walk around a bit //We need to make sure we have set up our waypoints or not //Remember this routine is interupted easily and may not be run yet, so try again if(!GetWalkCondition(NW_WALK_FLAG_INITIALIZED)) { WalkWayPoints(); } // dk: special code: not part of OAI. Makes creatures follow assigned leaders // with occasional comments voiced in their native tongue (hls_lang) else if(GetIsObjectValid(GetLocalObject(OBJECT_SELF, "MyLeader"))) { ExecuteScript("follow_leader", OBJECT_SELF); } // If we have the 'constant' waypoints flag set, walk to the next // waypoint. 0.5% (plus value of 0.1 * CHANCE_SKIPWALK) chance of not waypoint walking // The skipping allows way point walkers to occasionally visit shops/toilets and have a break else if(GetWalkCondition(NW_WALK_FLAG_CONSTANT) && (Random(1000) > GetLocalInt(oNPC, "CHANCE_SKIPWALK") + 4)) { // There is a 15% (plus 5% * value of CHANCE_NOWALK) chance of just standing there // These longer the normall pause add a bit of flavour if(d20() > GetLocalInt(oNPC, "CHANCE_NOWALK") + 3) WalkWayPoints(); } // This handles special attacking/fleeing behavior // for omnivores & herbivores. else if(GetBehaviorState(NW_FLAG_BEHAVIOR_OMNIVORE) || GetBehaviorState(NW_FLAG_BEHAVIOR_HERBIVORE)) { OAI_DetermineSpecialBehavior(); } //Now play some Animations else if(!IsInConversation(OBJECT_SELF)) { if(GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS) || GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN) || GetIsEncounterCreature()) { PlayMobileAmbientAnimations(); } else if (GetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS)) { PlayImmobileAmbientAnimations(); } } //:: BEHAVIOR /******************************************************************************/ // Send the user-defined event signal if specified // Note Search or Light weild/unweild operations will stop getting here // As will certain AIOff situations, so be careful what you use it for. if(GetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT)) { SignalEvent(OBJECT_SELF, EventUserDefined(1001)); } }