Aller au contenu

Photo

Can't find an old post...start conversation at 1 hp?


  • Veuillez vous connecter pour répondre
35 réponses à ce sujet

#1
Sprinkles22

Sprinkles22
  • Members
  • 4 messages
 Hey there! Sorry to bother everone, but there was a script I once used from these forums I can't find anymore, and I'm not a fantastic scripter.

The script was for the ondamage of a creature. when the creature reached 1 hp (we set the creature to immortal) the script stoped combat and started the creature's conversation file.

Can anyone give me a hand with this It was such a great script....
Thanks!

#2
Tchos

Tchos
  • Members
  • 5 030 messages
Hello.  I don't know which one you were using, but I knew I had one like this, so I dug it out.  See if this works for you?  One thing is that I changed it to anything under 5 HP, because it seemed more reliable that way.

void main()
{
    object oSelf = OBJECT_SELF;
    location lLoc = GetLocation(oSelf);
    int nHP = GetCurrentHitPoints(oSelf);

    // If the NPC currently has 5 or fewer Hit Points left
    if(nHP <= 5)
    {
        // Search through all creatures in a 20 meter radius centered on oSelf
        object oNPC = GetFirstObjectInShape(SHAPE_SPHERE, 20.0f, lLoc, FALSE, OBJECT_TYPE_CREATURE);

        while(GetIsObjectValid(oNPC))
        {
            // Clear combat states for every creature found in search.  Creatures cannot converse while in combat.
            AssignCommand(oNPC, ClearAllActions(TRUE));

            // Change NPC to Commoner Faction so no longer hostile
            if((!GetIsPC(oNPC)) && (!GetIsOwnedByPlayer(oNPC)) && (!GetIsPlayerCreated(oNPC)))
            {
                ChangeToStandardFaction(oNPC, STANDARD_FACTION_COMMONER);
            }
            oNPC = GetNextObjectInShape(SHAPE_SPHERE, 20.0f, lLoc, FALSE, OBJECT_TYPE_CREATURE);
        }

        // Have the NPC begin a conversation with PC
        object oPC = GetFirstPC(FALSE); // This is the player's currently controlled character
        AssignCommand(oSelf, ActionStartConversation(oPC, "", FALSE, TRUE, FALSE, FALSE ));
    }

    // Else NPC is not yet at 5 Hit points, so fire normal OnDamaged script
    else
    {
        ExecuteScript("nw_c2_default6", oSelf);
    }
}

EDIT: Corrected a spelling error and changed it to converse with the currently controlled character instead of the main PC.

Modifié par Tchos, 03 août 2013 - 07:28 .


#3
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
I like it and will use this in the next area coming up.

#4
Dann-J

Dann-J
  • Members
  • 3 161 messages
Rather than looping through everyone within 20 metres and stopping their combat individually, you could change the faction of the creature to Defender and give them the ethereal effect temporarily (for at least seven seconds, so everyone goes through an entire combat round). That way the existing AI scripts do all the hard work for you.

#5
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
Show me the SCRIPT

#6
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
seriously you don't have a script of this technique?

#7
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
Ok since no one answered, I have tried this. The results aren't good as companions seem to keep
fighting when I am in conversation (even though th NPC has turned to neutral faction)

Ideas?


// This on damaged function causes the creature to cease combat, and switch to neutral faction, and converse
// Eguintir Eligard, Aug 2013 * * * * *

#include "ee_debug"
#include "ginc_param_const"

void main()

