| 06-01-2010, 04:17 AM | #1 |
- Without Gamecache or Hashtable(I mean... the HT that supplied by WE). - Affect your target and damage it periodically. 10 damage every 3 seconds, lasts 15 seconds. - One unit can only attach one such spell on one target. That means, the former damaging timer will be destroyed or restarted when you cast this spell on a target who is still affected by this spell. -Example: - Casters: A, B, C. Targets: a, b, c. - Case 1: A casts this spell on a, then casts this spell on b after 1 second. - Result: a and b are damaged by A every 3 seconds respectively. - Case 2-1: A casts this spell on a. After 2 seconds casts it on b. - Result: On 3 seconds, a si damaged. On 5 seconds, b is damaged - Case 2-2: A casts this spell on a again on 4 seconds. - Result: On 8 seconds, b is damaged(the second damage). On 7 seconds, a is damaged(the first damage) - Note: I am a Chinese and my English is not that good, so I try me best to make you clear. Forgive my poor expression. |
| 06-01-2010, 06:16 AM | #2 |
Why do you need it to be triggered? You could very easily do this in the ability editor - Shadow Strike comes to mind. |
| 06-01-2010, 06:38 AM | #3 | |
Quote:
The damage is uncertain, and I have many other effects during the damages. This is only an instance. |
| 06-01-2010, 08:32 AM | #4 |
What systems does your map have? e.g. a buff system, damage system, timer system, unit indexing system? |
| 06-03-2010, 04:01 AM | #5 | |
Aha, what is a buff system, damage sys....? I'm not advanced and still learning. Simply design a struct for me, please. PUI is now being using, other helpful libraries are also available, just tell me. Many thanks. Quote:
|
| 06-03-2010, 06:02 AM | #6 |
JASS:scope SomeSpell initializer Init globals private constant integer ABILITY_ID = 'A000' private constant real DAMAGE = 25. private constant real DURATION = 15. private constant real TIMEOUT = 3. private trigger Trigger = CreateTrigger() private SomeStruct array Instances endglobals struct SomeStruct unit caster unit target real damage real elapsed timer timer static method PeriodicDamage takes nothing returns nothing local SomeStruct this = GetTimerData(GetExpiredTimer()) set .elapsed = .elapsed + TIMEOUT call UnitDamageTarget(.caster, .target, .damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null) if .elapsed >= DURATION or GetWidgetLife(.target) < 0.405 then call .destroy() endif endmethod static method create takes unit caster, unit target, real damage returns SomeStruct local SomeStruct this = SomeStruct.allocate() set .caster = caster set .target = target set .damage = damage set .elapsed = 0. set .timer = NewTimer() call SetTimerData(.timer, this) call TimerStart(.timer, TIMEOUT, true, function SomeStruct.PeriodicDamage) return this endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.timer) set Instances[GetUnitIndex(.target)] = 0 set .caster = null set .target = null set .timer = null endmethod endstruct private function Conditions takes nothing returns boolean return GetSpellAbilityId() == ABILITY_ID endfunction private function Actions takes nothing returns nothing local unit c = GetTriggerUnit() local unit t = GetSpellTargetUnit() local integer id = GetUnitIndex(t) local real damage = DAMAGE if Instances[id] != 0 then call Instances[id].destroy() endif set Instances[id] = SomeStruct.create(c, t, damage) set c = null set t = null endfunction //=========================================================================== private function Init takes nothing returns nothing call TriggerRegisterAnyUnitEventBJ(Trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(Trigger, Condition(function Conditions)) call TriggerAddAction(Trigger, function Actions) endfunction endscope Requires TimerUtils, which you can find in the script section here. |
| 06-03-2010, 10:17 AM | #7 |
So, use a Thistype array to store instances and GetUnitIndex(unit u) act as the unique key. I greatly appreciate it! Using a global array of specified struct to store the instances is quite a nice idea. Got that. |
| 06-04-2010, 04:18 AM | #8 |
One more question. Why must the struct not be private? I found that if I make the struct be private, I cound not destroy its instance out of it. But all the functions are included in the same scope. The Pjass told me that Inst[index] is not a bla bla bla that allows destroy, things like this. |
| 06-04-2010, 06:04 AM | #9 |
Because the struct type is declared after the global block. If you want it to be private, just add a private keyword SomeStruct above the global block. |
| 06-05-2010, 12:42 PM | #10 |
Question comes again :) I'm always using ABC instead of TimerUtils, because I need to attach structs to triggers sometimes. And question comes here: private method onDestroy takes nothing returns nothing ... DestroyTimer(.t); ClearTimerStructA(.t); ... endmethod All the structs' onDestroy method are like this in my map. I found that sometimes ABC warned me of the collision. So, in fact, I did not Clear the Struct that attached to a timer after the timer is destroyed? |
| 06-06-2010, 11:00 AM | #11 |
I'm not familuar with ABC but TimerUtils allows you to attach a struct (see how I did it in the code I gave you) to a timer, as well as recycling timers. As for your error, you're destroying the timer before you clear the struct from it, swap the DestroyTimer and ClearTimerStructA around. Although I'd recommend switching to TimerUtils simply because recycling is better than constantly Creating/Destroying. |
| 06-06-2010, 12:24 PM | #12 |
I've already swap DestroyTimer and ClearStruct this morning(ur...GMT+8..). The collision still happened, but no problem happened after TimerUtils is used later. Since I've started to learn Vjass, I used to use TimerUtils, later on I found that I need to attach structs on Triggers, so I got to know ABC(By: Cohadar), which also allows attach structs on Timers. OK, thank you for telling me so many points these days. By the way, one more question... :P how to use the JassHighlighter in wc3c? |
| 06-06-2010, 12:29 PM | #13 |
You can use TimerUtils to attach structs.. Again, look at the code I gave you JASS:scope SomeSpell initializer Init globals private constant integer ABILITY_ID = 'A000' private constant real DAMAGE = 25. private constant real DURATION = 15. private constant real TIMEOUT = 3. private trigger Trigger = CreateTrigger() private SomeStruct array Instances endglobals struct SomeStruct unit caster unit target real damage real elapsed timer timer static method PeriodicDamage takes nothing returns nothing local SomeStruct this = GetTimerData(GetExpiredTimer()) set .elapsed = .elapsed + TIMEOUT call UnitDamageTarget(.caster, .target, .damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null) if .elapsed >= DURATION or GetWidgetLife(.target) < 0.405 then call .destroy() endif endmethod static method create takes unit caster, unit target, real damage returns SomeStruct local SomeStruct this = SomeStruct.allocate() set .caster = caster set .target = target set .damage = damage set .elapsed = 0. set .timer = NewTimer() call SetTimerData(.timer, this) call TimerStart(.timer, TIMEOUT, true, function SomeStruct.PeriodicDamage) return this endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.timer) set Instances[GetUnitIndex(.target)] = 0 set .caster = null set .target = null set .timer = null endmethod endstruct private function Conditions takes nothing returns boolean return GetSpellAbilityId() == ABILITY_ID endfunction private function Actions takes nothing returns nothing local unit c = GetTriggerUnit() local unit t = GetSpellTargetUnit() local integer id = GetUnitIndex(t) local real damage = DAMAGE if Instances[id] != 0 then call Instances[id].destroy() endif set Instances[id] = SomeStruct.create(c, t, damage) set c = null set t = null endfunction //=========================================================================== private function Init takes nothing returns nothing call TriggerRegisterAnyUnitEventBJ(Trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(Trigger, Condition(function Conditions)) call TriggerAddAction(Trigger, function Actions) endfunction endscope What do you mean using JassHighligher in wc3c? |
| 06-06-2010, 12:35 PM | #14 | |
Quote:
Yes, I'm now using TimerUtils. No problem happened. //========================== I mean, some codes that surrounded by the box..Sorry about my expression.. test: JASS:scope Test initializer Init{ pirvate void Init() debug BJDebugMsg("Hello world!"); } |
| 06-06-2010, 02:43 PM | #15 |
Use zinc tags for zing code :p |
