- Joined
- Jul 10, 2007
- Messages
- 6,306
update will be able to display hero level and will be able to use unit levels rather than point values
Update Specs
Safe Max Hero Level: 10000
Good Max Unit Level: 100000
Be able to add from .01% to 100% xp.
End Update Specs
Go Here
This script is also currently 100% untested (haven't even run it yet).
Anyways, with all of the masses of bugs concerning hero level/xp, I decided that it was better to just go 100% custom.
I called this library Hero Bounty since it handles all hero rewards-
hero xp
hero gold bounty
hero lumber bounty
hero ability leveling
It can also handle which units share kills with a unit
Right now its behavior is set up so that only heroes get bounty. If a player has multiple heroes, then that player gets bounty multiple times. If the player doesn't have a hero, then that player can't get bounty (since only heroes receive bounty). I'm not sure whether this is a desired behavior in an RTS or not =). It could be good as it would put more stress on the importance of heroes (heroes representing the player, not the units) This is more set up for non RTS maps. Even then, if a player kills a unit with like a pet and their hero is across the map, that player won't get bounty.
Update Specs
Safe Max Hero Level: 10000
Good Max Unit Level: 100000
Be able to add from .01% to 100% xp.
End Update Specs
Go Here
This script is also currently 100% untested (haven't even run it yet).
Anyways, with all of the masses of bugs concerning hero level/xp, I decided that it was better to just go 100% custom.
I called this library Hero Bounty since it handles all hero rewards-
hero xp
hero gold bounty
hero lumber bounty
hero ability leveling
It can also handle which units share kills with a unit
Right now its behavior is set up so that only heroes get bounty. If a player has multiple heroes, then that player gets bounty multiple times. If the player doesn't have a hero, then that player can't get bounty (since only heroes receive bounty). I'm not sure whether this is a desired behavior in an RTS or not =). It could be good as it would put more stress on the importance of heroes (heroes representing the player, not the units) This is more set up for non RTS maps. Even then, if a player kills a unit with like a pet and their hero is across the map, that player won't get bounty.
JASS:
library HeroBounty /* v1.0.0.0
*************************************************************************************
*
* Benefits:
*
* - Bugless levels and xp up to any* level
* - More control of how heroes recieve xp and bounty
* - More control over ability leveling requirements
*
* Cons:
*
* - Can't display hero level normally (hero will always be level 1)
* - Have to use custom functions to add/remove xp and levels
* - Have to use custom functions for ability level requirements
*
* Requirements:
*
* - Ensure all hero level gameplay constants are set to default
* - A non hero level must be represented by point value in object editor
*
*************************************************************************************
*
* */ uses /*
*
* */ UnitIndexer /* hiveworkshop.com/forums/jass-functions-413/unit-indexer-172090/
* */ UnitList /* hiveworkshop.com/forums/jass-functions-413/snippet-unit-list-191657/
* */ Bounty /* hiveworkshop.com/forums/submissions-414/snippet-bounty-196926/
*
************************************************************************************
*
* Run when unit is expected to recieve xp, gold, or lumber
*
* This function can't call anything within the library. It is meant to handle things like
* stat growths and ability point allocation.
*
* unit whichUnit
* integer bountyGold
* integer bountyLumber
* integer killedLevel
* integer partySize
* integer averagePartyLevel
* integer maxPartyLevel
* real distance
*
***********************************************************************************/
//! textmacro SETTINGS
private function GiveBounty takes unit whichUnit, integer bountyGold, integer bountyLumber, integer killedLevel, integer partySize, integer averagePartyLevel, integer maxPartyLevel, real distance returns nothing
endfunction
//! endtextmacro
/***********************************************************************************
*
* Run when unit has leveled
*
* unit whichUnit
* integer prevLevel
* integer newLevel
*
***********************************************************************************/
//! textmacro SETTINGS_2
private function OnLevel takes unit whichUnit, integer prevLevel, integer newLevel returns nothing
endfunction
//! endtextmacro
/***********************************************************************************
*
* Run when unit levels abilities. Used to prevent units from upping abilities
* that require too high a level.
*
* unit whichUnit
* integer whichAbility
* integer abilityLevel
*
***********************************************************************************/
//! textmacro SETTINGS_3
private function OnLevelAbility takes unit whichUnit, integer whichAbility, integer abilityLevel returns nothing
endfunction
//! endtextmacro
/***********************************************************************************
*
* Returns whether unit should be in party or not (share kill)
*
* unit whichUnit
* unit originUnit
* unit killedUnit
*
***********************************************************************************/
//! textmacro SETTINGS_4
private function IsUnitInParty takes unit whichUnit, unit originUnit, unit killedUnit, real distance returns boolean
return GetPlayerAlliance(GetOwningPlayer(whichUnit),GetOwningPlayer(originUnit),ALLIANCE_SHARED_XP) and /*
*/distance<2500 and /*
*/IsUnitAlly(whichUnit,GetOwningPlayer(originUnit))
endfunction
//! endtextmacro
/***********************************************************************************
*
* Functions
*
* function GetLevel takes unit whichUnit returns integer
* function SetLevel takes unit whichUnit, integer level, boolean showEyeCandy returns nothing
* function AddLevel takes unit whichUnit, integer levelsToAdd, boolean showEyeCandy returns nothing
*
* function AddXP takes unit whichUnit, integer xp, boolean showEyeCandy returns nothing
* function AddPercentXP takes unit whichUnit, real percent, boolean showEyeCandy returns nothing
*
* function GetRequiredToLevelXP takes unit whichUnit returns integer
* function GetRequiredToLevelPercentXP takes unit whichUnit returns real
*
* function GetLevelXP takes unit whichUnit returns integer
* function GetLevelPercentXP takes unit whichUnit returns real
*
************************************************************************************/
//! runtextmacro SETTINGS_2()
globals
private integer array levels
private unit lastUnit = null
private timer reset
endglobals
function GetLevel takes unit whichUnit returns integer
return levels[GetUnitUserData(whichUnit)]
endfunction
function SetLevel takes unit whichUnit, integer level, boolean showEyeCandy returns nothing
local integer i = GetUnitUserData(whichUnit)
local integer prev = levels[i]
if (level!=prev) then
call SuspendHeroXP(whichUnit,false)
if (level>levels[i] and showEyeCandy) then
call SetHeroLevel(whichUnit,2,true)
call UnitStripHeroLevel(whichUnit,1)
else
set levels[i]=level
endif
call AddHeroXP(whichUnit,-200,false)
if (0>levels[i]) then
set levels[i]=1
endif
call SuspendHeroXP(whichUnit,true)
call OnLevel(whichUnit,prev,level)
endif
endfunction
function AddLevel takes unit whichUnit, integer levelsToAdd, boolean showEyeCandy returns nothing
call SetLevel(whichUnit,levels[GetUnitUserData(whichUnit)]+levelsToAdd,showEyeCandy)
endfunction
function AddXP takes unit whichUnit, integer xp, boolean showEyeCandy returns nothing
local integer i=GetUnitUserData(whichUnit)
local integer prev = levels[i]
call SuspendHeroXP(whichUnit,false)
set xp=xp+GetHeroXP(whichUnit)
set levels[i]=levels[i]+xp/200
if (0>levels[i]) then
set levels[i]=1
endif
if (0<xp and showEyeCandy) then
call SetHeroLevel(whichUnit,2,true)
call UnitStripHeroLevel(whichUnit,1)
endif
call SetHeroXP(whichUnit,xp-xp/200*200,false)
call SuspendHeroXP(whichUnit,true)
if (levels[i]!=prev) then
call OnLevel(whichUnit,prev,levels[i])
endif
endfunction
function AddPercentXP takes unit whichUnit, real percent, boolean showEyeCandy returns nothing
call AddXP(whichUnit,R2I(percent*2),showEyeCandy)
endfunction
function GetRequiredToLevelXP takes unit whichUnit returns integer
return 200-GetHeroXP(whichUnit)
endfunction
function GetRequiredToLevelPercentXP takes unit whichUnit returns real
return .5*GetRequiredToLevelXP(whichUnit)
endfunction
function GetLevelXP takes unit whichUnit returns integer
return GetHeroXP(whichUnit)
endfunction
function GetLevelPercentXP takes unit whichUnit returns real
return .5*GetHeroXP(whichUnit)
endfunction
//! runtextmacro SETTINGS()
//! runtextmacro SETTINGS_3()
//! runtextmacro SETTINGS_4()
private function Reset takes nothing returns nothing
set lastUnit = null
endfunction
private function HandleReward takes nothing returns boolean
local UnitList n
local unit t = GetTriggerUnit()
local unit u = GetKillingUnit()
local player p = GetOwningPlayer(u)
local integer array us
local real array ud
local integer c = 0
local integer max = 0
local integer avg = 0
local integer l
local real x
local real y
local real x2
local real y2
local integer gold
local integer lumber
local integer klevel
local integer s
if (null!=u and t!=lastUnit and IsUnitEnemy(t,p)) then
set klevel=GetUnitPointValue(t)
set lastUnit=t
call TimerStart(reset,0,false,function Reset)
set x = GetWidgetX(t)
set y = GetWidgetY(t)
set gold = Bounty.gold
set lumber = Bounty.lumber
set n = UnitList[0].next
call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)-gold)
call SetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER,GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)-lumber)
loop
exitwhen 0==n
set x2=GetWidgetX(n.unit)-x
set y2=GetWidgetY(n.unit)-y
set ud[n]=SquareRoot(x2*x2+y2*y2)
if ((n.unit == u and IsHeroUnitId(GetUnitTypeId(u))) or (not IsUnitType(n.unit,UNIT_TYPE_DEAD) and GetWidgetLife(n.unit)>=.405 and IsHeroUnitId(GetUnitTypeId(n.unit))) and IsUnitInParty(n.unit,u,t,ud[n])) then
set us[c]=n
set c=c+1
set l = GetHeroLevel(n.unit)
set avg = avg + l
if (l>max) then
set max=l
endif
endif
set n=n.next
endloop
if (0<c) then
set s=c
set avg = avg/c
loop
exitwhen 0==c
set c=c-1
call GiveBounty(GetUnitById(us[c]),gold,lumber,klevel,s,avg,max,ud[us[c]])
endloop
endif
endif
set t=null
set u=null
set p=null
return false
endfunction
private function Index takes nothing returns boolean
set levels[GetIndexedUnitId()]=1
call SuspendHeroXP(GetIndexedUnit(),true)
return false
endfunction
private function HandleAbility takes nothing returns boolean
call OnLevelAbility(GetTriggerUnit(),GetLearnedSkill(),GetLearnedSkillLevel())
return false
endfunction
private module N
private static method onInit takes nothing returns nothing
local trigger deathHandler=CreateTrigger()
local trigger abilityHandler=CreateTrigger()
local integer i=15
set reset = CreateTimer()
call TriggerAddCondition(deathHandler,Condition(function HandleReward))
call TriggerAddCondition(abilityHandler,Condition(function HandleAbility))
call Bounty.event.register(Condition(function HandleReward))
loop
call TriggerRegisterPlayerUnitEvent(deathHandler,Player(i),EVENT_PLAYER_UNIT_DEATH,null)
call TriggerRegisterPlayerUnitEvent(abilityHandler,Player(i),EVENT_PLAYER_HERO_SKILL,null)
exitwhen 0==i
set i=i-1
endloop
call RegisterUnitIndexEvent(Condition(function Index),UnitIndexer.INDEX)
set deathHandler=null
set abilityHandler=null
endmethod
endmodule
private struct T extends array
implement N
endstruct
endlibrary
Last edited: