Warbird1 Posted February 26, 2018 Share Posted February 26, 2018 Is it possible to script a npc to run (follow and run) after another running npc? Like chasing game of some sort.How to specify any waypoints? Link to comment Share on other sites More sharing options...
ProfArmitage Posted February 26, 2018 Share Posted February 26, 2018 (edited) I know almost nothing about scripting, but according to Morrowind Scripting for Dummies, the Follow AI package can make an NPC follow another NPC, so it's just a matter of scripting the first NPC's movement. There's also a ForceRun script that was added by Tribunal to make characters run.For waypoints, you have to specify the coordinates in the cell. For example, the script that makes Fargoth sneak around Seyda Neen when you're on the lighthouse includes lines like:Fargoth->AiTravel -11468.595,-71511.531,173.728 ; goes to treeFargoth->AiTravel -11410.590,-72057.188,133.644 ; goes to wall Edited February 26, 2018 by ProfArmitage Link to comment Share on other sites More sharing options...
Warbird1 Posted February 26, 2018 Author Share Posted February 26, 2018 Thanks. That clears a lot. Now on to experiments! :cool: Link to comment Share on other sites More sharing options...
Warbird1 Posted February 26, 2018 Author Share Posted February 26, 2018 Ok so I ran into a problem. What I did is this:1) I made an activator. It works ok. The npcs are spawned in their correct locations:2) But both npcs don't move, I mean Fargoth doesn't go to his waypoint which is a couple of meters before him. Taros looks like he is about to chase him (the running animation kicks in) but suddenly stops, because Fargoth doesn't move. Why is that so? I took coordinates by prior placing some static objects (plant pots), writing down their coordinates (few non-complicated runs around Balmora on short distance), typing them into the script and then obviously deleting all those „plant pots”: Could somebody please take a look into my script and tell me what's wrong? It compiles all right though.The script: Begin poscigshort stateshort jeden_razif ( MenuMode == 1 )returnendifif ( OnActivate == 1 )"player"->Say "Vo\w\m\Fle_WM005.mp3" "WAAAAAAAOOOOOOOOOOAAAAAAAAAGGGHHHHHH!!!!!""taros dral"->PositionCell, -18906, -10545, 185, 97.4, "Balmora""fargoth"->PositionCell, -18901, -10762, 186, 97.4, "Balmora"set state to 10endifif ( "taros dral"->OnDeath == 1 )set jeden_raz to -1returnendifif ( jeden_raz == -1 )returnendifif ( state == 10 )"fargoth"->ForceRun"taros dral"->ForceRun"fargoth"->AiTravel -18976, -1096, 190"fargoth"->AiTravel -19462, -11917, 206"fargoth"->AiTravel -19806, -12695, 206"fargoth"->AiTravel -19992, -13028, 206"fargoth"->AiTravel -19381, -12970, 304"fargoth"->AiTravel -18607, -12929, 201"fargoth"->AiTravel -18171, -12162, 201"fargoth"->AiTravel -18063, -11718, 201"fargoth"->AiTravel -17606, -11120, 201"fargoth"->AiTravel -17138, -11911, 189"fargoth"->AiTravel -17943, -12318, 189"fargoth"->AiTravel -18312, -12962, 189"fargoth"->AiTravel -19224, -12944, 302"fargoth"->AiTravel -19992, -13028, 206"fargoth"->AiTravel -20235, -12673, 175"fargoth"->AiTravel -19910, -11628, 175"fargoth"->AiTravel -20148, -10561, 225"fargoth"->AiTravel -20119, -9858, 225"fargoth"->AiTravel -19864, -10577, 225"fargoth"->AiTravel -19216, -10966, 225"fargoth"->AiTravel -19002, -10657, 215endifend poscig Of course Taros Dral has the appriopriate „AI Package” set to Follow target "fargoth". The problem is why the Wood Elf fetcher does not move his ass. Link to comment Share on other sites More sharing options...
Warbird1 Posted February 27, 2018 Author Share Posted February 27, 2018 Okay, so I expanded the script by adding „walkstate” checks EVERY single waypoint, but all to naught. At least I know the script doesn't go pass the first step, because in the second step there should be heard Wood Elf shout going on, but there isn't such thing at all. The script: Begin poscigshort walkstateset walkstate to 1if ( MenuMode == 1 )returnendifif ( OnActivate == 1 )"player"->Say "Vo\d\m\Atk_DM004.mp3" "You n'wah!""taros dral"->PositionCell, -18906, -10545, 185, 97.4, "Balmora""fargoth"->PositionCell, -18901, -10762, 186, 97.4, "Balmora"elseif ( walkstate == 1 )"taros dral"->ForceRunset walkstate to 2elseif ( walkstate == 2 )"player"->Say "Vo\d\m\Hit_WM015.mp3" "Aaaaaaha!""fargoth"->ForceRun"fargoth"->AiTravel -18976,-1096,190set walkstate to 3elseif ( walkstate == 3 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 4endifelseif ( walkstate == 4 )"fargoth"->ForceRun"fargoth"->AiTravel -19462,-11917,206set walkstate to 5elseif ( walkstate == 5 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 6endifelseif ( walkstate == 6 )"fargoth"->ForceRun"fargoth"->AiTravel -19806,-12695,206set walkstate to 7elseif ( walkstate == 7 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 8endifelseif ( walkstate == 8 )"fargoth"->ForceRun"fargoth"->AiTravel -19992,-13028,206set walkstate to 9elseif ( walkstate == 9 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 10endifelseif ( walkstate == 10 )"fargoth"->ForceRun"fargoth"->AiTravel -19381,-12970,304set walkstate to 11elseif ( walkstate == 11 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 12endifelseif ( walkstate == 12 )"fargoth"->ForceRun"fargoth"->AiTravel -18607,-12929,201set walkstate to 13elseif ( walkstate == 13 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 14endifelseif ( walkstate == 14 )"fargoth"->ForceRun"fargoth"->AiTravel -18171,-12162,201set walkstate to 15elseif ( walkstate == 15 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 16endifelseif ( walkstate == 16 )"fargoth"->ForceRun"fargoth"->AiTravel -18063,-11718,201set walkstate to 17elseif ( walkstate == 16 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 17endifelseif ( walkstate == 17 )"fargoth"->ForceRun"fargoth"->AiTravel -17606,-11120,201set walkstate to 18elseif ( walkstate == 18 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 19endifelseif ( walkstate == 19 )"fargoth"->ForceRun"fargoth"->AiTravel -17138,-11911,189set walkstate to 20elseif ( walkstate == 20 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 21endifelseif ( walkstate == 21 )"fargoth"->ForceRun"fargoth"->AiTravel -17943,-12318,189set walkstate to 22elseif ( walkstate == 23 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 24endifelseif ( walkstate == 24 )"fargoth"->ForceRun"fargoth"->AiTravel -18312,-12962,189set walkstate to 25elseif ( walkstate == 25 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 26endifelseif ( walkstate == 26 )"fargoth"->ForceRun"fargoth"->AiTravel -19224,-12944,302set walkstate to 27elseif ( walkstate == 27 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 28endifelseif ( walkstate == 28 )"fargoth"->ForceRun"fargoth"->AiTravel -19992,-13028,206set walkstate to 29elseif ( walkstate == 29 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 30endifelseif ( walkstate == 30 )"fargoth"->ForceRun"fargoth"->AiTravel -20235,-12673,175set walkstate to 31elseif ( walkstate == 31 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 32endifelseif ( walkstate == 32 )"fargoth"->ForceRun"fargoth"->AiTravel -19910,-11628,175set walkstate to 33elseif ( walkstate == 33 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 34endifelseif ( walkstate == 34 )"fargoth"->ForceRun"fargoth"->AiTravel -20148,-10561,225set walkstate to 35elseif ( walkstate == 35 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 36endifelseif ( walkstate == 36 )"fargoth"->ForceRun"fargoth"->AiTravel -20119,-9858,225set walkstate to 37elseif ( walkstate == 37 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 38endifelseif ( walkstate == 38 )"fargoth"->ForceRun"fargoth"->AiTravel -19864,-10577,225set walkstate to 39elseif ( walkstate == 39 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 40endifelseif ( walkstate == 40 )"fargoth"->ForceRun"fargoth"->AiTravel -19216,-10966,225set walkstate to 41elseif ( walkstate == 41 )if ("fargoth"->GetAiPackageDone == 1 )set walkstate to 42endifelseif ( walkstate == 42 )"fargoth"->ForceRun"fargoth"->AiTravel -19002,-10657,215set walkstate to 43elseif ( walkstate == 43 )if ("fargoth"->GetAiPackageDone == 1 )"fargoth"->ClearForceRunPlaySound "mysticism hit""fargoth"->disable"taros dral"->disableMessageBox "KONIEC"endifendifend poscig It looks like this AiTravel thingy doesn't work at all. Could somebody shed some light om this weird situation and share his insights, please? Link to comment Share on other sites More sharing options...
abot Posted February 27, 2018 Share Posted February 27, 2018 (edited) it could be many things...I'd start replacing (" with ( ", generally try using MWEdit strong syntax checking if possibletry splitting elseifs e.g. fromif ( cond1 ) blahelseif ( cond2 ) blahelseif ( cond3 ) blahelseif ( cond4 ) blahendif to if ( cond1 ) blahelseif ( cond2 ) blahendif; splitif ( cond3 ) blahelseif ( cond4 ) blahendifsometimes too long elseifs are simply not executed correctly Also AITravel usually does not work between cell boundaries, in this case you may have to position the npc or use a "stronger " Ai package (e.g. AIActivate or StartCombat) but position/setPos is probably simpler[EDIT] to see cell boundaries/borders, B in Construction set, TB in game console[EDIT2]probably examples about trying to solve AI wander/follow could be in the traveling merchants mod Edited February 27, 2018 by abot Link to comment Share on other sites More sharing options...
Warbird1 Posted February 27, 2018 Author Share Posted February 27, 2018 Damn, so complicated.I think I'll give that mod a try and peek on some scripts.Thanks for answering. Link to comment Share on other sites More sharing options...
cyran0 Posted February 28, 2018 Share Posted February 28, 2018 The last script you posted has the right structure: you issue the travel package in one state and check for its completion in the next state before traveling to the next waypoint. One thing (there may be other issues) that is preventing your NPCs from moving is the first line after your declaration of variables. Every game cycle you are setting walkstate to 1 which means it repeatedly reassigns the same travel package. If you are coming from Skyrim modding, the error is understandable. Unlike with Papyrus, Morrowind scripts run every frame until they are stopped (that is why the early 'returns' on the menumode check are so important). There is no need to set walkstate to 1. You could make your first logic block check walkstate == 0. But if for some reason you need to set walkstate to 1 before stating the travel code try this: if ( walkstate == 0 ) set walkstate to 1endif There is no difficulty with using AITravel to cross (exterior) cell boundaries, but it won't work if traveling between interior and exterior cells. AIWander will not cross cell boundaries since pathgrids are restricted to one cell and an adjacent cell would have its own distinct pathgrid. It appears that your script is running on the activator rather than the NPC (Fargoth) himself. This will introduce a limit to how far Fargoth can run since if the player moves too far from the cell where the script is running a point will be reached when the object's cell is no longer 'loaded' and the script will stop executing. You could make it a 'targeted' script to run directly on the NPC if you do not want to add scripts to the NPCs in the editor. Check out the code for the mod that abot linked. You will discover the scripts are more complicated - in part to handle an interruption in the AI by waiting in the cell or fast travel. You may not require that code for your project. Link to comment Share on other sites More sharing options...
Warbird1 Posted March 1, 2018 Author Share Posted March 1, 2018 Hey thanks!That thing with assigning 0 to walkstate did the trick! Thank you! Who could have thought of that? Nope, I don't come from Skyrim, never played it.Fortunately those provisional waypoints (coordinates) I set were within the boundaries of a single cell so no, no interruptions, but thanks for that pointer.Yeah, AiTravel is complicated (or perhaps very limited), especially taking into account all variables that might occur in the process. No wonder developers had seldomly used it! (I can recall only two instances to be honest, except Fargoth the next one is Mehra Milo walking few meters away from the player and that's that!)I'm still using the activator, because I don't understand how to use the targeted script… what would trigger the script to fire? I am not very knowledgable in this matter I'm afraid. Link to comment Share on other sites More sharing options...
cyran0 Posted March 1, 2018 Share Posted March 1, 2018 You are welcome. It seems the more complicated a script the more likely that we overlook the simple errors. Just to be clear, all variables have an initial value of 0 except for global variables and only if they are set to have a different value in the editor. Because Fargoth is not running very far you are fine running the script off of the activator. However, if that is not the most natural way of triggering the action or if you want to have more options in the future I will explain how to apply a targeted script. A targeted script is a global script that runs on an object like an NPC. The common way of starting a targeted script on an NPC is through dialogue with that NPC. You could create a new greating for Fargoth (filter it so it does not happen all the time). For example, you could make it so he only freaks out at night. Fargoth might say: "What are you doing? Don't touch me!" Then in the dialogue results window for that new greeting you type: Goodbyeif ( ( ScriptRunning "poscig" ) == 0 ) StartScript "poscig"endif Goodbye forces the player to close the dialogue window. The check is to make certain the script is not already running on Fargoth. It is possible to have multiple targeted scripts running on an object, but two that are the same could give some strange (and undesirable) results. You could also start the targeted script from the activator. The code for the script you would attach to the activator might look like this: Begin ActivatorScript short doOnce if ( doOnce == 1 ) return endif if ( OnActivate == 1 ) set doOnce to 1 "Fargoth"->StartScript "poscig" endif End At some point you will want to stop the script from executing. Use the line: StopScript "poscig" If you do not already have it, Morrowind Scripting for Dummies is the single, most valuable scripting reference. Link to comment Share on other sites More sharing options...
Recommended Posts