- Joined
- Jun 17, 2007
- Messages
- 3,837
Never heard of it. I'll check it out.
We had thought about making him a ranged champion where he just threw balls of paint, but the idea of Mr Gobo smacking people with a giant paint brush sounded more intriguing.
Thats FANTASTIQUE WORK!Trying to find spell names and correct the theme with my team, this is going to be the result if they're ok;
View attachment 287891
View attachment 287889
View attachment 287890
How about a Hero Glow to differ him from other units?The Hero model is done.
![]()
Ok.it isn't shown in that gif. He has a hero glow.
The scourge may be lacking, but it still has the passion for destruction.
Similarly, the team may lack a modeler, but we are one in creating the model.
![]()
![]()
Welp I guess it's my turn to post WIPs.
Our Hero basically has a sub-ability that lets them switch the color of their paint. The color of the paint will decide the mechanic of the primary ability. As you can see below, when they learn the ability, they start off a default color.
![]()
This shouldn't have been the case, but the Switch Paint mechanic took forever to make ._.
SPaint Cast
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to SPaint_ABILITY
Actions
-------- SPaint Cast --------
-------- this trigger will switch the "color mode" for the unit --------
-------- if the unit reaches the end of the color palette, it will moved back to color #1 --------
-------- --------
-------- --------
Set SPaint_TempUnit = (Triggering unit)
Custom script: set udg_SPaint_UnitId = GetHandleId(udg_SPaint_TempUnit)
Set SPaint_CurrentColor = (Load PBomb_KEY_CURRENT_COLOR of SPaint_UnitId from PBomb_Hash)
Unit - Remove SPaint_SFX_ABILITY[SPaint_CurrentColor] from SPaint_TempUnit
Unit - Remove SPaint_SFX_BUFF[SPaint_CurrentColor] buff from SPaint_TempUnit
-------- --------
-------- checking which color the unit will now have --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
SPaint_CurrentColor Not equal to SPaint_TOTAL_COLORS
Then - Actions
-------- unit is not at the end of the color palette; move up one --------
Set SPaint_CurrentColor = (SPaint_CurrentColor + 1)
Else - Actions
-------- unit is at the end of the color palette; move back to the beginning --------
Set SPaint_CurrentColor = 1
-------- --------
Unit - Add SPaint_SFX_ABILITY[SPaint_CurrentColor] to SPaint_TempUnit
-------- --------
Hashtable - Save SPaint_CurrentColor as PBomb_KEY_CURRENT_COLOR of SPaint_UnitId in PBomb_Hash
Thank you, but I only finished the switch xD I haven't started on the primary ability yet. Although, I do already have something in mind that should make it really easy.It would have been difficult to maintain the overall idea in creating such a behaviour (spell mechanic, not the switch) in vJASS alone, even more so in JASS, but you did it in GUI, which is another level altogether.
Out of curiousity, why wouldJust a suggestion, you could use less than as a comparison instead of not equal to just to be safe.
a < b
be safer than a != b
?Total=4
Current_color=5
If Current_color != Total
Current_color++
else
Current_color = 1
Ahh okay. CurrentColor acts as a private member basically. The user would have to physically go into the code to change the current color.I think that somewhere out there, there will be a user who would not understand enough of the spell to change the current colour to something higher than the total.
Literally no interaction happened from your side after any of these ...Would the image above suffice as a WIP on the model?
Now:
I would be showing the second WIP here
@MyPad it's cool you code, but... do you even have a team concept and a modeler? ;s
... nor any attempt or statement to solve the issue anyhow, or to talk with Murloc, or me.Your ignorance is welcome as always.
Literally no interaction happened from your side after any of these ...
... nor any attempt or statement to solve the issue anyhow, or to talk with Murloc, or me.
I don't believe it's valid WIP for model.
Defining only yourself as team is not allowed.
A team is defined by 3 members, respectively responsible for: Model, Icons, Code
OK, so that's a Rule that would generally preclude going *into* a situation like this, that way.
It is what I had done, freely choosing not to discuss with either of you about the modeller problem because I had thought that the problem would be easily resolved, (assuming that a modeller will be available).
we'll let your team enter the contest with the penalty points for not having three members. IcemanBo will announce how many points will be taken in the poll thread.
Nope.The deadline is 30 November 23:59 GMT right? I want to confirm the time left.
What?.. what's the current state or exact lack? Or there's just absolutly nothing?Speaking of lacking teammates, unfortunately our team won't be able to submit anything (lack of communication) thus we're withdrawing from the contest.
Is there an issue with the info from main post? It's clearly stated 30th Dec GMT (day included) ...The deadline is 30 November 23:59 GMT right? I want to confirm the time left.
GUI always and forever.Thank you for using GUI, I was afraid I'm the old guy here![]()
//! externalblock extension=lua ObjectMerger $FILENAME$
//! i ID = "e002"
//! i ATTACK_SPEED = 1.0
//! i MOVE_SPEED = 500
//! i NAME = "Fel Spiderling"
//! i function declare_spider(atkSpeed, mvSpeed, paramName)
//! i setobjecttype("units")
//! i createobject("nspd", ID)
//! i makechange(current, "uico", "ReplaceableTextures\CommandButtons\BTNSpiderBlack.blp")
//! i makechange(current, "umdl", "units\creeps\SpiderBlack\SpiderBlack.mdl")
//! i makechange(current, "usca", 0.4)
//! i makechange(current, "ussc", 0.9)
//! i makechange(current, "ushx", 15)
//! i makechange(current, "ushy", 15)
//! i makechange(current, "ushh", 40)
//! i makechange(current, "ushw", 40)
//! i makechange(current, "ua1t", "chaos")
//! i makechange(current, "ua1c", math.min(math.max(atkSpeed, 0.1), 5.0))
//! i makechange(current, "ua1b", 0)
//! i makechange(current, "ua1s", 1)
//! i makechange(current, "ua1d", 1)
//! i makechange(current, "ua1r", 90)
//! i makechange(current, "umvs", math.min(mvSpeed, 522))
//! i makechange(current, "umas", math.min(mvSpeed, 522))
//! i makechange(current, "umis", math.min(mvSpeed - 1, 100))
//! i makechange(current, "uhpm", 250)
//! i makechange(current, "urac", "undead")
//! i makechange(current, "unam", paramName)
//! i makechange(current, "utip", "Summon " .. paramName)
//! i makechange(current, "utub", "Light melee unit. Deals damage based on attribute. |n|n|cffffcc00Attacks land units.|r")
//! i end
//! i declare_spider(ATTACK_SPEED, MOVE_SPEED, NAME)
//! endexternalblock
library OvermindSpellThree initializer Init requires /*
* ----------------------
*/ AllocationAndLinks, /* https://www.hiveworkshop.com/threads/allocation-and-links.293621/
* ----------------------
*
* - Contains the doubly linked list and custom allocation which is preferred by the coder.
* - If you don't want extends array syntax, just change AllocLinkBundle to DoubleLink
*
* ----------------------
*/ TimerUtils, /* http://www.wc3c.net/showthread.php?t=101322
* ----------------------
*
* - Too lazy to create a timer library that allows attachment of data,
* but not too lazy to completely rewrite it.
*
* ----------------------------
*/ CustomFunctions, /*
* ----------------------------
*
* - Allows a nice not-red debug setting, and allows the instant generation of a search function.
* Technically not useless.
*
* --------------------------------
*/ DamageEvent, DamageModify, /* https://www.hiveworkshop.com/threads/damagepackage.287101/
* --------------------------------
*
* - Allows the manipulation of damage
* - DamageModify is the takeaway here. (Modifies the damage dealt by the spiderlings).
*
* --------------------------------
*/ optional TextTag /* https://www.hiveworkshop.com/threads/library-text-tag.290924/page-2#post-3138916
* --------------------------------
* - Optionally displays the amount restored to the hive creator.
* - Can be used informationally.
*
*/
/*
* __________________________
*
* OvermindSpellThree
* __________________________
*
* ______________
*
* The Hive
* ______________
*
* - A spell based on Pocket Factory that plants a targeted location with a hive mind.
* - This spell is active, and has a sub-spell component, namely Ravage Hive.
*
* __________________
*
* How it goes
* __________________
*
* - The spell is cast, triggering a spell-effect trigger and creating an associated
* struct instance of type Data.
*
* - The Data struct instance then activates a timer, which is set to expire based on
* the speed of the missile created by the ability and the distance therefrom.
*
* - After expiration, the hive is created with a delay in its' timed life. During this
* time, the hive is rendered invulnerable.
*
* - After the delay, the expiration timer for the hive is started. The hive may or may
* not be harmed based on the data flag section.
*
* - If it dies, its' expiration timer expires, or a Ravage Hive sub-spell has taken effect,
* the hive will execute its' death-related event. This may bug out with certain scripts,
* which remove units on death.
*
* ____________
*
* API
* ____________
*
* native functions:
* - UnitAlive(unit id) returns boolean
*
* external functions:
* - external func:
* exe: ObjectMerger.exe
* type: w3u / units
* base id: 'hfoo' / footman
* new id: '!000' / footman derivative.
*
* model: "dummy.mdx"
*
* globals:
* private constant group ENUM_GROUP
* - Enumerator group
* private unit enum_unit
* - Enumerator unit variable.
*
* configurable functions:
* function SPELL_ID() returns integer
* - Returns the raw code of the spell. (See in Object Editor (Ctrl + D))
* function RAW_ID(int i) returns integer
* - Returns some raw code based on request. (Defaults to 0)
* function DATA(int i, int lev) returns real
* - Returns the necessary soft-coded data field. (Defaults to 0)
*
* External scripts:
* - Used mostly for the generation of the spiderling with the added speed properties.
* Can be modified to a certain extent by script.
*
*/
native UnitAlive takes unit id returns boolean
/* The following scripts are external lua scripts which generate the necessary unit data.
* Since I wanted to make this configurable (to a certain extent), the script for declaring
* a spider is given below.
*
* This line of code has been deemed redundant due to the pathing script being removed.
* ___________________________________________________________
*
* ///! external ObjectMerger w3u hfoo "!000" umdl "dummy.mdx"
* ___________________________________________________________
*
* The code below may be commented out by adding a delimited comment.
* Delimited comments look like this:
*
* /*
* Put some stuff here.
* */
*
* To enable the script again, just remove the delimiters.
*
* ___________
*
* API
* ___________
*
* ID = "char"
* - The rawcode of the spider.
*
* ATTACK_SPEED = float r
* - The attack speed defined as a float.
* MOVE_SPEED = float r
* - The movement speed of the spider defined as an integer.
* NAME = string nam
* - The name of the spider. If you like, you can change it.
*
* function declare_spider(real atkSpeed, int mvSpeed, string paramName)
* - Due to the lack of explicit type definition, the type of the parameters have been
* supplied for you.
*
* - Generates a spider with a certain raw id based on the ID variable (string)
* - The only configurable parts are the attack speed, move speed and name
* Even then, the attack speed is capped off at 5.0 and 0.1.
*
* - Will cause the Typecasting library to fail if the external script is not delimited.
*/
/*
//! externalblock extension=lua ObjectMerger $FILENAME$
//! i ID = "e002"
//! i ATTACK_SPEED = 1.0
//! i MOVE_SPEED = 500
//! i NAME = "Fel Spiderling"
//! i function declare_spider(atkSpeed, mvSpeed, paramName)
//! i setobjecttype("units")
//! i createobject("nspd", ID)
//! i makechange(current, "uico", "ReplaceableTextures\\CommandButtons\\BTNSpiderBlack.blp")
//! i makechange(current, "umdl", "units\\creeps\\SpiderBlack\\SpiderBlack.mdl")
//! i makechange(current, "usca", 0.4)
//! i makechange(current, "ussc", 0.9)
//! i makechange(current, "ushx", 15)
//! i makechange(current, "ushy", 15)
//! i makechange(current, "ushh", 40)
//! i makechange(current, "ushw", 40)
//! i makechange(current, "ua1t", "chaos")
//! i makechange(current, "ua1c", math.min(math.max(atkSpeed, 0.1), 5.0))
//! i makechange(current, "ua1b", 0)
//! i makechange(current, "ua1s", 1)
//! i makechange(current, "ua1d", 1)
//! i makechange(current, "ua1r", 90)
//! i makechange(current, "umvs", math.min(mvSpeed, 522))
//! i makechange(current, "umas", math.min(mvSpeed, 522))
//! i makechange(current, "umis", math.min(mvSpeed - 1, 100))
//! i makechange(current, "uhpm", 250)
//! i makechange(current, "urac", "undead")
//! i makechange(current, "unam", paramName)
//! i makechange(current, "utip", "Summon " .. paramName)
//! i makechange(current, "utub", "Light melee unit. Deals damage based on attribute. |n|n|cffffcc00Attacks land units.|r")
//! i end
//! i declare_spider(ATTACK_SPEED, MOVE_SPEED, NAME)
//! endexternalblock
*/
globals
private constant group ENUM_GROUP = CreateGroup()
private unit enum_unit = null
endglobals
private constant function SPELL_ID takes nothing returns integer
return 'A002'
endfunction
private constant function RAW_ID takes integer request returns integer
if request == 0 then
// Returns the ID of the hatchery.
return 'e001'
elseif request == 1 then
// Returns the ID of the fel spiderlings
return 'e002'
elseif request == 2 then
// Returns the ID of the sub-spell
return '1001'
endif
return 0
endfunction
private constant function DATA takes integer request, integer level returns real
if request == 0 then
// Returns the duration of the hive
if level == 1 then
return 50.
elseif level == 2 then
return 75.
elseif level == 3 then
return 100.
endif
elseif request == 1 then
// Returns the effective detection range.
if level == 1 then
return 150.
elseif level == 2 then
return 250.
elseif level == 3 then
return 350.
endif
elseif request == 2 then
// Returns the tick rate.
// Defaults to 1.
return 1.
elseif request == 3 then
// Returns the amount of mana burned around the hive
if level == 1 then
return 5.
elseif level == 2 then
return 7.
elseif level == 3 then
return 10.
endif
elseif request == 4 then
// Returns the amount of health rejuvenated by ratio.
// Only takes effect when used as a nydus canal.
if level == 1 then
return 0.1
elseif level == 2 then
return 0.12
elseif level == 3 then
return 0.16
endif
elseif request == 5 then
// Returns the range field for allowing mana burn
// Defaults to 500.
return 500.
elseif request == 6 then
// Returns the flag for allowing the hive to be invulnerable.
// Defaults to true (not equal to 0.)
return 0.
elseif request == 7 then
// Returns the damage dealt when hive (simulating death or actually dying)
if level == 1 then
return 85.
elseif level == 2 then
return 150.
elseif level == 3 then
return 220.
endif
elseif request == 8 then
// Returns the amount of spiders that will spawn.
if level == 1 then
return 4.
elseif level == 2 then
return 5.
elseif level == 3 then
return 6.
endif
elseif request == 9 then
// Returns the speed of the missile
// Must correspond to the object data equivalent.
return 1000.
elseif request == 10 then
// Returns the frequency of the global timer
// Cannot be configured to the level of the unit
return 1/32.
elseif request == 11 then
// Returns the fade-in total duration.
// Cannot be configured to the level of the unit
return 2.5
elseif request == 12 then
// Returns the duration of the death animation
// Cannot be configured to the level of the unit
return 5.
elseif request == 13 then
// Returns the main attribute to follow
// Higher values will return modulo of 3.
// Strength: 1
// Agility: 2
// Intelligence: 3
return 3.
elseif request == 14 then
// Returns damage dealt based on percentage
if level == 1 then
return 0.1
elseif level == 2 then
return 0.14
elseif level == 3 then
return 0.18
endif
elseif request == 15 then
// Returns the amount of mana rejuvenated by ratio.
// Only takes effect when used as a nydus canal.
if level == 1 then
return 0.12
elseif level == 2 then
return 0.16
elseif level == 3 then
return 0.2
endif
endif
return 0.
endfunction
/* Generated boolean comparison (inlined) */
globals
private constant boolean REG_11_BOOL = 2.5 <= 0.
endglobals
/* The strings which will be used for projecting certain effects and such */
private constant function MDL_FILE takes integer request returns string
if request == 0 then
return "Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl"
elseif request == 1 then
return "Abilities\\Spells\\NightElf\\ManaBurn\\ManaBurnTarget.mdl"
elseif request == 2 then
return "Abilities\\Weapons\\snapMissile\\snapMissile.mdl"
elseif request == 3 then
return "Units\\NightElf\\Wisp\\WispExplode.mdl"
endif
return ""
endfunction
private function real_GetDist takes real x1, real y1, real x2, real y2 returns real
return SquareRoot((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2))
endfunction
private function echo takes string s returns nothing
static if DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 16, s)
endif
endfunction
// Generates a module with the name DoubleLink_local. It has the property of a private module.
// Same with the next textmacro. A private module DoubleLink_active is generated.
//! runtextmacro link_module("local", "private")
//! runtextmacro link_module("active", "private")
private struct Data extends array
implement AllocLinkBundle
implement DoubleLink_local
implement DoubleLink_active
private static constant timer ACTIVE_TIMER = CreateTimer()
private static constant group STORED_SPIDERS = CreateGroup()
// Assistant to the stored spider group
private static integer stored_spider_count = 0
// Counter for a forGroupEx call
private static integer spider_group_count = 0
// Mode checker
private integer mode
private real mode_data
/* Part One
* - This will store the unit, level, timer, target x, and target y for
* the successful creation of the hive. */
private unit unit
private unit hive
private integer level
private timer timer
private real tx
private real ty
// Part Two
/* - This will be the main part of the spell, the mechanics of which will
* be the main focus and intention of this spell. */
// For speed purposes
private static player feedback_player
private static thistype hive_this
private static thistype spider_this
private real stored
private integer eventtype
private unit target
private trigger detector
private group spider_group
/*
These textmacros can be found at CustomFunctions. It's easy to port them to this library, though.
They generate a searching algorithm for finding a certain instance.
If not fully explained, the parameters are defined as follows:
search_list(encapsulation-keyword, name, searched type, iterator variable, conditional statement)
*/
//! runtextmacro search_list("private", "get", "unit", "next", "unit == id")
//! runtextmacro search_list("private", "get_hive", "unit", "active_next", "hive == id")
//! runtextmacro search_list("private", "get_targ", "unit", "active_next", "target == id")
//! runtextmacro search_list("private", "get_trig", "trigger", "active_next", "detector == id")
//! runtextmacro search_list("private", "get_group", "unit", "active_next", "IsUnitInGroup(id, spider_group)")
// Detaches a certain instance from a global list if it is found and in the local list.
// Pushes the next local instance to the global list if there exists at least one more.
private method detach takes nothing returns nothing
if head != 0 then
if local_next != this then
set local_next.head = 1
call local_next.insert(next)
endif
set head = 0
call pop()
endif
call local_pop()
endmethod
/* Mimics death for the spiders */
private static method spider_preDestroy_enum takes nothing returns nothing
set enum_unit = GetEnumUnit()
call PauseUnit(enum_unit, true)
call SetUnitAnimation(enum_unit, "death")
endmethod
private method spider_preDestroy takes nothing returns nothing
call ForGroup(spider_group, function thistype.spider_preDestroy_enum)
set enum_unit = null
endmethod
/* Resets the animation for the next group */
private static method spider_onDestroy_enum takes nothing returns nothing
set enum_unit = GetEnumUnit()
call QueueUnitAnimation(enum_unit, "stand")
call SetUnitX(enum_unit, 0)
call SetUnitY(enum_unit, 0)
call SetUnitOwner(enum_unit, Player(15), true)
call ShowUnit(enum_unit, false)
endmethod
private method spider_onDestroy takes nothing returns nothing
call ForGroup(spider_group, function thistype.spider_onDestroy_enum)
set enum_unit = null
endmethod
/* Check if the hive is still alive. If not, attempt to nullify hive and prepare a new one. */
private method preDestroy takes nothing returns nothing
if not UnitAlive(hive) then
call RemoveUnit(hive)
set hive = null
else
call PauseUnit(hive, true)
call ShowUnit(hive, false)
call SetUnitX(hive, 0)
call SetUnitY(hive, 0)
call SetWidgetLife(hive, GetUnitState(hive, UNIT_STATE_MAX_LIFE))
call SetUnitOwner(hive, Player(15), false)
if not (DATA(6, level) != 0) then
call echo("Unit is vulnerable")
call UnitRemoveAbility(hive, 'Aloc')
debug else
call echo("Unit is invulnerable")
endif
endif
endmethod
private method destroy takes nothing returns nothing
call spider_onDestroy()
call preDestroy()
call ReleaseTimer(timer)
call DestroyTrigger(detector)
set unit = null
set target = null
set timer = null
set detector = null
set tx = 0.
set ty = 0.
set mode_data = 0.
set stored = 0.
set head = 0
set mode = 0
set eventtype = 0
call active_pop()
set active_head = 0
set thistype(0).active_head = thistype(0).active_head - 1
call deallocate()
endmethod
// Part two
private static method target_attack_enum takes nothing returns nothing
local thistype this = spider_this
set enum_unit = GetEnumUnit()
if target != null then
if GetUnitTypeId(target) != 0 or UnitAlive(target) then
call IssueTargetOrder(enum_unit, "attack", target)
else
call IssuePointOrder(enum_unit, "move", GetUnitX(hive) + GetRandomReal(-DATA(1, level), DATA(1, level)), GetUnitY(spider_this.hive) + GetRandomReal(-DATA(1, level), DATA(1, level)))
endif
else
call IssuePointOrder(enum_unit, "move", GetUnitX(hive) + GetRandomReal(-DATA(1, level), DATA(1, level)), GetUnitY(hive) + GetRandomReal(-DATA(1, level), DATA(1, level)))
endif
endmethod
private method target_attack takes nothing returns nothing
set spider_this = this
call ForGroup(spider_group, function thistype.target_attack_enum)
set spider_this = 0
endmethod
private method target_search takes nothing returns nothing
set feedback_player = GetOwningPlayer(hive)
call GroupEnumUnitsInRange(ENUM_GROUP, GetUnitX(hive), GetUnitY(hive), DATA(1, level), null)
call GroupRemoveUnit(ENUM_GROUP, target)
loop
set enum_unit = FirstOfGroup(ENUM_GROUP)
exitwhen enum_unit == null
if UnitAlive(enum_unit) and IsUnitEnemy(enum_unit, feedback_player) and UnitDamageTarget(enum_unit, enum_unit, 0, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null) then
set target = enum_unit
exitwhen true
endif
call GroupRemoveUnit(ENUM_GROUP, enum_unit)
endloop
if enum_unit == null then
set target = null
call echo("No valid target found")
else
call echo("Target was discovered: " + GetUnitName(target))
endif
endmethod
private static method target_onDeathEvent takes nothing returns nothing
local thistype this = get_targ(GetTriggerUnit())
if this != 0 then
call target_search()
call target_attack()
endif
endmethod
private static method hive_onDeathProxy takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
call destroy()
endmethod
private static method hive_onErupt takes nothing returns nothing
local thistype this = hive_this
set hive_this = 0
set feedback_player = GetOwningPlayer(hive)
call GroupEnumUnitsInRange(ENUM_GROUP, GetUnitX(hive), GetUnitY(hive), DATA(5, level), null)
loop
set enum_unit = FirstOfGroup(ENUM_GROUP)
exitwhen enum_unit == null
if UnitAlive(enum_unit) and IsUnitEnemy(enum_unit, feedback_player) then
if UnitDamageTarget(hive, enum_unit, DATA(7, level), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_UNIVERSAL, null) then
call DestroyEffect(AddSpecialEffectTarget(MDL_FILE(1), enum_unit, "chest"))
endif
endif
call GroupRemoveUnit(ENUM_GROUP, enum_unit)
endloop
endmethod
private method hive_onDeath takes nothing returns nothing
call PauseTimer(timer)
call TimerStart(timer, DATA(12, 0), false, function thistype.hive_onDeathProxy)
set mode = 3
if eventtype != 1 then
call SetUnitAnimation(hive, "death")
endif
if local_next == this then
call echo("Last reserved instance!")
call UnitRemoveAbility(unit, RAW_ID(2))
debug else
call echo("Current instance: " + I2S(this))
call echo("Next instance: " + I2S(local_next) + "\n")
call echo("There are some instances left!")
endif
call detach()
set hive_this = this
call ForForce(bj_FORCE_PLAYER[0], function thistype.hive_onErupt)
call spider_preDestroy()
endmethod
private method overmind_onTeleport takes nothing returns nothing
local real rx = GetUnitX(unit)
local real ry = GetUnitX(unit)
local player p = GetOwningPlayer(unit)
if this == 0 then
call echo("thistype.overmind_onTeleport: Invalid instance!")
return
endif
call SetWidgetLife(unit, GetWidgetLife(unit) + stored*DATA(4, level))
call SetUnitState(unit, UNIT_STATE_MANA, GetUnitState(unit, UNIT_STATE_MANA) + stored*DATA(15, level))
static if LIBRARY_TextTag then
call CreateTextTagBJ(p, rx, ry, 75, 0, 255, 255, "+" + I2S(R2I(stored*(DATA(4, level)))) + " health!\n+" + I2S(R2I(stored*(DATA(15, level)))) + " mana!")
set vj_lastCreatedTextTag.duration = 3.0
set vj_lastCreatedTextTag.fade = 2.25
endif
// For boolean consistency
set eventtype = 3
if not (DATA(6, level) != 0) then
call echo("Removing timed life buffs")
call UnitRemoveBuffsEx(hive, true, true, false, false, true, false, false)
endif
call DestroyEffect(AddSpecialEffect(MDL_FILE(3), rx, ry))
call DestroyEffect(AddSpecialEffect(MDL_FILE(0), rx, ry))
call SetUnitX(unit, GetUnitX(hive))
call SetUnitY(unit, GetUnitX(hive))
// Unimportant to deallocate players (hear-say)
endmethod
private static method hive_onDeathEvent takes nothing returns nothing
local thistype this = get_hive(GetTriggerUnit())
if this != 0 then
if eventtype == 0 then
set eventtype = 1
endif
call hive_onDeath()
endif
endmethod
private static method hive_onFeedback_loop takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
set mode_data = mode_data - DATA(2, level)
if mode_data > 0. then
call target_attack()
set feedback_player = GetOwningPlayer(hive)
call GroupEnumUnitsInRange(ENUM_GROUP, GetUnitX(hive), GetUnitY(hive), DATA(5, level), null)
loop
set enum_unit = FirstOfGroup(ENUM_GROUP)
exitwhen enum_unit == null
if UnitAlive(enum_unit) and IsUnitEnemy(enum_unit, feedback_player) then
if GetUnitState(enum_unit, UNIT_STATE_MAX_MANA) != 0 then
call DestroyEffect(AddSpecialEffectTarget(MDL_FILE(1), enum_unit, "chest"))
call SetUnitState(enum_unit, UNIT_STATE_MANA, GetUnitState(enum_unit, UNIT_STATE_MANA) - DATA(3, level))
call UnitDamageTarget(hive, enum_unit, DATA(3, level), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null)
set stored = stored + DATA(3, level)
endif
endif
call GroupRemoveUnit(ENUM_GROUP, enum_unit)
endloop
else
set eventtype = 2
call hive_onDeath()
endif
endmethod
private static method hive_onDetectEnemy takes nothing returns nothing
local thistype this = get_trig(GetTriggeringTrigger())
if IsUnitEnemy(GetTriggerUnit(), GetOwningPlayer(hive)) then
if target == null then
set target = GetTriggerUnit()
call target_attack()
endif
endif
endmethod
private static method spider_forGroupEx_enum takes nothing returns nothing
local thistype this = spider_this
set enum_unit = GetEnumUnit()
set spider_group_count = spider_group_count + 1
call SetUnitOwner(enum_unit, feedback_player, true)
call SetUnitPosition(enum_unit, tx, ty)
call SetUnitFacing(enum_unit, GetRandomReal(0, 360))
call PauseUnit(enum_unit, false)
call ShowUnit(enum_unit, true)
call UnitRemoveAbility(enum_unit, 'Aloc')
call UnitAddAbility(enum_unit, 'Aloc')
endmethod
private method spider_forGroupEx takes nothing returns integer
set spider_this = this
set spider_group_count = 0
call ForGroup(spider_group, function thistype.spider_forGroupEx_enum)
set enum_unit = null
return spider_group_count
endmethod
private method hive_spider_init takes nothing returns nothing
local integer int = R2I(DATA(8, level))
set feedback_player = GetOwningPlayer(unit)
if spider_group == null then
set spider_group = CreateGroup()
endif
set int = int - spider_forGroupEx()
if int < 0 then
loop
set enum_unit = FirstOfGroup(spider_group)
exitwhen int >= 0
call SetUnitOwner(enum_unit, Player(15), true)
call SetUnitX(enum_unit, 0)
call SetUnitY(enum_unit, 0)
call PauseUnit(enum_unit, true)
call ShowUnit(enum_unit, false)
call UnitRemoveAbility(enum_unit, 'Aloc')
call UnitAddAbility(enum_unit, 'Aloc')
call GroupRemoveUnit(spider_group, enum_unit)
call GroupAddUnit(STORED_SPIDERS, enum_unit)
set stored_spider_count = stored_spider_count + 1
set int = int + 1
endloop
else
// We check if there are any free spiders in the group.
loop
set enum_unit = FirstOfGroup(STORED_SPIDERS)
exitwhen enum_unit == null or int <= 0 or stored_spider_count <= 0
call SetUnitOwner(enum_unit, feedback_player, true)
call SetUnitPosition(enum_unit, tx, ty)
call SetUnitFacing(enum_unit, GetRandomReal(0, 360))
call PauseUnit(enum_unit, false)
call ShowUnit(enum_unit, true)
call UnitRemoveAbility(enum_unit, 'Aloc')
call UnitAddAbility(enum_unit, 'Aloc')
call GroupRemoveUnit(STORED_SPIDERS, enum_unit)
call GroupAddUnit(spider_group, enum_unit)
set stored_spider_count = stored_spider_count - 1
set int = int - 1
endloop
// If there are none, proceed to the next loop
loop
exitwhen int <= 0
set bj_lastCreatedUnit = CreateUnit(feedback_player, RAW_ID(1), tx, ty, GetRandomReal(0, 360))
call SetUnitAcquireRange(bj_lastCreatedUnit, DATA(1, level))
call UnitAddAbility(bj_lastCreatedUnit, 'Aloc')
call Damage.add(bj_lastCreatedUnit)
call GroupAddUnit(spider_group, bj_lastCreatedUnit)
set int = int - 1
endloop
endif
call echo("Number of spiders: " + I2S(CountUnitsInGroup(spider_group)))
endmethod
private method hive_addDetection takes nothing returns nothing
set detector = CreateTrigger()
call TriggerRegisterUnitInRange(detector, hive, DATA(1, level), null)
call TriggerAddCondition(detector, function thistype.hive_onDetectEnemy)
endmethod
private method hive_addFeedback takes nothing returns nothing
if not (DATA(6, level) != 0) then
call SetUnitInvulnerable(hive, false)
call UnitApplyTimedLife(hive, 'BTLF', mode_data)
call UnitPauseTimedLife(hive, false)
endif
call hive_addDetection()
call hive_spider_init()
call TimerStart(timer, DATA(2, level), true, function thistype.hive_onFeedback_loop)
endmethod
private static method hive_runList takes nothing returns nothing
local thistype this = thistype(0).active_next
if thistype(0).active_head == 0 then
call PauseTimer(ACTIVE_TIMER)
return
endif
loop
exitwhen this == 0
if mode == 1 then
call DestroyEffect(AddSpecialEffect(MDL_FILE(0), GetUnitX(hive), GetUnitY(hive)))
static if REG_11_BOOL then
call SetUnitVertexColor(hive, 255, 255, 255, 255)
set mode = 2
call hive_addFeedback()
else
set mode_data = mode_data + (255)*DATA(10, 0)/DATA(11, 0)
if mode_data >= 255 then
call SetUnitVertexColor(hive, 255, 255, 255, 255)
set mode = 2
set mode_data = DATA(0, level)
call hive_addFeedback()
else
call SetUnitVertexColor(hive, 255, 255, 255, R2I(mode_data))
endif
endif
endif
set this = active_next
endloop
endmethod
private static method hive_spider_onDamage takes nothing returns nothing
local thistype this = get_group(Damage.source)
local real mode = ModuloReal(mode, 3.)
if mode == 0 then
set mode = 3
endif
if this != 0 then
if mode == 1 then
set Damage.amount = DATA(14, level)*GetHeroStr(unit, true)
elseif mode == 2 then
set Damage.amount = DATA(14, level)*GetHeroAgi(unit, true)
elseif mode == 3 then
set Damage.amount = DATA(14, level)*GetHeroInt(unit, true)
endif
endif
endmethod
// Part one
private static method hive_bufferAdd takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
call UnitAddAbility(hive, 'Aloc')
call ReleaseTimer(GetExpiredTimer())
endmethod
private method hive_create takes nothing returns nothing
if hive == null then
set hive = CreateUnit(GetOwningPlayer(unit), RAW_ID(0), tx, ty, 0)
set mode = 1
call SetUnitVertexColor(hive, 255, 255, 255, 0)
if DATA(6, level) != 0 then
call TimerStart(NewTimerEx(this), 0., false, function thistype.hive_bufferAdd)
else
call SetUnitInvulnerable(hive, true)
endif
else
call SetUnitAnimation(hive, "stand")
call QueueUnitAnimation(hive, "stand")
call SetUnitInvulnerable(hive, false)
call SetUnitOwner(hive, GetOwningPlayer(unit), true)
call SetUnitPosition(hive, tx, ty)
call PauseUnit(hive, false)
call ShowUnit(hive, true)
if DATA(6, level) != 0 then
call UnitRemoveAbility(hive, 'Aloc')
call UnitAddAbility(hive, 'Aloc')
endif
set mode = 1
call SetUnitVertexColor(hive, 255, 255, 255, 0)
endif
if GetLocalPlayer() == GetOwningPlayer(unit) then
call SelectUnit(hive, true)
call SelectUnit(hive, false)
endif
call active_push()
set active_head = 1
if thistype(0).active_head == 0 then
call TimerStart(ACTIVE_TIMER, DATA(10, 0), true, function thistype.hive_runList)
endif
set thistype(0).active_head = thistype(0).active_head + 1
endmethod
private static method prepare_hive_flag takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
call hive_create()
endmethod
private method prepare_hive takes nothing returns nothing
set timer = NewTimerEx(this)
call TimerStart(timer, real_GetDist(GetUnitX(unit), GetUnitY(unit), GetSpellTargetX(), GetSpellTargetY())/DATA(9, 0), false, function thistype.prepare_hive_flag)
endmethod
static method create takes unit u returns thistype
local thistype this = get(u)
local thistype that
if this == 0 then
set this = allocate()
set unit = u
set level = GetUnitAbilityLevel(u, SPELL_ID())
set head = 1
call UnitAddAbility(u, RAW_ID(2))
call UnitMakeAbilityPermanent(u, true, RAW_ID(2))
call push()
call local_insert(this)
set tx = GetSpellTargetX()
set ty = GetSpellTargetY()
call prepare_hive()
return this
endif
set that = allocate()
set that.unit = unit
set that.level = GetUnitAbilityLevel(unit, SPELL_ID())
call that.local_insert(this)
set that.tx = GetSpellTargetX()
set that.ty = GetSpellTargetY()
call UnitAddAbility(u, RAW_ID(2))
call UnitMakeAbilityPermanent(u, true, RAW_ID(2))
call that.prepare_hive()
return that
endmethod
static method teleport takes unit u, real x, real y returns nothing
local thistype this = get(u)
local thistype head = this
local thistype nearest = head
if this == 0 then
call echo("thistype.teleport: Instance of unit does not exist.")
call echo("thistype.teleport: Returning")
return
endif
set this = local_next
loop
exitwhen this == head
if (real_GetDist(x, y, GetUnitX(hive), GetUnitY(hive)) <= real_GetDist(x, y, GetUnitX(nearest.hive), GetUnitY(nearest.hive))) and mode == 2 then
set nearest = this
endif
set this = local_next
endloop
if nearest.mode != 2 then
call DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, "|cffffcc00The hives are not available.|r")
else
call nearest.overmind_onTeleport()
endif
endmethod
// Init method
public static method init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(t, function thistype.hive_onDeathEvent)
call TriggerAddCondition(t, function thistype.target_onDeathEvent)
set t = CreateTrigger()
call Damage.registerModifierTrigger(t)
call TriggerAddCondition(t, function thistype.hive_spider_onDamage)
// Located at part two
set t = null
endmethod
endstruct
private function OnSpellEvent takes nothing returns nothing
if GetSpellAbilityId() == SPELL_ID() then
call Data.create(GetTriggerUnit())
elseif GetSpellAbilityId() == RAW_ID(2) then
call Data.teleport(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY())
endif
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, function OnSpellEvent)
call ForForce(bj_FORCE_PLAYER[0], function Data.init)
set t = null
endfunction
endlibrary
As far as I know, entries whether written in GUI, JASS, vJASS or Wurst are all judged equally and does not affect the scoring so I think Cokemonkey will give you a fair review.Side note: @Cokemonkey11 is going to hate me after this contest. Give me a fair review and I promise to consider Wurst next year!
This way it is unequivocal which day, date, month & year are being talked about, and most importantly both the time frame & the time zone. (if we use/assume midnight (generally considered the 'end of the day' but technically the beginning of the next), people might assume the 31st is part of it. Or move back from 12 & be a minute late, etc).Saturday, December 30th, 2017, @ 11:59:59PM (GMT 0)
For the record, I didn't start on my entry until the 16th of December because I had school, so I had a lot less time. With that in mind, I agree with the extension. I start school again on the 2nd, but the extra few days will allow me to debug and review my code more thoroughly.say Tuesday, January 2nd, 2018 @ 11:59:59PM (GMT 0) or somesuch