[Editor1] Tingil's Scripting Thread

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Mein Tip: Benutze zur Zeitmessung und -berechnung die Sekunden vom Modulstart ab in einem Integer. Damit hast Du nicht die Ungehauigkeit eines Float und das reicht für 2^32 / 2 - 1 (> 2 Milliarden) Sekunden, oder etwas mehr als 68 Real-Zeit-Jahre; das sollte reichen. :D

Das sind die Funktionen, die ich mir dazu geschrieben habe:
Code:
//::///////////////////////////////////////////////
//:: Zeit-Funktionen
//:: tin_i0_time.nss
//:: Copyright (c) 2005 Marius Bauer
//:://////////////////////////////////////////////
/*

*/
//:://////////////////////////////////////////////
//:: Created By: Tingil
//:: Created On: November 1, 2005
//:: Changed On: November 4, 2005
//:://////////////////////////////////////////////

// Gibt den Zeitstempel fuer den uebergebenen Zeitpunkt zurueck.
int MakeTime(int iYear, int iMonth = 1, int iDay = 1, int iHour = 0,
    int iMinute = 0, int iSecond = 0);

// Gibt die Anzahl der Sekunden seit dem ersten Ladens des Modules zurueck.
int Now();

// Gibt die Zeitspanne zwischen dem uebergebenen Zeitstempel und jetzt in
// Stunden zurueck.
int GetHoursSince(int iTimestamp);

// Gibt die Zeitspanne zwischen dem uebergebenen Zeitstempel und jetzt in
// Tagen zurueck.
int GetDaysSince(int iTimestamp);

// Stellt die Zeit um iSeconds vor. Mit Aus- und Einblendeeffekt.
void AdvanceTimeBy(int iSeconds);

// Teil der Funktion AdvanceTimeBy.
void AdvanceTimeAndFadeFromBlack(int iSeconds);

// Kommentarklammern nur zum Kompilieren entfernen!
/*void main()
{
}*/

//::///////////////////////////////////////////////
//:: MakeTime
//:: Copyright (c) 2005 Marius Bauer
//:://////////////////////////////////////////////
/*
    Gibt den Zeitstempel fuer den uebergebenen
    Zeitpunkt zurueck.

    1 Jahr = HoursToSeconds(8064) Sekunden
    1 Monat = HoursToSeconds(672) Sekunden
    1 Tag = HoursToSeconds(24) Sekunden
    1 Stunde = HoursToSeconds(1) Sekunden
    1 Minute = 60 Sekunden
*/
//:://////////////////////////////////////////////
//:: Created By: Tingil
//:: Created On: November 1, 2005
//:: Changed On: November 4, 2005
//:://////////////////////////////////////////////
int MakeTime(int iYear, int iMonth = 1, int iDay = 1, int iHour = 0,
    int iMinute = 0, int iSecond = 0)
{
    object oModule = GetModule();
    int iYears = iYear - GetLocalInt(oModule, "iZeroYear");
    int iMonths = iMonth - GetLocalInt(oModule, "iZeroMonth");
    int iDays = iDay - GetLocalInt(oModule, "iZeroDay");
    int iHours = iHour - GetLocalInt(oModule, "iZeroHour");

    return FloatToInt(HoursToSeconds(8064 * iYears + 672 * iMonths + 24 *
        iDays + iHours)) + 60 * iMinute + iSecond;
}

//::///////////////////////////////////////////////
//:: Now
//:: Copyright (c) 2005 Marius Bauer
//:://////////////////////////////////////////////
/*
    Gibt die Anzahl der Sekunden seit dem ersten
    Ladens des Modules zurueck.
*/
//:://////////////////////////////////////////////
//:: Created By: Tingil
//:: Created On: October 29, 2005
//:: Changed On: November 4, 2005
//:://////////////////////////////////////////////
int Now()
{
    return MakeTime(GetCalendarYear(), GetCalendarMonth(), GetCalendarDay(),
        GetTimeHour(), GetTimeMinute(), GetTimeSecond());
}

//::///////////////////////////////////////////////
//:: GetHoursSince
//:: Copyright (c) 2005 Marius Bauer
//:://////////////////////////////////////////////
/*
    Gibt die Zeitspanne zwischen dem uebergebenen
    Zeitstempel und jetzt in Stunden zurueck.
*/
//:://////////////////////////////////////////////
//:: Created By: Tingil
//:: Created On: October 29, 2005
//:: Changed On:
//:://////////////////////////////////////////////
int GetHoursSince(int iTimestamp)
{
    int iSeconds = Now() - iTimestamp;
    return FloatToInt(iSeconds / HoursToSeconds(1));
}

//::///////////////////////////////////////////////
//:: GetDaysSince
//:: Copyright (c) 2005 Marius Bauer
//:://////////////////////////////////////////////
/*
    Gibt die Zeitspanne zwischen dem uebergebenen
    Zeitstempel und jetzt in Tagen zurueck.
*/
//:://////////////////////////////////////////////
//:: Created By: Tingil
//:: Created On: October 29, 2005
//:: Changed On:
//:://////////////////////////////////////////////
int GetDaysSince(int iTimestamp)
{
    return GetHoursSince(iTimestamp) / 24;
}

//::///////////////////////////////////////////////
//:: AdvanceTimeBy
//:: Copyright (c) 2005 Marius Bauer
//:://////////////////////////////////////////////
/*
    Stellt die Zeit um iSeconds Sekunden vor
*/
//:://////////////////////////////////////////////
//:: Created By: Tingil
//:: Created On: October 30, 2005
//:: Changed On:
//:://////////////////////////////////////////////
void AdvanceTimeBy(int iSeconds)
{
    // Fade To Black
    object oPC = GetFirstPC();
    while (oPC != OBJECT_INVALID)
    {
        if (!GetIsDM(oPC) && !GetPlotFlag(oPC))
        {
            FadeToBlack(oPC, FADE_SPEED_FASTEST);
        }
        oPC = GetNextPC();
    }

    DelayCommand(1.0, AdvanceTimeAndFadeFromBlack(iSeconds));
}

