Aller au contenu

Photo

Helpful Scripts (repost)


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

#1
Shaun the Crazy One

Shaun the Crazy One
  • Members
  • 183 messages
This is a repost of this old forum topic.

If you have a script that you feel would be helpful to the community at
large, and would like to share it with the community, post it here.


Here's a few useful ones from the old thread:

XP for level and level for XP:
// Data function: Return the corresponding level for the given XP. 
int C_GetLevelByXP(int iXP);

// Data function: Return the corresponding XP for the given Level.
int C_GetXPByLevel(int iLevel);

// Data function: Return the corresponding level for the given XP.
int C_GetLevelByXP(int iXP)
{
  int iLevel = 1;
  int iXPLimit = 0;
  while (iXPLimit <= iXP) {
    iXPLimit += (iLevel * 1000);
    iLevel++;
  }
  return iLevel - 1;
}

// Data function: Return the corresponding XP for the given Level.
int C_GetXPByLevel(int iLevel)
{
  return 500 * iLevel * (iLevel - 1);
}

Posted by: weby


A rest script, hardcoded for 8 hours rest:

void main()
{
object oPC ;
int nRest ;
location nloc ;
int hour ;
int thour ;
int day ;
int lhour ;
int lday ;
int diff ;
    
    day = GetCalendarDay() ;
    hour = GetTimeHour() ;    
    nRest = GetLastRestEventType();
    oPC = GetLastPCRested() ;
    if (nRest == REST_EVENTTYPE_REST_FINISHED) {
        SetLocalInt(oPC, "LastRestedDay", day) ;
        SetLocalInt(oPC, "LastRestedHour", hour) ;
    }
    else if (nRest == REST_EVENTTYPE_REST_STARTED) {    
        if (GetIsObjectValid(oPC)) {
            nloc = GetLocation(oPC) ;
            lday = GetLocalInt(oPC, "LastRestedDay") ;
            lhour = GetLocalInt(oPC, "LastRestedHour") ;
            thour = hour+(day-lday)*24 ;
            diff = thour-lhour ;
            if (diff < 8)  {
                SendMessageToPC(oPC, "You are not tired enough to rest. Wait "+IntToString(8-diff)+" more hours.") ;
                AssignCommand(oPC, ClearAllActions());
            }
        }
        
    }
}

Posted by: Olblach[/b]


Inventory locking script:

Here's a custom function that will identify all carried items, make them undroppable and make them unremovable (i.e. cursed). Helpful say for a companion whose inventory you don't want the player to empty. Also circumvents having to create identified versions of blueprints of magic items. Use anywhere, but a logical place is in an OnSpawn script.


[nwscript]
void HandsOffMyInventory( object oTarget )

{
        //Check inventory items
        object oItem = GetFirstItemInInventory( oTarget );
        while ( GetIsObjectValid( oItem ) )
        {
            SetIdentified( oItem, TRUE );
            SetDroppableFlag( oItem, FALSE );
            SetItemCursedFlag( oItem, TRUE );
                                 
            oItem = GetNextItemInInventory( oTarget );
        }
       
        //Check equipped items
        int nSlot;
        for (nSlot=0; nSlot<NUM_INVENTORY_SLOTS; nSlot++)
        {
            oItem=GetItemInSlot( nSlot, oTarget );

            if (GetIsObjectValid( oItem ))
            {
                SetIdentified( oItem, TRUE );
                SetDroppableFlag( oItem, FALSE );
                SetItemCursedFlag( oItem, TRUE );
               
            }
        }
}

[/nwscript]

Posted by: ciViLiZed



Treasure pile script:


Here's a simple script to use for a treasure placeable to give the PC some gold when they click on it and destroy the gold pile afterwards. Placeable must be useable and non-static, and attach a variable - integer called iGold, set to the amount of gold you wish to give


void main()
{
object oPC = GetLastUsedBy();

int nGP = GetLocalInt(OBJECT_SELF, "iGold");

GiveGoldToCreature(oPC, nGP, TRUE);

DestroyObject(OBJECT_SELF);
}

