Aller au contenu

Photo

A Mass of Questions from NineCoronas


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

#1
JediMindTrix

JediMindTrix
  • Members
  • 283 messages
I have tried using the new, illustrious search tool, powered by google, unfortunately it doesn't seem to be loading results on my browsers >.< So apologies if I ask questions with which the answers are lying glaringly obvious too.

1) How does that XP slider in Module Properties affect XP gain? A semi-detailed explanation if possible (it's relationship to CR, the base XP given, etc.
Are there scripts I can edit to achieve this myself?

2) Is there a way to manipulate the way ILR works using scripting rather than editing and including
itemvalue.2da in a hak?

3)Is there a simple way to initiate conversations when a PC tries to take an item out of a Henchman's inventory, and is there a way to keep items "locked" into a slot, I.E. an Amulet on the PC, a cloak on a Henchman (both specifically, actually).

That's it for now, but there will definitely be many more!

Cheers!

-NineCoronas


#2
LoA_Tristan

LoA_Tristan
  • Members
  • 40 messages
As to 1, the slider is the percentage of what experience value would normally be awarded, for players of a certain level versus opponents of a certain CR, under the pen and paper rules.  (Default is 10%.  This is a video game— so resting, heals, items, and big mobs of enemies come way thicker than PnP)

For 3, the OnDisturbed event handler. It could undo whatever the PC does to muck things up, but I don't know if it could prevent any action.

ex.
void main()
{
    object oItem = GetLastDisturbed();
    if (GetTag(oItem) == "MY_TREASURED_ITEM") ActionEquipItem(oItem, INVENTORY_SLOT_x);
}
...would instantly re-equip an item.  A conversation could also be initiated by this event.

Don't forget about tagging NPC's personal possessions as undroppable.

Modifié par LoA_Tristan, 01 février 2013 - 12:23 .


#3
Squatting Monk

Squatting Monk
  • Members
  • 445 messages
Adding to number 1, you can set the slider to 0 and assign XP yourself. There's some good systems on the Vault for this.

As for number 2, you can't mess with ILR directly, but you can unequip items too powerful for the PC from the OnPlayerEquipItem event. This also ties into the second part of number 3: use the OnPlayerUnEquipItem event to keep the PC from unequipping an essential item.

Modifié par Squatting Monk, 01 février 2013 - 12:37 .


#4
JediMindTrix

JediMindTrix
  • Members
  • 283 messages

LoA_Tristan wrote...

As to 1, the slider is the percentage of what experience value would normally be awarded, for players of a certain level versus opponents of a certain CR, under the pen and paper rules.  (Default is 10%.  This is a video game— so resting, heals, items, and big mobs of enemies come way thicker than PnP)


I think I'll toy with this slider before heading to the Vault. I'm not looking for anything complex.


LoA_Tristan wrote...

For 3, the OnDisturbed event handler. It could undo whatever the PC does to muck things up, but I don't know if it could prevent any action.

ex.

void main()
{
    object oItem = GetLastDisturbed();
    if (GetTag(oItem) == "MY_TREASURED_ITEM") ActionEquipItem(oItem, INVENTORY_SLOT_x);
}
...would instantly re-equip an item.  A conversation could also be initiated by this event.

Don't forget about tagging NPC's personal possessions as undroppable.


If it's undroppable would the conversation still be triggerable?

#5
LoA_Tristan

LoA_Tristan
  • Members
  • 40 messages

NineCoronas2021 wrote...
If it's undroppable would the conversation still be triggerable?

As long as the creature's OnDisturb event fires you can script it to start a conversation, but I can't remember if trying to remove an undroppable item fires it. Shouldn't be hard to test if you have a henchman set up already...

#6
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Oh, you're one of THOSE people. Willing to search, huh? Nice. :P

Two pieces of advice.

First, the forum search tool is terrible. I don't know why, but it rarely yeilds anything useful, especially as compared to the old boards.

Second, get the Omnibus, by OldTimeRadio. It's stupid useful:
Teh Grate and Powrful Omneybuss

You'll save yourself a ton of time. I've been coding NWN for...yeesh, going on 9 years, and I still use it a lot.

Funky

Modifié par FunkySwerve, 01 février 2013 - 03:38 .


#7
JediMindTrix

JediMindTrix
  • Members
  • 283 messages
Thanks Funky! Apparently I already have the Omnibus.

1) I'm about to embark on creating a custom death system. For some reason, I can't find the thread that mentioned this before, but apparently it is possible to have a system where instead of dying, your henchman are knocked out. Is it also possible for you, the player to "knocked out" while your henchman fight on, and if they survive, then you get back up?