//::///////////////////////////////////////////////
//:: AdvanceTimeAndFadeFromBlack
//:: Copyright (c) 2005 Marius Bauer
//:://////////////////////////////////////////////
/*
    Teil der Funktion AdvanceTimeBy.
*/
//:://////////////////////////////////////////////
//:: Created By: Tingil
//:: Created On: October 30, 2005
//:: Changed On:
//:://////////////////////////////////////////////
void AdvanceTimeAndFadeFromBlack(int iSeconds)
{
    SetTime(GetTimeHour(), GetTimeMinute(), GetTimeSecond() + iSeconds,
        GetTimeMillisecond());

    // Fade From Black
    object oPC = GetFirstPC();
    while (oPC != OBJECT_INVALID)
    {
        if (!GetIsDM(oPC) && !GetPlotFlag(oPC))
        {
            FadeFromBlack(oPC, FADE_SPEED_FASTEST);
        }
        oPC = GetNextPC();
    }
}
Wie Du siehst hängt alles davon ab, daß auf dem Modul die lokalen Integer "iZeroYear", "iZeroMonth", "iZeroDay" und "iZeroHour" gespeichert wurden. Das ist alles, was als Voraussetzung benötigt wird.
 
Zuletzt bearbeitet:

Kamiryn

Senior Member
Registriert
21.07.2003
Beiträge
1.357
Vielen Dank für das Skript :).

Bei mir sieht es in etwa so ähnlich aus, allerdings mit float statt int und es steckt auch noch etwas in den Kinderschuhen. Dass es im Sekundenbereich vielleicht etwas ungenau ist, stört mich im Moment nicht so sehr, da ich zur Zeit zumindest eher an den Stunden und eventuell Minuten interessiert bin - aber vielleicht stell ich das ganze auch noch um.
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Das System ist ja prinzipiell universell einsetzbar. Wie Du siehst habe ich auch Funktionen geschrieben, die eine Zeitspanne in Stunden oder Tagen zurückgeben.
Das, was ich da geskriptet habe, ist quasi eine Kopie des UNIX-Timestamp-Systems. Dort repräsentiert ein Timestamp die Anzahl der Sekunden ab dem 01.01.1970 00:00:00 Uhr GMT und reicht bis Januar 2038 (eben 68 Jahre ;)). Von daher ist es ein bewährtes System. ;)
Gut geklaut ist halb gewonnen, oder wie war das? :D
 
Zuletzt bearbeitet:

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Bin ich einfach nur blind oder gibt's tatsächlich keine Funktion, mit der man den "No Permanent Death"-Flag einer Kreatur auslesen kann? Die Funktionen zum Auslesen des Disarmable-, Plot- und Immortal-Flags habe ich gefunden, aber nicht die für den "No Permanent Death"-Flag. Gibt es dafür überhaupt eine und wenn ja, wie heißt sie? :confused:
 

Kamiryn

Senior Member
Registriert
21.07.2003
Beiträge
1.357
Scheint es nicht zu geben. Scheint wohl bisher auch noch niemand vermisst zu haben.

Ich würde aber trotzdem mal im Bioware Scripting Forum fragen.

PS: Hatte übrigens meine Zeitstempel-Routinen doch nicht auf Integer umgestellt. Im nachhinein war das auch ganz gut, weil ich so relativ einfach auch die Tausendstel-Sekunden noch mitspeichern konnte, um z.B. tatsächliche Zeit- bzw. Geschwindigkeitsmessungen machen zu können (wie schnell läuft ein gehasteter Stufe 40 Mönch... :D).
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
'Mal wieder ein Skript von mir...

Wer kennt das nicht: Eigentlich möchte man nur ein paar Statisten generieren, die in Städten im Hintergrund 'rumlaufen und sonst nichts tun. Also stampft man x Kreaturen aus dem Boden, die eigentlich alle die gleichen Werte haben, aber nur anders aussehen und die fliegen dann alle rechts im Kreaturen-Baum herum und man sieht wegen ihnen die wirklich wichtigen NSC nicht mehr; doch das muß nicht sein! :D
Genau darauf hatte ich nämlich keinen Bock und hab' mir daher kurzerhand ein OnSpawn-Skript geschrieben, das das Aussehen eines NSC bei dessen erster Erstellung (OnSpawn eben) zufällig festlegt. Außerdem wird auch noch ein zufälliger Name erzeugt und dem NSC zugewiesen.
Sowohl bei der Wahl des Aussehens als auch des Namens werden sowohl die Rasse als auch das Geschlecht des NSC berücksichtigt. Man muß, wenn man dieses Skript benutzt, pro Fraktion (bzw. Rasse), von der man Statisten haben möchte, nur noch ein Paar generieren, nämlich einen männlichen und einen weiblichen. Dann diesen beiden nur noch das folgende Skript ins OnSpawn-Event packen und fertig ist der universelle Statist.
Von diesen Klonen, wie sie im Toolset erscheinen, verteilt man dann nun noch so viele im gewünschten Gebiet, wie man haben möchte. Das Skript besorgt den Rest.
Code:
//:://////////////////////////////////////////////////
//:: NW_C2_DEFAULT9
/*
 * Default OnSpawn handler with XP1 revisions.
 * This corresponds to and produces the same results
 * as the default OnSpawn handler in the OC.
 *
 * This can be used to customize creature behavior in three main ways:
 *
 * - Uncomment the existing lines of code to activate certain
 *   common desired behaviors from the moment when the creature
 *   spawns in.
 *
 * - Uncomment the user-defined event signals to cause the
 *   creature to fire events that you can then handle with
 *   a custom OnUserDefined event handler script.
 *
 * - Add new code _at the end_ to alter the initial
 *   behavior in a more customized way.
 */
