jamochawoke Posted October 30, 2011 Author Share Posted October 30, 2011 (edited) Ok Ok... since I decided I wasn't going to sleep until I get this figured out... Here is my latest iteration of the script. It needs some cleaning up and changes. The problems are: 1) When he's using the wander within 50 radius package he tends to just circle the player and not heal2) Sometimes he'd rather rush off to fight than heal3) Sometimes when he's supposed to use the wander package after player health has dropped below 50% I'll look around and find that he's run really REALLY far away Otherwise if I can stay close to him he will usually heal, even out of combat, and will tend to keep you alive for longer than you'd usually be if just on your own. Please look at the script and show me EXACTLY how I can improve it. I've included big comments to make things clear as to what is going on. For reference.. the VDHealPlayer packages 1-5 are CastMagic AI packages. They are set to Location -> Player and Target -> the appropriate spell for his level of casting. It works like a charm when he's not having the problems I listed above. scn VDSimon short doOnce short healOnce float timer begin gameMode ;;; CONVERSATION WITH PLAYER if doOnce == 0 if Player.getdistance VDBrotherSimonREF <= 200 VDBrotherSimonREF.StartConversation Player VDOracleQuestTopic4 set doOnce to 1 endif endif if getstage VDOracleQuest1 >= 60 ;;;THIS STAGE MAKES HIM A FOLLOWER WITH WAIT/FOLLOW COMMANDS ;;; REMOVES HEALING PACKAGES WHEN HEALTH GREATER THAN HALF if Player.GetAV Health > (Player.GetBaseAV Health / 2) if healOnce == 1 removeScriptPackage VDHealPlayerPackage1 removeScriptPackage VDHealPlayerPackage2 removeScriptPackage VDHealPlayerPackage3 removeScriptPackage VDHealPlayerPackage4 removeScriptPackage VDHealPlayerPackage5 EvaluatePackage setfactionrank VDSimonFaction 0 set healOnce to 0 endif endif ;;; HEALING SCRIPTS if VDOracleDatabase.SimonFollower == 1 set timer to timer+getsecondspassed if timer >= 5 ;;; ADDS PACKAGES TO HEAL THE PLAYER WHEN LESS THAN HALF HEALTH if player.GetAV Health <= (player.GetBaseAV Health / 2) Message "Player health has fallen to half." VDBrotherSimonREF.StopCombat SCAOnActor ;;; SETTING FACTION RANK HERE CAUSES HIM TO USE WANDER NEAR PLAYER PACKAGE setfactionrank VDSimonFaction 1 Message "NPC is casting Restoration spell on player." if VDBrotherSimonREF.GetAV Restoration < 25 addScriptPackage VDHealPlayerPackage1 elseif VDBrotherSimonREF.GetAV Restoration < 50 addScriptPackage VDHealPlayerPackage2 elseif VDBrotherSimonREF.GetAV Restoration < 75 addScriptPackage VDHealPlayerPackage3 elseif VDBrotherSimonREF.GetAV Restoration < 100 addScriptPackage VDHealPlayerPackage4 elseif VDBrotherSimonREF.GetAV Restoration == 100 addScriptPackage VDHealPlayerPackage5 endif set healOnce to 1 endif ;;; HEAL OTHER PARTY MEMBERS IF THEY ARE IN THE PARTY AND NEAR if VDOracleDatabase.JessaFollower == 1 && VDJessaREF.GetAV Health < (VDJessaREF.GetBaseAV Health / 2) if VDJessaREF.getdistance VDBrotherSimonREF <= 200 Message "Jessa health has fallen to half." VDBrotherSimonREF.StopCombat Message "NPC is casting Restoration spell on Jessa." if VDBrotherSimonREF.GetAV Restoration < 25 Cast VDRestoreHealthArea1Novice VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration < 50 Cast VDRestoreHealthArea2Apprentice VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration < 75 Cast VDRestoreHealthArea3Journeyman VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration < 100 Cast VDRestoreHealthArea4Expert VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration == 100 Cast VDRestoreHealthArea5Master VDJessaREF endif endif endif if VDOracleDatabase.InohenFollower == 1 && VDInohenREF.GetAV Health < (VDInohenREF.GetBaseAV Health / 2) if VDInohenREF.getdistance VDBrotherSimonREF <= 200 Message "Inohen health has fallen to half." VDBrotherSimonREF.StopCombat Message "NPC is casting Restoration spell on Inohen." if VDBrotherSimonREF.GetAV Restoration < 25 Cast VDRestoreHealthArea1Novice VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration < 50 Cast VDRestoreHealthArea2Apprentice VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration < 75 Cast VDRestoreHealthArea3Journeyman VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration < 100 Cast VDRestoreHealthArea4Expert VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration == 100 Cast VDRestoreHealthArea5Master VDInohenREF endif endif endif set timer to 0 endif endif endif end Edited October 30, 2011 by jamochawoke Link to comment Share on other sites More sharing options...
fg109 Posted October 30, 2011 Share Posted October 30, 2011 (edited) Well, first thing I notice is that you have "RemoveScriptPackage X" commands for many different packages. You don't need a separate one for each package (it doesn't working that way), just use "RemoveScriptPackage" once. Since you are using AI packages in order to cast the spells, there is no point in having a faction to control AI package selection like I gave you in the example. You should just take that part out. I also wonder if it's necessary to have so many AI packages for the different spells. Try just setting the "Object Type" on the target tab to Restoration spells and seeing if the highest available level spell is used automatically. Most of the vanilla "Use Item At" packages for spells have the location set as an XMarkerHeading so that the NPC aims in a specific direction. I know that using the "MoveTo" command on static objects doesn't work really well, but maybe you can still try using that along with "GetHeadingAngle" and "SetAngle Z" in order to point it at the player. Then the NPC will be casting at the player when he or she chooses the package. The last thing I ask, do you use OBSE? Because I could think of some OBSE functions that would help with doing this. Edited October 30, 2011 by fg109 Link to comment Share on other sites More sharing options...
jamochawoke Posted October 31, 2011 Author Share Posted October 31, 2011 (edited) No I don't use OBSE. I actually tried the X-Marker with X-Target of the Player before. The problem is the X-Marker tends to get placed either inside of the player (and the NPC won't reach it or cast, just stand there trying to get inside you... lol that sounds bad) or the player moves and for 5 seconds while the timer is going the NPC will stand at the target and look dumb because the player is out of the casting range (happens a lot during fights). It could work, but I'm not sure how to get it to work. I was still using the faction modifier to cause him to wander near the player so he was in range to then use the CastMagic packages. I'll see what it's like without the NPC being near. I was trying to force it to stop the NPC running away behavior (which is really odd since he has Confidence 100 and all of his packages are marked Defensive Combat). --------EDIT------------ So I tried what you said. There is no "Restoration Spells" as a target like the Use Item At AI Package in the CastMagic package. I also tried to make a leveled list of all the spells and selecting that as the target for the Cast Magic package but leveled lists don't work for that package either. So I pretty much am forced to use the multiple package setup so he casts the correct spell. However, I was able to finally stop him from continuing to fight when he's supposed to heal by setting his aggression to 0 when he's supposed to be healing and then setting it back to 5 when he's done. Here's the script. It actually works really well minus one flaw. scn VDSimon short doOnce short healOnce float timer begin gameMode ;;; CONVERSATION WITH PLAYER if doOnce == 0 if Player.getdistance VDBrotherSimonREF <= 200 VDBrotherSimonREF.StartConversation Player VDOracleQuestTopic4 set doOnce to 1 endif endif if getstage VDOracleQuest1 >= 60 ;;; REMOVES HEALING PACKAGES WHEN HEALTH GREATER THAN HALF if Player.GetAV Health > (Player.GetBaseAV Health / 2) if healOnce == 1 removeScriptPackage EvaluatePackage VDBrotherSimonREF.SetActorValue Aggression 5 set healOnce to 0 endif endif ;;; HEALING SCRIPTS if VDOracleDatabase.SimonFollower == 1 set timer to timer+getsecondspassed if timer >= 5 ;;; ADDS PACKAGES TO HEAL THE PLAYER WHEN LESS THAN HALF HEALTH if player.GetAV Health <= (player.GetBaseAV Health / 2) Message "Player health has fallen to half." StopCombat SCAOnActor VDBrotherSimonREF.SetActorValue Aggression 0 Message "NPC is casting Restoration spell on player." if VDBrotherSimonREF.GetAV Restoration < 25 addScriptPackage VDHealPlayerPackage1 elseif VDBrotherSimonREF.GetAV Restoration < 50 addScriptPackage VDHealPlayerPackage2 elseif VDBrotherSimonREF.GetAV Restoration < 75 addScriptPackage VDHealPlayerPackage3 elseif VDBrotherSimonREF.GetAV Restoration < 100 addScriptPackage VDHealPlayerPackage4 elseif VDBrotherSimonREF.GetAV Restoration == 100 addScriptPackage VDHealPlayerPackage5 endif set healOnce to 1 endif ;;; HEAL OTHER PARTY MEMBERS IF THEY ARE IN THE PARTY AND NEAR if VDOracleDatabase.JessaFollower == 1 && VDJessaREF.GetAV Health < (VDJessaREF.GetBaseAV Health / 2) if VDJessaREF.getdistance VDBrotherSimonREF <= 200 Message "Jessa health has fallen to half." VDBrotherSimonREF.StopCombat Message "NPC is casting Restoration spell on Jessa." if VDBrotherSimonREF.GetAV Restoration < 25 Cast VDRestoreHealthArea1Novice VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration < 50 Cast VDRestoreHealthArea2Apprentice VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration < 75 Cast VDRestoreHealthArea3Journeyman VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration < 100 Cast VDRestoreHealthArea4Expert VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration == 100 Cast VDRestoreHealthArea5Master VDJessaREF endif endif endif if VDOracleDatabase.InohenFollower == 1 && VDInohenREF.GetAV Health < (VDInohenREF.GetBaseAV Health / 2) if VDInohenREF.getdistance VDBrotherSimonREF <= 200 Message "Inohen health has fallen to half." VDBrotherSimonREF.StopCombat Message "NPC is casting Restoration spell on Inohen." if VDBrotherSimonREF.GetAV Restoration < 25 Cast VDRestoreHealthArea1Novice VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration < 50 Cast VDRestoreHealthArea2Apprentice VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration < 75 Cast VDRestoreHealthArea3Journeyman VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration < 100 Cast VDRestoreHealthArea4Expert VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration == 100 Cast VDRestoreHealthArea5Master VDInohenREF endif endif endif set timer to 0 endif endif endif end The flaw is that he still runs his ass off half the time. I have no idea why he does this. Having confidence to 100 doesn't work. Adding an AI package to force him to stand next to the player only works about 25% of the time. I usually find him standing still in a few different spots on the map or he runs so far from the specific encounter that the triggers a fight with more monsters in a different part of the cavern. My other companions at this stage (depending on which you pick, they are both wizards with different specialties) of the quest also run too. They are using the DEFAULT combat style and I was positive they were doing it because of their class (Mage) and that they have no items aside from their robes and spells. So they'd run really far out of range then back in to cast a spell then really far out of range again. Again this is using the DEFAULT combat style, just with no weapons. Every now and then they will run in and try to use hand to hand but they mostly stay clear of the fight and cast their spells. But then again... the running. I'll often find both of them in a corner of the caverns on some specific path nodes just standing there until I bring the monsters to them... then they'll begin fighting and/or healing again. I'm really kind of stumped as to why they do that. It's also extremely frustrating when they do that and run all the way to another part of the cave where I have another encounter setup with tons of monsters and they both die. I have the quest setup that if any of the companions die it makes you take an alternate path through the questline. So when they die when they're supposed to have an easy encounter it's kind of enraging. ----- EDIT EDIT ------- I tried using a moveto player command if he was healing and supposed to be next to the player... and he still takes off... except because of the moveto command he keeps warping back and forth. It's pretty funny actually. He'll moveto the player and instead of casting the spell he runs away as fast as he can then gets moveto'ed again. If I follow him to the particular path node he wants to go to (like halfway through the cave in another room) he'll cast the spell. Edited October 31, 2011 by jamochawoke Link to comment Share on other sites More sharing options...
jamochawoke Posted October 31, 2011 Author Share Posted October 31, 2011 I might be going crazy from lack of sleep... but I reloaded my game to check again and none of the problems I was having happened (except once I had an overzealous party member outrun the group and die by themselves... but that's standard Oblivion behavior). I loaded up the dungeon and the NPCs from my quest save and what do you know? They all acted like they were scripted to and used their Combat Styles and everything just WORKED. I couldn't believe it so I loaded it up again and it worked again! I did an entire dungeon crawl without my NPCs doing insane behavior!!! The only thing I had to change was when that overzealous party member outran the group my healer went over to them and kept casting his healing spell over and over trying to heal their dead body :( It was sad lol. So I fixed that and here is the final script (I went ahead and included the entire NPC script which has a lot of other stuff because I didn't care to edit the whole thing for this post lol), that for me at least is working 100% and is ready for beta testing once I get the rest of my mod done. I cannot tell you how HAPPY I AM!!! scn VDSimon short doOnce short healOnce float timer begin gameMode ;;; CONVERSATION WITH PLAYER if doOnce == 0 if Player.getdistance VDBrotherSimonREF <= 200 VDBrotherSimonREF.StartConversation Player VDOracleQuestTopic4 set doOnce to 1 endif endif if getstage VDOracleQuest1 >= 60 && VDBrotherSimonREF.GetDead != 1 ;;; REMOVES HEALING PACKAGES WHEN HEALTH GREATER THAN HALF if Player.GetAV Health > (Player.GetBaseAV Health / 2) if healOnce == 1 removeScriptPackage EvaluatePackage VDBrotherSimonREF.SetActorValue Aggression 5 set healOnce to 0 endif endif ;;; HEALING SCRIPTS if VDOracleDatabase.SimonFollower == 1 set timer to timer+getsecondspassed if timer >= 5 ;;; ADDS PACKAGES TO HEAL THE PLAYER WHEN LESS THAN HALF HEALTH if player.GetAV Health <= (player.GetBaseAV Health / 2) Message "Player health has fallen to half." StopCombat SCAOnActor VDBrotherSimonREF.SetActorValue Aggression 0 Message "NPC is casting Restoration spell on player." if VDBrotherSimonREF.GetAV Restoration < 25 addScriptPackage VDHealPlayerPackage1 elseif VDBrotherSimonREF.GetAV Restoration < 50 addScriptPackage VDHealPlayerPackage2 elseif VDBrotherSimonREF.GetAV Restoration < 75 addScriptPackage VDHealPlayerPackage3 elseif VDBrotherSimonREF.GetAV Restoration < 100 addScriptPackage VDHealPlayerPackage4 elseif VDBrotherSimonREF.GetAV Restoration >= 100 addScriptPackage VDHealPlayerPackage5 endif set healOnce to 1 endif ;;; HEAL OTHER PARTY MEMBERS IF THEY ARE IN THE PARTY, ALIVE, BELOW 50%, AND NEAR if VDOracleDatabase.JessaFollower == 1 && VDJessaREF.GetDead != 1 if VDJessaREF.GetAV Health < (VDJessaREF.GetBaseAV Health / 2) if VDJessaREF.getdistance VDBrotherSimonREF <= 200 Message "Jessa health has fallen to half." VDBrotherSimonREF.StopCombat Message "NPC is casting Restoration spell on Jessa." if VDBrotherSimonREF.GetAV Restoration < 25 Cast VDRestoreHealthArea1Novice VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration < 50 Cast VDRestoreHealthArea2Apprentice VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration < 75 Cast VDRestoreHealthArea3Journeyman VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration < 100 Cast VDRestoreHealthArea4Expert VDJessaREF elseif VDBrotherSimonREF.GetAV Restoration == 100 Cast VDRestoreHealthArea5Master VDJessaREF endif endif endif endif if VDOracleDatabase.InohenFollower == 1 && VDInohenREF.GetDead != 1 if VDInohenREF.GetAV Health < (VDInohenREF.GetBaseAV Health / 2) if VDInohenREF.getdistance VDBrotherSimonREF <= 200 Message "Inohen health has fallen to half." VDBrotherSimonREF.StopCombat Message "NPC is casting Restoration spell on Inohen." if VDBrotherSimonREF.GetAV Restoration < 25 Cast VDRestoreHealthArea1Novice VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration < 50 Cast VDRestoreHealthArea2Apprentice VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration < 75 Cast VDRestoreHealthArea3Journeyman VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration < 100 Cast VDRestoreHealthArea4Expert VDInohenREF elseif VDBrotherSimonREF.GetAV Restoration == 100 Cast VDRestoreHealthArea5Master VDInohenREF endif endif endif endif set timer to 0 endif endif endif end begin OnDeath ;;; ADVANCES THE ALTERNATE QUEST LINE IF SIMON DIES if getstage VDOracleQuest1 == 60 setstage VDOracleQuest1 65 endif VDSimonResolve.disable end Link to comment Share on other sites More sharing options...
fg109 Posted October 31, 2011 Share Posted October 31, 2011 OK, I made and tested a small mod with a companion that will heal you: http://www.mediafire.com/?q5p938nr65082m5 The companion is a mage apprentice in the market district. You can test it out and see how you can adapt it to your own mod. Link to comment Share on other sites More sharing options...
jamochawoke Posted October 31, 2011 Author Share Posted October 31, 2011 (edited) Everything is working 100% now with that last script like I said in my last post... but if your mod has better scripting code in it then I will definitely use what you've made! Why this is so important to me is that this event that the NPC is in is the climax of the biggest quest in my mod. Then there's the fact I have 3 other NPC's that can heal you in my mod during their own quests (and 1 is a wandering adventurer who if you're around and hurt will stop what they're doing and heal you). So getting this right on one NPC gets it right on 4 :). I cannot stress how helpful you've been to me. Just from this thread and the other threads you've helped me in my scripting you might as well be a co-author of this mod with all the work you've done lol! Edited October 31, 2011 by jamochawoke Link to comment Share on other sites More sharing options...
jamochawoke Posted October 31, 2011 Author Share Posted October 31, 2011 (edited) After checking your little mage guy out... yeah I was able to use pieces of that script. It's a lot cleaner than mine! I'm keeping the CastMagic AI for this particular healer since he is fighting in really tight spaces and he already misses sometimes and heals the monsters (which is a behavior I do want, but only occasionally... adds some "unknown" factor to the fight). If I use your UseItemAt packages on him he tends to be in the wrong spot 75% of the time and will always heal the monster during that time lol! But I was able to basically lift your entire script an packages for the other 3 healers in my mod who are located in outdoor worldspaces and are more likely to be whacking away at a monster next to you rather than running around acting like a coward (the healer I've been trying to get the questline is that you help him find his courage). So that script is perfect for them! Thanks so much man! Edited October 31, 2011 by jamochawoke Link to comment Share on other sites More sharing options...
Recommended Posts