{
string sTalk = GetLocalString(OBJECT_SELF, sTalk); // optional conversation tag
object oPC = GetFirstPC(FALSE);
object oNext = GetFirstFactionMember(oPC);
object oFaction = GetObjectByTag("ip_describer");  // assumes invisible man with neutral faction of this tag name
effect ePause = EffectEthereal(); // Pause so we can remove this creature from combat

int iHP = GetCurrentHitPoints(OBJECT_SELF);

if (iHP < 3) // do the process of ending combat without death
	{
	DBT("Hit points < 3, initiating combat end/clear...");
	AssignCommand(OBJECT_SELF, ClearAllActions(TRUE) );
	ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ePause, OBJECT_SELF, 8.5f);
	ChangeFaction(OBJECT_SELF, oFaction);	
	
	do	{		
		AssignCommand(oNext, ClearAllActions(TRUE) );
		oNext = GetNextFactionMember(oPC, FALSE);
		} while (GetIsObjectValid(oNext) );
	
	// try to converse until sucess now that battle is paused/cleared	
	DBT("Attempt conv..");
	do {	
		DBT("Attempt made");
		
		AssignCommand(OBJECT_SELF, ActionStartConversation(oPC, sTalk, FALSE, FALSE, TRUE, TRUE) );
		
		} while (IsInConversation(OBJECT_SELF)==FALSE);
	
	} else ExecuteScript("nw_c2_default6", OBJECT_SELF); // use regular script otherwise
	


}


#8
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
The last time this happened I was controlling a non PC party member just in case that's relevant.

Do I have to clear the monsters actions too?

Modifié par Eguintir Eligard, 18 août 2013 - 10:21 .


#9
kevL

kevL
  • Members
  • 4 052 messages
you might give this a try, ee.

I haven't used it; all i remember is back in NwN getting mass combat to stop is one of the most diffucult things ... ther's always one guy who just needs to take the last swipe, and it all starts back up again.

// Use this on an NPC to cause all creatures within a 10-metre radius to stop
// what they are doing and sets the NPC's enemies within this range to be
// neutral towards the NPC for roughly 3 minutes. If this command is run on a PC
// or an object that is not a creature, nothing will happen.
void SurrenderToEnemies();


- it may experience the NwN->NwN2 improbability drive, esp. since it says "for roughly 3 minutes" which iirc means it relies on 'personal reputations' that are problematic in NwN2.

but yeah you should cycle through all hostiles in the vicinity and change their factions/reputations along with Clears all 'round.



found this in some old scripts:
// Stop the fight
ClearAllActions();
AssignCommand(oPC, ClearAllActions());
SurrenderToEnemies();
ClearPersonalReputation(oPC, OBJECT_SELF);

but don't rely on it as-is. (it was called in the onDamaged of a user-defined script, btw)

'ginc_group', if you're into Groups, has void GroupSurrenderToEnemies(string sGroupName);
and, lol it has this note: "// note: testing on 9/14/05 indicates SurrenderToEnemies() is unreliable."

'x0_i0_partywide' has this
// Cause all members of the faction of the given surrendering
// object to issue a SurrenderToEnemies call. Does not work
// on PCs, but DOES work on their associates.
void SurrenderAllToEnemies(object oSurrendering = OBJECT_SELF);

but it lacks a ClearAll command as it is. Obsidian used this code to stop Lorne in the OC:

SurrenderToEnemies();
ClearAllActions(TRUE);
ChangeFaction(OBJECT_SELF, GetObjectByTag("20_spectator"));
- then goes on to start a dialog w/ CreateIPSpeaker() ...

i Notice some of the Pausanius NwN scripting sets a local_var on the surrendered NPCs: "Generic_Surrender", that stops them from responding to further shouts to attack,


Anyway, good luck. Just tossing out some things and refreshing my memory :) I suggest cycling through both the party-faction *and* the enemy faction(s) and doing ClearAllActions, SurrenderToEnemies, and ChangeFaction ( or AdjustReputation )

#10
Dann-J

Dann-J
  • Members
  • 3 161 messages
You'll be very lucky if the SurrenderToEnemies function still works in NWN2.

My ankeg burrowing scripts stop combat against Hellfire's ankheg model, when it plays its retreat animation and goes script-hidden, by using the ethereal effect. Otherwise companions continue to attack the script-hidden creature (and can even kill it while script-hidden if you don't set the ankheg to immortal). Making it ethereal seems to end non-PC party members' combat rounds, then they all act as if there are no hostiles around at all (they start following the PC, for instance). The PC stops being able to attack due solely to the ankeg being script-hidden. However I don't have any other non-party Defenders in the same area as the ankhegs.

