- Joined
- Oct 12, 2011
- Messages
- 3,449
I have put so much effort in this shity systems named Creep Behavior System it has been uploaded at spell section (linky) but I'm not satisfied with feedbacks I got there (because I got almost nothing) that's why I uploaded it here.
Here's is the shit (oh I love this word)
I need you guys to find any bugs/mistake there (I also attached the map).
I'm so motivated to make this system decent enough for 5/5 or even 6/5 (my mission in hive is making at least one DC-ed shit)
Please, gimme your feedbacks also don't troll in the poll, also give valid argument why you vote for? thnks!
Here's is the shit (oh I love this word)
JASS:
// ******************************************************************************************************//
// ------------------------------------Creep Behavior System v1.6----------------------------------------//
// by: Dalvengyr a.k.a ..... //
// //
// This system gives special behavior to creep units. Makes your RPG has so much more lifes. This //
// system gives some brains to those shrimp-head creeps. They can flee, they have sight radius (which //
// you can sneak behind them, how cool!), they are able to help each other, they become aggressive and //
// not aggressive as well. And many other advantages you get by using this system. Even you are able //
// mix some characteristics for each single creep. //
// //
// Requirements: //
// - GetClosestWidget by Spinnaker //
// //
// Optionals: //
// - Any DDS //
// //
// Disadvantages: //
// - Needs 2 player slots //
// - You have to evade glithces where creep (Priest in demo map) cast supportive spells on players //
// by setting the target of spell only for players unit. Check heal ability at OE for example //
// - Not friendly for GUI users. Sorry.. //
// //
// Implementation: //
// 1. Copy paste CBS folder into your map //
// 2. Give two player slots for passive and aggresive player, better just leave'em as empty slot //
// 3. Configure the system //
// 4. Done. //
// //
// Closing Words: //
// Please, report any mistake, bug, word mispelling, inefficiency, anything bad about this system //
// at the main thread. Thnks a lot. Enjoy... //
// //
// ******************************************************************************************************//
// ******************************************************************************************************//
// //
// ----------------------------------------CONFIGURATION-------------------------------------------------//
// //
// 1. CBS_PassivePlayer returns player number of player that owns any non-aggressive units or any units //
// that is not in combat mode. Note that giving global sight radius for both player is better //
constant function CBS_PassivePlayer takes nothing returns integer
return 10 // Remember! Player 1 = Player(0) so the value must be "0"
endfunction
// //
// 2. CBS_AggressivePlayer returns player number of player that owns any aggressive units or any //
// units that is in combat mode. //
constant function CBS_AggressivePlayer takes nothing returns integer
return 11 // Same as above
endfunction
// //
// 3. Return true if you want to use Passive Player's color as creep's team color. Return false if you //
// want to use Aggressive Player's color. //
constant function CBS_ColorBool takes nothing returns boolean
return true
endfunction
// //
// 4. CBS_Accuracy returns how often the looping action triggered. Smaller value will result in smoother //
// performance, but you will take more disadvantages if you have many creeps. So I don't recommend you //
// to set the value too low //
constant function CBS_Accuracy takes nothing returns real
return 0.03125 // Recommended: around 0.1~0.5 for a huge RPG
// Note: This high accuracy started to cause lag if there are more than ~110 units at the same time
// But, lately I discovered this high accuracy will improve the performance a lot
// Be wise in setting the accuracy
endfunction
//
// You need a simple JASS knowledge for this part, where you could configure the event of attacked creep //
// This part could be useful if you want to change the event from Unit is Attacked (default) to any //
// damage event using any DDS. //
function CBS_Event takes trigger t returns nothing
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
// Example in using DDS:
//
// call TriggerRegisterVariableEvent(t, "udg_DamageEventTrigger", EQUAL, 1.00)
//
// But then you need to change local unit u at CBS_OnHit function below from GetTriggerUnit() to
// udg_DmgEventTarget. And remember to only use one event!
endfunction
// //
// Now let's personalize your library. Follow the instructions below to help you understand how to //
// configure it correctly. //
function CBS_InitLibrary takes nothing returns nothing
// ===============
// - THE LIBRARY -
// ===============
// Registering unit type id and their indexes.
// call SaveInteger(udg_CBS_Hash, 1911, *UnitType Id*, *Index*)
call SaveInteger(udg_CBS_Hash, 1911, 'hfoo', 1) // Footman
call SaveInteger(udg_CBS_Hash, 1911, 'hrif', 2) // Rifleman
call SaveInteger(udg_CBS_Hash, 1911, 'hmpr', 3) // Priest
call SaveInteger(udg_CBS_Hash, 1911, 'hkni', 4) // Knight
call SaveInteger(udg_CBS_Hash, 1911, 'hspt', 5) // Spell Breaker
// True if that creep is tamed. Tamed is creep that is harmless to player (will never attack)
// call SaveInteger(udg_CBS_Hash, 2343, *Index*, *Flag Boolean*)
call SaveBoolean(udg_CBS_Hash, 2343, 1, false)
call SaveBoolean(udg_CBS_Hash, 2343, 2, false)
call SaveBoolean(udg_CBS_Hash, 2343, 3, true) // Priest is tamed. Will never attacks player
call SaveBoolean(udg_CBS_Hash, 2343, 4, false)
call SaveBoolean(udg_CBS_Hash, 2343, 5, false)
// True if you want the creep to reset combat mode timer when attacking any unit
// Note that this timer will only reset when creeps are nearby their nest or if they are attacked
// call SaveInteger(udg_CBS_Hash, 2934, *Index*, *Flag Boolean*)
call SaveBoolean(udg_CBS_Hash, 2934, 1, true)
call SaveBoolean(udg_CBS_Hash, 2934, 2, true)
call SaveBoolean(udg_CBS_Hash, 2934, 3, false)
call SaveBoolean(udg_CBS_Hash, 2934, 4, false)
call SaveBoolean(udg_CBS_Hash, 2934, 5, true)
// If true, the creep will run away to his nest when low health
// call SaveInteger(udg_CBS_Hash, 5885, *Index*, *Flag Boolean*)
call SaveBoolean(udg_CBS_Hash, 5885, 1, true)
call SaveBoolean(udg_CBS_Hash, 5885, 2, false)
call SaveBoolean(udg_CBS_Hash, 5885, 3, false)
call SaveBoolean(udg_CBS_Hash, 5885, 4, true)
call SaveBoolean(udg_CBS_Hash, 5885, 5, false)
// If true, the creep will run to nearby helper, if there is no one he will run to nest instead
// The creep must be able to call at least one helper (configure it below) to make this work
// call SaveInteger(udg_CBS_Hash, 6111, *Index*, *Flag Boolean*)
call SaveBoolean(udg_CBS_Hash, 6111, 1, true)
call SaveBoolean(udg_CBS_Hash, 6111, 4, false) // Because knight can't call for help
// Note: Remember that any creep that is in combat mode wont accept any help calls
// Set the low bound to be considered as low health
// call SaveInteger(udg_CBS_Hash, 6543, *Index*, *lowHealth bound*)
call SaveReal(udg_CBS_Hash, 6543, 1, 100.0)
call SaveReal(udg_CBS_Hash, 6543, 4, 175.0)
// Set the max range for the creep to seek for help when low health
// call SaveInteger(udg_CBS_Hash, 1919, *Index*, *radius*)
call SaveReal(udg_CBS_Hash, 1919, 1, 1200.0)
call SaveReal(udg_CBS_Hash, 1919, 4, 2000.0)
// Now set the acquistion range
// Acquistion range is maximum range for unit to acquire a target
// This is custom acquistion range so it will not change the default acquistion at OE
// And will not affects unit's attack range
// call SaveReal(udg_CBS_Hash, 4441, *Index*, *Acquistion Range*)
call SaveReal(udg_CBS_Hash, 4441, 1, 600.0) // Footman is aggressive, so let's set the acquistion range
call SaveReal(udg_CBS_Hash, 4441, 2, 0.0)
call SaveReal(udg_CBS_Hash, 4441, 3, 0.0)
call SaveReal(udg_CBS_Hash, 4441, 4, 0.0)
call SaveReal(udg_CBS_Hash, 4441, 5, 400.0) // This dude too
// Set the attack delay. Only for units with acquistion range (aka aggressive)
// In this duration, creeps will only staring at their threats
// But if their threats remain close to them, they will attack that threat
// If not they will just move away
// And they are not acquiring another target in this duration
// call SaveReal(udg_CBS_Hash, 3377, *Index*, *Attack Delay*)
call SaveReal(udg_CBS_Hash, 3377, 1, 5.0) // 5 seconds attack delay for Footman
call SaveReal(udg_CBS_Hash, 3377, 5, 0.0) // No delay for Spell Breaker
//
// Note: Creep will targets the closest unit
// Set the sight radius (in degree) for each creep. Only for units with acquistion range
// call SaveReal(udg_CBS_Hash, 5511, *Index*, *degreeRadius*)
call SaveReal(udg_CBS_Hash, 5511, 1, 180.0) // I recommend 160.0s~180.0s is a normal sight radius
call SaveReal(udg_CBS_Hash, 5511, 5, 90.0) // This dude is a little blind @.@
// Set the max of allies that will be called to help the attacked creep
// This is also known as max total of help
// call SaveInteger(udg_CBS_Hash, 1002, *Index*, *TotalCalled*)
call SaveInteger(udg_CBS_Hash, 1002, 1, 1)
call SaveInteger(udg_CBS_Hash, 1002, 2, 5) // Rifleman will calls 5 allies to help him when attacked
call SaveInteger(udg_CBS_Hash, 1002, 3, 2)
call SaveInteger(udg_CBS_Hash, 1002, 4, 0)
call SaveInteger(udg_CBS_Hash, 1002, 5, 0)
// If true, the creep will also calls for help when attacking
// call SaveInteger(udg_CBS_Hash, 7651, *Index*, *Flag Boolean*)
call SaveBoolean(udg_CBS_Hash, 7651, 1, true)
call SaveBoolean(udg_CBS_Hash, 7651, 2, false)
call SaveBoolean(udg_CBS_Hash, 7651, 3, false)
call SaveBoolean(udg_CBS_Hash, 7651, 4, true)
call SaveBoolean(udg_CBS_Hash, 7651, 5, false)
// Set max range to the unit to call for help from allies
// call SaveReal(udg_CBS_Hash, 6000, *Index*, *Help AoE*)
call SaveReal(udg_CBS_Hash, 6000, 1, 500.0)
call SaveReal(udg_CBS_Hash, 6000, 2, 1000.0) // Rifleman will calls allies within 1000.0 range
call SaveReal(udg_CBS_Hash, 6000, 3, 500.0)
call SaveReal(udg_CBS_Hash, 6000, 4, 0.0)
call SaveReal(udg_CBS_Hash, 6000, 5, 0.0)
// Set the helper type. <1 = will not help. 1 = only help same unit. >1 = help anything
// call SaveInteger(udg_CBS_Hash, 7550, *Index*, *Help Type*)
call SaveInteger(udg_CBS_Hash, 7550, 1, 0) // Won't help anybody
call SaveInteger(udg_CBS_Hash, 7550, 2, 1) // Rifleman only helps Rifleman
call SaveInteger(udg_CBS_Hash, 7550, 3, 0)
call SaveInteger(udg_CBS_Hash, 7550, 4, 2) // Knight will help Rifleman in this demo map
call SaveInteger(udg_CBS_Hash, 7550, 5, 0)
// Combat duration: how long the unit will stay at combat mode. In second.
// 0.0 for everlasting combat mode. No need to set for tamed.
// call SaveReal(udg_CBS_Hash, 6399, *Index*, *Combat Duration*)
call SaveReal(udg_CBS_Hash, 6399, 1, 20.0) // Footman will calm down after 20.0 seconds
call SaveReal(udg_CBS_Hash, 6399, 2, 15.0)
call SaveReal(udg_CBS_Hash, 6399, 4, 10.0)
call SaveReal(udg_CBS_Hash, 6399, 5, 5.0)
// Set to true if you want the unit to wander every certain seconds.
// call SaveBoolean(udg_CBS_Hash, 7112, *Index*, *Flag Boolean*)
call SaveBoolean(udg_CBS_Hash, 7112, 1, true)
call SaveBoolean(udg_CBS_Hash, 7112, 2, false)
call SaveBoolean(udg_CBS_Hash, 7112, 3, false)
call SaveBoolean(udg_CBS_Hash, 7112, 4, true)
call SaveBoolean(udg_CBS_Hash, 7112, 5, true)
// Set how often the unit will wander. In second.
// call SaveReal(udg_CBS_Hash, 9999, *Index*, *Wander Delay*)
call SaveReal(udg_CBS_Hash, 9999, 1, 12.0)
call SaveReal(udg_CBS_Hash, 9999, 4, 15.0)
call SaveReal(udg_CBS_Hash, 9999, 5, 7.5)
// Set the variants of wander delay. Don't set this greater than the wander delay
// This variants will make wander delay randomized. Use 0.0 for constant delay
// call SaveReal(udg_CBS_Hash, 1915, *Index*, *Wander Variants*)
call SaveReal(udg_CBS_Hash, 1915, 1, 7.0)
call SaveReal(udg_CBS_Hash, 1915, 4, 12.0)
call SaveReal(udg_CBS_Hash, 1915, 5, 4.0)
// Set min wander distance
// call SaveReal(udg_CBS_Hash, 8330, *Index*, *Min Wander Distance*)
call SaveReal(udg_CBS_Hash, 8330, 1, 200.0)
call SaveReal(udg_CBS_Hash, 8330, 2, 200.0)
call SaveReal(udg_CBS_Hash, 8330, 3, 0.0)
call SaveReal(udg_CBS_Hash, 8330, 4, 200.0)
call SaveReal(udg_CBS_Hash, 8330, 5, 0.0)
// Set nest area a.k.a max wander distance
// call SaveReal(udg_CBS_Hash, 8331, *Index*, *Nest Area*)
call SaveReal(udg_CBS_Hash, 8331, 1, 500.0)
call SaveReal(udg_CBS_Hash, 8331, 2, 500.0)
call SaveReal(udg_CBS_Hash, 8331, 3, 900.0)
call SaveReal(udg_CBS_Hash, 8331, 4, 1000.0)
call SaveReal(udg_CBS_Hash, 8331, 5, 200.0)
// Set the flee distance/radius from nest
// call SaveReal(udg_CBS_Hash, 6789, *Index*, *Flee Distance*)
call SaveReal(udg_CBS_Hash, 6789, 1, 0.0)
call SaveReal(udg_CBS_Hash, 6789, 2, 0.0)
call SaveReal(udg_CBS_Hash, 6789, 3, 200.0)
call SaveReal(udg_CBS_Hash, 6789, 4, 50.0)
call SaveReal(udg_CBS_Hash, 6789, 5, 0.0)
endfunction
//
// - END OF LIBRARY -
// //
// Now configure the filtration of units that you wont affects with this system. This part requires a //
// basic knowledge about JASS. What you need is to return false if you want a certain unit type is //
// filtered out //
function CBS_Filter takes unit u returns boolean
// Example:
//
// if IsUnitType(u, whichType) then
// return false
// endif
//
// That unit type will be filtered out (will not affected by this system)
if IsUnitType(u, UNIT_TYPE_HERO) then
return false
endif
if IsUnitType(u, UNIT_TYPE_STRUCTURE) then
return false
endif
// ===================================
// ======Don't thouch this part=======
// ===================================
if IsUnitInGroup(u, udg_CBS_Group) then
return false
endif
// ===================================
call GroupAddUnit(udg_CBS_Group, u)
return not IsUnitType(u, UNIT_TYPE_DEAD)
endfunction
// =====================================================================//
// //
// ----------------------------------------END OF CONFIGURATION------------------------------------------//
// //
// ******************************************************************************************************//
// ******************************************************************************************************//
function DistanceBetweenCoords takes real x,real y,real xt,real yt returns real
local real dx = xt - x
local real dy = yt - y
return SquareRoot(dx * dx + dy * dy)
endfunction
function AngleBetweenCoords takes real x, real y, real xt, real yt returns real
local real angle = Atan2((yt - y), (xt - x)) * bj_RADTODEG
if angle > 360 then
loop
set angle = angle - 360
exitwhen (angle <= 360)
endloop
elseif angle < 0 then
loop
set angle = angle + 360
exitwhen angle >= 0
endloop
endif
return angle
endfunction
function CBS_Filter2 takes nothing returns boolean
local unit u = GetFilterUnit()
local unit c = LoadUnitHandle(udg_CBS_Hash, 0, 0)
local real a1
local real a2
local real rad
local integer dex
local player pa = Player(CBS_PassivePlayer())
local player ag = Player(CBS_AggressivePlayer())
local player p = GetOwningPlayer(u)
set dex = LoadInteger(udg_CBS_Hash, 1911, GetUnitTypeId(c))
set a1 = GetUnitFacing(c) + 360.0
set a2 = AngleBetweenCoords(GetUnitX(c),GetUnitY(c),GetUnitX(u),GetUnitY(u)) + 360.0
// Load sight radius
set rad = LoadReal(udg_CBS_Hash, 5511, dex) * 0.5
// Filter out target not in sight radius
if (a2 <= a1 - rad or a2 >= a1 + rad) and (a2 <= a1 - rad - 360.0 or a2 >= a1 + rad - 360.0) then
return false
endif
if p == pa or p == ag then
return false
endif
return IsUnitVisible(u, pa) and IsUnitVisible(u, ag) and not IsUnitType(u, UNIT_TYPE_DEAD)
endfunction
function CBS_HelpFilter takes nothing returns boolean
local unit u = GetFilterUnit()
local integer ut = GetUnitTypeId(u)
local integer dex = LoadInteger(udg_CBS_Hash, 1911, ut)
local integer ht = LoadInteger(udg_CBS_Hash, 7550, dex)
if ht == 1 then
if ut != udg_CBS_DuTy then
return false
endif
else
if ht < 1 then
return false
endif
endif
return GetOwningPlayer(u) == Player(CBS_PassivePlayer()) and not LoadBoolean(udg_CBS_Hash, 2343, dex)
endfunction
function CBS_Pick takes nothing returns nothing
local unit u = GetEnumUnit()
local unit t
local integer hand
local integer dex
local real delay
local real var
local real wdx
local real angle
local real x1
local real x2
local real y1
local real y2
local player pa
// If the creep is available
if GetUnitTypeId(u) != 0 then
set hand = GetHandleId(u)
// Get creep's index in hashtable
set dex = LoadInteger(udg_CBS_Hash, 1911, GetUnitTypeId(u))
// If still alive
if GetWidgetLife(u) > .405 then
set pa = Player(CBS_PassivePlayer())
// Wander if only not in combat mode
if GetOwningPlayer(u) == pa then
// If the creep is not threated then go on
if LoadReal(udg_CBS_Hash, hand, 5) < 0.0 then
// Check if wandering or not
if LoadBoolean(udg_CBS_Hash, 7112, dex) then
// Load the wander delay
set delay = LoadReal(udg_CBS_Hash, hand, 1) - CBS_Accuracy()
// Wander
if delay <= 0.0 then
// Set wander distance (randomized)
set wdx = GetRandomReal(LoadReal(udg_CBS_Hash, 8330, dex), LoadReal(udg_CBS_Hash, 8331, dex))
// Variants of delay
set var = LoadReal(udg_CBS_Hash, 1915, dex) * 0.5
// Set the next delay
set delay = LoadReal(udg_CBS_Hash, 9999, dex) + GetRandomReal(-1.0*var, var)
set angle = GetRandomReal(0.0, 359.9) * bj_DEGTORAD
call IssuePointOrder(u, "move", LoadReal(udg_CBS_Hash, hand, 2) + wdx * Cos(angle), LoadReal(udg_CBS_Hash, hand, 3) + wdx * Sin(angle))
endif
call SaveReal(udg_CBS_Hash, hand, 1, delay)
endif
// If the creep is aggressive
if LoadReal(udg_CBS_Hash, 4441, dex) > 0.0 and DistanceBetweenCoords(GetUnitX(u), GetUnitY(u), LoadReal(udg_CBS_Hash, hand, 2), LoadReal(udg_CBS_Hash, hand, 3)) <= LoadReal(udg_CBS_Hash, 8331, dex) then
call SaveUnitHandle(udg_CBS_Hash, 0, 0, u)
// Get closest target around him
set t = GetClosestUnitInRange(GetUnitX(u), GetUnitY(u), LoadReal(udg_CBS_Hash, 4441, dex), Condition(function CBS_Filter2))
// If there is any threat
if t != null then
// Save the threat/target
call SaveUnitHandle(udg_CBS_Hash, hand, 6, t)
// Save the attack delay
call SaveReal(udg_CBS_Hash, hand, 5, LoadReal(udg_CBS_Hash, 3377, dex))
call IssueImmediateOrder(u, "stop")
set t = null
endif
endif
// When the creep has threat
else
// Load the target/threat
set t = LoadUnitHandle(udg_CBS_Hash, hand, 6)
set x1 = GetUnitX(u)
set y1 = GetUnitY(u)
set x2 = GetUnitX(t)
set y2 = GetUnitY(t)
// Order to stare at target
call SetUnitFacing(u, AngleBetweenCoords(x1, y1, x2, y2))
// Check if the target stay close
if DistanceBetweenCoords(x1, y1, x2, y2) <= LoadReal(udg_CBS_Hash, 4441, dex) then
// Load attack delay
set delay = LoadReal(udg_CBS_Hash, hand, 5) - CBS_Accuracy()
// Attack!
if delay < 0.0 then
if CBS_ColorBool() then
call SetUnitOwner(u, Player(CBS_AggressivePlayer()), false)
else
call SetUnitOwner(u, Player(CBS_AggressivePlayer()), true)
endif
call SaveReal(udg_CBS_Hash, hand, 4, LoadReal(udg_CBS_Hash, 6399, dex))
call IssueTargetOrder(u, "attack", t)
endif
call SaveReal(udg_CBS_Hash, hand, 5, delay)
else
// Reset attack delay timer
call SaveReal(udg_CBS_Hash, hand, 5, -1.0)
endif
set t = null
endif
// If in combat mode
else
// Load combat duration
set delay = LoadReal(udg_CBS_Hash, hand, 4)
// If not everlasting combat duration
if delay > 0.0 then
set delay = delay - CBS_Accuracy()
// Evade critical bug (everlasting combat duration where it's not supposed to)
if delay == 0.0 then
set delay = -1.0
endif
endif
// Calm down if the combat timer is up
if delay < 0.0 then
if CBS_ColorBool() then
call SetUnitOwner(u, pa, true)
else
call SetUnitOwner(u, pa, false)
endif
// Reset total help
call SaveInteger(udg_CBS_Hash, hand, 6, 0)
// Order to move away
set wdx = GetRandomReal(0.0, LoadReal(udg_CBS_Hash, 8331, dex))
set angle = GetRandomReal(0.0, 359.9) * bj_DEGTORAD
call IssuePointOrder(u, "move", LoadReal(udg_CBS_Hash, hand, 2) + wdx * Cos(angle), LoadReal(udg_CBS_Hash, hand, 3) + wdx * Sin(angle))
endif
call SaveReal(udg_CBS_Hash, hand, 4, delay)
endif
// If dead then reset everything
else
// Get wander variants
set var = LoadReal(udg_CBS_Hash, 1915, dex) * 0.5
// Get wander delay
set delay = LoadReal(udg_CBS_Hash, 9999, dex) + GetRandomReal(-1.0*var, var)
// Reset wander delay
call SaveReal(udg_CBS_Hash, hand, 1, delay)
// Reset combat duration
call SaveReal(udg_CBS_Hash, hand, 5, -1.0)
// Reset total help
call SaveInteger(udg_CBS_Hash, hand, 6, 0)
endif
// Kick out from the list if the creep has been removed from game
else
call GroupRemoveUnit(udg_CBS_Group, u)
set udg_CBS_Total = udg_CBS_Total - 1
if udg_CBS_Total == 0 then
call PauseTimer(udg_CBS_Timer)
endif
endif
set u = null
endfunction
function CBS_Loop takes nothing returns nothing
call ForGroup(udg_CBS_Group, function CBS_Pick)
endfunction
function CBS_OnHit takes nothing returns boolean
local unit u = GetTriggerUnit()
local unit a = GetAttacker()
local unit h
local integer hand
local integer dex
local integer i
local integer ix
local integer ht
local real wdx
local real angle
local real x
local real x2
local real y
local real y2
local player pa = Player(CBS_PassivePlayer())
if GetOwningPlayer(a) == Player(CBS_AggressivePlayer()) then
set hand = GetHandleId(a)
// Get creep's index in hashtable
set dex = LoadInteger(udg_CBS_Hash, 1911, GetUnitTypeId(a))
// If reset
if LoadBoolean(udg_CBS_Hash, 2934, dex) then
// Reset the combat timer when the creep attacks anything nearby his nest
if DistanceBetweenCoords(GetUnitX(a), GetUnitY(a), LoadReal(udg_CBS_Hash, hand, 2), LoadReal(udg_CBS_Hash, hand, 3)) <= LoadReal(udg_CBS_Hash, 8331, dex) then
// Reset combat timer
call SaveReal(udg_CBS_Hash, hand, 4, LoadReal(udg_CBS_Hash, 6399, dex))
endif
endif
// If call for help when attacking
if LoadBoolean(udg_CBS_Hash, 7651, dex) then
// Load help total
set ht = LoadInteger(udg_CBS_Hash, hand, 6)
set i = 0
// Set desired amount of helps
set ix = LoadInteger(udg_CBS_Hash, 1002, dex)
// Save attacked creep's type in global
set udg_CBS_DuTy = GetUnitTypeId(a)
loop
// Continue the loop ala total help hasn't reach the max
if ht < ix then
// Look for closest helper around
set h = GetClosestUnitInRange(GetUnitX(a),GetUnitY(a),LoadReal(udg_CBS_Hash, 6000, dex),Condition(function CBS_HelpFilter))
// If there is no helper
if h == null then
set i = ix
// If there is helper
else
set i = i + 1
// Set total helper
set ht = ht + 1
// Helper enters combat mode
if CBS_ColorBool() then
call SetUnitOwner(h, Player(CBS_AggressivePlayer()), false)
else
call SetUnitOwner(h, Player(CBS_AggressivePlayer()), true)
endif
// Save helper's combat duration
call SaveReal(udg_CBS_Hash, GetHandleId(h), 4, LoadReal(udg_CBS_Hash, 6399, LoadInteger(udg_CBS_Hash, 1911, GetUnitTypeId(h))))
call IssueTargetOrder(h, "attack", u)
set h = null
endif
// If total helper has reached the max
else
set i = ix
endif
exitwhen i == ix
endloop
// Save total helper
call SaveInteger(udg_CBS_Hash, hand, 6, ht)
endif
else
set hand = GetHandleId(u)
// Get creep's index in hashtable
set dex = LoadInteger(udg_CBS_Hash, 1911, GetUnitTypeId(u))
// Reset the combat duration if the creep is attacked
call SaveReal(udg_CBS_Hash, hand, 4, LoadReal(udg_CBS_Hash, 6399, dex))
// If has flee distance more than 0.0 then order to run away
if LoadReal(udg_CBS_Hash, 6789, dex) > 0.0 then
set x = GetUnitX(u)
set y = GetUnitY(u)
set x2 = LoadReal(udg_CBS_Hash, hand, 2)
set y2 = LoadReal(udg_CBS_Hash, hand, 3)
set wdx = LoadReal(udg_CBS_Hash, 6789, dex)
if DistanceBetweenCoords( x, y, x2, y2) < LoadReal(udg_CBS_Hash, 8331, dex) then
set angle = AngleBetweenCoords(GetUnitX(a), GetUnitY(a), x, y)*bj_DEGTORAD
// Run further away from attacker if still around nest
call IssuePointOrder(u, "move", x + wdx * Cos(angle), y + wdx * Sin(angle))
else
// Run back to nest area if too far from nest
set angle = GetRandomReal(0.0, 359.9)*bj_DEGTORAD
call IssuePointOrder(u, "move", x2 + wdx * Cos(angle), y2 + wdx * Sin(angle))
endif
endif
// If not in combat mode
if GetOwningPlayer(u) == pa then
// If not tamed
if not LoadBoolean(udg_CBS_Hash, 2343, dex) then
if CBS_ColorBool() then
call SetUnitOwner(u, Player(CBS_AggressivePlayer()), false)
else
call SetUnitOwner(u, Player(CBS_AggressivePlayer()), true)
endif
endif
// Set desired amount of helps
set ix = LoadInteger(udg_CBS_Hash, 1002, dex)
// If unit is able to call for helps
if ix > 0 then
set i = 0
set ht = LoadInteger(udg_CBS_Hash, hand, 6)
// Save attacked creep's type in global
set udg_CBS_DuTy = GetUnitTypeId(u)
loop
// Continue the loop ala total help hasn't reach the max
if ht < ix then
// Look for closest helper around
set h = GetClosestUnitInRange(GetUnitX(u),GetUnitY(u),LoadReal(udg_CBS_Hash, 6000, dex),Condition(function CBS_HelpFilter))
// If there is no helper
if h == null then
set i = ix
// If there is helper
else
set i = i + 1
// Set total helper
set ht = ht + 1
// Helper enters combat mode
if CBS_ColorBool() then
call SetUnitOwner(h, Player(CBS_AggressivePlayer()), false)
else
call SetUnitOwner(h, Player(CBS_AggressivePlayer()), true)
endif
// Save helper's combat duration
call SaveReal(udg_CBS_Hash, GetHandleId(h), 4, LoadReal(udg_CBS_Hash, 6399, LoadInteger(udg_CBS_Hash, 1911, GetUnitTypeId(h))))
call IssueTargetOrder(h, "attack", a)
set h = null
endif
// If total helper has reached the max
else
set i = ix
endif
exitwhen i == ix
endloop
// Save total helper
call SaveInteger(udg_CBS_Hash, hand, 6, ht)
endif
endif
// If run away when low health
if LoadBoolean(udg_CBS_Hash, 5885, dex) then
// If low health
if GetWidgetLife(u) <= LoadReal(udg_CBS_Hash, 6543, dex) then
// If seek for help first
if LoadBoolean(udg_CBS_Hash, 6111, dex) then
// If able to call help
if LoadInteger(udg_CBS_Hash, 1002, dex) > 0 then
set udg_CBS_DuTy = GetUnitTypeId(u)
// Seek helper
set h = GetClosestUnitInRange(GetUnitX(u),GetUnitY(u),LoadReal(udg_CBS_Hash, 1919, dex),Condition(function CBS_HelpFilter))
// Order to move to helper's position
if h != null then
call IssuePointOrder(u, "move", GetUnitX(h), GetUnitY(h))
set h = null
// If there is no helper order to move to nest
else
call IssuePointOrder(u, "move", LoadReal(udg_CBS_Hash, hand, 2), LoadReal(udg_CBS_Hash, hand, 3))
endif
// If unable then order to run to nest
else
call IssuePointOrder(u, "move", LoadReal(udg_CBS_Hash, hand, 2), LoadReal(udg_CBS_Hash, hand, 3))
endif
// If directly run onto nest
else
call IssuePointOrder(u, "move", LoadReal(udg_CBS_Hash, hand, 2), LoadReal(udg_CBS_Hash, hand, 3))
endif
endif
endif
endif
set u = null
set a = null
return false
endfunction
function CBS_InitUnit takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer hand
local integer dex
local real delay
local real var
local player p = GetOwningPlayer(u)
local player pa = Player(CBS_PassivePlayer())
local player ag = Player(CBS_AggressivePlayer())
if p == pa or p == ag then
if p == ag then
call SetUnitOwner(u, pa, false)
if CBS_ColorBool() then
call SetUnitColor(u, GetPlayerColor(pa))
endif
else
if not CBS_ColorBool() then
call SetUnitColor(u, GetPlayerColor(ag))
endif
endif
if CBS_Filter(u) then
set hand = GetHandleId(u)
// Get Index
set dex = LoadInteger(udg_CBS_Hash, 1911, GetUnitTypeId(u))
// Get wander variants
set var = LoadReal(udg_CBS_Hash, 1915, dex) * 0.5
// Get wander delay
set delay = LoadReal(udg_CBS_Hash, 9999, dex) + GetRandomReal(-1.0*var, var)
// Save wander delay(1)
call SaveReal(udg_CBS_Hash, hand, 1, delay)
// Save init x(2)
call SaveReal(udg_CBS_Hash, hand, 2, GetUnitX(u))
// Save init y(3)
call SaveReal(udg_CBS_Hash, hand, 3, GetUnitY(u))
// 4 is reserved for combat timer
// Save combat duration(5)
call SaveReal(udg_CBS_Hash, hand, 5, -1.0)
// Save total help(6)
call SaveInteger(udg_CBS_Hash, hand, 6, 0)
set udg_CBS_Total = udg_CBS_Total + 1
if udg_CBS_Total == 1 then
call TimerStart(udg_CBS_Timer, CBS_Accuracy(), true, function CBS_Loop)
endif
endif
endif
set u = null
endfunction
function CBS_InitPick takes nothing returns nothing
local unit u = GetEnumUnit()
local integer hand
local integer dex
local real delay
local real var
local player p = GetOwningPlayer(u)
local player pa = Player(CBS_PassivePlayer())
local player ag = Player(CBS_AggressivePlayer())
if p == pa or p == ag then
if p == ag then
call SetUnitOwner(u, pa, false)
if CBS_ColorBool() then
call SetUnitColor(u, GetPlayerColor(pa))
endif
else
if not CBS_ColorBool() then
call SetUnitColor(u, GetPlayerColor(ag))
endif
endif
if CBS_Filter(u) then
set hand = GetHandleId(u)
// Get Index
set dex = LoadInteger(udg_CBS_Hash, 1911, GetUnitTypeId(u))
// Get wander variants
set var = LoadReal(udg_CBS_Hash, 1915, dex) * 0.5
// Get wander delay
set delay = LoadReal(udg_CBS_Hash, 9999, dex) + GetRandomReal(-1.0*var, var)
// Save wander delay(1)
call SaveReal(udg_CBS_Hash, hand, 1, delay)
// Save init x(2)
call SaveReal(udg_CBS_Hash, hand, 2, GetUnitX(u))
// Save init y(3)
call SaveReal(udg_CBS_Hash, hand, 3, GetUnitY(u))
// 4 is reserved for combat timer
// Save combat duration(5)
call SaveReal(udg_CBS_Hash, hand, 5, -1.0)
// Save total help(6)
call SaveInteger(udg_CBS_Hash, hand, 6, 0)
set udg_CBS_Total = udg_CBS_Total + 1
if udg_CBS_Total == 1 then
call TimerStart(udg_CBS_Timer, CBS_Accuracy(), true, function CBS_Loop)
endif
endif
endif
set u = null
endfunction
function CBS_Alliance takes nothing returns nothing
local player p = GetEnumPlayer()
local player pa = Player(CBS_PassivePlayer())
local player ag
if p != pa then
set ag = Player(CBS_AggressivePlayer())
if p != ag then
// Aggressive player threats others as enemies
call SetPlayerAllianceStateBJ(ag, p, bj_ALLIANCE_UNALLIED)
// Passive player threats other players as allies
call SetPlayerAllianceStateBJ(pa, p, bj_ALLIANCE_ALLIED)
endif
endif
endfunction
function InitTrig_CBS_default takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
local player pa = Player(CBS_PassivePlayer())
local player ag = Player(CBS_AggressivePlayer())
local group g = CreateGroup()
set udg_CBS_Hash = InitHashtable()
call CBS_InitLibrary()
call GroupEnumUnitsInRect(g, GetWorldBounds(), null)
call ForGroup(g, function CBS_InitPick)
call TriggerRegisterEnterRectSimple(t, GetWorldBounds())
call CBS_Event(t2)
call TriggerAddAction(t, function CBS_InitUnit)
call TriggerAddCondition(t2, Condition(function CBS_OnHit))
// Make both passive and aggressive player allied
call SetPlayerAllianceStateBJ(ag, pa, bj_ALLIANCE_ALLIED_VISION)
call SetPlayerAllianceStateBJ(pa, ag, bj_ALLIANCE_ALLIED_VISION)
// Alliance setting
call ForForce(bj_FORCE_ALL_PLAYERS, function CBS_Alliance)
// Destroy leak
call DestroyGroup(g)
set g = null
endfunction
I need you guys to find any bugs/mistake there (I also attached the map).
I'm so motivated to make this system decent enough for 5/5 or even 6/5 (my mission in hive is making at least one DC-ed shit)
AFAIK and IMO this system is:
- Very original, something new in Hive
- Could magicaly enhance theperformancequality of any RPG game
- Well coded
- Very easy to implement and configure
- All the written disadvantages there are not really a disadvantage because you can evade them easily
- You can make so many possibilities using this system
the only one con is:
- a very little not GUI friendly because you need very basic jass knowledge about filtering, just that
Please, gimme your feedbacks also don't troll in the poll, also give valid argument why you vote for? thnks!