I'm looking for something similar to how it was done in DO:A.

If that is not possible, how does one go about having henchman leave corpses that are raisable when they die? I seem to remember this being the case in HotU.

Is there anything on the vault similar to what I'm looking to do? I understand there is a module, but reading other people's code confuses me very, very quickly when it isn't commented and formatted well (not sure how that particular modulescores on that, whose name I cannot for the life of me remember! >:( )

2) How would one go about clearing a room (not a whole area) of all hostile creatures?

3) Conversely, can someone point me in the right direction to creating a rest system similar to Baldur's Gate, where if you rest in a hostile area there is a chance (preferably a scaleable chance) of being attacked in your sleep? xD

Modifié par NineCoronas2021, 02 février 2013 - 03:31 .


#8
Squatting Monk

Squatting Monk
  • Members
  • 445 messages
2: use a trigger in the room. Then either store the creatures that entered the trigger to get later or use GetFirstInPersistentObject().

3 is used in HotU.

#9
JediMindTrix

JediMindTrix
  • Members
  • 283 messages

Squatting Monk wrote...

2: use a trigger in the room. Then either store the creatures that entered the trigger to get later or use GetFirstInPersistentObject().


That would work, yes, however I need it be centered around wherever the PC dies. <.<

Could a perception event be called, or something?

4) Is it possible to give an NPC an immunity to a specific effect via scripting, such as Blindness?

Modifié par NineCoronas2021, 02 février 2013 - 04:08 .


#10
Squatting Monk

Squatting Monk
  • Members
  • 445 messages
Here's the immunities that can be conferred via scripting. You can implement them like so:

EffectImmunity(IMMUNITY_TYPE_BLINDNESS);

Modifié par Squatting Monk, 02 février 2013 - 05:29 .


#11
JediMindTrix

JediMindTrix
  • Members
  • 283 messages
Thanks SM!

I want to FadeToBlack (FadeFromBlack also) upon death, will ActionDoCommand work?

#12
Squatting Monk

Squatting Monk
  • Members
  • 445 messages
It will, but you have to assign it with AssignCommand(). See the Lexicon for details.

#13
JediMindTrix

JediMindTrix
  • Members
  • 283 messages
So AssignCommand(ActionDoCommand(restofscriptfollows));?

Modifié par NineCoronas2021, 04 février 2013 - 05:32 .


#14
henesua

henesua
  • Members
  • 3 863 messages
Nine -

AssignCommand(oCommanded, ActionDoCommand(FunctionFoo()) );

You would define all the code to be executed from oCommanded's action queue in a function named (in this case) FunctionFoo()

in other words, wrap up that rest-of-script you mention in a function and call it with an ActionDoCommand


-edit-

alterantively if you do NOT want the code to execute from the action queue but rather to execute immediately

AssignCommand(oCommanded, FunctionFoo() );

In both cases the code executes on the oCommanded object, rather than on the object running the script which calls AssignCommand

Modifié par henesua, 04 février 2013 - 05:25 .


#15
JediMindTrix

JediMindTrix
  • Members
  • 283 messages

henesua wrote...

alterantively if you do NOT want the code to execute from the action queue but rather to execute immediately

AssignCommand(oCommanded, FunctionFoo() );

In both cases the code executes on the oCommanded object, rather than on the object running the script which calls AssignCommand


Thanks Henesua!

Another question:

    if (GetModuleSwitchValue(MODULE_SWITCH_USE_XP2_RESTSYSTEM) == TRUE)
    {
        /*  Georg, August 11, 2003
            Added this code to allow the designer to specify a variable on the module
            Instead of using a OnAreaEnter script. Nice new toolset feature!
            Basically, the first time a player rests, the area is scanned for the
            encounter table string and will set it up.
        */
        object oArea = GetArea (oPC);

        string sTable = GetLocalString(oArea,"X2_WM_ENCOUNTERTABLE") ;
        if (sTable != "" )
        {
            int nDoors = GetLocalInt(oArea,"X2_WM_AREA_USEDOORS");
            int nDC = GetLocalInt(oArea,"X2_WM_AREA_LISTENCHECK");
            WMSetAreaTable(oArea,sTable,nDoors,nDC);

            //remove string to indicate we are set up
            DeleteLocalString(oArea,"X2_WM_ENCOUNTERTABLE");
        }


I'm trying to understand this, it says a variable is specified on the module, but only area's are called. Is this erroneous?


EDIT:

Also, this line:

GetFirstObjectInShape(SHAPE_SPHERE, 17, oPlayer, TRUE);


Continues to give me a "Declaration doesn't match parameters".

GetFirstObjectInShape(SHAPE_SPHERE, 17, oPlayer, TRUE, OBJECT_TYPE_CREATURE);


doesn't work either. oPlayer has already been defined by GetLastPlayedDied();.


EDIT EDIT
I figured out it was looking for a location and not an object, so I added

location lPlayerDeath = GetLocation(oPlayer);
and placed lPlayerDeath in where oPlayer was previously and it compiled, still not sure it will work though.

Modifié par NineCoronas2021, 04 février 2013 - 06:10 .


#16
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<floating...>

GetFirstObjectInShape is expecting a float for the distance. Change 17 to 17.0f and give it a try :-)

