Jump to content

How to make an NPC forcegreet the player during combat?


mooglechick

Recommended Posts

 

You most likely need to stop combat with script, make the actor who you want to forcegreet non-hostile and evaluate his package. Then when conversation ends you can turn him hostile again and force start combat with script.

 

Have you done console command "sqv quest number" to see if the alias fills too?

 

Yeah, the alias is filled. I thought that was my problem initially too but I even tried using a unique actor and even though it says the alias is filled, it still didn't work, so I'm back to trying to suss out the package.

 

As for the script, I'm not sure how to go about doing that because none of the NPCs are unique actors. The alias is supposed to randomly pick one to forcegreet the player based on which NPC is closest, or at least I assumed that's how it works.

 

You can add a script directly to your alias. Then OnInit you register it for some event (i.e. distance event , so the script will wait for player to be close enough) ..And then in this event you do what you want.

And you can also try to see if your greeting will work without combat.

And about flags - you should leave "ignore combat " flag checked.

Edited by kitcat81
Link to comment
Share on other sites

 

 

You most likely need to stop combat with script, make the actor who you want to forcegreet non-hostile and evaluate his package. Then when conversation ends you can turn him hostile again and force start combat with script.

 

Have you done console command "sqv quest number" to see if the alias fills too?

 

Yeah, the alias is filled. I thought that was my problem initially too but I even tried using a unique actor and even though it says the alias is filled, it still didn't work, so I'm back to trying to suss out the package.

 

As for the script, I'm not sure how to go about doing that because none of the NPCs are unique actors. The alias is supposed to randomly pick one to forcegreet the player based on which NPC is closest, or at least I assumed that's how it works.

 

You can add a script directly to your alias. Then OnInit you register it for some event (i.e. distance event , so the script will wait for player to be close enough) ..And then in this event you do what you want.

And you can also try to see if your greeting will work without combat.

And about flags - you should leave "ignore combat " flag checked.

 

 

I tested it without combat and it still doesn't work. I'm actually glad because I was starting to think that was the problem. But it's just me and my forcegreet package, I guess! lol

 

Next I'll give your script a try.

Link to comment
Share on other sites

Thanks again for all the help! I try to figure this stuff out on my own but sometimes it doesn't work out that way. You guys are helping a lot!

 

EDIT:

 

Alright! I got a script on the Quest Alias. I had to use IsPlayerEnemy instead of GetDistance because it was saying I needed an ObjectReference.

Scriptname MyQuestScript extends ReferenceAlias


Event OnInit()


if (NPCFaction.IsPlayerEnemy())
NPC.TryToStopCombat()
NPC.TryToEvaluatePackage()
endif


EndEvent


ReferenceAlias Property NPC Auto Const


Faction Property NPCFaction Auto Const

However the forcegreet/dialogue still isn't happening. Grr.

 

EDIT:

 

Also messing around a bit with the first line of the dialogue, I got it to start if I get near the NPC alias -- without combat already happening. I then started combat and when I got near him again, he kept repeating the initial line over and over but no dialogue choices popped up. I also tried adding "Game.GetPlayer().StopCombat()" on a Begin fragment but the rest of the NPCs still attacked while he stood there repeating the first line.

 

Yet if I start combat first, the dialogue never happens. And the forcegreet package still flat out isn't working.

 

So close... yet so far.

Edited by friendlyyan
Link to comment
Share on other sites

Hmm, the problem could be that like most dialogues, it has flag Actor Behaviour pause or end on combat.

 

The problem could be his friends. They are still alerted by you, and the npc you try to talk has "helps friends and allies" and won't actually do the conversation more than first line.

 

Maybe you should try does the conversation/force greet work on non-hostile npcs first. Also give the force greet big enough distance, like 1000 or so, should help getting it started.

 

Maybe there is a vanilla quest that could hep, can't think of any now, that has first hostile guys and then starting dialogue with the same guys. There are things like gunners on bridge that ask for money to pass, but they are NOT hostile at first if you check them on Vats.

 

I guess it could also be done with a bit more advanced script. Like using GetAllCombatTargets on player to array, then cycling trough all of them and making them all non-hostile. Just need to make conditions when you manipulate the targets so not random Mirelurk get's on the way. (Not sure actually if GetAllCombatTargets work on player)

 

Also, you should be able to use Distance, if you put ReferenceAlias player and ReferenceAlias npc on your properties(First add them in Quest aliases tab). Then just:

ReferenceAlias Property PlayerRef Auto Const

ReferenceAlias Property NpcRef Auto Const

Event OnInit()
	RegisterForDistanceLessThanEvent(PlayerRef, NpcRef, 150.0)
        ; Must register for it to work at all
endEvent

Event OnDistanceLessThan(ObjectReference akObj1, ObjectReference akObj2, float afDistance)
        Debug.Notification("distance less than 150")
        ; You can do your things here
        ; Also you need to re-register here, otherwise it only works once
        ; Better do some good conditions here, otherwise it gets spammed everytime distance is less than 150, but only if you re-register. Utility.Wait can be handy.
        ; If you dont re-register, the event is done and wont fire again.
        RegisterForDistanceLessThanEvent(PlayerRef, NpcRef, 150.0)