//:://////////////////////////////////////////////////
//:: Copyright (c) 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 12/11/2002
//:://////////////////////////////////////////////////
//:: Updated 2003-08-20 Georg Zoeller: Added check for variables to active spawn in conditions without changing the spawnscript


#include "x0_i0_anims"
// #include "x0_i0_walkway" - in x0_i0_anims
#include "x0_i0_treasure"
#include "x2_inc_switches"


// Gibt einen nach Rasse und Geschlecht von oCreature zufaellig bestimmten
// APPEARANCE_TYPE_ zurueck.
int GetRandomAppearanceType(object oCreature = OBJECT_SELF);

// Gibt einen nach Rasse und Geschlecht von oCreature zufaellig bestimmten
// Namen zurueck.
string GetRandomName(object oCreature = OBJECT_SELF);


void main()
{
    // ***** Spawn-In Conditions ***** //

    // * REMOVE COMMENTS (// ) before the "Set..." functions to activate
    // * them. Do NOT touch lines commented out with // *, those are
    // * real comments for information.

    // * This causes the creature to say a one-line greeting in their
    // * conversation file upon perceiving the player. Put [NW_D2_GenCheck]
    // * in the "Text Seen When" field of the greeting in the conversation
    // * file. Don't attach any player responses.
    // *
    // SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);

    // * Same as above, but for hostile creatures to make them say
    // * a line before attacking.
    // *
    // SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);

    // * This NPC will attack when its allies call for help
    // *
    // SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);

    // * If the NPC has the Hide skill they will go into stealth mode
    // * while doing WalkWayPoints().
    // *
    // SetSpawnInCondition(NW_FLAG_STEALTH);

    //--------------------------------------------------------------------------
    // Enable stealth mode by setting a variable on the creature
    // Great for ambushes
    // See x2_inc_switches for more information about this
    //--------------------------------------------------------------------------
    if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_STEALTH) == TRUE)
    {
        SetSpawnInCondition(NW_FLAG_STEALTH);
    }
    // * Same, but for Search mode
    // *
    // SetSpawnInCondition(NW_FLAG_SEARCH);

    //--------------------------------------------------------------------------
    // Make creature enter search mode after spawning by setting a variable
    // Great for guards, etc
    // See x2_inc_switches for more information about this
    //--------------------------------------------------------------------------
    if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_SEARCH) == TRUE)
    {
        SetSpawnInCondition(NW_FLAG_SEARCH);
    }
    // * This will set the NPC to give a warning to non-enemies
    // * before attacking.
    // * NN -- no clue what this really does yet
    // *
    // SetSpawnInCondition(NW_FLAG_SET_WARNINGS);

    // * Separate the NPC's waypoints into day & night.
    // * See comment on WalkWayPoints() for use.
    // *
    // SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);

    // * If this is set, the NPC will appear using the "EffectAppear"
    // * animation instead of fading in, *IF* SetListeningPatterns()
    // * is called below.
    // *
    //SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);

    // * This will cause an NPC to use common animations it possesses,
    // * and use social ones to any other nearby friendly NPCs.
    // *
    // SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);

    //--------------------------------------------------------------------------
    // Enable immobile ambient animations by setting a variable
    // See x2_inc_switches for more information about this
    //--------------------------------------------------------------------------
    if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_AMBIENT_IMMOBILE) == TRUE)
    {
        SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
    }
    // * Same as above, except NPC will wander randomly around the
    // * area.
    // *
    SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);


    //--------------------------------------------------------------------------
    // Enable mobile ambient animations by setting a variable
    // See x2_inc_switches for more information about this
    //--------------------------------------------------------------------------
    if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_AMBIENT) == TRUE)
    {
        SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
    }
    // **** Animation Conditions **** //
    // * These are extra conditions you can put on creatures with ambient
    // * animations.

    // * Civilized creatures interact with placeables in
    // * their area that have the tag "NW_INTERACTIVE"
    // * and "talk" to each other.
    // *
    // * Humanoid races are civilized by default, so only
    // * set this flag for monster races that you want to
    // * behave the same way.
    // SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);

    // * If this flag is set, this creature will constantly
    // * be acting. Otherwise, creatures will only start
    // * performing their ambient animations when they
    // * first perceive a player, and they will stop when
    // * the player moves away.
    // SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);

    // * Civilized creatures with this flag set will
    // * randomly use a few voicechats. It's a good
    // * idea to avoid putting this on multiple
    // * creatures using the same voiceset.
    // SetAnimationCondition(NW_ANIM_FLAG_CHATTER);

    // * Creatures with _immobile_ ambient animations
    // * can have this flag set to make them mobile in a
    // * close range. They will never leave their immediate
    // * area, but will move around in it, frequently
    // * returning to their starting point.
    // *
    // * Note that creatures spawned inside interior areas
    // * that contain a waypoint with one of the tags
    // * "NW_HOME", "NW_TAVERN", "NW_SHOP" will automatically
    // * have this condition set.
    // SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);


    // **** Special Combat Tactics *****//
    // * These are special flags that can be set on creatures to
    // * make them follow certain specialized combat tactics.
    // * NOTE: ONLY ONE OF THESE SHOULD BE SET ON A SINGLE CREATURE.

    // * Ranged attacker
    // * Will attempt to stay at ranged distance from their
    // * target.
    // SetCombatCondition(X0_COMBAT_FLAG_RANGED);

    // * Defensive attacker
    // * Will use defensive combat feats and parry
    // SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE);

    // * Ambusher
    // * Will go stealthy/invisible and attack, then
    // * run away and try to go stealthy again before
    // * attacking anew.
    // SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER);

    // * Cowardly
    // * Cowardly creatures will attempt to flee
    // * attackers.
    // SetCombatCondition(X0_COMBAT_FLAG_COWARDLY);


    // **** Escape Commands ***** //
    // * NOTE: ONLY ONE OF THE FOLLOWING SHOULD EVER BE SET AT ONE TIME.
    // * NOTE2: Not clear that these actually work. -- NN

    // * Flee to a way point and return a short time later.
    // *
    // SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN);

    // * Flee to a way point and do not return.
    // *
    // SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE);

    // * Teleport to safety and do not return.
    // *
    // SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE);

    // * Teleport to safety and return a short time later.
    // *
    // SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN);



    // ***** CUSTOM USER DEFINED EVENTS ***** /


    /*
      If you uncomment any of these conditions, the creature will fire
      a specific user-defined event number on each event. That will then
      allow you to write custom code in the "OnUserDefinedEvent" handler
      script to go on top of the default NPC behaviors for that event.

      Example: I want to add some custom behavior to my NPC when they
      are damaged. I uncomment the "NW_FLAG_DAMAGED_EVENT", then create
      a new user-defined script that has something like this in it:

      if (GetUserDefinedEventNumber() == 1006) {
          // Custom code for my NPC to execute when it's damaged
      }

      These user-defined events are in the range 1001-1007.
    */

    // * Fire User Defined Event 1001 in the OnHeartbeat
    // *
    SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);

    // * Fire User Defined Event 1002
    // *
    SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT);

    // * Fire User Defined Event 1003
    // *
    SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT);

    // * Fire User Defined Event 1004
    // *
    SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT);

    // * Fire User Defined Event 1005
    // *
    SetSpawnInCondition(NW_FLAG_ATTACK_EVENT);

    // * Fire User Defined Event 1006
    // *
    SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT);

    // * Fire User Defined Event 1007
    // *
    SetSpawnInCondition(NW_FLAG_DEATH_EVENT);

    // * Fire User Defined Event 1008
    // *
    SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT);

    // * Fire User Defined Event 1010
    // *
    SetSpawnInCondition(NW_FLAG_RESTED_EVENT);

    // * Fire User Defined Event 1011
    SetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT);


    // ***** DEFAULT GENERIC BEHAVIOR (DO NOT TOUCH) ***** //

    // * Goes through and sets up which shouts the NPC will listen to.
    // *
    SetListeningPatterns();

    // * Walk among a set of waypoints.
    // * 1. Find waypoints with the tag "WP_" + NPC TAG + "_##" and walk
    // *    among them in order.
    // * 2. If the tag of the Way Point is "POST_" + NPC TAG, stay there
    // *    and return to it after combat.
    //
    // * Optional Parameters:
    // * void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
    //
    // * If "NW_FLAG_DAY_NIGHT_POSTING" is set above, you can also
    // * create waypoints with the tags "WN_" + NPC Tag + "_##"
    // * and those will be walked at night. (The standard waypoints
    // * will be walked during the day.)
    // * The night "posting" waypoint tag is simply "NIGHT_" + NPC tag.
    WalkWayPoints();

    //* Create a small amount of treasure on the creature
    if ((GetLocalInt(GetModule(), "X2_L_NOTREASURE") == FALSE)  &&
        (GetLocalInt(OBJECT_SELF, "X2_L_NOTREASURE") == FALSE)   )
    {
        CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF);
    }


    // ***** ADD ANY SPECIAL ON-SPAWN CODE HERE ***** //

    // * If Incorporeal, apply changes
    if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_IS_INCORPOREAL) == TRUE)
    {
        effect eConceal = EffectConcealment(50, MISS_CHANCE_TYPE_NORMAL);
        eConceal = ExtraordinaryEffect(eConceal);
        effect eGhost = EffectCutsceneGhost();
        eGhost = ExtraordinaryEffect(eGhost);
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eConceal, OBJECT_SELF);
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, OBJECT_SELF);
    }

    // Aussehen zufaellig nach Rasse und Geschlecht bestimmen
    SetCreatureAppearanceType(OBJECT_SELF, GetRandomAppearanceType());

    // Zufaelligen Namen generieren
    SetName(OBJECT_SELF, GetRandomName());
}