Posted by: Wyrin_D'njargo


Universal door/lever script:

I've seen several requests for a "pull a lever and the door opens" script over the last couple months, so thought I would offer this.

The nice thing about this script is that it's tag based, so you can use the same script for every lever and door without altering the script. The lever should have the tag leverXX and the door should have the tag doorXX where XX is the same for both.


[nwscript]
/*
Modified from standard template "use_lever"

Assumes initial state is deactivated.
If initial state is activated, apply variable
set "ActivatedState" to placeable

Assumes the Tag of the activating lever is
"leverXX" and the target door is "doorXX" where
XX is the same for both.
*/

void main()
{
PlaySound("as_sw_lever1");   
ExecuteScript("x2_plc_used_act", OBJECT_SELF);
int bActivated = GetLocalInt(OBJECT_SELF,"X2_L_PLC_ACTIVATED_STATE");

// Get the right target
object oTarget; //The door to be opened
string sSubstring; //The lever number
sSubstring = GetSubString(GetTag(OBJECT_SELF), 5, 2);
// SpeakString("Using lever number: " + sSubstring);
oTarget = GetObjectByTag("gate" + sSubstring);   
// SpeakString("Affecting door with tag: " + GetTag(oTarget));

// Open or close it depending on the current state.
// Play the sound effect for the lever.
if (bActivated == TRUE)
  {
  SetLocked(oTarget, FALSE);
  AssignCommand(oTarget, ActionOpenDoor(oTarget));
  SpeakString("Door unlocked and opened.");
  }
else
  {
  AssignCommand(oTarget, ActionCloseDoor(oTarget));
  SetLocked(oTarget, TRUE);
  SpeakString("Door closed and locked.");
  }   
}
[/nwscript]

Posted by: ddaedelus



Feel free to post new ones or bring other ones over from the origenal topic.

[/b]

#2
Shaun the Crazy One

Shaun the Crazy One
  • Members
  • 183 messages
More from the old thread

Move and Use:


/*_____________________________________________________________
Filename:           ga_move_and_use                            |
System:                                                        |
Author:             ShadowDragon311007                         |
Date Created:       Nov 16th, 2008                             |
Summary:                                                       |
This script moves someone to a object and makes the use it.    |
Place in actions on a conversation node hit refreash           | 
add the tag of the object to move to and use.                  |
                                                               |
 sObject = List the the object the NPC is moving to and using. |
 nRun    = Defaults to walk, set to 1 for running              |
                                                               |
_______________________________________________________________|
Revision:
*/        
#include "ginc_param_const"
void main(string sObject, int nRun)
{
    object oTarg = OBJECT_SELF;
    object oObject = GetObjectByTag(sObject);
    if (!GetIsObjectValid(oObject))
    {
        PrintString("WARNING - ga_move_and_use: couldn't find Object: " + sObject);    
        return;
    }
    
    AssignCommand(oTarg, ActionForceMoveToObject(oObject, nRun));
    AssignCommand(oTarg, ActionInteractObject(oObject));
    
}

Posted by: ShadowDragon311007


AI Scripts:

Here are a couple of useful AI scripts, set a local string on the creature called "X2_SPECIAL_COMBAT_AI_SCRIPT", to use these scripts.

Null AI, the creature will do nothing in combat, this is useful if you want an enemy creature to perform out of combat actions, or set up an AI to use heartbeats or user defined events:

#include "ginc_ai"
void main()
{
    SetCreatureOverrideAIScriptFinished();
    return;
}

This is a dog-brained combat AI. It just selects the nearest member of the PC's party and attacks.  The advantage is it's a low calculation AI.  So if you have hordes of mindless creatures it can improve performance over the default AI.

