Surrender script?
#1
Posté 20 juillet 2011 - 05:10
#2
Posté 20 juillet 2011 - 05:31
#3
Posté 20 juillet 2011 - 06:38
#4
Posté 20 juillet 2011 - 07:13
#5
Posté 20 juillet 2011 - 07:50
#6
Posté 20 juillet 2011 - 08:13
henesua wrote...
How does one get the functionality of SurrenderToEnemies but for less time than 3 minutes?
SetIsTemporaryFriend
#7
Posté 20 juillet 2011 - 08:15
#8
Posté 20 juillet 2011 - 08:28
#9
Posté 20 juillet 2011 - 08:49
henesua wrote...
I have not had much success with SetIsTemporaryFriend ending combat. I'll try some more experiments.
I dont think it stops combat. If you do not Clear the actions of the Characters involved, They will still wack each other. In that case the rep wil most likely get adjusted right back to hostile. That would be my guess anyway.
#10
Posté 20 juillet 2011 - 09:08
henesua wrote...
I have not had much success with SetIsTemporaryFriend ending combat. I'll try some more experiments.
You will need to do a ClearAllActions(TRUE);, for both the player and the NPC, at the same time. As well as any of the players henchmen etc. It's not nearly as simple as using the function Lightfoot suggested. But if you need a specific amount of time this might be the way to go.
Modifié par GhostOfGod, 20 juillet 2011 - 09:10 .
#11
Posté 21 juillet 2011 - 12:27
#12
Posté 27 juillet 2011 - 05:46
SetCommandable(TRUE, oPC);
SetCommandable(TRUE, oEnemy);
AssignCommand(oPC, ClearAllActions(TRUE));
SetIsTemporaryFriend(oEnemy, oPC, TRUE, fTime);
AssignCommand(oEnemy, ClearAllActions(TRUE));
SetIsTemporaryFriend(oPC, oEnemy, TRUE, fTime);
But the full function is failing, and I can't find the error.
http://pastebin.com/Dxx3V5ST
Modifié par henesua, 27 juillet 2011 - 05:53 .
#13
Posté 27 juillet 2011 - 10:07
void StopFactionCombat(object oPC, object oEnemy)
{
int iNth = 1;
object oCombatant = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oPC, iNth);
object oMember;
while (GetIsObjectValid(oCombatant))
{
if (GetFactionEqual(oEnemy, oCombatant))
{
oMember = GetFirstFactionMember(oPC, FALSE);
while (GetIsObjectValid(oMember))
{
if (GetCurrentAction(oMember) == ACTION_ATTACKOBJECT)
AssignCommand(oMember, ClearAllActions(TRUE));
if (GetCurrentAction(oCombatant) == ACTION_ATTACKOBJECT)
AssignCommand(oCombatant, ClearAllActions(TRUE));
SetIsTemporaryFriend(oMember, oCombatant, FALSE);
oMember = GetNextFactionMember(oPC, FALSE);
}
}
iNth++;
oCombatant = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oPC, iNth);
}
}
void main()
{
object oPC = GetLastDamager(OBJECT_SELF);
object oEnemy = OBJECT_SELF;
if (GetCurrentHitPoints(OBJECT_SELF) < 4)
StopFactionCombat(oPC, oEnemy);
}
P.S. Using the GetFirst/NextFactionMember functions works fine for single player as well since associates are considered faction members.
Modifié par GhostOfGod, 27 juillet 2011 - 10:09 .
#14
Posté 27 juillet 2011 - 04:22
You did not use GetNearestEnemy as I did. Rather you are simply going through all nearby creatures. Is there something wrong with the GetNearestEnemy function?
Curious as to your thinking here.
#15
Posté 27 juillet 2011 - 05:42
#16
Posté 27 juillet 2011 - 05:54
henesua wrote...
FYI - this seems to work with one enemy present
SetCommandable(TRUE, oPC);
SetCommandable(TRUE, oEnemy);
AssignCommand(oPC, ClearAllActions(TRUE));
SetIsTemporaryFriend(oEnemy, oPC, TRUE, fTime);
AssignCommand(oEnemy, ClearAllActions(TRUE));
SetIsTemporaryFriend(oPC, oEnemy, TRUE, fTime);
But the full function is failing, and I can't find the error.
http://pastebin.com/Dxx3V5ST
There are a couple of errors in your script. mainly around the ++ operator.
Line34: if (++x==max) break;
should be: if (x++ ==max) break;
make sure you have a space between the ++ and ==. it is not need in this case but does help advoid anbiguity.
You have the same problem on lines: 64, 67 and 77, with the ++ operator on the wrong side of the var you are trying to increase.
...
As to the use of GetNearestEnemy vs GetNearestCreature, I see the use of GetNearestCreature easier to use in this case just because you are not changing the state of the object being a creature or not in the script. The script is however changing there state of being an enemy or not. Sometimes it is hard to tell if changes like this take place while the script is running or wait untill after the script is finished to take effect. Therefore the loop through the creatures is more strightforward then the loop through enemies.
#17
Posté 27 juillet 2011 - 06:07
GhostOfGod wrote...
Honestly, I just didn't know there was a "GetNearestEnemy" function. I've never used it. I just tried to look for it in nw_i0_generic and can't find it though it is on the list of functions.
It is in: X0_I0_ENEMY
it is in the lower branches of the nw_i0_generic includes. here is the include path from there.
"nw_i0_generic" > "x0_i0_anims">"x0_i0_walkway">"x0_i0_spawncond">"x0_i0_combat"> "x0_i0_talent"> "x0_inc_generic"> "x0_i0_equip">" x0_i0_enemy"
Modifié par Lightfoot8, 27 juillet 2011 - 06:09 .
#18
Posté 27 juillet 2011 - 06:20
Lightfoot8 wrote...
GhostOfGod wrote...
Honestly, I just didn't know there was a "GetNearestEnemy" function. I've never used it. I just tried to look for it in nw_i0_generic and can't find it though it is on the list of functions.
It is in: X0_I0_ENEMY
it is in the lower branches of the nw_i0_generic includes. here is the include path from there.
"nw_i0_generic" > "x0_i0_anims">"x0_i0_walkway">"x0_i0_spawncond">"x0_i0_combat"> "x0_i0_talent"> "x0_inc_generic"> "x0_i0_equip">" x0_i0_enemy"
Ah ha! Thanks L8.
#19
Posté 27 juillet 2011 - 07:31
that said I have not tested to see whether NWN operates this way. Typically however this is how it works in other C flavors.
Thanks for the word on GetNearest Enemies... I'll get to work on that.
#20
Posté 27 juillet 2011 - 08:19
henesua wrote...
Lightfoot, putting the ++ operator on the left side of a variable in an expression increments the variable before the expression is evaluated. Putting it on the right increments after the expression is evaluated.
that said I have not tested to see whether NWN operates this way. Typically however this is how it works in other C flavors.
I Just tested it in NWScript. You are correct I does work that way. Thanks, for the lesson.
#21
Posté 27 juillet 2011 - 11:56
#22
Posté 29 juillet 2011 - 01:58
As soon as I increased the time of "friendship" that I was sending to the function, it successfully stopped combat. The problem is in that you need to give more time for "friendship" than you actually get. This is due to the way the friendship decays. It appears to decay from the moment it is adjusted, rather than after the time delay you give for friendship.
Also GetNearestEnemy works.
[EDIT]
Nevermind... I found some weirdness. (1) I SetIsTemporaryFriend twice on oEnemy which seemed to cause problems. and (2) the loop was ending early.
Both of these are fixed and now "friendship" appears to be decaying properly.
Modifié par henesua, 29 juillet 2011 - 04:15 .
#23
Posté 29 juillet 2011 - 04:48
***EDIT*** removed MULTIPLAYER constant so that this functions for other people than myself
http://pastebin.com/pytSBPmE
void StopCombat(object oPC1, object oEnemy, int nRounds, int bAll = FALSE)
{
float fTime = RoundsToSeconds(nRounds);
int x = 1; // iterations of combatant loop
int y = 0; // iterations of pc loop
int z; // iterations of associate type
int max = x+50; // maximum combatants of each character to neutralize
object oPC = GetFirstFactionMember(oPC1); // get first member of party
object oNPC; // associates of oPC
object oCombatant; // additional enemies of oPC or oNPC
while (GetIsObjectValid(oPC))
{
// targeted enemy of PC
SetCommandable(TRUE, oPC);
SetCommandable(TRUE, oEnemy);
AssignCommand(oPC, ClearAllActions(TRUE));
AssignCommand(oEnemy, ClearAllActions(TRUE));
SetIsTemporaryFriend(oPC, oEnemy, TRUE, fTime);
SetLocalInt(oEnemy, "STOPPED_COMBAT", TRUE);
DelayCommand(1.0, DeleteLocalInt(oEnemy, "STOPPED_COMBAT"));
if (bAll)
{
// next loop through all remaining enemies of oPC
x = 1;
oCombatant = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oPC, x);
while (GetIsObjectValid(oCombatant) && x < max)
{
if (!GetLocalInt(oCombatant, "STOPPED_COMBAT") && GetDistanceBetween(oPC, oCombatant) <= 20.0)
{
SetLocalInt(oCombatant, "STOPPED_COMBAT", TRUE);
DelayCommand(1.0, DeleteLocalInt(oCombatant, "STOPPED_COMBAT"));
SetCommandable(TRUE, oCombatant);
if(GetIsInCombat(oCombatant))
AssignCommand(oCombatant, ClearAllActions(TRUE));
SetIsTemporaryFriend(oPC, oCombatant, TRUE, fTime);
}
oCombatant = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oPC, ++x);
}
}
// loop through all Associates of oPC
for (z = 1; z <= 5; z ++)
{
int w = 1;
oNPC = GetAssociate(z, oPC, w);
while (GetIsObjectValid(oNPC))
{
// first enemy of NPC
SetCommandable(TRUE, oNPC);
AssignCommand(oNPC, ClearAllActions(TRUE));
AssignCommand(oEnemy, ClearAllActions(TRUE));
SetIsTemporaryFriend(oEnemy, oNPC, TRUE, fTime);
SetIsTemporaryFriend(oNPC, oEnemy, TRUE, fTime);
if(bAll)
{ // next loop through all remaining enemies of NPC
x = 1;
oCombatant = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oNPC, x);
while (GetIsObjectValid(oCombatant) && x < max)
{
if (!GetLocalInt(oCombatant, "STOPPED_COMBAT") && GetDistanceBetween(oPC, oCombatant) <= 20.0)
{
SetLocalInt(oCombatant, "STOPPED_COMBAT", TRUE);
DelayCommand(1.0, DeleteLocalInt(oCombatant, "STOPPED_COMBAT"));
SetCommandable(TRUE, oCombatant);
if(GetIsInCombat(oCombatant))
AssignCommand(oCombatant, ClearAllActions(TRUE));
SetIsTemporaryFriend(oCombatant, oNPC, TRUE, fTime);
SetIsTemporaryFriend(oNPC, oCombatant, TRUE, fTime);
}
oCombatant = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oPC, ++x);
}
}
oNPC = GetAssociate(z, oPC, ++w);
}
}
// Get Next PC Party Member
oPC = GetNextFactionMember(oPC1);
} // loop through PC party members
}
Modifié par henesua, 29 juillet 2011 - 05:47 .





Retour en haut