//::///////////////////////////////////////////////
//:: GetRandomAppearanceType
//:: Copyright (c) 2006 Marius Bauer
//:://////////////////////////////////////////////
/*

*/
//:://////////////////////////////////////////////
//:: Created By: Tingil
//:: Created On: June 5, 2006
//:: Changed On:
//:://////////////////////////////////////////////
int GetRandomAppearanceType(object oCreature = OBJECT_SELF)
{
    int iAppearanceType = GetAppearanceType(oCreature);

    switch (GetRacialType(oCreature))
    {
        case RACIAL_TYPE_DWARF:
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iAppearanceType = APPEARANCE_TYPE_DWARF_NPC_FEMALE;
                break;

                case GENDER_MALE:
                    iAppearanceType = APPEARANCE_TYPE_DWARF_NPC_MALE;
                break;
            }
        break;

        case RACIAL_TYPE_ELF:
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iAppearanceType = APPEARANCE_TYPE_ELF_NPC_FEMALE;
                break;

                case GENDER_MALE:
                    switch (d2())
                    {
                        case 1:
                            iAppearanceType = APPEARANCE_TYPE_ELF_NPC_MALE_01;
                        break;

                        case 2:
                            iAppearanceType = APPEARANCE_TYPE_ELF_NPC_MALE_02;
                        break;
                    }
                break;
            }
        break;

        case RACIAL_TYPE_GNOME:
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iAppearanceType = APPEARANCE_TYPE_GNOME_NPC_FEMALE;
                break;

                case GENDER_MALE:
                    iAppearanceType = APPEARANCE_TYPE_GNOME_NPC_MALE;
                break;
            }
        break;

        case RACIAL_TYPE_HALFELF:
        case RACIAL_TYPE_HUMAN:
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    switch (Random(14) + 1)
                    {
                        case 1:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_01;
                        break;

                        case 2:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_02;
                        break;

                        case 3:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_03;
                        break;

                        case 4:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_04;
                        break;

                        case 5:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_06;
                        break;

                        case 6:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_07;
                        break;

                        case 7:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_09;
                        break;

                        case 8:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_10;
                        break;

                        case 9:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_11;
                        break;

                        case 10:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_FEMALE_12;
                        break;

                        case 11:
                            iAppearanceType = APPEARANCE_TYPE_FEMALE_01;
                        break;

                        case 12:
                            iAppearanceType = APPEARANCE_TYPE_FEMALE_02;
                        break;

                        case 13:
                            iAppearanceType = APPEARANCE_TYPE_FEMALE_03;
                        break;

                        case 14:
                            iAppearanceType = APPEARANCE_TYPE_FEMALE_04;
                        break;
                    }
                break;

                case GENDER_MALE:
                    switch (Random(17) + 1)
                    {
                        case 1:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_01;
                        break;

                        case 2:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_02;
                        break;

                        case 3:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_03;
                        break;

                        case 4:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_04;
                        break;

                        case 5:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_05;
                        break;

                        case 6:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_07;
                        break;

                        case 7:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_12;
                        break;

                        case 8:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_13;
                        break;

                        case 9:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_15;
                        break;

                        case 10:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_16;
                        break;

                        case 11:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_17;
                        break;

                        case 12:
                            iAppearanceType = APPEARANCE_TYPE_HUMAN_NPC_MALE_18;
                        break;

                        case 13:
                            iAppearanceType = APPEARANCE_TYPE_MALE_01;
                        break;

                        case 14:
                            iAppearanceType = APPEARANCE_TYPE_MALE_02;
                        break;

                        case 15:
                            iAppearanceType = APPEARANCE_TYPE_MALE_03;
                        break;

                        case 16:
                            iAppearanceType = APPEARANCE_TYPE_MALE_04;
                        break;

                        case 17:
                            iAppearanceType = APPEARANCE_TYPE_MALE_05;
                        break;
                    }
                break;
            }
        break;

        case RACIAL_TYPE_HALFLING:
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iAppearanceType = APPEARANCE_TYPE_HALFLING_NPC_FEMALE;
                break;

                case GENDER_MALE:
                    iAppearanceType = APPEARANCE_TYPE_HALFLING_NPC_MALE;
                break;
            }
        break;

        case RACIAL_TYPE_HALFORC:
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iAppearanceType = APPEARANCE_TYPE_HALF_ORC_NPC_FEMALE;
                break;

                case GENDER_MALE:
                    switch (d2())
                    {
                        case 1:
                            iAppearanceType = APPEARANCE_TYPE_HALF_ORC_NPC_MALE_01;
                        break;

                        case 2:
                            iAppearanceType = APPEARANCE_TYPE_HALF_ORC_NPC_MALE_02;
                        break;
                    }
                break;
            }
        break;
    }

    return iAppearanceType;
}