#include "ginc_ai"
void main()
{
    object oPC=GetFirstPC();
    object oTarget=GetFirstFactionMember(oPC,FALSE);
    float  fDistance, fClosest=100000000.0;
    object oClosest=OBJECT_INVALID;
    while (GetIsObjectValid(oTarget))
    {
        if (GetObjectSeen(oTarget)||GetObjectHeard(oTarget))
        {
            fDistance=GetDistanceBetween(oTarget, OBJECT_SELF);
            if (fDistance<fClosest)
            {
                oClosest=oTarget;
                fClosest=fDistance;
            };
        };
        oTarget=GetNextFactionMember(oPC,FALSE);
    };
    if (!GetIsObjectValid(oClosest)) return;
    ClearAllActions(TRUE);
    WrapperActionAttack(oClosest);
    SetCreatureOverrideAIScriptFinished();
    return;
}

Here's an AI script that attacks a specific target that's specified by a local variable on the attacker.  It's handy for getting NPCs attack combat dummies or archery targets.

#include "ginc_ai"
void main()
{
    object oTarget=GetNearestObjectByTag(GetLocalString(OBJECT_SELF, "TargetTag"));
    WrapperActionAttack(oTarget);
    SetCreatureOverrideAIScriptFinished();
    return;
}

Posted by: Mithdradates

#3
Shaun the Crazy One

Shaun the Crazy One
  • Members
  • 183 messages
Here's two of my own:

Object Hardness:

The hardness property for doors or placeables doesn't actually work.  This script does hardness according to the D&D 3.5 rules.
Use this script on the door on container's "On Damaged Script".


//object_hardness

/*
    Use for a doors or placables with a hardness rating.  Set this as the "On Dameged Script"
    This script subtracts the object's hardness from the damege delt in acordance to D&D 3.5
    rules.  The objects hit points must be greater than it's hardness for this script to
    work properly.
    
    You can assign a material by creating a local string variable on the object called 
    "Material".  The object will take different amounts of damege for differnt energy types
    based on it's material.  If no material is assigned the program will use a generic set of
    proporties for the material.
    
    string Material = object material (for determing damage resistances)
        "wood" = double damege from fire, half damege from acid and cold, quarter damege from electricity, and normal damege from sonic
        "stone" = *1.5 damege from sonic, half damege from fire and electricity, quarter damege from cold, and normal damege from acid
        "iron" = *1.5 damege from acid, half damege from fire and electricity, quarter damege from cold, and normal damege from sonic
        (Default) = half damege from fire and electricity, quarter damege from cold, and normal damege from acid and sonic (D&D 3.5 standard)
    
    All materials take normal damage from devine or negative energy and half from peircing.
    Magic damage bypasses hardness
*/

//Shaun H. 6/15/10

void main()
{
    int iHardness = GetHardness(OBJECT_SELF);
    string sMaterial = GetLocalString(OBJECT_SELF,"Material");
    int iDamage = GetDamageDealtByType(DAMAGE_TYPE_BLUDGEONING)+GetDamageDealtByType(DAMAGE_TYPE_SLASHING)+GetDamageDealtByType(DAMAGE_TYPE_PIERCING)/2;//Physical damage
    
    if (sMaterial == "wood")
    {
        iDamage += GetDamageDealtByType(DAMAGE_TYPE_ACID)/2+GetDamageDealtByType(DAMAGE_TYPE_COLD)/2+GetDamageDealtByType(DAMAGE_TYPE_ELECTRICAL)/4+GetDamageDealtByType(DAMAGE_TYPE_FIRE)*2+GetDamageDealtByType(DAMAGE_TYPE_SONIC);
    }
    else if (sMaterial == "stone")
    {
        iDamage += GetDamageDealtByType(DAMAGE_TYPE_ACID)+GetDamageDealtByType(DAMAGE_TYPE_COLD)/4+GetDamageDealtByType(DAMAGE_TYPE_ELECTRICAL)/2+GetDamageDealtByType(DAMAGE_TYPE_FIRE)/2+GetDamageDealtByType(DAMAGE_TYPE_SONIC)+GetDamageDealtByType(DAMAGE_TYPE_SONIC)/2;
    }
    else if (sMaterial == "iron")
    {
        iDamage += GetDamageDealtByType(DAMAGE_TYPE_ACID)+GetDamageDealtByType(DAMAGE_TYPE_COLD)/4+GetDamageDealtByType(DAMAGE_TYPE_ELECTRICAL)/2+GetDamageDealtByType(DAMAGE_TYPE_FIRE)/2+GetDamageDealtByType(DAMAGE_TYPE_SONIC)+GetDamageDealtByType(DAMAGE_TYPE_ACID)/2;
    }
    else
    {
        iDamage += GetDamageDealtByType(DAMAGE_TYPE_ACID)+GetDamageDealtByType(DAMAGE_TYPE_COLD)/4+GetDamageDealtByType(DAMAGE_TYPE_ELECTRICAL)/2+GetDamageDealtByType(DAMAGE_TYPE_FIRE)/2+GetDamageDealtByType(DAMAGE_TYPE_SONIC);
    }
    
    iDamage += GetDamageDealtByType(DAMAGE_TYPE_DIVINE) + GetDamageDealtByType(DAMAGE_TYPE_NEGATIVE);
    
    if (iHardness > iDamage) ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(iDamage),OBJECT_SELF);
    else ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(iHardness),OBJECT_SELF);
}