#11
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
Well I definitely had to put the fight out of site of the guards I found pretty quick. But are we throwing in the towel hear anyway and saying it's buggy no matter what? Should I set the conversation to fire more than once in that case?

Currently the conversation is started by an IP speaker (Im sure youve seen my post on that) and then resumed on a second node from the on damaged script. I supposed I could use a different conversation altogether the first time then resume talking from a second one after the fight portion.

#12
kevL

kevL
  • Members
  • 4 052 messages

Eguintir Eligard wrote...

... But are we throwing in the towel hear anyway and saying it's buggy no matter what?

I wouldn't say that yet. But striving for robustness is a law of diminishing returns ...


Should I set the conversation to fire more than once in that case? ... I supposed I could use a different conversation altogether the first time then resume talking from a second one after the fight portion.


- just a reminder. Set a local_int perhaps on the module from within an attempted conversation, then do a check for it during another startup routine as the backup. Have the two attempts initiate entirely independently,

#13
Dann-J

Dann-J
  • Members
  • 3 161 messages
Another approach entirely would be to script-hide and 'ethereal' the original combatant (or destroy it, or jump it to an inaccessable place in another area) and spawn in a stand-in from a blueprint that has only 1 HP and a Defender faction. You could give the stand-in an OnSpawn script that applies a looping kneeling-injured animation via PlayCustomAnimation, then jump to a cut-scene conversation between the PC (ClearAllActions(TRUE)-ed, and resurrected if necessary) and the stand-in so that the transition between original and stand-in is hidden. A slight delay after clearing the PC's combat state might be prudent (even if it's only 0.1 seconds).

The main problem with stopping combat is that once non-PCs are locked onto a target, it can be hard to convince them to stop attacking. Player-controlled characters can't initiate combat with a Defender, nor can they continue to attack a script-hidden creature, but non-PCs don't seem to be bound by such laws. The new Defender stand-in won't ever have registered as an enemy in their perception lists, so they won't even think of trying to attack it.

#14
Tchos

Tchos
  • Members
  • 5 030 messages
I like the sound of that approach and how it solves the problems, and also the chance for some animation and posing with it.

#15
Dann-J

Dann-J
  • Members
  • 3 161 messages
I had to resort to a similar situation in my current module. On entering an interior area, a cutscene fires where you encounter a mage. You can defuse the situation and declare your intentions non-hostile, or you can attack him. If you choose to attack, he teleports to a distant part of the interior, and all his minions in the place become hostile. The intention was that if you choose to attack, you have to fight through his minons to get to him.

That didn't work out though, since once he was teleported and hostile he then ran all the way back through his own minions to get at your party. Since he didn't 'shout' that he'd perceived an enemy, none of his minions followed him either. Even turning him hostile several seconds after he'd teleported didn't work. ClearAllActions(TRUE) might stop combat, but it doesn't seem to affect a creature's perception list. He seemed to be seeking out the party retroactively, since you weren't a hostile target when he first perceived you.