//::///////////////////////////////////////////////
//:: GetRandomName
//:: Copyright (c) 2006 Marius Bauer
//:://////////////////////////////////////////////
/*

*/
//:://////////////////////////////////////////////
//:: Created By: Tingil
//:: Created On: June 5, 2006
//:: Changed On:
//:://////////////////////////////////////////////
string GetRandomName(object oCreature = OBJECT_SELF)
{
    string sName = GetName(oCreature);
    int iNameFirst, iNameLast;

    switch (GetRacialType(oCreature))
    {
        case RACIAL_TYPE_DWARF:
            iNameLast = NAME_LAST_DWARF;
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iNameFirst = NAME_FIRST_DWARF_FEMALE;
                break;

                case GENDER_MALE:
                    iNameFirst = NAME_FIRST_DWARF_MALE;
                break;
            }
        break;

        case RACIAL_TYPE_ELF:
            iNameLast = NAME_LAST_ELF;
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iNameFirst = NAME_FIRST_ELF_FEMALE;
                break;

                case GENDER_MALE:
                    iNameFirst = NAME_FIRST_ELF_MALE;
                break;
            }
        break;

        case RACIAL_TYPE_GNOME:
            iNameLast = NAME_LAST_GNOME;
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iNameFirst = NAME_FIRST_GNOME_FEMALE;
                break;

                case GENDER_MALE:
                    iNameFirst = NAME_FIRST_GNOME_MALE;
                break;
            }
        break;

        case RACIAL_TYPE_HALFELF:
            iNameLast = NAME_LAST_HALFELF;
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iNameFirst = NAME_FIRST_HALFELF_FEMALE;
                break;

                case GENDER_MALE:
                    iNameFirst = NAME_FIRST_HALFELF_MALE;
                break;
            }
        break;

        case RACIAL_TYPE_HALFLING:
            iNameLast = NAME_LAST_HALFLING;
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iNameFirst = NAME_FIRST_HALFLING_FEMALE;
                break;

                case GENDER_MALE:
                    iNameFirst = NAME_FIRST_HALFLING_MALE;
                break;
            }
        break;

        case RACIAL_TYPE_HALFORC:
            iNameLast = NAME_LAST_HALFORC;
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iNameFirst = NAME_FIRST_HALFORC_FEMALE;
                break;

                case GENDER_MALE:
                    iNameFirst = NAME_FIRST_HALFORC_MALE;
                break;
            }
        break;

        case RACIAL_TYPE_HUMAN:
            iNameLast = NAME_LAST_HUMAN;
            switch (GetGender(oCreature))
            {
                case GENDER_FEMALE:
                    iNameFirst = NAME_FIRST_HUMAN_FEMALE;
                break;

                case GENDER_MALE:
                    iNameFirst = NAME_FIRST_HUMAN_MALE;
                break;
            }
        break;
    }

    if (iNameFirst > 0 && iNameLast > 0)
    {
        sName = RandomName(iNameFirst) + " " + RandomName(iNameLast);
    }

    return sName;
}
Edit: Bevor ich vergesse, es zu erwähnen: Das Skript bastelt das Aussehen nicht aus den x Möglichkeiten zusammen, die man von den Möglichkeiten zur Veränderung des Aussehens eines SC kennt. Es benutzt lediglich die verschiedenen vorgefertigten Erscheinungen. Da die Anzahl derer bei Menschen deutlich größer ist als bei allen anderen Rassen, eignet sich das Skript daher am besten für menschliche (und halbelfische) Statisten. Bei den anderen Rassen gibt es leider nur 1-2 alternative Erscheinungstypen pro Geschlecht.