Get a creature's level based on thier experience:

/*
    Get's the expected level of a creature (oCreature) based on experience
    so as to account for level ajustment and leveling up
*/
// Shaun Hentchel_9/15/09

//get the experience level of oCreature taking level ajustment into account
int GetExperienceLevel(object oCreature)
{
    int nXP = GetXP(oCreature);
    
    int n, i = 0;
    int nlevel = 1;
    while(i <= nXP)
    {
        i = 0;
        nlevel += 1;
        
        for(n = 1; n <= nlevel; ++n)
        {
            i += (n-1)*1000;
        }
    }
    nlevel -= 1;
    
    return nlevel;
}


#4
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
You can also use the Community Script Library, for which I've gone thru the various threads like this for NWN1 and NWN2 and set up a library based on the available posted functions and the in game functions. I also have gone thru requested features and functions, and taken things from other languages like Basic, Php, C and others which are needed to round out the language. And things have been reworked to prevent lag and the like.

A searchable reference Community Script Library Doxygen Reference is here in a temporary location, which has source code as well if you just want to find a function similar to those posted.

The benefit of this is that the various functions posted often have corrections, improved versions, more elegant ways of being written and the like, and these also are designed to work together and be self sufficient, you just have to include it. As i update and further refine it, or as bugs are reported or found these can be fixed.

Modifié par painofdungeoneternal, 14 juillet 2010 - 08:06 .


#5
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Hi All,

// ***************************** PLEASE READ THE FOLLOWING UPDATE **********************************

UPDATE: This script does not appear to function correctly with multiple attacks. :( I think that must have been why I originally tracked HPs in a separate variable. I will look at correcting it and updating later.

I have now FIXED this script to work with multiple attacks in this post:

http://social.biowar...56033/1#4969712


I will leave the following older (broken) code below to see the changes with the new.

// *****************************************************************************************************************

This is another placeable and door hardness compensation script. It differs from Shaun's above in the following ways:-

1) Hardness level can be less than the HP value of the object. (E.g. Object can have 1 HP and Hardness 5.)

2) This script does not test for object material as it is expected the builder will take this into account when setting the Hardness value in the first place. (E.g. A door made of iron should be given a higher Hardness level than one made of wood.)

3) It gives the player feedback on the remaining integrity value (in percentage score) of the object being damaged. This gives the player an idea of how much longer the item may take to be destroyed without giving direct HP feedback.

The thinking behind this approach is that it is easier for a builder to work on a single Hardness figure as a guide of how much damage a PC must be able to do to bypass any Hardness factor. If the PC can deliver damage above this figure, then they will break down the object eventually anyway.

There are two scripts involved: The alb_object_damaged and the alb_object_attacked scripts. The first script must always go on the object's "on damaged" hook (or be added to the script already there), but the latter script can go onto both the object's "on attacked" and "on spell cast at" hooks (or added to the scripts already there) ... OR can be put on (or added to) the object's "heartbeat" hook alone. (Some builder's prefer to limit the amount of heartbeat scripts they use, but if their objects already use a heartbeat script, then this small bit of code may as well be added there as well.)

