Author Topic: Unique Items  (Read 2617 times)

Legacy_C Writer

  • Jr. Member
  • **
  • Posts: 73
  • Karma: +0/-0
Unique Items
« Reply #15 on: August 26, 2010, 11:53:57 pm »


               Whilst messing around with the toolset and scripting out of bordom, I came up with a rod which summons eight "floating bombs" which are basically proximity mines in the form of HotU eyeballs which either float randomly or approach your enemies to blow them up. I created it on a different ("testing") module so this is the only unique item the module has (wheras the ones I'm working on which I'm planning to release have multiple). I've just finished it, and I haven't had much time to go over it (for instance, I could probably have used a while loop for the following script), but it works for me:

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

        if (GetTag(GetItemActivated()) == "ITEM_TAG_HERE")
        {
         SetLocalInt(oPC, "CurrentHP", GetCurrentHitPoints(oPC));
                ForceRest(oPC);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(GetMaxHitPoints(oPC) - GetLocalInt(oPC, "CurrentHP")), oPC);
        }
        else
     {
            location lSpawn1 = Location(GetArea(oPC), GetPosition(oPC) +
           Vector(IntToFloat(d8()) - 4.5, IntToFloat(d8()) - 4.5), IntToFloat(Random(360)));
            location lSpawn2 = Location(GetArea(oPC), GetPosition(oPC) +
           Vector(IntToFloat(d8()) - 4.5, IntToFloat(d8()) - 4.5), IntToFloat(Random(360)));
            location lSpawn3 = Location(GetArea(oPC), GetPosition(oPC) +
           Vector(IntToFloat(d8()) - 4.5, IntToFloat(d8()) - 4.5), IntToFloat(Random(360)));
            location lSpawn4 = Location(GetArea(oPC), GetPosition(oPC) +
           Vector(IntToFloat(d8()) - 4.5, IntToFloat(d8()) - 4.5), IntToFloat(Random(360)));
            location lSpawn5 = Location(GetArea(oPC), GetPosition(oPC) +
           Vector(IntToFloat(d8()) - 4.5, IntToFloat(d8()) - 4.5), IntToFloat(Random(360)));
            location lSpawn6 = Location(GetArea(oPC), GetPosition(oPC) +
           Vector(IntToFloat(d8()) - 4.5, IntToFloat(d8()) - 4.5), IntToFloat(Random(360)));
            location lSpawn7 = Location(GetArea(oPC), GetPosition(oPC) +
           Vector(IntToFloat(d8()) - 4.5, IntToFloat(d8()) - 4.5), IntToFloat(Random(360)));
            location lSpawn8 = Location(GetArea(oPC), GetPosition(oPC) +
           Vector(IntToFloat(d8()) - 4.5, IntToFloat(d8()) - 4.5), IntToFloat(Random(360)));

            CreateObject(OBJECT_TYPE_CREATURE, "floating_bomb", lSpawn1);
            CreateObject(OBJECT_TYPE_CREATURE, "floating_bomb", lSpawn2);
            CreateObject(OBJECT_TYPE_CREATURE, "floating_bomb", lSpawn3);
            CreateObject(OBJECT_TYPE_CREATURE, "floating_bomb", lSpawn4);
            CreateObject(OBJECT_TYPE_CREATURE, "floating_bomb", lSpawn5);
            CreateObject(OBJECT_TYPE_CREATURE, "floating_bomb", lSpawn6);
            CreateObject(OBJECT_TYPE_CREATURE, "floating_bomb", lSpawn7);
            CreateObject(OBJECT_TYPE_CREATURE, "floating_bomb", lSpawn8);

            DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectTimeStop(), oPC, 2.0)); // Time to get away
        }
}

The floating bombs' OnSpawn scripts are:

void main()
{
    object oBomb = OBJECT_SELF;

       if (GetLocalInt(oBomb, "Exploded") ==1) return;

        if (GetDistanceBetween(oBomb, GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, oBomb, 1,
           CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC))
       GetDistanceBetween(oBomb, GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, oBomb, 1,
           CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC)) !=0.0) // 0.0 is returned if there are no valid creatures in the area
        {
                 ExecuteScript("walkbomb_explode", oBomb);
        }
        else
        {
                ActionMoveAwayFromObject(GetFirstPC(), FALSE, 8.0);
        }

        ExecuteScript("nw_c2_default1", oBomb);
        DelayCommand(1.5, ExecuteScript("walkbomb_hb_rept", oBomb));
        DelayCommand(3.0, ExecuteScript("walkbomb_hb_rept", oBomb));
        DelayCommand(4.5, ExecuteScript("walkbomb_hb_rept", oBomb));
}

Their HB scripts are (similar but still different):

void main()
{
    object oBomb = OBJECT_SELF;

        if (GetLocalInt(oBomb, "Exploded") ==1) return;

        if (GetDistanceBetween(oBomb, GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, oBomb, 1,
           CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC))
       GetDistanceBetween(oBomb, GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, oBomb, 1,
           CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC)) !=0.0) // 0.0 is returned if there are no valid creatures in the area
        {
                ExecuteScript("walkbomb_explode", oBomb);
        }
        else if (GetDistanceBetween(oBomb, GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, oBomb, 1,
               CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC)) > 8.0 ||
            GetDistanceBetween(oBomb, GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, oBomb, 1,
               CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC)) ==0.0)
        {
                ActionRandomWalk();
        }
        else
        {
            ClearAllActions();
            ActionMoveToObject(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, oBomb, 1,
               CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC));
        }

        ExecuteScript("nw_c2_default1", oBomb);
        DelayCommand(1.5, ExecuteScript("walkbomb_hb_rept", oBomb));
        DelayCommand(3.0, ExecuteScript("walkbomb_hb_rept", oBomb));
        DelayCommand(4.5, ExecuteScript("walkbomb_hb_rept", oBomb)); // Core part of script effectively runs once every 1.5 seconds
}

And the "walkbomb_hb_rept" script is basically a replication of the HB script only without the ExecuteScript() commands as running the same script again three times would only cause a chain reaction of potentially infinite scripts running causing the game to be overloaded with commands and crash. I learned that the hard way. Their OnDeath script triggers the following script which handles their detonation:

void main()
{
     object oArea = GetArea(OBJECT_SELF);
        object oBomb = OBJECT_SELF;
        location lCentre = GetLocation(oBomb);
        object oVictim = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, lCentre);

        AssignCommand(oArea, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_FIREBALL), lCentre));

        while (GetIsObjectValid(oVictim))
        {
            AssignCommand(oArea, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d100(), DAMAGE_TYPE_FIRE), oVictim));
            oVictim = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lCentre);
        }

        SetLocalInt(oBomb, "Exploded", 1);
        ExecuteScript("nw_c2_default7", OBJECT_SELF);
}

So basically, the floatings bombs will be detonated by your enemies (neutral to them), but not by you, your allies, or each other (friendly to them) - although their explosion damage can detonate each other and hurt you so you have to use it tactically (especially since the time stop effect is delayed meaning that you could get blown up before it kicks in - an intentional feature to keep it from becoming overpowered).

The floating bombs will immediately move eight meters away from you and will then randomly float about. If however, an enemy comes within eight meters, it approaches them. If it gets within three meters, it explodes.
               
               

               


                     Modifié par C Writer, 26 août 2010 - 10:59 .