wc3campaigns
WC3C Homepage - www.wc3c.netUser Control Panel (Requires Log-In)Engage in discussions with other users and join contests in the WC3C forums!Read one of our many tutorials, ranging in difficulty from beginner to advanced!Show off your artistic talents in the WC3C Gallery!Download quality models, textures, spells (vJASS/JASS), systems, and scripts!Download maps that have passed through our rigorous approval process!

Go Back   Wc3C.net > Warcraft III Modding > Developer's Corner > Triggers & Scripts
User Name
Password
Register Rules Get Hosted! Chat Pastebin FAQ and Rules Members List Calendar



Reply
 
Thread Tools Search this Thread
Old 03-06-2013, 02:06 PM   #1
cohadar
master of fugue
 
cohadar's Avatar
 
Join Date: Jun 2007
Posts: 2,558

Submissions (5)

cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)

Default UHS - Item Request #4

Soul Orb:

When an undead hero that has the orb kills a unit it captures the soul in the orb.
He can that eat that soul to heal himself (cast on self) or cast it as shadow strike on an enemy unit. (cast on enemy)
Eating the soul should play some wailing sound. (and display vampiric effect on hero)
Orb can have max X charges.

Make sure everything works ok if hero has more than one orb.
__________________
<nosignature />

Last edited by cohadar : 03-06-2013 at 02:10 PM.
cohadar is offline   Reply With Quote
Sponsored Links - Login to hide this ad!
Old 03-07-2013, 05:16 PM   #2
HerrStanev
User
 
HerrStanev's Avatar
 
Join Date: Mar 2013
Posts: 49

HerrStanev has little to show at this moment (8)

Default

What happens if there are multiple orbs? When one gets full the others start filling consecutively?
HerrStanev is offline   Reply With Quote
Old 03-07-2013, 07:00 PM   #3
cohadar
master of fugue
 
cohadar's Avatar
 
Join Date: Jun 2007
Posts: 2,558

Submissions (5)

cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)

Default

Yes, and you always fill the one that has the lowest slot index first.
__________________
<nosignature />
cohadar is offline   Reply With Quote
Old 03-11-2013, 12:04 AM   #4
HerrStanev
User
 
HerrStanev's Avatar
 
Join Date: Mar 2013
Posts: 49

HerrStanev has little to show at this moment (8)

Default

Is there a native to get the target unit of item used?
Otherwise I can't trace down from which item the spell was cast...
HerrStanev is offline   Reply With Quote
Old 03-11-2013, 12:30 AM   #5
Fledermaus
default string
 
Fledermaus's Avatar
 
Join Date: May 2006
Posts: 604

Submissions (1)

Fledermaus has a spectacular aura about (134)

Send a message via MSN to Fledermaus
Default

Spells cast via items still trigger SPELL_EFFECT so just use that event and you can use GetSpellTargetUnit().
Fledermaus is offline   Reply With Quote
Old 03-11-2013, 12:31 AM   #6
cohadar
master of fugue
 
cohadar's Avatar
 
Join Date: Jun 2007
Posts: 2,558

Submissions (5)

cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)

Default

You can use % wildcards to find functions in editor: get%target%
__________________
<nosignature />

Last edited by cohadar : 03-11-2013 at 12:31 AM.
cohadar is offline   Reply With Quote
Old 03-11-2013, 12:48 AM   #7
HerrStanev
User
 
HerrStanev's Avatar
 
Join Date: Mar 2013
Posts: 49

HerrStanev has little to show at this moment (8)

Default

Quote:
Originally Posted by Fledermaus
Spells cast via items still trigger SPELL_EFFECT so just use that event and you can use GetSpellTargetUnit().
Yes but if a unit has two items I wouldn't know which item was used.
Also, if I use SPELL_EFFECT I cannot manipulate item charges.
If I use EVENT_UNIT_USE_ITEM I can't get the target of the item.

Last edited by HerrStanev : 03-11-2013 at 12:48 AM.
HerrStanev is offline   Reply With Quote
Old 03-11-2013, 06:03 AM   #8
Fledermaus
default string
 
Fledermaus's Avatar
 
Join Date: May 2006
Posts: 604