endEvent

I'm using something similiar on Quest script, but I believe it should work fine on ReferenceAlias too.

 

edit: I don't know what those colours are in the code block, just ignore them, lol.

 

If you want to check distance in if statement for example, you can do this:

Scriptname xx:xxxxx extends ReferenceAlias ; put this on your npc you want to forcegreet

Event OnInit() ; please note, this is not very useful on OnInit event, since it only works once. I think simply registering for distance works better, unless you find a good event to use this on.

Actor mySelf = Self.GetReference() as Actor
Actor Player = Game.GetPlayer()

float mindistance = 500 ; or whatever you want
float distance = mySelf.GetDistance(Player)

if (distance <= mindistance)
   ;do your things
endif

EndEvent

Timer event can work but simply registering for distance should be easier and better.

Edited by vkz89q
Link to comment
Share on other sites

Hmm, the problem could be that like most dialogues, it has flag Actor Behaviour pause or end on combat.

 

The problem could be his friends. They are still alerted by you, and the npc you try to talk has "helps friends and allies" and won't actually do the conversation more than first line.

 

Maybe you should try does the conversation/force greet work on non-hostile npcs first. Also give the force greet big enough distance, like 1000 or so, should help getting it started.

 

Maybe there is a vanilla quest that could hep, can't think of any now, that has first hostile guys and then starting dialogue with the same guys. There are things like gunners on bridge that ask for money to pass, but they are NOT hostile at first if you check them on Vats.

 

I guess it could also be done with a bit more advanced script. Like using GetAllCombatTargets on player to array, then cycling trough all of them and making them all non-hostile. Just need to make conditions when you manipulate the targets so not random Mirelurk get's on the way. (Not sure actually if GetAllCombatTargets work on player)

 

Also, you should be able to use Distance, if you put ReferenceAlias player and ReferenceAlias npc on your properties(First add them in Quest aliases tab). Then just:

ReferenceAlias Property PlayerRef Auto Const

ReferenceAlias Property NpcRef Auto Const

Event OnInit()
	RegisterForDistanceLessThanEvent(PlayerRef, NpcRef, 150.0)
        ; Must register for it to work at all
endEvent

Event OnDistanceLessThan(ObjectReference akObj1, ObjectReference akObj2, float afDistance)
        Debug.Notification("distance less than 150")
        ; You can do your things here
        ; Also you need to re-register here, otherwise it only works once
        ; Better do some good conditions here, otherwise it gets spammed everytime distance is less than 150, but only if you re-register. Utility.Wait can be handy.
        ; If you dont re-register, the event is done and wont fire again.
        RegisterForDistanceLessThanEvent(PlayerRef, NpcRef, 150.0)
endEvent

I'm using something similiar on Quest script, but I believe it should work fine on ReferenceAlias too.

 

edit: I don't know what those colours are in the code block, just ignore them, lol.

 

If you want to check distance in if statement for example, you can do this:

Scriptname xx:xxxxx extends ReferenceAlias ; put this on your npc you want to forcegreet

Event OnInit() ; please note, this is not very useful on OnInit event, since it only works once. I think simply registering for distance works better, unless you find a good event to use this on.

Actor mySelf = Self.GetReference() as Actor
Actor Player = Game.GetPlayer()

float mindistance = 500 ; or whatever you want
float distance = mySelf.GetDistance(Player)

if (distance <= mindistance)
   ;do your things
endif

EndEvent

Timer event can work but simply registering for distance should be easier and better.

 

Thanks for your suggestions! I removed pause/end combat from Actor Behavior. I even tried using some quest stages just to do some more testing. I did want to avoid using them because of the possible delay between stopping the combat and starting the forcegreet. But just to test things out, I set up a stage that checks for the combat, then one that stops it and evaluates the package if the NPC is close enough.

 

Unfortunately, I've still got nothing. Whether I use a script on the alias or use quest stages. I can't seem to stop the combat at all. The CK wiki says that when you make a faction mad you just become a temporary enemy until some time has passed, so I tried using SetPlayerEnemy(false) to get the combat to stop and the forcegreet package to start but even that didn't work! Nor is StopCombat().

 

I feel like this is way more complicated than it should be! I was worried this is hard coded somehow but the combat functions exist for a reason so I don't see why it wouldn't work.

Link to comment
Share on other sites

With the script requires Object Reference you can add "as ObjectReference". The same thing goes to Actor:

(Self as ObjectReference).DoSomething() 
(Self as Actor).DoSomething()

To stop the combat you can add actors to factions or remove them from factions. For example to stop almost anyone from attacking the player you can add them to playerfaction. You also can remove them from all factions.

To make the effect appear immeditelly you might need to reset their ai (function resetai) or set then unconscious, then change factions, then setunconscious(false).

 

 

I`m sorry, think I misunderstud about object reference...Though the thing I wrote is still valid when you need to use actor functions for something defined as object reference etc.

But with Alias if you want to use some certrain functions you type Self.GetReference().DoSomething() or Self.GetActorReference().DoSomething()

In this case DoSomething can be replaced with any Actor and Object Reference usual functions ( not those starting with tryto)

Edited by kitcat81
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...