I ended up having two versions of him. One of them initiated that first conversation, then went script-hidden while the teleport effect played on him at the end of the cutscene (he teleports regardless of whether you're friend or foe). The other version was in his sanctum all along, so had never perceived the players. When he and his group turn hostile, he waits there patiently since he's never actually seen the players.

#16
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
My Script continues to show failures to complete.

Has no one seriously found a script that does this properly without 1000 and 1 exceptions to the rule? It seemed to work in the OC but I have no idea what the script would be called. These are the type of life sucking (2 week long now) wastes of time I hope to avoid so I don't burn out on another module. I just want the guy to stop fighting and talk so I can move on with the module. With no bugs and workarounds

Modifié par Eguintir Eligard, 26 août 2013 - 04:25 .


#17
Tchos

Tchos
  • Members
  • 5 030 messages
Did you experience problems with the one I posted?

#18
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
I actually just tried it exactly as is.

The conversation began, my entire party "unjoined" so it was only the PC left, and the guy still took a shot at me while we were talking and broke the conversation.

#19
Kaldor Silverwand

Kaldor Silverwand
  • Members
  • 1 585 messages
In King's Festival I used a combination of the standard gb_surrender_sp spawn script and my own bb_surrender_ud script which was modified from the gb_surrender_ud script. In my script I used both SurrenderToEnemies and also changed the faction to commoner. My script only changes the particular creature, it does not handle allies.

The bb_surrender_sp script is this:

// bb_surrender_ud - Based on gb_surrender_ud
/*
Modified by B. Bellina Feb-May, 2009
- Added Shout string SurrenderShout (string variable on creature)
- Uses ChangeToStandardFaction instead of surrenderall function

If the creature is set to be able to talk to non-player owned creatures then forcing a conversation
may start a conversation that cannot be exited. So, to avoid that if the creature is set to talk to
non-player owned creatures the conversation will not fire. Use the SurrenderShout in this case.
*/

/*
When creature drop below percentage of HP, he surrenders and speaks w/ the nearest PC

How to use:
make copy of this script and assign it and gb_surrender_sp to creature.
works best if creature is immortal

*/

#include "x0_i0_partywide" //has SurrenderAllToEnemies()
#include "ginc_misc"

const float HP_PERCENT_SURRENDER = 25.0f;

void main()
{
int nUser = GetUserDefinedEventNumber();

if(nUser == 1001) //HEARTBEAT
{
}
else if(nUser == 1002) // PERCEIVE
{
}
else if(nUser == 1003) // END OF COMBAT
{
}
else if(nUser == 1004) // ON DIALOGUE
{
}
else if(nUser == 1005) // ATTACKED
{
}
else if(nUser == 1006) // DAMAGED
{
if (IsMarkedAsDone())
return;

int nMaxHP = GetMaxHitPoints();
int nCurrHP = GetCurrentHitPoints();

int nPercentofMaxHP = FloatToInt((IntToFloat(nMaxHP) * (HP_PERCENT_SURRENDER/100.0f)));

// * generic surrender should only fire once
if((GetIsDead(OBJECT_SELF) == FALSE) && ((nCurrHP <= nPercentofMaxHP) || (nCurrHP <=1)))
{
string sSurrenderString = GetLocalString(OBJECT_SELF, "SurrenderShout");
if (sSurrenderString != "") { SpeakString(sSurrenderString); }
MarkAsDone();
//PrintString (GetName(OBJECT_SELF) + " surrenders!");
//SurrenderAllToEnemies(OBJECT_SELF);
object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
//SpeakString(GetName(OBJECT_SELF) + " surrenders to " + GetName(oPC));
//SurrenderAllToEnemies(oPC);
SurrenderToEnemies(); // stops everyone fighting for a few seconds
ChangeToStandardFaction(OBJECT_SELF, STANDARD_FACTION_COMMONER);
ClearAllActions();

if (GetCanTalkToNonPlayerOwnedCreatures(OBJECT_SELF) != TRUE)
ActionStartConversation(oPC); // start talking with nearest PC
}
}
else if(nUser == 1007) // DEATH
{
}
else if(nUser == 1008) // DISTURBED
{
}
}

Regards

#20
Kaldor Silverwand

Kaldor Silverwand
  • Members
  • 1 585 messages
As written my script above defaults to checking for reduction to 25% of the person's hp, but you can change the percentage to whatever you want by changing the constant HP_PERCENT_SURRENDER.

Regards

#21
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
DO I have to know or do anything or just copy this? The comments give me pause

#22
I_Raps

I_Raps
  • Members
  • 1 262 messages
This forum does not like exotic punctuation and replaces or deletes it. It's impossible to post code here verbatim without jumping through considerable hoops. I wouldn't be at all surprised if "just copying" it produced tons of errors.

If it does, go through the errors and see if you can't get rid of them with a little reformatting.

#23
kamal_

kamal_
  • Members
  • 5 238 messages
I recommend http://pastebin.myrror.net/ for providing links to the code, it's specifically for nwscript.

#24
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
I'm not really sure if anythings missing or not but King's Festival script had yielded a simple non-response...

#25
andysks

andysks
  • Members
  • 1 645 messages
Is this thread closed? If so, may I ask how the script that Kaldor posted is handled? Is it an OnDamage event or it requires something more?