Submissions (1)

Fledermaus has a spectacular aura about (134)

Send a message via MSN to Fledermaus
Default

Wont the charges automatically go down anyway when the item's used?

Edit: tested and yes, they do.

Last edited by Fledermaus : 03-11-2013 at 06:04 AM.
Fledermaus is offline   Reply With Quote
Old 03-11-2013, 08:39 AM   #9
Anitarf
Procrastination Incarnate


Development Director
 
Join Date: Feb 2004
Posts: 8,083

Submissions (19)

Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)

2008 Spell olympics - Fire - SilverApproved Map: Old School Alliance TacticsHero Contest #2 - 3rd PlaceSpell making session 2 winner

Default

You can always use both events and attach the data to the unit between them (or simply manipulate the charges in one of them and deal damage in the other).
__________________
Anitarf is offline   Reply With Quote
Old 03-11-2013, 03:56 PM   #10
HerrStanev
User
 
HerrStanev's Avatar
 
Join Date: Mar 2013
Posts: 49

HerrStanev has little to show at this moment (8)

Default

Sorry, I didn't specify what I meant by manipulating item charges.
The thing is, you can still use the item's spell when it has 0 charges.
And for the above reasons I can't interrupt things on time (SPELL_EFFECT would still run on 0 charges).
Maybe I should add an inactive version when charges are 0 for a particular item?

Last edited by HerrStanev : 03-11-2013 at 03:56 PM.
HerrStanev is offline   Reply With Quote
Old 03-11-2013, 04:25 PM   #11
cohadar
master of fugue
 
cohadar's Avatar
 
Join Date: Jun 2007
Posts: 2,558

Submissions (5)

cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)

Default

Quote:
Originally Posted by HerrStanev
The thing is, you can still use the item's spell when it has 0 charges.
No you can't. Charged item with zero charges cannot cast a spell.
__________________
<nosignature />

Last edited by cohadar : 03-11-2013 at 04:28 PM.
cohadar is offline   Reply With Quote
Old 03-11-2013, 04:43 PM   #12
HerrStanev
User
 
HerrStanev's Avatar
 
Join Date: Mar 2013
Posts: 49

HerrStanev has little to show at this moment (8)

Default

I'm really good at dumb conclusions.
I started with 0 charges on the item in Object Editor, that's why it allowed me to cast the spell. Starting with 1 is fine, though.

Collapse Zinc:
//! zinc

library SoulOrb requires OID, Trig
{
    // Raw code to the ability contained in the Soul Orb item:
    public constant integer AID_SOUL_ORB = 'A003';
    // Raw code of the Soul Orb item:
    public constant integer IID_SOUL_ORB = 'I002';
    // Raw code of the Shadow Strike-based ability that is cast on enemies:
    public constant integer AID_SOUL_ORB_SHADOW_STRIKE = 'A004';
    // Order ID of the Shadow Strike ability:
    public constant integer OID_SOUL_ORB_SHADOW_STRIKE = OID_shadowstrike;
    
    // Path to the sound which is played when the spell is used on enemies:
    constant string PATH_SOUND_ON_CAST = "Units\\Undead\\Banshee\\BansheeDeath.wav";
    
    // Special effect attached to the caster when the orb is used:
    constant string SFX_SOUL_ORB_CAST = "Abilities\\Spells\\Undead\\RaiseSkeletonWarrior\\RaiseSkeleton.mdl";
    // Attachment point of the special effect:
    constant string AP_SOUL_ORB_CAST = "origin";
    
    // The item charges limit of the Soul Orb:
    public function SoulOrb_GetLimit(unit whichUnit) -> integer 
    {
        return 5;
    }
    // The amount of life healed when the Orb is used on self:
    function GetHealAmount(unit whichUnit) -> real
    {
        return 33.;
    }
//===========================================================================
//      E N D    O F    C O N F I G U R A T I O N
//===========================================================================
    
    function ApplySoundUnit(unit whichUnit, string filename)
    {
        // Credits to Rising_Dusk 
        sound s = CreateSound(filename, false, false, false, 0, 0, "");
        
        SetSoundDuration(s, 5000);
        SetSoundChannel(s, 5);
        SetSoundVolume(s, 100);
        SetSoundPitch(s, 1.);
        AttachSoundToUnit(s, whichUnit);
        StartSound(s);
        
        s = null;
    }
    
    function Actions()
    {
        unit cast = GetTriggerUnit();
        unit targ = GetSpellTargetUnit();
        
        DestroyEffect(AddSpecialEffectTarget(SFX_SOUL_ORB_CAST, cast, AP_SOUL_ORB_CAST));
        // Is it cast on self?
        if ( cast == targ )
        {
            SetWidgetLife(cast, GetWidgetLife(cast) + GetHealAmount(cast));
        }
        else if ( IsUnitEnemy(targ, GetOwningPlayer(cast)) )
        {
            IssueTargetOrderById(Dummy_Create(cast, AID_SOUL_ORB_SHADOW_STRIKE, 1), /*
            */ OID_SOUL_ORB_SHADOW_STRIKE, targ);
            ApplySoundUnit(targ, PATH_SOUND_ON_CAST);
        }
        
        cast = null; targ = null;
    }
    
    function Conditions() -> boolean
    {
        return ( GetSpellAbilityId() == AID_SOUL_ORB );
    }
    
    function onInit()
    {
        Trig_SpellEffect(function Conditions, function Actions);
    }
}

