wraithseeker
Tired.
- Reaction score
- 122
As usual, I don't like typing things so I will let the documention take my place.
Requirements: AutoIndex & SimError
Requirements: AutoIndex & SimError
JASS:
Hero Tavern System
v1.00
By wraithseeker
Changelog v1.00
- Initial Release
Main Purpose
- Saving space
- Extending Taverns
- Hero Selection System
HTS is a system that extends the selection of Taverns. As most people know, when you select a hero from a
tavern, you cannot see his abilities his stats. This system does that when you buy a unit from the tavern,
it creates a final verison of the hero for you to look at it and see if you like it. It has 2 abilities
that are able to be used which is SelectHero and Random. Random is just randoming a hero out of a unitpool
and you get one correctly, nicely and efficiently. You can specify the weight for it, the higher the value,
the easier it is to get the unit. There are many boolean that can help you setup the system your way.
Somewhat interesting facts.
This tavern system helps you save space if you want to, there is a next page ability that selects the next
tavern without the player knowing it so you can have endless amount of tavern but in reality, it looks
just like one tavern only!.
Available function
function AddPlayerToTeam takes player whichPlayer, integer team returns nothing
function AddForceStartLocation takes rect whichRect, integer team returns nothing
function AddHeroToPool takes integer HeroId, real weight returns nothing
function SetTavern takes unit u returns nothing
function CreateMoreTavern takes integer tavernId returns nothing
AddPlayerToTeam simply adds the player to team 1 or team 2, only 2 teams are allowed.
AddForceToStart location sets the location where the heroes spawn in a random point in that rect.
AddHeroToPool adds the hero into the random unitpool so you can random all your heroes.
If you do not add it, randoming a hero is impossible.
SetTavern must be used first before CreateMoreTavern is used.
CreateMoreTavern simply stacks the tavern together.
JASS:
library HSS initializer Init uses AutoIndex, SimError
globals
private constant integer RANDOMID = 039;RAND039;
private constant integer CHOOSEID = 039;CHOS039;
private constant integer NEXTPAGEID = 039;NEXT039;
private constant integer MAXLEVEL = 100 // max level of heroes in your game
private constant integer AMOUNTOfRepicks = 1 // How many times can a hero repick
private constant integer MAXSTOCK = 99 // totally random
private constant integer MAXHEROESTOVIEW = 1 // How many heroes you can view at once
private constant real PANTIME = 0.5 // when bought, pan the camera
private constant real SELECTIONTIME = 30
private constant string TAVERNSFX = "Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl" // "" == nothing != "" == effect
private constant string SFXPOINT = "origin" // attach point of effect
private constant string CHOOSESFX = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl" // effect when you choose and pick or random a hero
private constant string ViewError = "You can only view a maximum of 1 heroes!" // set the value of 1 to the value of MAXHEROESTOVIEW
private constant boolean EYECANDY = false // eye candy of leveling when player choose a unit
private constant boolean GIVERANDOMHEROES = true // after selection time, give random heroes
private constant boolean REPICKTYPE = true // false = random true = user specificed
private constant boolean SHOWBOARD = true // show the amount of time left
private constant boolean DEFEATAFKPLAYERS = true // Anybody who hasn't finished choosing a hero will get defeated
endglobals
globals
private constant integer GHOSTID = 039;Aeth039;
private constant integer MOVEID = 039;Amov039;
private constant integer ATKID = 039;Aatk039; // stuffs here you will probaby never touch
private integer Count = 1 // why 1? Simple, because the default tavern is array 0
private rect FORCE1
private rect FORCE2
private real sx1
private real sy1
private real mx1
private real my1
private real sx2
private real sy2
private real mx2
private real my2
private force TEAM1 = CreateForce()
private force TEAM2 = CreateForce()
private force Playing = CreateForce()
private force Unused = CreateForce()
private group Testers = CreateGroup()
private group Enum = CreateGroup()
private group Chosen = CreateGroup()
private unitpool Heroes = CreateUnitPool()
private boolexpr ChosenB
private timer Board = CreateTimer()
private timerdialog T = CreateTimerDialog(Board)
private trigger Sold = CreateTrigger()
private trigger Orders = CreateTrigger()
private trigger ChatRepick = CreateTrigger()
private trigger OnDeath = CreateTrigger()
private trigger Next = CreateTrigger()
private trigger NoClick = CreateTrigger()
private unit array Tavern
private integer array Counter
private integer array Times
private string array Colours
private effect TavernEffect
private constant integer CHOOSEIDCLICK = 852273
private constant integer RANDOMIDCLICK = 852277
endglobals
function AddPlayerToTeam takes player whichPlayer, integer team returns nothing
if team == 1 then
call ForceAddPlayer(TEAM1,whichPlayer)
elseif team == 2 then
call ForceAddPlayer(TEAM2,whichPlayer)
endif
endfunction
private function GetPlayerColour takes player p returns string // A string system
local integer it = GetPlayerId(p)
local string s = Colours[it] + GetPlayerName(p)+ "|r"
return s
endfunction
private function RepickCond takes nothing returns boolean
return IsUnitType(GetFilterUnit(),UNIT_TYPE_HERO) and not IsUnitInGroup(GetFilterUnit(),Testers) and IsUnitInGroup(GetFilterUnit(),Chosen)
endfunction
function AddForceStartLocation takes rect whichRect, integer team returns nothing
if team == 1 then
set FORCE1 = whichRect
set sx1 = GetRectMaxX(FORCE1)
set sy1 = GetRectMaxY(FORCE1)
set mx1 = GetRectMinX(FORCE1)
set my1 = GetRectMinY(FORCE1)
elseif team == 2 then
set FORCE2 = whichRect
set sx2 = GetRectMaxX(FORCE2)
set sy2 = GetRectMaxY(FORCE2)
set mx2 = GetRectMinX(FORCE2)
set my2 = GetRectMaxY(FORCE2)
endif
endfunction
function AddHeroToPool takes integer HeroId, real weight returns nothing
call UnitPoolAddUnitType(Heroes,HeroId,weight)
endfunction
function CreateMoreTavern takes integer tavernId returns nothing
set Tavern[Count] = CreateUnit(Player(0),tavernId,GetUnitX(Tavern[0]),GetUnitY(Tavern[0]),GetUnitFacing(Tavern[0]))
set Count = Count + 1 // we need to increase it everytime new taverns appear
endfunction
private function DisplayText takes string s returns nothing
if IsPlayerInForce(GetLocalPlayer(),Playing) then // oh just to tell you, i took the GetLocalPlayer() usage from the BJ
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0,s)
endif
endfunction
function SetTavern takes unit u returns nothing
set Tavern[0] = u
if TAVERNSFX != "" then
set TavernEffect = AddSpecialEffectTarget(TAVERNSFX,u,SFXPOINT)
endif
endfunction
private function Choose takes nothing returns boolean
local unit u = GetTriggerUnit()
local unit t = GetSoldUnit()
local integer i = 0
local string s
local player p = GetOwningPlayer(t)
local integer it = GetPlayerId(p)
if Times[it] >= MAXHEROESTOVIEW then
call SimError(p,ViewError)
call RemoveUnitEx(t)
call AddUnitToStock(u,GetUnitTypeId(t),0,1)
set u = null
set t = null
return false
endif
loop
exitwhen i >= bj_MAX_PLAYERS
call SetPlayerTechMaxAllowed(Player(i),GetUnitTypeId(t),0)
set i = i + 1
endloop
set Times[it] = Times[it] + 1
if GetLocalPlayer() == p then
call ClearSelection()
call PanCameraToTimed(GetUnitX(t),GetUnitY(t),PANTIME)
endif
call SelectUnit(t,true)
if IsPlayerInForce(p,TEAM1) then
call SetUnitX(t,GetRandomReal(mx1,sx1))
call SetUnitY(t,GetRandomReal(my1,sy1))
if GetLocalPlayer() == GetOwningPlayer(t) then
call PanCameraToTimed(GetUnitX(t),GetUnitY(t),PANTIME)
endif
if not EYECANDY then
call SetHeroLevel(t,MAXLEVEL,false)
else
call SetHeroLevel(t,MAXLEVEL,true)
endif
call GroupAddUnit(Testers,t)
call UnitAddAbility(t,GHOSTID)
call UnitRemoveAbility(t, 039;Amov039; ) //* Removes movement
call UnitRemoveAbility(t, 039;Aatk039; ) //* Removes Attack
call UnitAddAbility(t,RANDOMID)
call UnitAddAbility(t,CHOOSEID)
call ForceRemovePlayer(Unused,p)
elseif IsPlayerInForce(p,TEAM2) then
call SetUnitX(t,GetRandomReal(mx2,sx2))
call SetUnitY(t,GetRandomReal(my2,sy2))
if GetLocalPlayer() == p then
call PanCameraToTimed(GetUnitX(t),GetUnitY(t),PANTIME)
endif
if not EYECANDY then
call SetHeroLevel(t,MAXLEVEL,false)
else
call SetHeroLevel(t,MAXLEVEL,true)
endif
call GroupAddUnit(Testers,t)
call UnitAddAbility(t,GHOSTID)
call UnitRemoveAbility(t,MOVEID)
call UnitRemoveAbility(t,ATKID)
call UnitAddAbility(t,RANDOMID)
call UnitAddAbility(t,CHOOSEID)
call ForceRemovePlayer(Unused,p)
endif
if CHOOSESFX != "" then
call DestroyEffect(AddSpecialEffect(CHOOSESFX,GetUnitX(t),GetUnitY(t)))
endif
set s = GetPlayerColour(p)
call DisplayText(s + " is currently viewing " + GetUnitName(t))
set u = null
set t = null
return false
endfunction
private function ReplaceUnit takes unit u, integer newUnitId returns unit
local integer index = 0 // modified specially for the system
local item indexItem
local real oldRatio
local unit p
call ShowUnit(u, false)
set p = CreateUnit(GetOwningPlayer(u), newUnitId, GetUnitX(u),GetUnitY(u),GetUnitFacing(u))
call SetUnitState(p, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE))
if GetUnitState(p, UNIT_STATE_MAX_MANA) > 0 then
call SetUnitState(p, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA))
endif
call SetResourceAmount(p,GetResourceAmount(u))
loop
set indexItem = UnitItemInSlot(u, index)
if indexItem != null then
call UnitRemoveItem(u, indexItem)
call UnitAddItem(p, indexItem)
endif
set index = index + 1
exitwhen index > 5
endloop
call RemoveUnitEx(u)
call GroupRemoveUnit(Testers,u)
return p
endfunction
private function BLOCK takes nothing returns boolean
local unit u = GetTriggerUnit()
local real x
local real y
local real angle
local unit f
local string s
local integer i = 0
local trigger t = GetTriggeringTrigger() // do triggers need to be nulled? I'll just null it for the sake of safety
if IsUnitInGroup(u,Testers) then
call DisableTrigger(t)
if GetIssuedOrderId() == RANDOMIDCLICK then
set f = PlaceRandomUnit(Heroes,GetOwningPlayer(u),GetUnitX(u),GetUnitY(u),GetUnitFacing(u))
if GetLocalPlayer() == GetOwningPlayer(f) then
call ClearSelection()
endif
loop
exitwhen i >= bj_MAX_PLAYERS
call SetPlayerTechMaxAllowed(Player(i),GetUnitTypeId(u),MAXSTOCK)
call SetPlayerTechMaxAllowed(Player(i),GetUnitTypeId(f),0)
set i = i + 1
endloop
if f == null then
call BJDebugMsg("Unitpool does not have anymore heroes left!")
endif
set s = GetPlayerColour(GetOwningPlayer(u))
call DisplayText(s + " has just randomed " + GetUnitName(f))
call SelectUnit(f,true)
call UnitPoolRemoveUnitType(Heroes,GetUnitTypeId(f))
call RemoveUnitEx(u)
call GroupRemoveUnit(Testers,u)
call GroupAddUnit(Chosen,f)
if CHOOSESFX != "" then
call DestroyEffect(AddSpecialEffect(CHOOSESFX,GetUnitX(f),GetUnitY(f)))
endif
set f = null
set u = null
call EnableTrigger(t)
set t = null
return false
elseif GetIssuedOrderId() == CHOOSEIDCLICK then
set f = ReplaceUnit(u,GetUnitTypeId(u))
set s = GetPlayerColour(GetOwningPlayer(u))
call DisplayText(s + " has just chosen " + GetUnitName(f))
if GetLocalPlayer() == GetOwningPlayer(u) then
call ClearSelection()
endif
call SelectUnit(f,true)
call GroupAddUnit(Chosen,f)
if CHOOSESFX != "" then
call DestroyEffect(AddSpecialEffect(CHOOSESFX,GetUnitX(f),GetUnitY(f)))
endif
call UnitPoolRemoveUnitType(Heroes,GetUnitTypeId(f))
set f = null
set u = null
call EnableTrigger(t)
set t = null
return false
endif
if GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_ORDER and GetHeroSkillPoints(u) >= 1 then
call EnableTrigger(t)
set t = null
set u = null
return false
endif
call PauseUnit(u,true)
call IssueImmediateOrder(u,"stop")
call PauseUnit(u,false)
call EnableTrigger(t)
set u = null
set t = null
set f = null
return false
endif
set u = null
set t = null
return false
endfunction
private struct data
unit target
integer times
implement AutoData
static method create takes unit u returns data
local data d = data.allocate()
set d.target = u
set d.times = 0
set data<u> = d
return d
endmethod
endstruct
private function Repick takes nothing returns nothing
local unit u
local unit f
local string s
local integer i = 0
local data d
local player p = GetTriggerPlayer()
call GroupEnumUnitsSelected(Enum,p,ChosenB)
set u = FirstOfGroup(Enum)
set d = data<u>
if d == 0 then
set d = data.create(u)
endif
if u != null and d.times < AMOUNTOfRepicks then
call RemoveUnitEx(u)
if GetLocalPlayer() == p then
call ClearSelection()
endif
if not REPICKTYPE then
set f = PlaceRandomUnit(Heroes,p,GetUnitX(u),GetUnitY(u),GetUnitFacing(u))
call SelectUnit(f,true)
set s = GetPlayerColour(p)
call DisplayText(s + " has repicked into " + GetUnitName(f))
call GroupAddUnit(Chosen,f)
call GroupRemoveUnit(Chosen,u)
call UnitPoolAddUnitType(Heroes,GetUnitTypeId(u),1)
call UnitPoolRemoveUnitType(Heroes,GetUnitTypeId(f))
elseif REPICKTYPE then
set s = GetPlayerColour(p)
call DisplayText(s + " has repicked")
loop
exitwhen i >= bj_MAX_PLAYERS
call SetPlayerTechMaxAllowed(Player(i),GetUnitTypeId(u),MAXSTOCK) // let them buy the hero again
set i = i + 1
endloop
if GetLocalPlayer() == p then
call PanCameraToTimed(GetUnitX(Tavern[0]),GetUnitY(Tavern[0]),PANTIME)
endif
endif // if you ask me why I don't destroy them, when I destroy, they bug and they are heroes anyway ^_^
set d.times = d.times + 1
set data[f] = d
call GroupRemoveUnit(Enum,u)
endif
set f = null
set u = null
endfunction
private function End takes nothing returns nothing
local unit f
local integer i = 0
local string s
debug call BJDebugMsg("Selection Has Ended")
if GIVERANDOMHEROES then
loop
exitwhen i > 12
if IsPlayerInForce(Player(i),Unused) then
if IsPlayerInForce(Player(i),TEAM1) then
set f = PlaceRandomUnit(Heroes,Player(i),GetRandomReal(mx1,sx1),GetRandomReal(my1,sy1),0)
call UnitPoolRemoveUnitType(Heroes,GetUnitTypeId(f))
elseif IsPlayerInForce(Player(i),TEAM2) then
set f = PlaceRandomUnit(Heroes,Player(i),GetRandomReal(mx2,sx2),GetRandomReal(my2,sy2),0)
call UnitPoolRemoveUnitType(Heroes,GetUnitTypeId(f))
endif
endif
set i = i + 1
endloop
endif
loop
set f = FirstOfGroup(Testers)
exitwhen f == null
call KillUnit(f)
if DEFEATAFKPLAYERS then
set s = GetPlayerColour(GetOwningPlayer(f))
call CustomDefeatBJ(GetOwningPlayer(f),"Defeat!")
call DisplayText(s + " has been kicked for not choosing a hero")
endif
call GroupRemoveUnit(Testers,f)
endloop
set i = 0
loop
exitwhen i > 12
if IsPlayerInForce(Player(i),Unused) and DEFEATAFKPLAYERS then
set s = GetPlayerColour(Player(i))
call CustomDefeatBJ(Player(i), "Defeat!")
call DisplayText(s + " has been kicked for not choosing a hero")
endif
set i = i + 1
endloop
call DisableTrigger(Sold)
call DisableTrigger(ChatRepick)
call DisableTrigger(Orders)
call DisableTrigger(OnDeath)
call DisableTrigger(Next)
call PauseTimer(Board)
call DestroyTimer(Board)
call DestroyForce(TEAM1)
call DestroyForce(TEAM2)
call DestroyForce(Playing)
call DestroyForce(Unused)
call DestroyGroup(Testers)
call DestroyGroup(Enum)
call DestroyGroup(Chosen)
call DestroyUnitPool(Heroes)
call DestroyBoolExpr(ChosenB)
if SHOWBOARD then
call TimerDialogDisplay(T,false)
call DestroyTimerDialog(T)
endif
endfunction
private function AfterInit takes nothing returns nothing
local timer t = GetExpiredTimer() // Had to do this.
if SHOWBOARD then
call TimerDialogDisplay(T,true)
call TimerDialogSetTitle(T,"Selection Time")
endif
call PauseTimer(t)
call DestroyTimer(t)
endfunction
private function IsTavern takes nothing returns boolean
local unit u = GetTriggerUnit() // Destroy the effect if the main tavern dies, simple?
if u == Tavern[0] then
call DestroyEffect(TavernEffect)
endif
set u = null
return false
endfunction
private function NextPage takes nothing returns boolean
local unit u = GetTriggerUnit() // Flips to the next page for the user.
local player p = GetOwningPlayer(u)
local integer Counting = GetPlayerId(p)
if GetSpellAbilityId() == NEXTPAGEID then
if GetLocalPlayer() == p then
call ClearSelection()
endif
call SelectUnit(Tavern[Counter[Counting]],true)
set Counter[Counting] = Counter[Counting] + 1
if Counter[Counting] >= Count then
set Counter[Counting] = 0
endif
return false
endif
return false
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local integer i = 0
call TriggerRegisterAnyUnitEventBJ(Sold,EVENT_PLAYER_UNIT_SELL)
call TriggerAddCondition(Sold,Condition(function Choose))
call TriggerRegisterAnyUnitEventBJ(Orders,EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerRegisterAnyUnitEventBJ(Orders,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterAnyUnitEventBJ(Orders,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerAddCondition(Orders, Condition(function BLOCK))
call TriggerRegisterAnyUnitEventBJ(OnDeath,EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(OnDeath,Condition(function IsTavern))
call TriggerRegisterAnyUnitEventBJ(Next,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(Next,Condition(function NextPage))
loop
exitwhen i > 12
call TriggerRegisterPlayerChatEvent(ChatRepick,Player(i),"-repick",true)
call TriggerAddAction(ChatRepick,function Repick)
set Counter<i> = 1
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
call ForceAddPlayer(Playing,Player(i))
call ForceAddPlayer(Unused,Player(i))
endif
set i = i + 1
endloop
set ChosenB = Filter(function RepickCond)
if SELECTIONTIME > 0 then
call TimerStart(Board,SELECTIONTIME,false,function End)
call TimerStart(CreateTimer(),0.,false,function AfterInit)
endif
set Colours[0] ="|cffff0000"
set Colours[1] = "|cff0000ff"
set Colours[2] = "|cff93ffc9"
set Colours[3] = "|cff400080"
set Colours[4] = "|cffffff00"
set Colours[5] = "|cffff8000"
set Colours[6] = "|cff00c400"
set Colours[7] = "|cffff80c0"
set Colours[8] = "|cff808080"
set Colours[9] = "|cffc1c1ff"
set Colours[10] = "|cff5e5e2f"
set Colours[11] = "|cff004000"
set Colours[12] = "|cff000000"
endfunction
endlibrary</i></u></u>