<...a suggestion>

#17
JediMindTrix

JediMindTrix
  • Members
  • 283 messages

Rolo Kipp wrote...

<floating...>

GetFirstObjectInShape is expecting a float for the distance. Change 17 to 17.0f and give it a try :-)

<...a suggestion>


It's at 17.0 at the moment. Compile error solved as mentioned above ^ :)



Now on to the next question....

object oPlayer = GetLastPlayerDied();
location lPlayerDeath = GetLocation(oPlayer);



object oHostile = GetFirstObjectInShape(SHAPE_SPHERE, 17.0, lPlayerDeath, TRUE, OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oHostile))
{
   if(GetIsReactionTypeHostile(oHostile))
   {
   if(GetLocalInt(oHostile, "ens_noclear")) return; //If the script finds this integer in any form on the creature, it will skip deleting it.
    {
    DestroyObject(oHostile);
    }
   }
   //Select the next target within the spell shape.
   oHostile = GetNextObjectInShape(SHAPE_SPHERE, 17.0, lPlayerDeath, TRUE, OBJECT_TYPE_CREATURE);
}


Specifically, I want to know if "   if(GetLocalInt(oHostile, "ens_noclear")) return; //If the script
finds this integer in any form on the creature, it will skip deleting
it."

will do what is intended? I'm also curious why "return FALSE" and "return TRUE" wouldn't compile in that instance. O.o

Modifié par NineCoronas2021, 04 février 2013 - 06:18 .


#18
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<stopping at the first...>

Hah! I did like a compiler and stopped at the first error I saw :-P Yeah, location...

On the next Q, the return will break out of the while loop, meaning that *no other* objects will be checked (or deleted) after it returns. Instead say
if ( !GetLocalInt( oHostile, "en_noclear")) DestroyObject(oHostile);

If you say return (value), it has to be within a function that is supposed to return a value of that type. I.e. if the function is a "void MyFunction()" then return shouldn't return anything.
If it's "int MyFunction()" then it *has to* return an integer (or boolean).

<...bar he finds>

#19
JediMindTrix

JediMindTrix
  • Members
  • 283 messages
Makes sense, thank you.

EDIT:
I seem to be getting in the habit of answering my own questions...

Modifié par NineCoronas2021, 04 février 2013 - 09:35 .


#20
henesua

henesua
  • Members
  • 3 863 messages

NineCoronas2021 wrote...

Makes sense, thank you.

Next question:

object oHench1 = GetHenchman(oPlayer, 1);
object oHench2 = GetHenchman(oPlayer, 2);
if (!GetCurrentHitPoints(oHench1) | GetCurrentHitPoints(oHench2) >= 1)
{
//If not, remove immortality and initiate player death
SetPlotFlag(oPlayer, FALSE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oPlayer));
}

 


I highlighted some suspicious code in red and changed your code to

object oHench1 = GetHenchman(oPlayer, 1);
object oHench2 = GetHenchman(oPlayer, 2);
if (!GetCurrentHitPoints(oHench1) || GetCurrentHitPoints(oHench2) >= 1)
{
//If not, remove immortality and initiate player death
SetPlotFlag(oPlayer, FALSE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oPlayer);
}

#21
JediMindTrix

JediMindTrix
  • Members
  • 283 messages
Thanks Henesua, I noticed the extra bracket but didn't catch the straight line thingy.

So my next question is thus:

