|
|
#1 |
|
master of fugue
Join Date: Jun 2007
Posts: 2,558
![]() ![]() ![]() ![]()
|
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. Last edited by cohadar : 03-06-2013 at 02:10 PM. |
|
|
|
| Sponsored Links - Login to hide this ad! |
|
|
|
|
#2 |
|
User
Join Date: Mar 2013
Posts: 49
|
What happens if there are multiple orbs? When one gets full the others start filling consecutively?
|
|
|
|
|
|
#3 |
|
master of fugue
Join Date: Jun 2007
Posts: 2,558
![]() ![]() ![]() ![]()
|
Yes, and you always fill the one that has the lowest slot index first.
__________________ |
|
|
|
|
|
#4 |
|
User
Join Date: Mar 2013
Posts: 49
|
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... |
|
|
|
|
|
#5 |
|
default string
|
Spells cast via items still trigger SPELL_EFFECT so just use that event and you can use GetSpellTargetUnit().
|
|
|
|
|
|
#6 |
|
master of fugue
Join Date: Jun 2007
Posts: 2,558
![]() ![]() ![]() ![]()
|
You can use % wildcards to find functions in editor: get%target%
__________________Last edited by cohadar : 03-11-2013 at 12:31 AM. |
|
|
|
|
|
#7 | |
|
User
Join Date: Mar 2013
Posts: 49
|
Quote:
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. |
|
|
|
|
|
|
#8 |
|
default string
|
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. |
|
|
|
|
|
#9 |
|
Procrastination Incarnate
Development Director
|
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).
__________________ |
|
|
|
|
|
#10 |
|
User
Join Date: Mar 2013
Posts: 49
|
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. |
|
|
|
|
|
#11 | |
|
master of fugue
Join Date: Jun 2007
Posts: 2,558
![]() ![]() ![]() ![]()
|
Quote:
Last edited by cohadar : 03-11-2013 at 04:28 PM. |
|
|
|
|
|
|
#12 |
|
User
Join Date: Mar 2013
Posts: 49
|
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. 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 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 Last edited by HerrStanev : 03-11-2013 at 04:43 PM. |
|
|
|
|
|
#13 |
|
master of fugue
Join Date: Jun 2007
Posts: 2,558
![]() ![]() ![]() ![]()
|
Very good.
__________________I noticed things got complicated because of inventory manipulations so I updated Inventory library for you. 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: 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 |
|
|
|
|
|
#14 |
|
User
Join Date: Mar 2013
Posts: 49
|
I knew I was overcomplicating things. :D
Anything else needs fixes? |
|
|
|
|
|
#15 |
|
master of fugue
Join Date: Jun 2007
Posts: 2,558
![]() ![]() ![]() ![]()
|
Well that is what libraries are for, making often used things simple.
__________________This is complete, take a break, you work too much ![]() |
|
|
|
![]() |
| Thread Tools | Search this Thread |
|
|
|
Donate |