SAC Posted October 29, 2019 Posted October 29, 2019 I am trying to script a friendly or neutral NPC to start combat with the player BareHands = Game.GetFormFromFile(0x000001F4, "Fallout4.esm") as Weapon (target as actor).EquipItem(BareHands, true, true) <= this works fine utility.wait(1) (target as actor).startcombat(game.GetPlayer()) <= this does nothing Help?
Seijin8 Posted October 29, 2019 Posted October 29, 2019 Think you'd be better off defining the target as a property, like Actor Target = Whoeverthehell rather than (target as actor), which as far as I know won't work. Also, the startcombat() function is flaky and is heavily influenced by pathing and faction relations.
Carabosse Posted October 29, 2019 Posted October 29, 2019 If you just want a brawl (set rules governing use of weapons etc) you can use the GenericBrawl quest as in Quest MS14 Stage 30. The code to start the brawl between you, Travis and the bullies. ;Put Travis in faction for brawl Alias_Travis.GetActorRef().AddToFaction(GenericBrawlPlayerAllyFaction) ;register for set stage events on brawl quest kmyquest.RegisterforRemoteEvent(GenericBrawl, "OnStageSet") ;start brawl GenericBrawlStart.SendStoryEvent(akRef1=Alias_Breadbox.GetRef(), akRef2=Alias_Bully2.GetRef()) GenericBrawlStart is a keyword. The startcombat() call you're using on a friendly actor probably isn't working because you need to overcome the factors that dictate how the actor responds to the player. Whether they're in a friendly faction and their relationship rank etc. Use functions like SetRelationshipRank() on the actor to force disposition towards another.
SAC Posted October 29, 2019 Author Posted October 29, 2019 Yep, I think factions are the problem with startcombat(). If I wanted to simplify the brawl (it's a brawl just between the player and one NPC whose reference is "target"): BareHands = Game.GetFormFromFile(0x000001F4, "Fallout4.esm") as Weapon keyword GenericBrawlStart = Game.GetFormFromFile(0x000AC074, "Fallout4.esm") as keyword (target as actor).EquipItem(BareHands, true, true) ;register for set stage events on brawl quest kmyquest.RegisterforRemoteEvent(GenericBrawl, "OnStageSet") ;start brawl GenericBrawlStart.SendStoryEvent(akRef1=target) ^^this does not compile, because it doesn't know what kmyquest is. I also don't know what it is, and how to declare it I've never called a quest in a script before
Carabosse Posted October 29, 2019 Posted October 29, 2019 19 minutes ago, SAC said: ^^this does not compile, because it doesn't know what kmyquest is. I also don't know what it is, and how to declare it I've never called a quest in a script before kmyQuest is the shorthand for the attached script you're accessing in quest stage fragments. As the quest script is limited in what you can do you need to rely on additional scripts often. At the top of each stage fragment is a dropdown letting you choose the script assigned to kmyQuest for that fragment (it must be attached to your quest to appear as an option here). It's equivalent to adding a script property like: MyOtherScript Property kmyQuest Auto But a lot less fuss. In the code above, that other script attached to your quest (the one you assign to kmyQuest) would be handling listening for events in the GenericBrawl quest. If you look at the GenericBrawl quest you'll see its setup to hit certain stages for various things. Like the player winning, the player being defeated, someone drawing a weapon etc. Your attached script (assigned to kmyQuest) would be listening for those stage events from GenericBrawl and you could then affect actions in your quest depending on what event (stage in GenericBrawl was triggered). The quest with id MS14 has a call to GenericBrawl set up. It's the quest where you help Travis fight the bullies in the Dugout Inn. Have a look at how it is done in there. Also take a look at the GenericBrawl quest. It might not do what you need but for simple brawls its a ready made option that I find easy to use. Also GenericBrawl already handles setting the actors involved to only start using their bare hands. So you wouldn't need to do that if you decide to use GenericBrawl. It doesn't stop them using another weapon later but will flag the actor who did as cheating and trigger the relevant stage (which you can be listening for in your originating quest as detailed above).
SAC Posted October 29, 2019 Author Posted October 29, 2019 I'll be very honest and say that I've read this three times and I don't understand this I mean: - I understand the fact about not needing the bare hands, because Brawl already takes care of this - I don't have my own quest to begin with (should I have one?) - I need to have a look at MS14 (to do) - I don't really understand the rest Now, if I just do this: keyword GenericBrawlStart = Game.GetFormFromFile(0x000AC074, "Fallout4.esm") as keyword GenericBrawlStart.SendStoryEvent(akRef1=target) ... then the "target" NPC comes up to me, punches me *once* (which is promising!), then walks away (which is disappointing!!). From there on, I'm a bit lost
Carabosse Posted October 29, 2019 Posted October 29, 2019 44 minutes ago, SAC said: I'll be very honest and say that I've read this three times and I don't understand this I mean: - I understand the fact about not needing the bare hands, because Brawl already takes care of this - I don't have my own quest to begin with (should I have one?) - I need to have a look at MS14 (to do) - I don't really understand the rest Now, if I just do this: keyword GenericBrawlStart = Game.GetFormFromFile(0x000AC074, "Fallout4.esm") as keyword GenericBrawlStart.SendStoryEvent(akRef1=target) ... then the "target" NPC comes up to me, punches me *once* (which is promising!), then walks away (which is disappointing!!). From there on, I'm a bit lost I think then that using the GenericBrawl quest is probably a bit of overkill for what it is you're trying to do. So I had a look at one of my scripts where I generate NPCs from templates. These could be templates that are hostile to the player by default. So for any of those spawned actors I have to run a few commands on them to make sure they don't instantly attack the player. Which is like what you want to do but in reverse I suppose. As you want to make a friendly NPC act hostile, In my testing, just applying an actor to a friendly or enemy faction is not enough to change their disposition towards the player. To make those potentially hostile actors NOT attack the player I run the follow commands on them. myActor.SetValue(Aggression, 0) myActor.SetValue(Assistance, 0) myActor.SetRelationshipRank(Game.GetPlayer(), 0) Aggression and assistance are actorvalue properties. Obviously don't use those values, those are the ones to make an actor effectively neutral. The CK wiki has explanations of the value grades for each function. For example, I think -4 for RelationshipRank is 'archnemesis'. I would urge caution using those commands on an NPC that is normally friendly. I've never used them to make an otherwise friendly NPC, unfriendly. You wouldn't want the change to be permanent I would guess. So you'd have to get and store the original values so that you could return them later. Getting the original values is: myActor.GetValue(Aggression) etc. I believe.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.