//! endzinc
Collapse Zinc:
//! zinc

library SoulOrbKills requires SoulOrb, Trig 
{

    // Looks up a unit's inventory from slot "startIndex" to slot "endIndex"
    // to check if it has the item type specified by "searchFor" and returns the first
    // slot that contains the searched item.
    function SearchItemIndex(unit whichUnit, integer searchFor, /*
    */ integer startIndex, integer endIndex) -> integer
    {
        integer currentIndex = startIndex;
        
        while ( currentIndex <= endIndex )
        {
            if ( GetItemTypeId(UnitItemInSlot(whichUnit, currentIndex)) == searchFor )
                return currentIndex;
                
            currentIndex += 1;
        }
        
        return -1;
    }
    
    function Actions()
    {
        unit killer = GetKillingUnit();
        integer index = 0;
        integer temp_index;
        item orb = null;
        integer charges;
        
        // "index" points to the currently viewed inventory index.
        while ( index <= 5 )
        {
            temp_index = SearchItemIndex(killer, IID_SOUL_ORB, index, 5);
            // Does the unit have any orbs?
            if ( temp_index != -1 )
            {
                orb = UnitItemInSlot(killer, temp_index);
                charges = GetItemCharges(orb);
                // Does the orb contain full charges?
                if ( charges < SoulOrb_GetLimit(killer) )
                {
                    // Possibly add a small sfx here?
                    SetItemCharges(orb, charges + 1);

                    // Exit the loop because a charge was already added,
                    // no need to add charges to next items.
                    break;
                }
                
                // Start checking for orbs from the next slot:
                index = temp_index + 1;
            }
            else
            {
                // Not having orbs breaks the loop:
                break;
            }
        }
        
        killer = null; orb = null;
    }

    function Conditions() -> boolean
    {
        return ( SearchItemIndex(GetKillingUnit(), IID_SOUL_ORB, 0, 5) >= 0 );
    }
    
    function onInit()
    {
        Trig_UnitDeath(function Conditions, function Actions);
    }

}

//! endzinc
Attached Files
File Type: w3x UHS ItemRequest04 v1.w3x (232.3 KB, 1 views)

Last edited by HerrStanev : 03-11-2013 at 04:43 PM.
HerrStanev is offline   Reply With Quote
Old 03-12-2013, 08:21 AM   #13
cohadar
master of fugue
 
cohadar's Avatar
 
Join Date: Jun 2007
Posts: 2,558

Submissions (5)

cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)

Default

Very good.

I noticed things got complicated because of inventory manipulations so I updated Inventory library for you.
Collapse JASS:
//===========================================================================
//  Generic inventory functions.
//  Last update: 2013-03-12
//===========================================================================
library Inventory