Edit 2: Das Skript benötigt übrigens HotU.
 
Zuletzt bearbeitet:

Theron

Kampfmagier
Registriert
01.04.2000
Beiträge
4.526
:eek:
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Das sieht nur nach so viel aus, weil ich das Standard-OnSpawn-Skript als Basis benutzt habe. Von mir sind lediglich die beiden Funktionen "GetRandomAppearanceType" und "GetRandomName" und die zwei Zeilen mit den entsprechenden Aufrufen ganz am Ende von "void main". ;)
 

Theron

Kampfmagier
Registriert
01.04.2000
Beiträge
4.526
Alles was mit programmieren zu tun hat entlockt mir diesen Smilie.;)
Verstehe nicht, wie man sowas verstehen kann.:D
 

Theron

Kampfmagier
Registriert
01.04.2000
Beiträge
4.526
Mein Held, gäb es nur so (Programmier-) Nixpeiler wie mich, würden wir immer noch mit Schreibmaschine schreiben.:D (wenn überhaupt)
 

Sir Darian

Ritter des Helm
Registriert
01.04.2000
Beiträge
33.907
Hmmm... *grübel*

Ja, ich wünschte, ich würde da auch mehr durchblicken.

Aber die Grundidee für dieses Skript ist klasse! :):up:
Danke für die Umsetzung!
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
@Theron: Je mehr es davon gibt, umso mehr verdiene ich. *muhahahahahaha* :D
Schließlich braucht jeder seine Nische. ;)
 
Zuletzt bearbeitet:

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Scardon schrieb:
<blockquote>
(...)
Ich habe jetzt einen Auslöser im Gebiet mit dem Leichenhaufen gemacht (falls jemand das Modul schon getestet hat). Wenn ein SC dort reinläuft, soll er Schaden erleiden, falls er den Zähigkeitswurf nicht schafft. Leider funktioniert das ganze nicht. Bisher sieht das Skript (auf onHeartbeat) folgendermaßen aus:

Code:
void main()
{
    object oTarget = GetFirstObjectInArea();
    effect eDam = EffectDamage(1,DAMAGE_TYPE_FIRE);
    if (FortitudeSave(oTarget,13,SAVING_THROW_TYPE_DISEASE,OBJECT_SELF))
    {
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
    }
}
Ich verstehe nicht wirklich, warum das nicht funktioniert. Ich hoffe, ihr könnt mir da weiterhelfen.

Und gleich noch eine Frage hinterher: Ist es möglich, im Skripteditor Umlaute und ß zu schreiben, ohne den Text umständlich aus Word oder sonstigem Programm zu kopieren und in den Editor einzufügen?
</blockquote>

Erstmal solltest Du Dir darüber im Klaren sein, wann welches Event ausgelöst wird. Das OnHeartbeat-Event wird nämlich nicht jedes Mal ausgelöst, wenn ein SC den Bereich betritt, sondern alle 6 Sekunden. Wenn Du willst, daß es beim Eintreten passiert, mußt Du das OnEnter-Event benutzen. Um das eintretende Objekt zu bekommen, wäre der Befehl dann "GetEnteringObject".

Daß es im OnHeartbeat nicht klappt, liegt daran, daß ein Trigger keine Area ist ;). Selbst wenn würdest Du nur das erste Objekt abhandeln. Um den gewünschten Effekt zu erhalten, müßtest Du schon alle durchgehen. Das könnte z.B. so aussehen:
Code:
void main()
{
    // Den Schadenseffekt definieren
    effect eDamage = EffectDamage(1, DAMAGE_TYPE_FIRE);

    // Ein kleiner visueller Effekt ;-)
    effect eVisual = EffectVisualEffect(VFX_IMP_FLAME_S);

    // Die Effekte verschmelzen
    eDamage = EffectLinkEffects(eDamage, eVisual);

    // Die erste Kreature in mir holen
    object oTarget = GetFirstInPersistentObject();

    // Fuer jede Kreatur in mir...
    while (oTarget != OBJECT_INVALID)
    {
        // Wenn der RW nicht geschafft wurde...
        if (!FortitudeSave(oTarget, 13, SAVING_THROW_TYPE_FIRE))
        {
            //...Schadenseffekt anwenden
            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
        }

        // Die naechste Kreatur in mir holen
        oTarget = GetNextInPersistentObject();
    }
}