if (GetCurrentHitPoints(oHench1) || GetCurrentHitPoints(oHench2) >= 1)
{
object oHostile = GetFirstObjectInShape(SHAPE_SPHERE, 17.0, lPlayerDying, TRUE, OBJECT_TYPE_CREATURE);
while (GetIsObjectValid(oHostile))
{
if (!GetIsReactionTypeHostile(oHostile))
//If not, bring player to 1 HP and remove immortality, destroy bloodstain after 10 minutes
{
SetPlotFlag(oPlayer, FALSE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(2), oPlayer);
CleanUpBloodSpatter(oPlayer);
}
oHostile = GetNextObjectInShape(SHAPE_SPHERE, 17.0, lPlayerDying, TRUE, OBJECT_TYPE_CREATURE);
}
}


This script is supposed to get all the creatures in a 17 meter sphere around the player and check to see if any of them are hostile, if none are then the character is healed out of the dying state, if there are hostile creatures (and this part I haven't gotten around to coding yet), then it will simply loop back through.
I'm either going to use a series of DelayCommands, but I can see that getting extremely clunky, quickly.

My questions are
1) Will the script I have quoted work as intended or am I "doing it wrong"?
&
2) Would it be possible to create a function (Foo), that uses a single delay command and calls itself everytime it finds a hostile creature, thereby creating a loop or "pseudo-heartbeat"?


EDIT:

And a very random, left-field question... can Henchmen wear items that aren't identified?

Modifié par NineCoronas2021, 04 février 2013 - 10:11 .


#22
Shadooow

Shadooow
  • Members
  • 4 470 messages

NineCoronas2021 wrote...

And a very random, left-field question... can Henchmen wear items that aren't identified?

no on his own, but you can identify the item before you assign him to equipt them item and unidentify it again, if neccessary

#23
JediMindTrix

JediMindTrix
  • Members
  • 283 messages
Hrm, unfortunate.

So, I put this function in an include file:

void CheckForHostiles(location lPlayerDying);
void CheckForHostiles(location lPlayerDying)
{
object oHostile = GetFirstObjectInShape(SHAPE_SPHERE, 17.0, lPlayerDying, TRUE, OBJECT_TYPE_CREATURE);
while (GetIsObjectValid(oHostile))
{
if (!GetIsReactionTypeHostile(oHostile)) //Checks for hostiles, if none, player heals
{
SetPlotFlag(oPlayer, FALSE); //Mortalize player
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(2), oPlayer); //Heal him to 1hp
CleanUpBloodSpatter(oPlayer); //Destroy blood spatter placeables after 10 minutes
}
else if (GetIsReactionTypeHostile(oHostile))
{
DelayCommand(6.0, CheckForHostiles(lPlayerDying));
}
oHostile = GetNextObjectInShape(SHAPE_SPHERE, 17.0, lPlayerDying, TRUE, OBJECT_TYPE_CREATURE);
}
}


and called it from my dying script with:

if (GetCurrentHitPoints(oHench1) || GetCurrentHitPoints(oHench2) >= 1)
{
CheckForHostiles(lPlayerDying); //Runs a check to see if hostiles are present,
// if they aren't, raise PC, if they are, check again in a round.
}

}


I'm off to test it, my main concern is that I put together that the script will actually check all creatures in the sphere to see if they're hostile before deciding to either run the script again in 6 seconds or raise the PC.

Any help on that would be appreciated!

-NineCoronas

#24
JediMindTrix

JediMindTrix
  • Members
  • 283 messages

LoA_Tristan wrote...

As to 1, the slider is the percentage of what experience value would normally be awarded, for players of a certain level versus opponents of a certain CR, under the pen and paper rules.  (Default is 10%.  This is a video game— so resting, heals, items, and big mobs of enemies come way thicker than PnP)

For 3, the OnDisturbed event handler. It could undo whatever the PC does to muck things up, but I don't know if it could prevent any action.

ex.

void main()
{
    object oItem = GetLastDisturbed();
    if (GetTag(oItem) == "MY_TREASURED_ITEM") ActionEquipItem(oItem, INVENTORY_SLOT_x);
}
...would instantly re-equip an item.  A conversation could also be initiated by this event.

Don't forget about tagging NPC's personal possessions as undroppable.


Just in case anyone runs across this question in the future, in fact, OnDisturbed on henchman only fires if a creature of another faction tries to pickpocket them.

To achieve what I wanted, in a somewhat sloppy manner, I had to write an OnAcquire script that 'yoinked' the item away if it went into my inventory and an NPC heartbeat that reequipped the items automatically (in case they were just dragged into the inventory).

Hope this helps someone someday.

Cheers!

-NineCoronas

Modifié par NineCoronas2021, 06 février 2013 - 01:45 .