//===========================================================================
//  returns first slot of item specified by type id.
//  returns -1 if not found.
//===========================================================================
public function GetFirstSlot takes unit whichUnit, integer typeId returns integer
    local integer i = 0
    loop
        exitwhen i >= 6
        if GetItemTypeId(UnitItemInSlot(whichUnit, i)) == typeId then
            return i
        endif
        set i = i + 1
    endloop
    return -1
endfunction

//===========================================================================
//  returns first slot of item specified by type id, and exact number of charges as specified.
//  returns -1 if not found.
//===========================================================================
public function GetFirstSlotEQ takes unit whichUnit, integer typeId, integer charges returns integer
    local integer i = 0
    loop
        exitwhen i >= 6
        if GetItemTypeId(UnitItemInSlot(whichUnit, i)) == typeId then
            if GetItemCharges(UnitItemInSlot(whichUnit, i)) == charges then
                return i
            endif
        endif
        set i = i + 1
    endloop
    return -1
endfunction

//===========================================================================
//  returns first slot of item specified by type id, and number of charges less than specified.
//  returns -1 if not found.
//===========================================================================
public function GetFirstSlotLT takes unit whichUnit, integer typeId, integer charges returns integer
    local integer i = 0
    loop
        exitwhen i >= 6
        if GetItemTypeId(UnitItemInSlot(whichUnit, i)) == typeId then
            if GetItemCharges(UnitItemInSlot(whichUnit, i)) < charges then
                return i
            endif
        endif
        set i = i + 1
    endloop
    return -1
endfunction

//===========================================================================
//  returns first slot of item specified by type id, and number of charges greater than specified.
//  returns -1 if not found.
//===========================================================================
public function GetFirstSlotGT takes unit whichUnit, integer typeId, integer charges returns integer
    local integer i = 0
    loop
        exitwhen i >= 6
        if GetItemTypeId(UnitItemInSlot(whichUnit, i)) == typeId then
            if GetItemCharges(UnitItemInSlot(whichUnit, i)) > charges then
                return i
            endif
        endif
        set i = i + 1
    endloop
    return -1
endfunction

endlibrary

Notice how much simpler is the SouldOrbKills trigger now:
Collapse Zinc:
//! zinc

library SoulOrbKills requires SoulOrb, Trig 
{

    function Actions()
    {
        unit killer = GetKillingUnit();
        integer index = 0;
        item orb = null;
        integer charges;
        
        index = Inventory_GetFirstSlotLT(killer, IID_SOUL_ORB, SoulOrb_GetLimit(killer));

        // Does the unit have any non-full orbs?
        if ( index != -1 )
        {
            orb = UnitItemInSlot(killer, index);
            charges = GetItemCharges(orb);

            // Possibly add a small sfx here?
            SetItemCharges(orb, charges + 1);
        }

        killer = null; orb = null;
    }

    // orb should collect only souls of heroes. 
    // since we don't have any hero mobs yet, we use archers
    function Conditions() -> boolean
    {
        return GetUnitTypeId(GetTriggerUnit()) == UID_ARCHER;
        //return IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true;
    }
    
    function onInit()
    {
        Trig_UnitDeath(function Conditions, function Actions);
    }

}

//! endzinc
__________________
<nosignature />
cohadar is offline   Reply With Quote
Old 03-12-2013, 03:40 PM   #14
HerrStanev
User
 
HerrStanev's Avatar
 
Join Date: Mar 2013
Posts: 49

HerrStanev has little to show at this moment (8)

Default

I knew I was overcomplicating things. :D
Anything else needs fixes?
HerrStanev is offline   Reply With Quote
Old 03-12-2013, 06:12 PM   #15
cohadar
master of fugue
 
cohadar's Avatar
 
Join Date: Jun 2007
Posts: 2,558

Submissions (5)

cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)cohadar is a jewel in the rough (247)

Default

Well that is what libraries are for, making often used things simple.
This is complete, take a break, you work too much
__________________
<nosignature />
cohadar is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off


All times are GMT. The time now is 12:43 PM.


Donate

Affiliates
The Hubb http://bylur.com - Warcraft, StarCraft, Diablo and DotA Blog & Forums The JASS Vault Clan WEnW Campaign Creations Clan CBS GamesModding Flixreel Videos

Powered by vBulletin (Copyright ©2000 - 2013, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services