Please offer feedback at my blog (in signature) if required.

Many Thanks.

Lance.

alb_object_damaged: Place on the object's "On Damaged".

/* HARDNESS DAMAGE RESISTANCE *********** BY LANCE BOTELLE (28/07/10) *******************
This script is the first of two to allow the Hardness value to work on placeables and doors.
The system works around a "Buffer" system to allow objects with fewer HPs than their Hardness level.
AT BUILD TIME: Set the object's HP Values & set the Hardness value to represent the Damage Resistance as normal.
Example guides:
- GLASS has a hardness of 1.
- WOOD has a hardness of 5.
- STONE has a hardness of 8.
- IRON has a hardness of 10.
- MITHRAL has a hardness of 15.
- ADAMANTINE has a hardness of 20.
Place this script on the door or placeable "On Damaged" hook.
Be sure to set the alb_object_attacked script on the correct hook as well. (See script)*/
void main()
{   
 // GATHER VARIABLES
 object oPC = GetLastDamager();     
 int iHardness = GetHardness(OBJECT_SELF); 
 int iDamDealt = GetTotalDamageDealt();  
 int iRealDam = iDamDealt - iHardness;  
 int iCURHPS = GetCurrentHitPoints();  
 
 // NO DAMAGE (ALL ABSORBED)
 if (iRealDam < 1)
 {
 ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(iDamDealt),OBJECT_SELF);
 AssignCommand(oPC, SpeakString("The target resisted my attack!"));
 AssignCommand(oPC, PlayVoiceChat(VOICE_CHAT_CUSS, oPC));
 }
   
 // DAMAGE DONE 
 else
 { 
  // ONLY DAMAGED
  if(iCURHPS > 0)
  {
  ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(iHardness),OBJECT_SELF);
  }
 
  // DESTROYED  
  else
  {  
  AssignCommand(oPC, PlayVoiceChat(VOICE_CHAT_LAUGH, oPC));  
  }     
 } 
 
 // REPORT INTEGRITY 
 int iREALHPS = GetCurrentHitPoints() - iHardness; int iMAXHPS = GetMaxHitPoints() - iHardness;
 float fPercent = (IntToFloat(iREALHPS)/IntToFloat(iMAXHPS)) * 100.00; int iPercent = FloatToInt(fPercent);
 string sReport = "DESTROYED!"; if (iPercent > 0){sReport =  IntToString(iPercent) + "%";}
 SendMessageToPC(oPC, "TARGET INTEGRITY: " + sReport);
}


alb_object_attacked: Place on the object's "On Attacked" and "On Spell Cast" ... OR ... just the "On Heartbeat".

/*HARDNESS DAMAGE RESISTANCE *********** BY LANCE BOTELLE (28/07/10) *******************
This script is the second of two to allow the Hardness value to work on placeables and doors.
The system works around a "Buffer" system to allow objects with fewer HPs than their Hardness level.
This script ensures an object has a buffer amount of HPs to absorb HP damage above its Hardness amount.
It should be placed on an object's "On Attacked" and "On Spell Cast At" ... OR ... "On Heartbeat" only.
Be sure to set the alb_object_damaged script on the correct hook as well. (See script)
The alb_object_damaged script also has more details. */

void main()
{
if(GetLocalInt(OBJECT_SELF, "HPSET") == 0)
 {SetLocalInt(OBJECT_SELF, "HPSET", 1); int Hardness = GetHardness(OBJECT_SELF);
 ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectBonus_Hitpoints(Hardness), OBJECT_SELF); // (*)
 ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(Hardness), OBJECT_SELF);}
}


(*) IMPORTANT: EffectBonus_Hitpoints should be all one word (without the underscore). Unfortunately, the swear filter is messing the format up and replacing some of the letters with ****. You can guess what that is now. Posted Image

SCRIPTS UPDATED TO USE HARDNESS VARIABLE AND AVOID HP TRACKING VARIABLES

Modifié par Lance Botelle, 06 octobre 2010 - 03:50 .