Aber davon 'mal abgesehen: Warum machst Du's nicht so, wie im Abenteuer vorgesehen? Ich mache das z.B. so:

OnEnter
Code:
void main()
{
    if (!GetLocalInt(GetModule(), "iDuvikSaved"))
    {
        SendMessageToPC(GetEnteringObject(),
            "Hitzewellen schlagen Euch entgegen und machen das Atmen schwer.");
    }
}

OnExit
Code:
void main()
{
    if (!GetLocalInt(GetModule(), "iDuvikSaved"))
    {
        SendMessageToPC(GetExitingObject(),
            "Die Luft hier ist wieder merklich kuehler.");
    }
}

OnHeartbeat
Code:
#include "NW_I0_SPELLS"

void main()
{
    if (!GetLocalInt(GetModule(), "iDuvikSaved"))
    {
        effect ePlaque = EffectDisease(DISEASE_FILTH_FEVER);
        int iRounds;
        object oCreature = GetFirstInPersistentObject();
        while (oCreature != OBJECT_INVALID)
        {
            if (!GetIsDead(oCreature) && !GetIsImmune(oCreature,
                IMMUNITY_TYPE_DISEASE))
            {
                iRounds = GetLocalInt(oCreature, "iRoundsInPlaqueArea");
                if (iRounds == 3)
                {
                    iRounds = 0;
                    if (!FortitudeSave(oCreature, 13, SAVING_THROW_TYPE_DISEASE))
                    {
                        DelayCommand(GetRandomDelay(), ApplyEffectToObject(
                            DURATION_TYPE_PERMANENT, ePlaque, oCreature));
                    }
                }
                else
                {
                    iRounds++;
                }
                SetLocalInt(oCreature, "iRoundsInPlaqueArea", iRounds);
            }
            oCreature = GetNextInPersistentObject();
        }
    }
}

Die OnEnter- und OnExit-Skripte sind nur zur Info für den Spieler. Das wichtige Skript ist das OnHeartbeat-Skript.
Die Modulvariable "iDuvikSaved" gibt an, ob der Endgegner besiegt wurde. Sie ist TRUE, wenn ja, ansonsten FALSE. Das dient dazu, daß die Seuche in der Leichengrube "abgeschaltet" wird, sobald der Endgegner besiegt wurde. Der Rest ist prinzipiell dem Schadens-Skript ähnlich. Nur benutze ich hier den EffectDisease und ich zähle pro Kreatur die Runden, die sie schon darin verbracht hat und mache nur alle 3 Runden einen RW, wie es im Modul vorgesehen ist.

Ich kenne leider auch keine andere Möglichkeit, Umlaute und ß im Skripteditor zu verwenden, ohne sie aus anderen Applikationen dort hineinzukopieren.
 
Zuletzt bearbeitet:

Scardon

Schlachtenwüter
Registriert
20.02.2002
Beiträge
1.271
Danke, jetzt funktioniert's :)

Ich glaube nicht, dass ich die Seuche so hinbekommen hätte, wie sie auch sein soll. Ich hatte mir zwar schon mal ein Skript angesehen, mit dem man bei Eintritt in ein Gebiet Säureschaden verursacht, aber so recht hab ich da nicht durchgesehen...

Und auch so hab ich noch ein paar Fragen zu dem Skript, ob ich das richtig verstehe:

"if (!GetLocalInt(GetModule(), "iDuvikSaved"))" bedeutet, dass das Programm abfragt, ob die Variable iDuvikSaved vorhanden ist und wenn das nicht der Fall ist, werden die nachfolgenden Anweisungen durchgeführt?

Damit die Seuche dann später nicht mehr ausgeführt wird, muss also beim Besiegen des Orks die Variable iDuvikSaved gesetzt werden? Wie genau mach ich das? :D
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Nicht ganz, aber nahe dran. Die Funktion "GetLocalInt" ließt eine Integer-Variable mit dem übergebenen Namen vom übergebenen Objekt aus und gibt ihren Wert zurück. Wenn eine Variable noch nicht initialisiert wurde, gibt diese Funktion den Standardwert dieses Variablentyps zurück. Im Falle eines Integers ist der Standardwert 0, was in NWScript gleichbedeutend mit FALSE ist.
0 wird also als FALSE interpretiert, während jeder andere Wert als TRUE interpretiert wird.
Wenn die Variable also noch nicht gesetzt ist, gibt der Aufruf...

GetLocalInt(GetModule(), "iDuvikSaved")

...also 0 zurück, also FALSE. Das Ausrufezeichen ist der logische NOT-Operator in NWScript (wie auch in C++ oder Java). D.h. der Ausdruck, der direkt dahinter steht, wird negiert und damit wird aus unserem FALSE ein TRUE, womit das Ergebnis der IF-Abfrage TRUE ist und er in den entsprechenden Block 'rein läuft.

Um den Wert nun zu setzen, benutzt Du die Funktion "SetLocalInt". Der konkrete Aufruf würde dann so aussehen:

SetLocalInt(GetModule(), "iDuvikSaved", true);

Der Ausdruck...

GetLocalInt(GetModule(), "iDuvikSaved")

...gibt also jetzt TRUE zurück, was negiert FALSE ist, wodurch er nun nicht mehr in den Block, der für das infektiöse Verhalten zuständig ist, hinein läuft.
 

Scardon

Schlachtenwüter
Registriert
20.02.2002
Beiträge
1.271
Okay, das hab ich jetzt verstanden. Aber wo muss ich die Variable dann auf TRUE setzen? Beim OnDeath-Skript des Orks? Oder beim OnUserDefined (Da gibt's ja auch eine Stelle, wo's um den Tod geht. Das hab ich da schon ausprobiert, aber es mag nicht so recht klappen...)? Oder vielleicht irgendwo bei den Modulskripts?
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Als Faustregel kann man sagen: Alles, was man im OnUserDefined unterbringen kann, sollte man auch dort unterbringen, denn

1. ist es dafür da :D und
2. hat man so alles zu einer Kreatur beisammen in einem Skript und nicht verteilt über mehrere.

Damit die User Defined Events aber auch ausgelöst werden, muß man im OnSpawn-Skript bei den entsprechenden Befehlen die Kommentarklammern entfernen. Ich habe z.B. in meinen Modulen immer im Standard-OnSpawn alle diese Events freigeschaltet. Und zwar geht es dabei um diese Sektion in der "nw_c2_default9":
Code:
    // ***** CUSTOM USER DEFINED EVENTS ***** /


    /*
      If you uncomment any of these conditions, the creature will fire
      a specific user-defined event number on each event. That will then
      allow you to write custom code in the "OnUserDefinedEvent" handler
      script to go on top of the default NPC behaviors for that event.

      Example: I want to add some custom behavior to my NPC when they
      are damaged. I uncomment the "NW_FLAG_DAMAGED_EVENT", then create
      a new user-defined script that has something like this in it:

      if (GetUserDefinedEventNumber() == 1006) {
          // Custom code for my NPC to execute when it's damaged
      }

      These user-defined events are in the range 1001-1007.
    */

    // * Fire User Defined Event 1001 in the OnHeartbeat
    // *
    // SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);

    // * Fire User Defined Event 1002
    // *
    // SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT);

    // * Fire User Defined Event 1005
    // *
    // SetSpawnInCondition(NW_FLAG_ATTACK_EVENT);

    // * Fire User Defined Event 1006
    // *
    // SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT);

    // * Fire User Defined Event 1008
    // *
    // SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT);

    // * Fire User Defined Event 1003
    // *
    // SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT);

    // * Fire User Defined Event 1004
    // *
    // SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT);
Wie Du sicher schon weißt, leiten zwei Slashes (//) einen einzeiligen Kommentar ein, d.h. alles, was in der selben Zeile dahinter steht, wird vom Compiler ignoriert. Also mußt Du nur die beiden Slashes vor den Aufrufen von "SetSpawnInCondition" entfernen und schon werden all die in diesem Skript genannten User Defined Events ausgelöst.

Edit: Öhm... wie ich gerade sehe, ist das OnDeath-Event standardmäßig nicht dabei. Um einfach alles freizuschalten kannst Du auch diese Zeilen verwenden:
Code:
    // ***** CUSTOM USER DEFINED EVENTS ***** /


    /*
      If you uncomment any of these conditions, the creature will fire
      a specific user-defined event number on each event. That will then
      allow you to write custom code in the "OnUserDefinedEvent" handler
      script to go on top of the default NPC behaviors for that event.

      Example: I want to add some custom behavior to my NPC when they
      are damaged. I uncomment the "NW_FLAG_DAMAGED_EVENT", then create
      a new user-defined script that has something like this in it:

      if (GetUserDefinedEventNumber() == 1006) {
          // Custom code for my NPC to execute when it's damaged
      }

      These user-defined events are in the range 1001-1007.
    */

    // * Fire User Defined Event 1001 in the OnHeartbeat
    // *
    SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);

    // * Fire User Defined Event 1002
    // *
    SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT);

    // * Fire User Defined Event 1003
    // *
    SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT);

    // * Fire User Defined Event 1004
    // *
    SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT);

    // * Fire User Defined Event 1005
    // *
    SetSpawnInCondition(NW_FLAG_ATTACK_EVENT);

    // * Fire User Defined Event 1006
    // *
    SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT);

    // * Fire User Defined Event 1007
    // *
    SetSpawnInCondition(NW_FLAG_DEATH_EVENT);

    // * Fire User Defined Event 1008
    // *
    SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT);

    // * Fire User Defined Event 1010
    // *
    SetSpawnInCondition(NW_FLAG_RESTED_EVENT);

    // * Fire User Defined Event 1011
    // *
    SetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT);
So sieht diese Sektion bei mir in der "nw_c2_default9" aus.
 
Zuletzt bearbeitet:

Scardon

Schlachtenwüter
Registriert
20.02.2002
Beiträge
1.271
Wenn ich schon mal hier bin, gleich die nächste Frage.

Wie schaffe ich es, dass bei einem Ereignis mehrere Objekte verschwinden? Ich hatte mir gedacht, wenn der Ork stirbt, sollen auch die giftgrünen Nebelschwaden im Seuchengebiet verschwinden. Also habe ich im OnUserDefined unter Death alle Objekte einzeln zu zerstören versucht, was dann in etwa so aussieht:

Code:
   DestroyObject(GetObjectByTag("smoke1"));
   DestroyObject(GetObjectByTag("smoke2"));
// Und so weiter, bis alle Objekte aufgelistet sind.

Dabei wird allerdings immer nur das erste Objekt in der Liste zerstört, die anderen bleiben aber immer noch da, wo sie waren. Bisher habe ich noch keine andere Idee, wie ich es ändern könnte :confused:
 
Oben