//TESH.scrollpos=0
//TESH.alwaysfold=0
library Rev initializer Init requires Embasic, LocationRecycling
globals
private player array PLAYER
private integer array TYPE
private timerdialog array TW
//private boolean array Dead
integer Dead = 0
private group gg = CreateGroup()
private boolexpr filt
endglobals
private function FilterUnits takes nothing returns boolean
local unit u = GetFilterUnit()
return ((GetUnitTypeId(u) == 'hpea' or GetUnitTypeId(u) == 'h00J') and GetUnitState(u,UNIT_STATE_LIFE) > 0.405 )
endfunction
function ReviveAction takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer index = Index(t)
local location l = NewLocation()
set Dead = Dead - 1
call GroupEnumUnitsInRect(gg,GetPlayableMapRect(),filt)
set l = GetUnitLoc(GroupPickRandomUnit(gg))
call GroupClear(gg)
call CreateUnitAtLoc(PLAYER[index],TYPE[index],l,0.)
call RemoveLocation(l)
//call ReleaseIndex(index)
call DestroyTimerDialog(TW[index])
call FlushIndex(t)
call ReleaseTimer(t)
call ReleaseLocation(l)
set l = Location(0.,0.)
set l = null
endfunction
function Revive takes unit u, integer time returns nothing
local timer t = NewTimer()
local integer index = Index(t)
local timerdialog tw = CreateTimerDialog(t)
call TimerDialogSetTitle(tw,ColorPlayer(GetOwningPlayer(u)))
call TimerDialogDisplay(tw,true)
if ( t == null ) then
call Debug("Timer = null")
endif
set PLAYER[index] = GetOwningPlayer(u)
set TYPE[index] = GetUnitTypeId(u)
set TW[index] = tw
set Dead = Dead + 1
if ( Dead == PLAYERNUMBER ) then
call PauseAllUnitsBJ(true)
call ConditionalTriggerExecute( gg_trg_OnLose )
call DisableTrigger(gg_trg_NextWave)
endif
call TimerStart(t,I2R(time),false,function ReviveAction)
endfunction
private function Init takes nothing returns nothing
set filt = Filter(function FilterUnits)
endfunction
endlibrary
function GetRandomRealValued takes real value, real maxvalue returns real
local real max = maxvalue/value
local integer Int = GetRandomInt(1,R2I(max))
return value*Int
endfunction
globals
integer c = 0
unit array Riese
endglobals
function Damage takes nothing returns nothing
local integer i = 0
loop
set i = i + 1
exitwhen i > c
//call DebugSpeicher("RM",OrderId2StringBJ(GetUnitCurrentOrder(Riese[i])))
if ( OrderId2StringBJ(GetUnitCurrentOrder(Riese[i])) == "smart" ) then
call SetWidgetLife(Riese[i],GetWidgetLife(Riese[i])-4.)
endif
if ( GetWidgetLife(Riese[i]) < 0.405 ) then
set Riese[i] = Riese[c]
set c = c - 1
endif
endloop
endfunction
function PrintRM takes nothing returns nothing
call CheckMemory("RM","Blub",true)
endfunction
function Music takes nothing returns nothing
call StopMusicBJ( false )
call PlaySoundBJ( gg_snd_War2IntroMusic01 )
endfunction
function AddRiese takes unit u returns nothing
call Debug("Riese")
set c = c + 1
set Riese[c] = u
endfunction
globals
force TempForce
endglobals
function GetForceOfPlayerNew takes player p returns force
local force f = NewForce()
call ForceAddPlayer(f, p)
set TempForce = f
return f
endfunction
//call DestroyTrigger(trig)
globals
integer PLAYERNUMBER = 0
real array GoldSpeicher
endglobals
// Alle 5 Runden, Bestien um 5 erhöhen. Basis; 44
function CalcDifficulty takes nothing returns nothing
local integer lvl = udg_Welle/2
local integer Beasts = 44 + (lvl/5)*5
local integer damage = 5+lvl
if ( lvl > 5 ) then
set damage = damage + lvl
endif
set udg_Difficulty = udg_Welle+(Beasts*damage/100)
endfunction
library Effects initializer InitFade requires Embasic
struct effectData
effect data
endstruct
function RemoveEffect takes nothing returns nothing
local timer t = GetExpiredTimer()
local effectData d = GetTimerData(t)
call DestroyEffect(d.data)
call d.destroy()
call ReleaseTimer(t)
endfunction
function AddEffectTimer takes effect h, real time returns nothing
local timer t = NewTimer()
local effectData d = effectData.create()
set d.data = h
call SetTimerData(t,d)
call TimerStart(t,time,false,function RemoveEffect)
endfunction
globals
private real TICK = 0.04
private integer c = 0
Fade array FadeData
endglobals
struct Fade
integer count
integer maxcount
unit u
real r
real g
real b
real a
real rm
real gm
real bm
real am
real time
boolean StartFade
endstruct
function FadeCreate takes nothing returns nothing
local Fade f
local integer i = 0
loop
set i = i + 1
exitwhen i > c
set f = FadeData[i]
set f.r = f.r - f.rm/f.maxcount
set f.g = f.g - f.gm/f.maxcount
set f.b = f.b - f.bm/f.maxcount
set f.a = f.a + f.am/f.maxcount
call RDebug("FS",R2S(f.r)+" | " + R2S(f.g)+" | "+ R2S(f.b)+" | "+ R2S(f.a)+" | ")
call SetUnitVertexColorBJ(f.u,R2I(f.r),R2I(f.g),R2I(f.b),R2I(f.a))
set f.count = f.count + 1
if ( f.count > f.maxcount ) then
call f.destroy()
set FadeData[i] = FadeData[c]
set c = c - 1
endif
endloop
endfunction
function FadeUnit takes unit u, real time, integer red, integer green, integer blue, integer alpha, boolean StartFade returns nothing
local Fade f = Fade.create()
set f.u = u
set f.r=100
set f.g=100
set f.b=100
set f.a=0
set f.rm = 100-red
set f.gm = 100-green
set f.bm = 100-blue
set f.am = alpha
if ( StartFade ) then
set f.a = 100
set f.am = -100
endif
call RDebug("FS","Init: "+R2S(f.rm)+" | " + R2S(f.gm)+" | "+ R2S(f.bm)+" | "+ R2S(f.am)+" | ")
set f.time = time
set f.count = 0
set f.maxcount = R2I(time/TICK)
set c = c + 1
set FadeData[c] = f
endfunction
function InitFade takes nothing returns nothing
call TimerStart(CreateTimer(),TICK,true,function FadeCreate)
endfunction
endlibrary
globals
group array GroupAttached
endglobals
function GroupRelease takes nothing returns nothing
//call SetUnitVertexColorBJ(GetEnumUnit(),100,100,100,100)
endfunction
function GroupInvis takes nothing returns nothing
local timer t = GetExpiredTimer()
local group g = GroupAttached[Index(t)]
call ForGroup(g,function GroupRelease)
call ReleaseGroup(g)
call ReleaseTimer(t)
endfunction
function CreateCircle takes location where, integer count, real time, real endrad returns nothing
local integer i = 0
local unit u
local location TL
local group g = NewGroup()
local timer t = NewTimer()
local integer index = Index(t)
call TimerStart(t,time,false,function GroupInvis)
loop
set i = i + 1
exitwhen i > count
set u = CreateUnit(Player(15),'e003',0.,0.,0.)
set TL = NewLocation()
//call SetUnitVertexColorBJ(u,100,100,100,100)
call ShowUnit(u,true)
call SetUnitX(u,GetLocationX(where))
call SetUnitY(u,GetLocationY(where))
call GroupAddUnit(g,u)
set TL = PolarProjectionBJ(where,endrad,i*(360/count))
call IssuePointOrderLoc(u,"move",TL)
call UnitApplyTimedLifeBJ(1.3,'BTLF',u)
call ReleaseLocation(TL)
set TL = Location(0.,0.)
endloop
set GroupAttached[index] = g
set TL = null
set g = null
set u = null
endfunction
library HandleVars initializer init
globals
private hashtable ht
endglobals
// too bad the Handle vars' old functionality forces me to make these things
// inline-unfriendly
function SetHandleHandle takes agent subject, string label, agent value returns nothing
if(value==null) then
call RemoveSavedHandle( ht, GetHandleId(subject), StringHash(label))
else
call SaveAgentHandle( ht, GetHandleId(subject), StringHash(label), value)
endif
endfunction
function SetHandleInt takes agent subject, string label, integer value returns nothing
if value==0 then
call RemoveSavedInteger(ht, GetHandleId(subject), StringHash(label))
else
call SaveInteger(ht, GetHandleId(subject), StringHash(label), value)
endif
endfunction
function SetHandleBoolean takes agent subject, string label, boolean value returns nothing
if (value == false) then
call RemoveSavedBoolean(ht, GetHandleId(subject), StringHash(label))
else
call SaveBoolean(ht, GetHandleId(subject), StringHash(label), value)
endif
endfunction
function SetHandleReal takes agent subject, string label, real value returns nothing
if (value == 0.0) then
call RemoveSavedReal(ht, GetHandleId(subject), StringHash(label))
else
call SaveReal(ht, GetHandleId(subject), StringHash(label), value)
endif
endfunction
function SetHandleString takes agent subject, string label, string value returns nothing
if ((value=="") or (value==null)) then
call RemoveSavedString(ht, GetHandleId(subject), StringHash(label))
else
call SaveStr(ht, GetHandleId(subject), StringHash(label), value) //yay for blizz' consistent naming scheme...
endif
endfunction
function GetHandleHandle takes agent subject, string label returns agent
debug call BJDebugMsg("[debug] What the heck? Why would you call HandleHandle I guess this was caused by a search and replace mistake")
return null
endfunction
// these are inline friendly, ok, maybe they aren't because jasshelper does not recognize
// GetHandleId as non-state changing. But they will be once I fix jasshelper...
function GetHandleInt takes agent subject, string label returns integer
return LoadInteger(ht, GetHandleId(subject), StringHash(label))
endfunction
function GetHandleBoolean takes agent subject, string label returns boolean
return LoadBoolean(ht, GetHandleId(subject), StringHash(label))
endfunction
function GetHandleString takes agent subject, string label returns string
return LoadStr(ht, GetHandleId(subject), StringHash(label))
endfunction
function GetHandleReal takes agent subject, string label returns real
return LoadReal(ht, GetHandleId(subject), StringHash(label))
endfunction
// got bored so I now use a textmacro...
//! textmacro FAUX_HANDLE_VARS_GetHandleHandle takes NAME, TYPE
function SetHandle$NAME$ takes agent subject, string label, $TYPE$ value returns nothing
if(value==null) then
call RemoveSavedHandle( ht, GetHandleId(subject), StringHash(label))
else
call Save$NAME$Handle( ht, GetHandleId(subject), StringHash(label), value)
endif
endfunction
function GetHandle$NAME$ takes agent subject, string label returns $TYPE$
return Load$NAME$Handle( ht, GetHandleId(subject), StringHash(label))
endfunction
//! endtextmacro
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Player","player")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Widget","widget")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Destructable","destructable")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Item","item")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Unit","unit")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Ability","ability")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Timer","timer")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Trigger","trigger")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("TriggerCondition","triggercondition")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("TriggerAction","triggeraction")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("TriggerEvent","event")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Force","force")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Group","group")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Location","location")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Rect","rect")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("BooleanExpr","boolexpr")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Sound","sound")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Effect","effect")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("UnitPool","unitpool")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("ItemPool","itempool")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Quest","quest")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("QuestItem","questitem")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("DefeatCondition","defeatcondition")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("TimerDialog","timerdialog")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Leaderboard","leaderboard")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Multiboard","multiboard")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("MultiboardItem","multiboarditem")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Trackable","trackable")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Dialog","dialog")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Button","button")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("TextTag","texttag")
//! runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Lightning","lightning")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Image","image")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Ubersplat","ubersplat")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Region","region")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("FogState","fogstate")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("FogModifier","fogmodifier")
// runtextmacro FAUX_HANDLE_VARS_GetHandleHandle("Hashtable","hashtable")
function FlushHandleVars takes agent subject returns nothing
call FlushChildHashtable(ht, GetHandleId(subject))
endfunction
function FlushHandleLocals takes agent subject returns nothing
call FlushHandleVars(subject)
endfunction
private function init takes nothing returns nothing
set ht=InitHashtable()
endfunction
endlibrary
Name | Type | is_array | initial_value |
AAA_Gold | integer | No | |
AAA_Type | unitcode | No | |
AAA_Wood | integer | No | |
Allies_Bestimmung | player | Yes | |
Allies_Voll_Verbuendet | integer | Yes | |
Allytimer_Warmay | integer | Yes | |
BA | boolean | Yes | |
Banned_yn | boolean | Yes | |
Basis_Einkommen_Gold | integer | Yes | |
Basis_Einkommen_Holz | integer | Yes | |
Basis_Handycap | real | No | |
Bezeichnung_Dying | integer | Yes | |
Bezeichnung_Feigheit | integer | Yes | |
Bezeichnung_Fiesheit | integer | Yes | |
Bezeichnung_Kampfkunst | integer | Yes | |
Bezeichnung_Kampfsucht | integer | Yes | |
Bezeichnung_Killstau | integer | Yes | |
Bezeichnung_Milizenkills | integer | Yes | |
Blocker | unit | Yes | |
BlockerAnzahl | integer | No | |
CG_Cache | gamecache | No | |
CG_Name | string | No | |
ChaosMode | boolean | No | false |
Color | string | Yes | |
ColorCodePlayer | string | Yes | |
D | dialog | No | |
Difficulty | integer | No | 0 |
END_MB_Max_Income | integer | Yes | |
END_MB_NGs_erobert | integer | Yes | |
END_MB_Zeit | integer | Yes | |
Handycap_Erhoehung | real | No | |
Heiler | unit | Yes | |
HeilerAnzahl | integer | No | |
Income | integer | Yes | 5 |
Income_Brutto | integer | Yes | |
Income_Leiste | leaderboard | Yes | |
IncomeWood | integer | Yes | 2 |
KB_Basic | string | No | |
KB_Density | integer | Yes | |
KB_Effect | string | Yes | |
KB_Friction | real | Yes | |
KB_Killtreerange | real | Yes | |
KB_Range | real | Yes | |
KB_Speed | real | Yes | |
KuenstlicheIntelligenz | string | No | |
Laufvariable | integer | No | |
Legendaerer | player | No | |
MB_Spielerplatz | integer | Yes | |
Messages_Written | integer | Yes | |
Minute | integer | No | |
Modus | string | No | |
MonatsTimer | timer | No | |
Multibaord_Text | string | No | |
Multiboard | multiboard | No | |
Multiboard_GoOn | boolean | No | |
Multiboard_Uhrentext | string | Yes | |
n | button | No | |
Playing_Players | force | No | |
Progress | quest | No | |
ProgressText | string | No | |
Rect | rect | Yes | |
rg | group | No | |
rh | group | No | |
Richtung | real | No | |
Rohstoff | unit | Yes | |
RohstoffAnzahl | integer | No | |
Spell | abilcode | Yes | |
spells | integer | No | |
SpentSold | integer | Yes | |
Spieleranzahl | integer | No | |
Stamp2 | unit | No | |
Stampedisierer | unit | No | |
Start_Gold | integer | Yes | |
Start_Holz | integer | Yes | |
td | timer | No | |
TempGroup2 | group | No | |
TempGroup3 | group | No | |
TempGroup4 | group | No | |
TempInt | integer | No | |
TempPoint | location | No | |
TempPoint2 | location | No | |
TempPoint3 | location | No | |
TempReal | real | No | |
TempString | string | No | |
TempUnit | unit | No | |
TempValue | real | No | |
TextToBeparsed | string | No | |
TextToBeParsed_LenghtsToken | integer | No | |
TextToBeParsed_Lines | integer | No | |
TextToBeParsedAusgabe | StringExt | Yes | |
tt | timer | No | |
Uhr_Minuten | integer | No | |
Uhr_Sekunden | integer | No | |
Uhr_Stunden | integer | No | |
Uhr_Text | string | No | |
Verlierer | force | No | |
Welle | integer | No | 1 |
Zufall | integer | No |
//TESH.scrollpos=0
//TESH.alwaysfold=0
Die Karte wurde ursprünglich von Jano_1 gemacht.
Ich habe das komplette script und die Gebäude von Jano_1 ersetzt und neue gemacht.
Und Memory-Leaks habe kich durch Recycling ersetzt, bis ich herausgefunden habe, dass Recycling mit
GUI Funktionen Schwachsinn ist und GUI die Variable immer neu füllt.
Naja, ein Großteil habe ich entfernt, z.T auch einfach das alte recycling system bearbeitet.
Aber ich denke nicht, dass zahlreiche memory leaks entstehen.
WENN du diese Karte bearbeiten willst, dann setz deinen Namen einfach in die credits.
WENN du in diese Karte cheats einbauen willst, wirst du von meinem anti-cheating system erfasst.
//TESH.scrollpos=0
//TESH.alwaysfold=0
All the systems except TimerUtils and Table are mady by Mr.Malte.
//TESH.scrollpos=12
//TESH.alwaysfold=0
scope WordOfMight
constant function isSpellIdValid takes integer spellId returns boolean
if ( spellId == 'A001' ) then
return true
elseif ( spellId == 'A00O' ) then
return true
endif
return false
endfunction
//= End of ObjectIds
//===========================================================================
//= Spell datas and settings
function Word_of_Might_AbsorbedDamage takes integer lvl returns real
return 250.
endfunction
// lvl is always 0
function Word_of_Might_Duration takes integer lvl returns real
return 3. // 0 == endless
endfunction
constant function Word_of_Might_ShieldEffect takes nothing returns string
return "Abilities\\Spells\\Human\\ManaShield\\ManaShieldCaster.mdl"
endfunction
//== Any other data/setting have to be changed within the object-editor
//= End of datas/settings
//===========================================================================
// *** Spell Script ***
function Word_of_Might_Condtions takes nothing returns boolean
return isSpellIdValid(GetSpellAbilityId())
endfunction
function DelayedDamageTimer takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetHandleUnit(t, "u")
call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + GetHandleReal(t, "dmg"))
endfunction
function DelayedDamage takes unit u,real r returns nothing
local timer t = CreateTimer()
call SetHandleReal(t, "dmg", r)
call SetHandleHandle(t, "u", u)
call TimerStart(t, 0, false,function DelayedDamageTimer)
endfunction
function DelayedDamageCheck takes unit u,real r returns nothing
local real maxL = GetUnitState(u, UNIT_STATE_MAX_LIFE)
local real l = GetUnitState(u, UNIT_STATE_LIFE)
if r > (maxL - l)then
if r >= l then
call SetUnitState(u, UNIT_STATE_LIFE, maxL)
call DelayedDamage(u, r - (maxL - l))
else
call DelayedDamage(u, r)
endif
else
call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u,UNIT_STATE_LIFE) + r)
endif
endfunction
globals
private triggeraction array TA
endglobals
private function SetHandleAction takes handle h, triggeraction b returns nothing
set TA[ModuloInteger(GetHandleId(h)-0x100000,8191)] = b
endfunction
private function GetHandleAction takes handle h returns triggeraction
return TA[ModuloInteger(GetHandleId(h)-0x100000,8191)]
endfunction
function Word_of_Might_Heal takes nothing returns nothing
local trigger t = GetTriggeringTrigger()
local real dmg = GetEventDamage()
local real life = GetHandleReal(t, "ShieldLife")
if( life < dmg )then
call DelayedDamageCheck(GetTriggerUnit(), life)
call DestroyEffect(GetHandleEffect(t,"ShieldFX"))
call TriggerRemoveAction(t, GetHandleAction(t))
call FlushHandleLocals(t)
call DestroyTrigger(t)
elseif(dmg > 0)then
call DelayedDamageCheck(GetTriggerUnit(), dmg)
call SetHandleReal(t,"ShieldLife", life-dmg)
endif
endfunction
function Word_of_Might_Actions takes nothing returns nothing
local trigger t = CreateTrigger()
local unit u = GetSpellTargetUnit()
local integer lvl = 0 // 0 anyways
local real dur = Word_of_Might_Duration(lvl)
local triggeraction a = TriggerAddAction(t, function Word_of_Might_Heal)
local effect e
local location loc
if ( IsUnitType(u,UNIT_TYPE_STRUCTURE) ) then
set loc = GetUnitLoc(u)
set e = AddSpecialEffectLoc(Word_of_Might_ShieldEffect(),loc)
call RemoveLocation(loc)
else
set e = AddSpecialEffectTarget(Word_of_Might_ShieldEffect(), u, "origin")
endif
call SetHandleAction(t, a)
call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DAMAGED)
call SetHandleReal(t, "ShieldLife", Word_of_Might_AbsorbedDamage(lvl))
call SetHandleHandle(t, "ShieldFX", e)
if dur > 0 and t != null then
call DestroyEffect(e)
call TriggerSleepAction(dur)
call TriggerRemoveAction(t, a)
call FlushHandleLocals(t)
call DestroyTrigger(t)
endif
set t = null
set loc = null
set u = null
set a = null
set e = null
endfunction
function ReturnTrue takes nothing returns boolean
return true
endfunction
function InitTrig_Word_of_Might takes nothing returns nothing
local integer i = 0
set gg_trg_Word_of_Might = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(gg_trg_Word_of_Might, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, Condition(function ReturnTrue))
set i = i + 1
exitwhen i == 16
endloop
call TriggerAddCondition(gg_trg_Word_of_Might, Condition(function Word_of_Might_Condtions))
call TriggerAddAction(gg_trg_Word_of_Might, function Word_of_Might_Actions)
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
library SellUnit initializer Init requires GetUnitCost
//===========================================================================
// Information:
//==============
//
// This library gives you a function that allows you to Sell Units to their owner.
// When you let a dummy cast transmute onto the unit, you've got the problem that
// only the costs for THIS unit are cought, so when I've got a unit that costs
// 200 gold and upgrade it for 100 gold, and I want to refund 75% of the cost
// to the owner, He'd only get 75 gold.
// With this, he'd get the full 225 gold.
//
//===========================================================================
globals
private sound GoldAdded
private sound LumberAdded
endglobals
function SellUnit takes unit who, real refundPercentage returns nothing
local texttag t = CreateTextTag()
local integer GoldCost = R2I(I2R(GetUnitCost(who,COST_GOLD))*refundPercentage)
local integer LumberCost = R2I(I2R(GetUnitCost(who,COST_LUMBER))*refundPercentage)
local real x = GetUnitX(who)
local real y = GetUnitY(who)
call KillUnit(who)
call SetPlayerState(GetOwningPlayer(who),PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(GetOwningPlayer(who),PLAYER_STATE_RESOURCE_GOLD)+GoldCost)
call SetPlayerState(GetOwningPlayer(who),PLAYER_STATE_RESOURCE_LUMBER,GetPlayerState(GetOwningPlayer(who),PLAYER_STATE_RESOURCE_LUMBER)+LumberCost)
if GoldCost > 0 then
call DestroyEffect(AddSpecialEffect("UI\\Feedback\\GoldCredit\\GoldCredit.mdl",x,y))
call SetSoundPosition(GoldAdded,x,y,100.)
call SetSoundVolume(GoldAdded, 127)
call StartSound(GoldAdded)
call SetTextTagText(t, "+"+I2S(GoldCost), 0.023)
call SetTextTagPos(t, x,y+30.,0.04)
call SetTextTagColor(t, 255, 204, 51, 255)
call SetTextTagVelocityBJ(t,64.,90.)
call SetTextTagVisibility(t, (GetLocalPlayer() == GetOwningPlayer(who)))
call SetTextTagFadepoint(t, 2)
call SetTextTagLifespan(t, 2.5)
call SetTextTagPermanent(t, false)
endif
if LumberCost > 0 then
set t = CreateTextTag()
if GoldCost <= 0 then
call SetSoundPosition(LumberAdded, x,y,100)
call SetSoundVolume(LumberAdded, 127)
call StartSound(LumberAdded)
endif
call SetTextTagText(t, "|cff006C00+"+I2S(LumberCost)+"|r", 0.023)
call SetTextTagPos(t, x,y,0.04)
call SetTextTagVelocityBJ(t,64.,90.)
call SetTextTagVisibility(t, (GetLocalPlayer() == GetOwningPlayer(who)))
call SetTextTagFadepoint(t, 2)
call SetTextTagLifespan(t, 2.5)
call SetTextTagPermanent(t, false)
endif
set t = null
endfunction
private function Init takes nothing returns nothing
set GoldAdded = CreateSound("Abilities\\Spells\\Other\\Transmute\\AlchemistTransmuteDeath1.wav" , false , true , true , 10 , 10 , "CombatSoundsEAX")
call SetSoundParamsFromLabel(GoldAdded , "TransmuteMissileImpact")
call SetSoundDuration(GoldAdded , 1601)
set LumberAdded = CreateSound("Abilities\\Spells\\Items\\ResourceItems\\BundleOfLumber.wav" , false , true , true , 10 , 10 , "SpellsEAX")
call SetSoundParamsFromLabel(LumberAdded , "ReceiveLumber")
call SetSoundDuration(LumberAdded , 1347)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CommonAIimports
native GetUnitGoldCost takes integer unitid returns integer
native GetUnitWoodCost takes integer unitid returns integer
native GetUnitBuildTime takes integer unitid returns integer
endlibrary
constant native GetFoodMade takes integer unitId returns integer
constant native GetFoodUsed takes integer unitId returns integer
constant native GetUnitFoodMade takes unit whichUnit returns integer
constant native GetUnitFoodUsed takes unit whichUnit returns integer
//TESH.scrollpos=246
//TESH.alwaysfold=0
library GetUnitCost initializer Init requires Table, CommonAIimports
//===========================================================================
// Information:
//==============
//
// This library allows you to get the cost of units in the following devices:
// Gold, Wood, Food, FoodIncrement. Normally this is not possible. This is useful
// for example, if you want to make a towerdefense and you want a sell button which gives
// 75% of the gold and wood back you payed for it. But when the tower is an upgrade, so the
// tower itself costs 100 gold plus 100 gold upgrade, and you'd use a dummy to cast Transmute on
// the unit, the player would only get 75% gold back, not the gold for all the upgrades.
// If you used this library, you'd be able to give him 150 instead of 75 gold back.
//
//===========================================================================
// Implementation:
//================
//
// 1. Make a new trigger, convert it to custom text
// and replace all the code in the trigger by this.
// 2. Give credits to Mr.Malte (:P) and use the system.
//===========================================================================
// Functions:
//===========
//
// GetUnitCost(unit,type*) : Returns the total gold cost of a unit (upgrades included)
// GetUnitTypeCost(unitId,type*) : Returns, how much a unit with ID X would cost. Note:
// This ignores upgrade gold costs, so when you just want the cost of
// THIS building/unit, you can use GetUnitTypeCost(GetUnitTypeId(#),#)
//
// * type can be COST_GOLD or COST_LUMBER
//
//===========================================================================
// Features:
//==========
// 1. Gets the cost of Units including its previous forms (when upgraded)
// 2. Works for units and structures
// 3. Uses a smart way to detect gold and wood
// 4. Destroys UnitCost structs automatically, even when the units are removed.
//
//===========================================================================
globals
private constant integer PLAYER_ID = 14
private constant integer DUMMY_ID = 'hpea'
private constant integer RESOURCE_LIMIT = 100000
private constant boolean CLONE = true
endglobals
globals
private trigger unitEnters = CreateTrigger()
private trigger unitDies = CreateTrigger()
private trigger unitUpgrades = CreateTrigger()
private HandleTable UnitData
private Table RawcodeData
private real maxX
private real maxY
private unit dummy = null
private player dummyOwner = Player(PLAYER_ID)
endglobals
// return true: Save the unit's cost.
// return false: Don't save the unit's cost.
private function UserFilter takes unit u returns boolean
return ( GetUnitAbilityLevel(u,'Aloc') == 0 )
endfunction
struct UnitCost
integer Lumber
integer Gold
UnitCost Link = 0
method increaseBy takes UnitCost inc returns nothing
set .Lumber = .Lumber + inc.Lumber
set .Gold = .Gold + inc.Gold
call inc.destroy()
// And now synchronize the Clone.
// Destroying and recreating would change its ID, so..
if CLONE then
if .Link != 0 then
set .Link.Gold = .Gold
set .Link.Lumber = .Lumber
endif
endif
endmethod
// We want to give the user the UnitCost struct, but we dont want him to access it
// and change its data. So we make a 'Parastruct'
method Clone takes nothing returns UnitCost
if CLONE then
if .Link == 0 then
set .Link = UnitCost.create()
endif
// Always restore the data to be safe.
set .Link.Gold = .Gold
set .Link.Lumber = .Lumber
set .Link.Link = -1 // -1 means: This is just a clone.
return .Link
else
return this
endif
endmethod
method onDestroy takes nothing returns nothing
if .Link > 0 then
call .Link.destroy()
endif
endmethod
endstruct
private function GetUnitCostSimple takes integer ID returns UnitCost
local UnitCost u = UnitCost.create()
//if RawcodeData.exists(ID) then
// return RawcodeData[ID]
//endif
if IsUnitIdType(ID,UNIT_TYPE_HERO) then
call SetPlayerState(dummyOwner, PLAYER_STATE_RESOURCE_GOLD, RESOURCE_LIMIT)
call SetPlayerState(dummyOwner, PLAYER_STATE_RESOURCE_LUMBER, RESOURCE_LIMIT)
call SetPlayerState(dummyOwner, PLAYER_STATE_RESOURCE_FOOD_USED,0)
call AddUnitToStock(dummy, ID, 1, 1)
call IssueNeutralImmediateOrderById(dummyOwner, dummy, ID)
call RemoveUnitFromStock(dummy,ID)
set u.Gold = RESOURCE_LIMIT - GetPlayerState(dummyOwner,PLAYER_STATE_RESOURCE_GOLD)
set u.Lumber = RESOURCE_LIMIT - GetPlayerState(dummyOwner,PLAYER_STATE_RESOURCE_LUMBER)
else
set u.Gold = GetUnitGoldCost(ID)
set u.Lumber = GetUnitWoodCost(ID)
endif
//set RawcodeData[ID] = u
return u
endfunction
// ======================================================================
// ============== USER FUNCTIONS ==============
// ======================================================================
globals
constant integer COST_GOLD = 0
constant integer COST_LUMBER = 1
endglobals
function GetUnitCost takes unit u, integer cost returns integer
local UnitCost temp = UnitData[u]
if temp == 0 then
set temp = GetUnitCostSimple(GetUnitTypeId(u))
set UnitData[u] = temp
endif
if cost == COST_GOLD then
return temp.Gold
elseif cost == COST_LUMBER then
return temp.Lumber
else
debug call BJDebugMsg("GetUnitCost: Used undefined cost-type")
endif
return 0
endfunction
function GetUnitTypeCost takes integer unitId, integer cost returns integer
local UnitCost temp = GetUnitCostSimple(unitId)
if cost == COST_GOLD then
return temp.Gold
elseif cost == COST_LUMBER then
return temp.Lumber
else
debug call BJDebugMsg("GetUnitCost: Used undefined cost-type")
endif
return 0
endfunction
// ======================================================================
// ======================================================================
// ======================================================================
private function onEnter takes nothing returns nothing
local UnitCost uc
local unit u = GetTriggerUnit()
// Kill dummies.
if GetOwningPlayer(u) == dummyOwner then
call RemoveUnit(u)
return
endif
// Actually it would make sense to only save the cost to the unit,
// when it has been upgraded. But we can't detect the unit type it was
// before, because the unit ID already changed when the onUpgrade trigger
// fired.
if UserFilter(u) then
if UnitData.exists(u) == false then
set uc = GetUnitCostSimple(GetUnitTypeId(u))
set UnitData[u] = uc
endif
endif
endfunction
private function onUpgrade takes nothing returns nothing
local UnitCost uc = GetUnitCostSimple(GetUnitTypeId(GetTriggerUnit()))
local UnitCost ucPrev = UnitData[GetTriggerUnit()]
call ucPrev.increaseBy(uc)
endfunction
private function Destruct takes unit u returns nothing
local UnitCost uc
if GetOwningPlayer(u) != dummyOwner then
set uc = UnitData[u]
if uc != null then
call uc.destroy()
call UnitData.flush(u)
endif
endif
endfunction
private function onDie takes nothing returns nothing
call Destruct(GetTriggerUnit())
endfunction
hook RemoveUnit Destruct
private function returnFlag takes nothing returns boolean
return UserFilter(GetFilterUnit())
endfunction
private function Init takes nothing returns nothing
local integer index = 0
local group g = CreateGroup() // Catch also initial units.
local unit u
local boolexpr condition = Condition(function returnFlag)
local UnitCost uc
set UnitData = HandleTable.create()
set RawcodeData = Table.create()
// ==========================================================================
set dummy = CreateUnit(dummyOwner,DUMMY_ID,GetRectMaxX(bj_mapInitialPlayableArea),GetRectMaxY(bj_mapInitialPlayableArea),270)
call UnitAddAbility(dummy,'Asud')
call UnitAddAbility(dummy,'Aloc')
call SetUnitAcquireRange(dummy,0.)
call ShowUnit(dummy,false)
call SetUnitInvulnerable(dummy,true)
// ==========================================================================
call SetPlayerState(dummyOwner, PLAYER_STATE_RESOURCE_FOOD_CAP,300)
call TriggerRegisterEnterRectSimple(unitEnters,bj_mapInitialPlayableArea)
loop
call TriggerRegisterPlayerUnitEvent(unitUpgrades, Player(index), EVENT_PLAYER_UNIT_UPGRADE_START, condition)
call TriggerRegisterPlayerUnitEvent(unitDies, Player(index), EVENT_PLAYER_UNIT_DEATH, condition)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction(unitEnters,function onEnter)
call TriggerAddAction(unitUpgrades,function onUpgrade)
call TriggerAddAction(unitDies,function onDie)
// ==========================================================================
call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,condition)
loop
set u = FirstOfGroup(g)
exitwhen u == null
set uc = GetUnitCostSimple(GetUnitTypeId(u))
set UnitData[u] = uc
call GroupRemoveUnit(g,u)
endloop
call DestroyBoolExpr(condition)
call DestroyGroup(g)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library ReplaceScape initializer Init
globals
private real maxX
private real maxY
private real minX
private real minY
private constant real INCREMENT = 25.
endglobals
function ReplaceTerrain takes integer ScapeA, integer ReplaceWith returns nothing
local real x = minX
local real y = minY
local integer ReturnValue = 0
loop
exitwhen y > maxY
set x = x + INCREMENT
if x > maxX then
set x = minX
set y = y + INCREMENT
endif
if GetTerrainType(x,y) == ScapeA then
call SetTerrainType(x,y,ReplaceWith,-1,1,0)
endif
set ReturnValue = ReturnValue + 1
if ReturnValue == 1000 then
set ReturnValue = 0
call ClearTextMessages()
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"=== Changing Terrain ===")
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Progress: "+I2S(R2I((maxY-minY)/y))+"%")
call TriggerSyncReady()
endif
endloop
endfunction
function Dark takes nothing returns nothing
call ReplaceTerrain(GetTerrainTypeBJ(GetRectCenter(gg_rct_Gebiet_013)),'Nsnr')
call ReplaceTerrain('Ldro','Nice')
call ReplaceTerrain('Bdsd','Wsnw')
call ReplaceTerrain('Bdrh','Nice')
call ReplaceTerrain('Bdrg','Nice')
call ReplaceTerrain('Bflr','Nice')
endfunction
private function Init takes nothing returns nothing
set maxX = GetRectMaxX(bj_mapInitialPlayableArea)
set minX = GetRectMinX(bj_mapInitialPlayableArea)
set maxY = GetRectMaxY(bj_mapInitialPlayableArea)
set minY = GetRectMinY(bj_mapInitialPlayableArea)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Kick
globals
constant integer HARD_KICK = 0
constant integer NORMAL_KICK = 1
constant integer LIGHT_KICK = 2
endglobals
private function Foo takes nothing returns nothing
call DoNothing() // We dont want this to be inlined
call Foo()
endfunction
function KickPlayer takes player p, integer How returns nothing
if How == NORMAL_KICK then
if GetLocalPlayer() == p then
call EndGame(false)
endif
elseif How == LIGHT_KICK then
if GetLocalPlayer() == p then
call EndGame(true)
endif
elseif How == HARD_KICK then
if GetLocalPlayer() == p then
loop
call Foo()
endloop
endif
endif
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
globals
boolean array German
endglobals
//TESH.scrollpos=0
//TESH.alwaysfold=0
globals
integer HPI //| Index of highest player
endglobals
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Debug initializer Irr requires Embasic
globals
constant integer MEMORY_MAXVALUES = 5
integer C = 0
string array String_A
string array String_B
boolean array Debug_D
integer array Integer_C
integer debugs = 0
//!
string array memString
string array memTypes
string array Memory
string array Memory_B
integer memc = 0
integer array mem
endglobals
function FindStringPartner takes string s returns integer
local integer i = 0
loop
set i = i + 1
exitwhen i > 150
if ( String_A[i] == s ) then
return i
//return udg_String_B
endif
endloop
return -1
endfunction
function Index2Debug takes integer sized, integer b returns integer
return sized+b*MEMORY_MAXVALUES
endfunction
function FindMemoryPartner takes string Identifier returns integer
local integer i = 0
loop
set i = i + 1
exitwhen i > 150
if ( Memory[i] == Identifier ) then
return i
//return udg_String_B
endif
endloop
return -1
endfunction
function Irr takes nothing returns nothing
local integer i = 0
loop
set i = i + 1
exitwhen i > 150
set mem[i] = 0
set Integer_C[i] = 0
endloop
endfunction
function CreateDebug takes string identifier, string replace returns nothing
set C = C + 1
set String_A[C] = identifier
set String_B[C] = replace
endfunction
// Ersetzt identifier durch den String_Partner
function ReplaceDebug takes string Identifier, string s returns nothing
local integer H = FindStringPartner(Identifier)
if ( Debug_D[H] ) == false then
return
endif
set s = String_B[H] + s
call DisplayTextToForce(GetPlayersAll(),s)
endfunction
function RDebug takes string Identifier, string s returns nothing
local integer H = FindStringPartner(Identifier)
if ( Debug_D[H] ) == false then
return
endif
set s = String_B[H] + s
call DisplayTextToForce(GetPlayersAll(),s)
endfunction
function MemoryDebug takes string Identifier, string s returns nothing
local integer H = FindMemoryPartner(Identifier)
set s = Memory_B[H] + s
call DisplayTextToForce(GetPlayersAll(),s)
endfunction
// Wenn ein Debug Identifier false ist, wird nichts geschrieben
function SetDebug takes string Identifier, boolean bool returns nothing
set Debug_D[FindStringPartner(Identifier)] = bool
endfunction
// Zählt einen integer für einen Identifier hoch
function NumDebug takes string Identifier returns nothing
local integer H = FindStringPartner(Identifier)
if ( Debug_D[H] ) == false then
return
endif
set Integer_C[H] = Integer_C[H] + 1
call DisplayTextToForce(GetPlayersAll(),String_B[H] + I2S(Integer_C[H]))
endfunction
function RPNumDebug takes string Identifier, string addstring returns nothing
local integer H = FindStringPartner(Identifier)
if ( Debug_D[H] ) == false then
return
endif
set Integer_C[H] = Integer_C[H] + 1
call DisplayTextToForce(GetPlayersAll(),String_B[H] + addstring + I2S(Integer_C[H]))
endfunction
// Setzt den Integer für einen Identifier auf 0
function ResetDebug takes string Identifier returns nothing
local integer H = FindStringPartner(Identifier)
if ( Debug_D[H] ) == false then
return
endif
call Debug("Reset_Debug for " + String_B[H])
set Integer_C[H] = 0
endfunction
function ClearMemory takes string Identifier returns nothing
local integer H = FindMemoryPartner(Identifier)
local integer i = 0
loop
set i = i + 1
exitwhen i > mem[H]
set memString[Index2Debug(H,i)] = ""
endloop
set mem[H] = 0
endfunction
function CreateMemory takes string Identifier, string replace returns nothing
set memc = memc + 1
set Memory[memc] = Identifier
set Memory_B[memc] = replace
endfunction
function DebugSpeicher takes string Identifier, string store returns nothing
local integer H = FindMemoryPartner(Identifier)
set mem[H] = mem[H] + 1
set memString[Index2Debug(H,mem[H])] = store
if ( H > MEMORY_MAXVALUES ) then
call Debug("Error: Erhoehe MEMORY_MAXVALUES in der Debug library")
endif
endfunction
function CheckMemory takes string Identifier, string toCheck, boolean displayErrors returns nothing
local integer i = 0
local integer H = FindMemoryPartner(Identifier)
local integer AbCount = 0
local string firststore = memString[Index2Debug(H,1)]
local string array errors
local integer errorcount = 0
set firststore = toCheck
call Debug("FIRST:"+firststore)
loop
set i = i + 1
exitwhen i > mem[H]
//call Debug(memString[Index2Debug(H,i)])
if ( firststore != memString[Index2Debug(H,i)] ) then
set AbCount = AbCount + 1
set errorcount = errorcount + 1
set errors[errorcount] = memString[Index2Debug(H,i)]
endif
endloop
call MemoryDebug(Identifier,"Memory checked. Values changed " +I2S(AbCount)+" Times")
if (displayErrors) then
set i = 0
loop
set i = i + 1
exitwhen i > errorcount
call Debug("Changed: " + errors[i])
endloop
endif
endfunction
endlibrary
//TESH.scrollpos=15
//TESH.alwaysfold=0
library UnitBars requires Debug
function CreateProgStr takes integer filles, integer Max, string color returns string
local integer i = 0
local string ret = color+"["
loop
set i = i + 1
exitwhen i > Max
if ( filles > i ) then
set ret = ret + "||||"
else
set ret = ret + " "
endif
endloop
set ret = ret + "]"
return ret
endfunction
struct UnitBar
unit caster
string progress
integer splits
real currentval
real max
string Color
texttag last
static method create takes unit u, real max, integer splits, string Colorcode returns UnitBar
local UnitBar l = UnitBar.allocate()
set l.caster = u
set l.splits = splits
set l.progress = ""
set l.Color = Colorcode
set l.currentval = 0.
set l.max = max
call RDebug("UB","Created")
return l
endmethod
method Update takes real value returns nothing
set .currentval = value
set .progress = CreateProgStr(R2I((value/.max)*.splits),.splits,.Color)
//call RDebug("Tb","Prog: "+.progress)
call DestroyTextTag(.last)
set .last = CreateTextTagUnitBJ(.progress,.caster,10,7,100.,100.,100.,0.)
if ( .currentval == .max ) then
//! D E S T R O Y
endif
endmethod
method GetValue takes nothing returns real
return .currentval
endmethod
method Increase takes nothing returns nothing
set .currentval = .currentval + .max/.splits
set .progress = CreateProgStr(R2I(.currentval/.max*.splits),.splits,.Color)
call DestroyTextTag(.last)
set .last = CreateTextTagUnitBJ(.progress,.caster,10,7,100.,100.,100.,0.)
endmethod
method IncreaseBy takes real val returns nothing
set .currentval = .currentval+val
set .progress = CreateProgStr(R2I((.currentval/.max)*.splits),.splits,.Color)
call DestroyTextTag(.last)
set .last = CreateTextTagUnitBJ(.progress,.caster,10,7,100.,100.,100.,0.)
call RDebug("UB","Update.")
if ( .currentval == .max ) then
//! D E S T R O Y
endif
endmethod
method onDestroy takes nothing returns nothing
call DestroyTextTag(.last)
endmethod
endstruct
endlibrary
//TESH.scrollpos=118
//TESH.alwaysfold=0
library ColorFunctions initializer InitColors
function Int2Hex takes integer int returns string
local string charMap = "0123456789ABCDEF"
local string hex = ""
local integer index = 0
if ((int < 0) or (int > 0x7FFFFFFF)) then
return "|cffff0000Invalid argument in function Int2Hex()!|r"
endif
loop
set index = ModuloInteger(int, 0x10) + 1
set int = int / 0x10
set hex = SubStringBJ(charMap, index, index) + hex
exitwhen (int == 0)
endloop
return hex
endfunction
function Per2Clr takes string text, integer r, integer g, integer b, integer alpha returns string
local string array str
if ((r >= 0) and (r <= 100) and (g >= 0) and (g <= 100) and (b >= 0) and (b <= 100) and (alpha >= 0) and (alpha <= 100)) then
set r = R2I(0xFF / 100.000 * r)
set g = R2I(0xFF / 100.000 * g)
set b = R2I(0xFF / 100.000 * b)
set alpha = R2I(0xFF / 100.000 * alpha)
if (alpha <= 0xF) then
set str[0] = "0" + Int2Hex(alpha)
else
set str[0] = Int2Hex(alpha)
endif
if (r <= 0xF) then
set str[1] = "0" + Int2Hex(r)
else
set str[1] = Int2Hex(r)
endif
if (g <= 0xF) then
set str[2] = "0" + Int2Hex(g)
else
set str[2] = Int2Hex(g)
endif
if (b <= 0xF) then
set str[3] = "0" + Int2Hex(b)
else
set str[3] = Int2Hex(b)
endif
return "|c" + str[0] + str[1] + str[2] + str[3] + text
else
return "|cffff0000Invalid arguments in function Per2Clr()!|r"
endif
endfunction
function Dec2Hex takes integer i returns string
local string charMap="0123456789ABCDEF"
local string hex
if i>255 then
return "|cffff0000This function is NOT designed to convert values above 255!|r"
elseif i<0 then
return "|cffff0000 The value is to small!|r"
endif
if i<16 then
return "0"+SubString(charMap, i, i+1)
else
set hex=SubString(charMap, i/16, i/16+1)
set i=ModuloInteger(i, 16)
set hex=hex+SubString(charMap, i, i+1)
return hex
endif
endfunction
function MakeGradientText takes string toColor, integer r1, integer g1, integer b1, integer r2, integer g2, integer b2 returns string
local integer length=StringLength(toColor)
local integer rDif=(r1-r2)/length
local integer gDif=(g1-g2)/length
local integer bDif=(b1-b2)/length
local integer rN=r1
local integer gN=g1
local integer bN=b1
local integer i=0
local string rS=""
loop
exitwhen i>length
set rS=rS+"|cff" +Dec2Hex(rN)+Dec2Hex(gN)+Dec2Hex(bN)+SubString(toColor, i, i+1)
set rN=rN-rDif
set gN=gN-gDif
set bN=bN-bDif
set i=i+1
endloop
return rS+"|r"
endfunction
globals
private string array Color
private string array COLOR
private string array COLORNAME
integer colcount = 0
private string ABC = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
endglobals
function GetRandomColor takes nothing returns string
local string s = COLORNAME[GetRandomInt(1,colcount)]
return s
endfunction
function NameToCode takes string colorname returns string
local integer i = 0
loop
set i = i + 1
exitwhen i > colcount
if ( colorname == COLORNAME[i] ) then
return COLOR[i]
endif
endloop
return "INVALID"
endfunction
function CreateColorData takes string name, integer red, integer green, integer blue, integer alpha returns nothing
set colcount = colcount + 1
set COLOR[colcount] = Per2Clr("",red,green,blue,alpha)
set COLORNAME[colcount] = name
endfunction
function ColorName takes nothing returns string
local integer i = 0
local string s = ""
local integer max = GetRandomInt(3,10)
local integer source
loop
set i = i + 1
exitwhen i > max
set source = GetRandomInt(1,62)
set s = s + SubStringBJ(ABC,source,source)
endloop
return s
endfunction
function CreateRandomColor takes nothing returns nothing
call CreateColorData(ColorName(),GetRandomInt(1,100),GetRandomInt(1,100),GetRandomInt(1,100),GetRandomInt(1,100))
endfunction
function InitColors takes nothing returns nothing
call CreateColorData("blue",0,0,100,0)
call CreateColorData("Tiberium",0,40,0,0)
call CreateColorData("green",0,100,0,0)
call CreateColorData("star",41,10,79,0)
call CreateColorData("strange",0,88,79,0)
call CreateColorData("blasphemy",77,1,1,7)
call CreateColorData("Midas Hand",100,80,20,7)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_MB_Zeit_Actions takes nothing returns nothing
local integer i = 0
call MultiboardSetItemValueBJ( GetLastCreatedMultiboard(), 2, 2, GameTimeString() )
endfunction
//===========================================================================
function InitTrig_MB_Zeit takes nothing returns nothing
set gg_trg_MB_Zeit = CreateTrigger( )
call DisableTrigger( gg_trg_MB_Zeit )
call TriggerRegisterTimerEventPeriodic( gg_trg_MB_Zeit, 1.00 )
call TriggerAddAction( gg_trg_MB_Zeit, function Trig_MB_Zeit_Actions )
endfunction
//TESH.scrollpos=9
//TESH.alwaysfold=0
function Trig_Sell_Func006C takes nothing returns boolean
if ( ( GetSpellAbilityId() == 'A003' ) ) then
return true
endif
if ( ( GetSpellAbilityId() == 'A00N' ) ) then
return true
endif
return false
endfunction
function Trig_Sell_Conditions takes nothing returns boolean
if ( not Trig_Sell_Func006C() ) then
return false
endif
return true
endfunction
function Trig_Sell_Func004C takes nothing returns boolean
if ( not ( udg_TempReal < 0.10 ) ) then
return false
endif
return true
endfunction
function Trig_Sell_Actions takes nothing returns nothing
set udg_TempReal = ( GetUnitLifePercent(GetTriggerUnit()) - 25.00 )
set udg_TempReal = ( udg_TempReal / 100.00 )
call DisplayTextToForce( GetPlayersAll(), R2S(udg_TempReal) )
if ( Trig_Sell_Func004C() ) then
set udg_TempReal = 0.10
else
endif
call SellUnit(GetTriggerUnit(),udg_TempReal)
endfunction
//===========================================================================
function InitTrig_Sell takes nothing returns nothing
set gg_trg_Sell = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Sell, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( gg_trg_Sell, Condition( function Trig_Sell_Conditions ) )
call TriggerAddAction( gg_trg_Sell, function Trig_Sell_Actions )
endfunction
//TESH.scrollpos=3
//TESH.alwaysfold=0
library MidasBarsLibrary requires UnitBars, Debug
globals
integer Midascounter = 0
UnitBar array MidasHandBar
integer array MidasBar
endglobals
function UpdateBar takes nothing returns nothing
local integer i = 0
local UnitBar tempMidas
local group g
call RDebug("MH","Update Bars")
//call ClearMemory("MH")
loop
set i = i + 1
exitwhen i > Midascounter
set tempMidas = MidasHandBar[i]
call MidasHandBar[i].IncreaseBy(1.)
if ( MidasHandBar[i].currentval > 140. ) then
set g = NewGroup()
set g = GetUnitsInRectOfPlayer(GetPlayableMapRect(),GetOwningPlayer(MidasHandBar[i].caster))
call UnitResetCooldown(MidasHandBar[i].caster)
call IssueTargetOrderBJ(MidasHandBar[i].caster,"charm",GroupPickRandomUnit(g))
call MidasHandBar[i].Update(0.)
call ReleaseGroup(g)
endif
endloop
// call CheckMemory("MH","",false)
set g = null
endfunction
endlibrary
function Trig_Midas_Hand_Actions takes nothing returns nothing
local integer ID = GetUnitTypeId(GetTriggerUnit())
local integer index = 0
local unit u = GetTriggerUnit()
local UnitBar MidasHand
if ( ID != 'h00E' and ID != 'h00T' ) then
call RDebug("MH","Entering unit is not a Midas Hand")
set u = null
return
endif
set index = Index(u)
set Midascounter = Midascounter + 1
//call Debug("Index for Midas Hand: "+I2S(index))
//call Debug("Midas Hand Nr."+I2S(Midascounter))
set GoldSpeicher[index] = 0
set MidasBar[index] = Midascounter
set MidasHandBar[Midascounter] = UnitBar.create(u,140.,50,NameToCode("Midas Hand"))
set u = null
endfunction
//===========================================================================
function InitTrig_Midas_Hand takes nothing returns nothing
set gg_trg_Midas_Hand = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Midas_Hand, EVENT_PLAYER_UNIT_UPGRADE_FINISH )
call TriggerAddAction( gg_trg_Midas_Hand, function Trig_Midas_Hand_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Gold_Speicher_Conditions takes nothing returns boolean
if GetSpellAbilityId() == 'A00C' or GetSpellAbilityId() == 'A00K' then
return true
endif
return false
endfunction
function Trig_Gold_Speicher_Actions takes nothing returns nothing
local integer index = Index(GetTriggerUnit())
local unit target = GetSpellTargetUnit()
set udg_TempValue = ( GetUnitStateSwap(UNIT_STATE_LIFE, GetSpellTargetUnit()) / 4.00 )
call FadeUnit(target,4.,100,100,0,0,false)
set GoldSpeicher[index] = GoldSpeicher[index] + udg_TempValue
call TriggerSleepAction( 4. )
call AddEffectTimer(AddSpecialEffect("Abilities\\Spells\\Other\\Transmute\\PileofGold.mdl",GetUnitX(target),GetUnitY(target)),1.)
call PlaySoundOnUnitBJ(gg_snd_AlchemistTransmuteDeath1,100,target)
call RemoveUnit(target)
set target = null
call MidasHandBar[MidasBar[index]].Update(0.)
endfunction
//===========================================================================
function InitTrig_Gold_Speicher takes nothing returns nothing
set gg_trg_Gold_Speicher = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Gold_Speicher, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( gg_trg_Gold_Speicher, Condition( function Trig_Gold_Speicher_Conditions ) )
call TriggerAddAction( gg_trg_Gold_Speicher, function Trig_Gold_Speicher_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Kraftfeld_Conditions takes nothing returns boolean
if GetSpellAbilityId() == 'A00H' or GetSpellAbilityId() == 'A00J' then
return true
endif
return false
endfunction
function Trig_Kraftfeld_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddAbility(u,'A00I')
call TriggerSleepAction(10.)
call UnitRemoveAbility(u,'A00I')
set u = null
endfunction
//===========================================================================
function InitTrig_Kraftfeld takes nothing returns nothing
set gg_trg_Kraftfeld = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Kraftfeld, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( gg_trg_Kraftfeld, Condition( function Trig_Kraftfeld_Conditions ) )
call TriggerAddAction( gg_trg_Kraftfeld, function Trig_Kraftfeld_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Death_Func001C takes nothing returns boolean
if ( ( GetUnitTypeId(GetTriggerUnit()) == 'hpea' ) ) then
return true
endif
if ( ( GetUnitTypeId(GetTriggerUnit()) == 'h00J' ) ) then
return true
endif
return false
endfunction
function OkRevive takes integer value, Dialog vote returns nothing
call vote.destroy()
endfunction
function Trig_Death_Conditions takes nothing returns boolean
if ( not Trig_Death_Func001C() ) then
return false
endif
if ( not ( GetPlayerSlotState(GetOwningPlayer(GetTriggerUnit())) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Death_Actions takes nothing returns nothing
local Dialog D
set udg_TempValue = ( I2R(udg_Difficulty) + 25.00 )
call Revive(GetTriggerUnit(),R2I(udg_TempValue))
if German[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] then
set D = Dialog.create("Du bist gestorben. Du wirst |cffFFC834in "+I2S(R2I(udg_TempValue))+" Sekunden wiederbelebt|r.",OkRevive,30.)
else
set D = Dialog.create("You died. You will |cffFFC834revive in "+I2S(R2I(udg_TempValue))+" seconds|r.",OkRevive,30.)
endif
call D.AddOption("Ok",0)
call D.ShowFor(GetOwningPlayer(GetTriggerUnit()))
endfunction
//===========================================================================
function InitTrig_Death takes nothing returns nothing
set gg_trg_Death = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Death, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( gg_trg_Death, Condition( function Trig_Death_Conditions ) )
call TriggerAddAction( gg_trg_Death, function Trig_Death_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Afk initializer Init requires I2T
//! Explicity
//: This is, how many different things are checked by the AFK System
//: 1 - Unit Orders are checked
//: 2 - The Chat is checked, too
//: 3 - Keyboard Events are registered, too.
//: 4 - Registers, if a unit is selected.
//: I recommend 2! Or 3. But 4 creates a lot of code stuff, becase I have to use a workaround
//! Note
//: This is non optimized! So.. if you want to use it :-)
//: Ok. It works.
//: But the code looks like Spaghetti. I2T and AfK System by Mr.Malte.
globals
private constant integer Explicity = 4
private constant string AfkStringType = "Highest Device" // possible: "Mathematical", "Highest Device" and "Linguar"
private constant string StatePrefix = ""
private constant integer START_AT = 0 //: 0 - variables use the first place of arrays.
private constant real UPDATE_INTERVAL = 1. //: Higher: More explicit AFK-Time Lower: Better Performance
private constant integer MAX_PLAYERS = 12 //: How many players can play your map?
private constant real AFK_AFTER = 110. //: Register AFK, when the Player didn't do anything for 30 seconds.
public boolean array AFK
private timer AfkTimer
private player array Playing_Players
private trigger UnitController
private trigger ChatController
private trigger KeyboardController
private trigger SelectionController
private trigger SelectionAdder
public real array AfkFor
endglobals
globals
public real array LastAfkTime
endglobals
private struct UserMethods
static method onReturn takes player p, real AfKtime returns nothing
set AFK[GetPlayerId(p)+START_AT] = false
call Display(ColorPlayer(p)+" is back",ColorPlayer(p)+" ist zurück.")
if German[GetPlayerId(p)] then
call DisplayTextToPlayer(p, 0, 0, "Willkommen zurück, "+ColorPlayer(p)+". Du warst "+I2T(R2I(LastAfkTime[GetPlayerId(p)+START_AT]),3)+" Stunden lang abwesend.")
else
call DisplayTextToPlayer(p, 0, 0, "Welcome back, "+ColorPlayer(p)+". You've been away for "+I2T(R2I(LastAfkTime[GetPlayerId(p)+START_AT]),3)+" hours.")
endif
endmethod
static method onAfk takes player p, real AfKtime returns nothing
call DisplayTextToForce(GetPlayersAll(),ColorPlayer(p)+ " ist abwesend.")
endmethod
endstruct
function IsPlayerAfk takes player p returns boolean
local integer num = GetPlayerId(p)+START_AT
set p = null
return AFK[num]
endfunction
function GetPlayerAfkTime takes player p returns real
local integer num = GetPlayerId(p)+START_AT
set p = null
return AfkFor[num]
endfunction
function GetPlayerAfkString takes player p returns string
if ( IsPlayerAfk(p) ) then
// First return: Returns the time in the highest Device (Not 2 minutes 4 seconds, but 2 Minutes or 2 seconds)
// Second return: Returns the time in hours ( 00:00:04 = 4 seconds)
// Third return: Returns the time in text devices (2 Minutes, 4 Seconds.)
if AfkStringType == "Highest Device" then
return StatePrefix+I2T_HD(R2I(GetPlayerAfkTime(p)))+" "+GetStringShortcut(I2T_Temp_Device)
elseif AfkStringType == "Mathematical" then
return StatePrefix+I2T(R2I(GetPlayerAfkTime(p)),3)
else
return StatePrefix+I2T_SF(R2I(GetPlayerAfkTime(p)),3)
endif
else
return StatePrefix
endif
endfunction
private function UpdateAfkState takes nothing returns nothing
local integer iterator = START_AT - 1
loop
set iterator = iterator + 1
exitwhen iterator > START_AT+MAX_PLAYERS
if GetPlayerSlotState(Player(iterator)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(iterator)) == MAP_CONTROL_USER then
set AfkFor[iterator] = AfkFor[iterator] + UPDATE_INTERVAL
if AfkFor[iterator] > AFK_AFTER then
if AFK[iterator] == false then
call UserMethods.onAfk(Player(iterator),AfkFor[iterator])
endif
set AFK[iterator] = true
else
set AFK[iterator] = false
endif
endif
endloop
endfunction
// The Rest is ugly code!
// And not interesting. Just creates the triggers that reset the Afk Values for players.
private function RegisterAfkReset takes player p returns nothing
local integer num = GetPlayerId(p)+START_AT
set LastAfkTime[num] = AfkFor[num]
if AFK[num] == true then
call UserMethods.onReturn(Player(num),AfkFor[num])
endif
set AfkFor[num] = 0.
endfunction
private function RegisterAfk takes nothing returns nothing
if ( IsUnitSelected(GetTriggerUnit(),GetOwningPlayer(GetTriggerUnit()) ) ) then
call RegisterAfkReset(GetOwningPlayer(GetTriggerUnit()))
endif
endfunction
private function RegisterAfkOnSelect takes nothing returns nothing
call RegisterAfkReset(GetOwningPlayer(GetTriggerUnit()))
endfunction
private function resetAfk takes nothing returns nothing
call RegisterAfkReset(GetTriggerPlayer())
endfunction
private function TriggerRegisterPlayerChat takes trigger t, string what, boolean case returns nothing
local integer index
set index = 0
loop
call TriggerRegisterPlayerChatEvent( t, Player(index), what, case )
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
endfunction
private function TriggerRegisterKeyboardEvent takes trigger trig returns nothing
local integer index
set index = 0
loop
call TriggerRegisterPlayerEvent(trig, Player(index), EVENT_PLAYER_ARROW_LEFT_DOWN)
call TriggerRegisterPlayerEvent(trig, Player(index), EVENT_PLAYER_ARROW_RIGHT_DOWN)
call TriggerRegisterPlayerEvent(trig, Player(index), EVENT_PLAYER_ARROW_UP_DOWN)
call TriggerRegisterPlayerEvent(trig, Player(index), EVENT_PLAYER_ARROW_DOWN_DOWN)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
endfunction
private function Selected takes nothing returns boolean
call TriggerRegisterUnitEvent( SelectionController, GetFilterUnit(), EVENT_UNIT_SELECTED )
return true
endfunction
// =================================================================================
// =================================================================================
private function Init takes nothing returns nothing
local group TempGroup
call TimerStart(CreateTimer(),UPDATE_INTERVAL,true,function UpdateAfkState)
if Explicity > 0 then
set UnitController = CreateTrigger()
call TriggerAddAction(UnitController,function RegisterAfk)
call TriggerRegisterAnyUnitEventBJ( UnitController, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterAnyUnitEventBJ( UnitController, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterAnyUnitEventBJ( UnitController, EVENT_PLAYER_UNIT_ISSUED_ORDER )
endif
if Explicity > 1 then
set ChatController = CreateTrigger()
call TriggerAddAction(ChatController,function resetAfk)
call TriggerRegisterPlayerChat ( ChatController, "", false )
endif
if Explicity > 2 then
set KeyboardController = CreateTrigger()
call TriggerAddAction(KeyboardController,function resetAfk)
call TriggerRegisterKeyboardEvent ( KeyboardController )
endif
if Explicity > 3 then
set SelectionController = CreateTrigger()
call TriggerAddAction(SelectionController,function RegisterAfkOnSelect)
set TempGroup = GetUnitsInRectMatching(GetPlayableMapRect(),Filter(function Selected))
call DestroyGroup(TempGroup)
set SelectionAdder = CreateTrigger()
call TriggerAddCondition(SelectionAdder,Filter(function Selected))
call TriggerRegisterEnterRectSimple( SelectionAdder, GetPlayableMapRect() )
endif
//call TriggerRegisterPlayerChatEvent(ChatController,Player(0),"",false)
endfunction
endlibrary
library I2T initializer Init requires Embasic // IntegerToTime - Converts a second integer to a time string.
// Device is, how many devices you want.
// Example:
// I2T(127,3) would return
// 00:02:07
// 3 devices: Hours, minutes, seconds
globals
private integer array Convertions
private string array ConvertionName
public string Temp_Device
endglobals
function GetStringShortcut takes string s returns string
return SubStringBJ(s,1,3)+"."
endfunction
function ConvertDevice takes integer Count returns integer
local integer device = 1
loop
exitwhen Count < 1
set device = device * Convertions[Count]
set Count = Count - 1
endloop
return device
endfunction
function I2T takes integer time, integer Devices returns string
local integer TempTime = 0
local integer Power
local string timeret = ""
loop
exitwhen Devices < 1
set Power = ConvertDevice(Devices)
set TempTime = time/Power // Hours
set time = time - (TempTime*Power)
if TempTime < 10 then
set timeret = timeret + "0"+I2S(TempTime)
else
set timeret = timeret + I2S(TempTime)
endif
if Devices > 1 then
set timeret = timeret+":"
endif
set Devices = Devices - 1
endloop
return timeret
endfunction
function I2T_SF takes integer time, integer Devices returns string
local integer TempTime = 0
local integer Power
local string timeret = ""
loop
exitwhen Devices < 1
set Power = ConvertDevice(Devices)
set TempTime = time/Power // Hours
set time = time - (TempTime*Power)
set timeret = timeret +I2S(TempTime)+" "+ConvertionName[Devices]
if Devices > 1 then
set timeret = timeret + ", "
endif
set Devices = Devices - 1
endloop
return timeret
endfunction
function I2T_HD takes integer time returns string
local integer i = 5
local integer dev
if time < 0 then
return "Error: Neagtive Time as Parameter"
endif
loop
set i = i - 1
set dev = ConvertDevice(i)
exitwhen dev < time
endloop
set time = time/dev
set Temp_Device = ConvertionName[i]
return I2S(time)
endfunction
private function Init takes nothing returns nothing
set Convertions [1] = 1
set ConvertionName[1] = "Sekunden"
set Convertions [2] = 60
set ConvertionName[2] = "Minuten"
set Convertions [3] = 60
set ConvertionName[3] = "Stunden"
set Convertions [4] = 24
set ConvertionName[4] = "Tage"
set Convertions [5] = 30
set ConvertionName[5] = "Monate"
set Convertions [6] = 364
set ConvertionName[6] = "Jahre"
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Tipps initializer Init requires Embasic
globals
private integer TC = 0
private string array T
private string array TT
endglobals
function DisplayTip takes nothing returns nothing
local integer i
if TC == 0 then
return
endif
set i = GetRandomInt(1,TC)
call Display("|cff009500Tip: |r"+TT[i],"|cff009500Tipp: |r"+T[i])
set T[i] = T[TC]
set TC = TC - 1
endfunction
private function Init takes nothing returns nothing
set TC = TC + 1
set T[TC] = "Manchmal greifen rote Kodos an, die an einem Gebäude explodieren"
set TT[TC] = "Sometimes red kodos attack that explode when hitting a building"
set TC = TC + 1
set T[TC] = "Wenn ein Spieler stört, schmeiße ihn mit dem Kommando '-votekick #' aus dem Spiel, wobei # für seine Spielernummer steht."
set TT[TC] = "If a player disturbs you, kick him out of the game with the command '-votekick #', where # stands for the player's number."
set TC = TC + 1
set T[TC] = "Jede Barrikade erhöht das Leben deiner anderen Barrikaden prozentual."
set TT[TC] = "Each barricade increases the life of your other barricades percentagely."
set TC = TC + 1
set T[TC] = "Goldspender können zu 'Midas Hand' ausgebaut werden, die dein Einkommen drastisch erhöht"
set TT[TC] = "Golddonors can be upgraded to 'Hand of Midas' which increases your income drastically"
set TC = TC + 1
set T[TC] = "Mit dem Kommande -votesell kann darüber abgestimmt werden, ob das von dir ausgewählt Gebäude verkauft werden soll"
set TT[TC] = "The command -votesell starts a poll about selling the selected building"
return
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//! textmacro implementHotkeyExtension
method MakeFirstLetterHotkeyMap takes nothing returns nothing
local integer i2 = Temp_Starter
local integer i3 = 0
local integer i4 = 0
local integer endAt
local integer givenCount = 0
local string array given
local string tempString
local boolean correct = false
if .OptionCount > ABC_LENGTH then
set .Rebuild = true
endif
if .Rebuild then
set endAt = i2 + MAX_OPTIONS_PER_PAGE
else
set endAt = .OptionCount
endif
loop
set i2 = i2 + 1
exitwhen i2 > endAt
if .Hotkeys[i2] == 0 then
set i3 = 0
loop
set i3 = i3 + 1
exitwhen i3 > StringLength(.Options[i2])
set tempString = SubString(.Options[i2],i3-1,i3)
set i4 = 0
set correct = true
loop
set i4 = i4 + 1
exitwhen i4 > givenCount
if tempString == given[i4] then
set correct = false // Strings can't have more than 820 letters, so this is safe.
endif
endloop
if correct then
set givenCount = givenCount + 1
set given[givenCount] = tempString
call StringContainsString(HOTKEY_CHARMAP,tempString)
set .Hotkeys[i2] = FoundAt
set .Options[i2] = SubString(.Options[i2],0,i3-1)+HOTKEY_COLOR+SubString(.Options[i2],i3-1,i3)+"|r"+SubString(.Options[i2],i3,StringLength(.Options[i2]))
set i3 = 850
endif
endloop
endif
endloop
set Temp_Starter = 0
endmethod
//! endtextmacro
//TESH.scrollpos=18
//TESH.alwaysfold=0
library DialogTimers initializer Init requires DialogSystem
private struct Timer
integer Max
integer Expired
Dialog d
string Msg
boolean ddestroy
// implement Collector :( Not approved
// So:
integer position
static thistype array Data
static integer Instances = 0
method onDestroy takes nothing returns nothing
set .Data[.position] = .Data[.Instances]
set .Instances = .Instances - 1
endmethod
static method create takes nothing returns thistype
local thistype w = thistype.allocate()
set .Instances = .Instances + 1
set w.position = .Instances
set .Data[.Instances] = w
return w
endmethod
endstruct
private function Loop takes nothing returns nothing
local integer i = 0
local Timer t
loop
set i = i + 1
exitwhen i > Timer.Instances
set t = Timer.Data[i]
set t.Expired = t.Expired + 1
if t.Expired > t.Max then
if t.ddestroy then
call t.d.destroy()
else
call t.d.HideAll()
endif
return
endif
call t.d.ChangeName(t.Msg+"|n|n|cffff0000"+I2S(t.Max-t.Expired)+"|r seconds left.|r") // The Dialog System will not parse this, since it contains |n
endloop
endfunction
function SetDialogTime takes Dialog d, real time, boolean destroy returns nothing
local Timer t = Timer.create()
set t.Max = R2I(time+0.5)
set t.d = d
set t.Msg = d.Name
set t.Expired = 0
set t.ddestroy = destroy
endfunction
private function Init takes nothing returns nothing
call TimerStart(CreateTimer(),1.,true,function Loop)
endfunction
endlibrary
//TESH.scrollpos=11
//TESH.alwaysfold=0
//*********************************************************************
//* Dialog System v1.06
//* -------------
//*
//* To implement it , create a custom text trigger called Dialog System
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: wc3c.net
//*
//* Made by Mr.Malte.
//* This system took a lot of time to create.
//* So be fair and give credits to me when you use it!
//*
//* Requires Table by Vexorian.
//********************************************************************
function interface AfterCode takes integer value, Dialog vote returns nothing
// Do whatever you want here.
// onVoteEnd: This happens, if a vote ended. VoteResult refers to the option that won the vote.
// onVoteTimeEnd: This happens, if a vote ended. VoteResult refers to the option that won the vote.
library DialogSystem initializer Init requires Table
// ============ ========================================= ============
// ============ C O N F I G U R A T I O N S E C T I O N ============
// ============ ========================================= ============
// MAKE THIS SYSTEM FIT YOUR NEEDS!
globals
constant integer INSIDE = 0 // Hotkeys are searched in the options texts
constant integer OUTSIDE = 1 // Options are numbered: 1, 2, 3 ... a, b, c usw.
constant boolean VOTING = true // To ease cheking if a vote is running.
constant boolean NOT_VOTING = false // Example: if GetVotingState() == VOTING then
endglobals
globals
private constant integer MAX_OPTIONS_PER_PAGE = 9 // How many options you can have per page until a 'Next' button will appear.
private constant integer MAX_OPTIONS_PER_DIALOG = 200 // How many options a dialog can have.
private constant integer ARRAY_SIZE = 8191 // You can have ARRAY_SIZE/MAX_OPTIONS_PER_DIALOG dialogs.
private constant string NEW_OPTION = ";" // How the options are parted (Example: AddOptions("Hey;You").
private constant string HOTKEY_COLOR = "|cffFA7512"
private constant string NEXT = "Next Page"
private constant string PREVIOUS = "Previous Page"
private constant string COLOR_DEBUG = "|cffff0000"
private constant boolean ALLOW_HIDING_VOTES = true // If this is false, votes cant be hidden.
private constant integer HOTKEY_SEARCH_STANDARD = INSIDE // If you don't change .HotkeySearchMethod,
// Hotkeys are searched like this.
private constant boolean CYCLE = true // If true, the pages are cycles, so if you click 'Next' on the
// Last page, you will get to the first page instead of the last one again.
private constant boolean SET_LINEBREAKS = true // If this is true, the system sets linebreaks in headings.
private constant real BASIC_DIALOG_WIDTH = 11. // If the Linebreak Set function causes problems, decrease this.
private constant boolean EXPLICIT_DEBUG = false // If this is true, the system also displays errors which can be fixed flawlessly.
endglobals
struct UserMethods
static method onVoteEnd takes string voteResult returns nothing
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Vote ended. Winning option: '|cffFFCC33"+voteResult+"|r'.")
endmethod
static method onVoteTimeEnd takes nothing returns nothing
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"|cffFFCC33Voting time ended.|r")
endmethod
endstruct
// ============ ========================================= ============
// ============ I N T E R N A L S E C T I O N ============
// ============ ========================================= ============
// DO NOT EDIT UNDER THIS LINE!
globals
player ClickingPlayer = null
private boolean IsVoting = false
private dialog array DS // Short: Dialog shown. The real dialog variable; Which dialog is shown to which player?
private button array Buttons[ARRAY_SIZE]
private button array Next_or_Previous[ARRAY_SIZE]
private integer array Result
private trigger ClickChecker
private integer Voted = 0
private integer array CurrentPage
private timer Voting = CreateTimer()
private integer LastWinningOption = 0
private integer FoundAt = 0
private integer Temp_Starter = 0
Dialog DSTempDialog // While voting
Dialog TempVoting
Dialog array CurrentOption // The dialogs that are shown to the players.
// If a dialog is started while another one is running, it is given to the stack
// and executed after the first one finished.
private constant integer DIALOG_TYPE_VOTE = 0
private constant integer DIALOG_TYPE_OPTION = 1
private Dialog array Stack
private integer array StackNumber
// Votes are more important: They are executed before options.
private Dialog array VoteStack
private integer VoteStackNumber = 0
endglobals
private function Index2D takes integer a, integer size, integer sized returns integer
return ((a*size)+sized)
endfunction
private function Debug takes Dialog causer, string s returns nothing
// In debug mode: No return. 0 is never 1.
debug if 0 == 1 then
return
debug endif
call DisplayTextToPlayer(GetLocalPlayer(),0,0,COLOR_DEBUG+"Dialog System: |r"+s)
if causer != 0 then
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Error caused by: '"+causer.Name+"'")
endif
endfunction
function RemoveColorcodes takes string from returns string
local string clear = from
local integer i = 0
local integer MAX = StringLength(from)
loop
set i = i + 1
exitwhen i > MAX
if SubString(from,i-1,i) == "|" then
if SubString(from,i-1,i+1) == "|c" then
set clear = SubString(clear,0,i-1)+SubString(clear,i+9,StringLength(clear))
set MAX = MAX - 9
else
set clear = SubString(clear,0,i-1)+SubString(clear,i+2,StringLength(clear))
set MAX = MAX - 2
endif
endif
endloop
return clear
endfunction
function GetClickingPlayer takes nothing returns player
return ClickingPlayer
endfunction
function GetVotingState takes nothing returns boolean
return IsVoting
endfunction
function GetPlayerDialog takes player p returns Dialog
if IsVoting then
return TempVoting
else
return CurrentOption[GetPlayerId(p)]
endif
endfunction
private function GetMostVotes takes nothing returns integer
local integer i = 0
local integer DStemp = 0
local integer option = 0
loop
set i = i + 1
exitwhen i > TempVoting.OptionCount
if Result[i] > DStemp then
set DStemp = Result[i]
set option = i
elseif Result[i] == DStemp then
// Two results match; Let a random generator decide which option won.
// Chances: 50% to 50%
if GetRandomInt(1,2) == 1 then
set option = i
endif
endif
endloop
return option
endfunction
private function ExecuteVoting takes nothing returns nothing
// Now each player voted. It's time to execute the Voting!
set IsVoting = false
set LastWinningOption = GetMostVotes()
set TempVoting.onVoteClick = 0
call UserMethods.onVoteEnd(RemoveColorcodes(TempVoting.Options[LastWinningOption]))
call TempVoting.EndVote.evaluate(TempVoting.Values[LastWinningOption],TempVoting)
endfunction
globals
public integer Main = 0
public integer Highest_ID = 0
private trigger Leave
private force Playing
endglobals
private function CompareID takes nothing returns nothing
if GetPlayerId(GetEnumPlayer()) > Highest_ID then
set Highest_ID = GetPlayerId(GetEnumPlayer())
endif
endfunction
// A player leaves
private function DecreasePlaying takes nothing returns nothing
set Main = Main - 1
if GetPlayerId(GetTriggerPlayer()) == Highest_ID then
call ForceRemovePlayer(Playing,GetTriggerPlayer())
set Highest_ID = 0
call ForForce(Playing, function CompareID)
endif
// Still voting: Check now if everybody voted.
if IsVoting then
if Voted == Main and TempVoting.Vote[GetPlayerId(GetTriggerPlayer())] != 0 then
call PauseTimer(Voting)
call ExecuteVoting()
endif
endif
endfunction
private function GetHID takes nothing returns integer
return Highest_ID
endfunction
private function EndVoting takes nothing returns nothing
// We can safely say, that the current options are TempVoting, because this is only
// called on Vote End.
call TempVoting.HideAll()
call UserMethods.onVoteTimeEnd()
call ExecuteVoting()
endfunction
private function CheckClicks takes nothing returns nothing
local integer i = 0
local integer ID = GetPlayerId(GetTriggerPlayer())
local boolean noStack = true
local Dialog DStemp
set ClickingPlayer = GetTriggerPlayer()
if IsVoting then
set DStemp = TempVoting
else
set DStemp = CurrentOption[ID]
endif
// A button was clicked.
// Next or previous button: A new page.
if GetClickedButton() == Next_or_Previous[Index2D(1,12,ID)] then
set CurrentPage[ID] = CurrentPage[ID] + 1
call DStemp.InternalShow(Player(ID))
return
elseif GetClickedButton() == Next_or_Previous[Index2D(2,12,ID)] then
set CurrentPage[ID] = CurrentPage[ID] - 1
call DStemp.InternalShow(Player(ID))
return
endif
// Was another button.
loop
set i = i + 1
exitwhen i > DStemp.OptionCount
// Check, which one the clicked button was
if GetClickedButton() == Buttons[Index2D(i,12,ID)] then
// Clicked during vote: Can just be a voting dialog.
if IsVoting then
set Result[i] = Result[i] + 1
set Voted = Voted + 1
set DStemp.Vote[ID] = DStemp.Values[i]
if DStemp.onVoteClick != 0 then
call DStemp.onVoteClick.evaluate(DStemp.Values[i],DStemp)
endif
// Everybody votet: End voting.
if Voted == Main then
call PauseTimer(Voting)
call ExecuteVoting()
// return: Commented return, because of the new Stack feature.
set i = DStemp.OptionCount + 1
endif
else
// Evaluate, dialog was shown as option.
// It is very important that the order is correct and CurrentOption is set to 0
// firstly. If you start another dialog in the EndCode otherwise, this is given
// to the stack and executed twice.
set CurrentOption[ID] = 0
call DStemp.EndVote.execute(DStemp.Values[i],DStemp)
set i = DStemp.OptionCount + 1
endif
endif
endloop
// Check if players has options on stack.
if StackNumber[ID] > 0 then
// I could show the highest Dialog from the stack, but I want the correct order.
call Stack[Index2D(1,12,ID)].ShowFor(GetTriggerPlayer())
set Stack[Index2D(1,12,ID)] = Stack[Index2D(StackNumber[ID],12,ID)]
set StackNumber[ID] = StackNumber[ID] - 1
return
endif
// Check if any player has still an option in the stack.
set i = 0
loop
exitwhen i > Highest_ID
set i = i + 1
if StackNumber[i] != 0 then
set noStack = false
set i = Highest_ID + 1
endif
endloop
// No? Execute vote from the stack.
if noStack and VoteStackNumber > 0 then
call VoteStack[1].StartVote()
set VoteStack[1] = VoteStack[VoteStackNumber]
set VoteStackNumber = VoteStackNumber - 1
endif
endfunction
// Give to stack when:
// -A vote stats
// -An option would interrupt another one.
// -If a vote starts, all options are given to the stacks.
public function GiveToStack takes player p, Dialog Next, integer DialogType returns nothing
local integer ID = GetPlayerId(p)
if Next == 0 then
call Debug(0,"Given null dialog to stack.")
return
endif
if DialogType == DIALOG_TYPE_OPTION then
set StackNumber[ID] = StackNumber[ID] + 1
set Stack[Index2D(StackNumber[ID],12,ID)] = Next
else
set VoteStackNumber = VoteStackNumber + 1
set VoteStack[VoteStackNumber] = Next
endif
endfunction
globals
private constant integer INVALID = -5
private constant integer FIRST_INDEX_NUMBERS = 47
private constant integer FIRST_INDEX_LETTERS = 54
private constant string HOTKEY_CHARMAP = "0123456789abcdefghijklmnopqrstuvwxyz"
private constant integer ABC_LENGTH = 35 // 25: We don't allow numbers.
endglobals
function S2HK takes integer ABCplace returns integer
if ABCplace < 11 then
return ABCplace + FIRST_INDEX_NUMBERS
else
return ABCplace + FIRST_INDEX_LETTERS
endif
return INVALID
endfunction
function StringContainsString takes string DialogStringa, string DialogStringb returns boolean
local integer i = 0
local integer max = StringLength(DialogStringa)
local integer lengthB = StringLength(DialogStringb)-1
set DialogStringa = StringCase(DialogStringa,false)
set DialogStringb = StringCase(DialogStringb,false)
loop
set i = i + 1
exitwhen i > max
if SubString(DialogStringa,i-1,i+lengthB) == DialogStringb then
set FoundAt = i
return true
endif
endloop
return false
endfunction
globals
private StringTable LetterSize
private constant real BasicSize = (0.35*100)
private constant real BasicSizeBIG = (0.55*100)
endglobals
function ParseDialogText takes string Text returns string
local real Width = 0.
local integer i = 0
local integer Max = StringLength(Text)
local boolean NextSpace = false
local string Sub
local boolean Open = true
if StringContainsString(Text,"|n") == true then
return Text
endif
//local string Pre = Text
loop
set i = i + 1
exitwhen i > Max
set Sub = SubString(Text,i-1,i)
// Colorcodes? No, we don't want Colorcodes.
if Sub == "|" then
if Open then
set i = i + 9
set Sub = SubString(Text,i-1,i)
set Open = false
else
set i = i + 2
set Sub = SubString(Text,i-1,i)
set Open = true
endif
endif
if NextSpace and ( Sub == " " or Sub == "-" ) then
set NextSpace = false
set Text = SubString(Text,0,i)+"|n"+SubString(Text,i,StringLength(Text))
elseif Width > BASIC_DIALOG_WIDTH then
set Width = 0.
set NextSpace = true
else
set Width = Width + (I2R(LetterSize[Sub])/100)
endif
endloop
set Sub = ""
//set Pre = ""
return Text
endfunction
private function FlushHotkey takes string s returns string
local integer length = StringLength(s)
// This is if a hotkey is made by []. This is safe, because the number in the bracket
// has never more than one digit.
if SubString(s,length-1,length) == "]" and SubString(s,length-3,length-2) == "[" then
return SubString(s,0,length-4) // 4: Example: Cell [2] ==> 8 digits.
// -4 = 4 digits = Cell
else
return RemoveColorcodes(s)
endif
endfunction
struct Dialog [ARRAY_SIZE]
boolean UsesHotkeys = false
boolean Rebuild = false
integer OptionCount = 0
string array Options[MAX_OPTIONS_PER_DIALOG]
integer array Values[MAX_OPTIONS_PER_DIALOG]
integer array Hotkeys[MAX_OPTIONS_PER_DIALOG]
integer array Vote[12]
integer HotkeySearchMethod
integer Data
string Name
real Time
AfterCode EndVote
AfterCode onVoteClick
//! runtextmacro implementHotkeyExtension()
method AttachData takes integer data returns nothing
set .Data = data
endmethod
method GetId takes nothing returns integer
return this
endmethod
method GetAttachedData takes nothing returns integer
return .Data
endmethod
method onDestroy takes nothing returns nothing
call .HideAll() // Of course we want to hide this!
loop
exitwhen .OptionCount == 0
set .Options[.OptionCount] = ""
set .Hotkeys[.OptionCount] = 0
set .Values[.OptionCount] = 0
set .OptionCount = .OptionCount - 1
endloop
set .Name = ""
endmethod
// Always attached the hotkey to the newest option!
method SetHotkey takes string HK returns nothing
set HK = SubString(HK,0,1) // More letters are not allowed as hotkey.
call StringContainsString(HOTKEY_CHARMAP,HK) // We abuse this, we want to find the ABC position of the Hotkey.
set .Hotkeys[.OptionCount] = FoundAt // FoundAt is the position where it was found, made with StringContainsString.
endmethod
method MakeHotkeyMap takes nothing returns nothing
// This takes really many Operations.
// But you will not notice any lag, even on the oldest computers.
// This is actually very, very fast (except the StringContainsString Func).
// It gets faster, if you don't look for the hotkeys in the words.
// Also, the hotkeys do only have to be initialized here; So if the page is opened 3 times,
// This generator does only create new hotkeys 1 time.
local integer i2 = Temp_Starter
local integer endAt = 0
local integer i4 = 0
local integer array Given
local integer givenCount = 0
local integer i3 = 0
local string tempOption // We could use .Option[index], but that would man a 2D index calculation each time.
local boolean given = false
// If this is true, the dialog has more options than hotkeys exist.
// In this case, the hotkey Charmap is rebuild each time, the page changes.
if .OptionCount > ABC_LENGTH then
set .Rebuild = true
endif
if .Rebuild then
// Just one page
set endAt = i2 + MAX_OPTIONS_PER_PAGE
else
set endAt = .OptionCount
endif
set .UsesHotkeys = true
// We know, that the dialog will not be configurated anymore.
// So we can get unique Hotkeys for the buttons.
// Loop through buttons
if .HotkeySearchMethod == INSIDE then
loop
set i2 = i2 + 1
set i3 = 0
exitwhen i2 > endAt
if .Hotkeys[i2] == 0 then
// Loop throuh ABC
set Given[i2] = 0
loop
set i3 = i3 + 1
set i4 = 0
exitwhen i3 > ABC_LENGTH
set given = false
// Loop through given hotkeys
loop
set i4 = i4 + 1
exitwhen i4 > givenCount
if i3 == Given[i4] then
set i4 = givenCount + 1
set given = true
endif
endloop
if given == false and StringContainsString(.Options[i2],SubString(HOTKEY_CHARMAP,i3-1,i3)) then
set .Hotkeys[i2] = i3
set tempOption = .Options[i2]
set .Options[i2] = SubString(tempOption,0,FoundAt-1)+HOTKEY_COLOR+SubString(tempOption,FoundAt-1,FoundAt)+"|r"+SubString(tempOption,FoundAt,StringLength(tempOption))
set givenCount = givenCount + 1
set Given[givenCount] = i3
set i3 = ABC_LENGTH + 1
endif
endloop
else
// If this happens, there are 2 possibilites:
// A: The hotkey was added by hand. The hotkey is not used automatically.
// Yes, this will drain performance, but not much.
// B: The page is initialized. Then it wont matter at all, cause
// nothing is checked.
set givenCount = givenCount + 1
set Given[givenCount] = .Hotkeys[i2]
endif
endloop
endif
// Always possible that there aren't enough hotkeys.
// If SEARCH_HOTKEYS is brackets, all data are 0.
set i2 = Temp_Starter
loop
set i2 = i2 + 1
// If they're in brackets; We want the first number be 1.
set i3 = .HotkeySearchMethod
exitwhen i2 > endAt
// Loop through ABC
if .Hotkeys[i2] == 0 then
loop
set i3 = i3 + 1
set i4 = 0
exitwhen i3 > ABC_LENGTH
set given = false
loop
set i4 = i4 + 1
exitwhen i4 > givenCount
if i3 == Given[i4] then
set i4 = givenCount + 1
set given = true
endif
endloop
if given == false then
set .Hotkeys[i2] = i3
set .Options[i2] = .Options[i2]+" ["+HOTKEY_COLOR+SubString(HOTKEY_CHARMAP,i3-1,i3)+"|r]"
set givenCount = givenCount + 1
set Given[givenCount] = i3
set i3 = ABC_LENGTH + 1
endif
endloop
// Else: Do nothing. We did also init hotkeys that were added by hand.
endif
endloop
set Temp_Starter = 0
endmethod
// This method is called by various functions/methods, so
// show methods forward the data to this dialog.
method InternalShow takes player p returns nothing
local integer index = GetPlayerId(p)
local integer i = 0
local integer exit = 0
local integer highestPage = ((.OptionCount-1)/MAX_OPTIONS_PER_PAGE)
call DialogClear(DS[index])
call DialogSetMessage(DS[index],.Name)
// Dialogs have many pages.
// A dialog has, lets say, 70 options.
// This figures out, at which place the options start/if there
// are more options.
// Clicked 'previous page' at page one.
if CurrentPage[index] < 0 then
if CYCLE then
set CurrentPage[index] = highestPage
else
set CurrentPage[index] = 0
endif
// Clicked next page at last page.
elseif CurrentPage[index] > highestPage then
if CYCLE then
set CurrentPage[index] = 0
else
set CurrentPage[index] = highestPage
endif
endif
// If the dialog has more than OPTIONS options, they don't fit to one
// page and have to be parted.
if .OptionCount > MAX_OPTIONS_PER_PAGE then
set i = (CurrentPage[index])*MAX_OPTIONS_PER_PAGE
set exit = (CurrentPage[index]+1)*MAX_OPTIONS_PER_PAGE
if exit > .OptionCount then
set exit = .OptionCount
endif
// Add Next/Previous buttons if neccesary
set Next_or_Previous[Index2D(1,12,index)] = DialogAddButton(DS[index],NEXT,0)
set Next_or_Previous[Index2D(2,12,index)] = DialogAddButton(DS[index],PREVIOUS,0)
else
set i = 0
set exit = .OptionCount
endif
// Noew add the buttons.
// We COULD add the buttons when the dialog is created, but that would make
// the system use really much much more memory, become more complicated and in fact
// even slower.
if .Rebuild then
set Temp_Starter = i
call .MakeHotkeyMap()
endif
loop
set i = i + 1
exitwhen i > exit
set Buttons[Index2D(i,12,index)] = DialogAddButton(DS[index],.Options[i],S2HK(.Hotkeys[i]))
endloop
call DialogDisplay(p,DS[index],true)
endmethod
method ShowFor takes player p returns nothing
local integer ID = GetPlayerId(p)
if IsVoting or CurrentOption[ID] != 0 then
call GiveToStack(p,this,DIALOG_TYPE_OPTION)
if EXPLICIT_DEBUG then
call Debug(this,"Tried to show as Option while another dialog is running.")
endif
return
endif
set CurrentPage[ID] = 0
set CurrentOption[ID] = this
call .InternalShow(p)
set p = null
endmethod
method HideFor takes player p returns nothing
local integer ID = GetPlayerId(p)
// This is a method, not a static one. We do only want to hide
// the dialog, if it is correct.
if IsVoting == false and CurrentOption[ID] != this then
return
endif
if IsVoting then
if ALLOW_HIDING_VOTES == false then
if EXPLICIT_DEBUG then
call Debug(this,"Tried to hide voting")
endif
set p = null
return
else
set Voted = Voted + 1
if Voted == Main then
call PauseTimer(Voting)
call ExecuteVoting()
endif
endif
endif
call DialogDisplay(p,DS[ID],false)
set CurrentOption[ID] = 0
set p = null
endmethod
static method PlayerLoopHide takes nothing returns nothing
call DSTempDialog.HideFor(GetEnumPlayer())
endmethod
method HideAll takes nothing returns nothing
set DSTempDialog = this
call ForForce(Playing,function Dialog.PlayerLoopHide)
endmethod
static method PlayerLoopShow takes nothing returns nothing
call DSTempDialog.ShowFor(GetEnumPlayer())
endmethod
method ShowAll takes nothing returns nothing
set DSTempDialog = this
call ForForce(Playing,function Dialog.PlayerLoopShow)
endmethod
static method PlayerLoopUpdate takes nothing returns nothing
local integer ID = GetPlayerId(GetEnumPlayer())
if CurrentOption[ID] == DSTempDialog then
call DialogSetMessage(DS[ID],DSTempDialog.Name)
endif
endmethod
method Update takes nothing returns nothing
set DSTempDialog = this
call ForForce(Playing,function Dialog.PlayerLoopUpdate)
endmethod
method StartVote takes nothing returns nothing
local integer index = 0
local integer i = 0
local integer exit = 0
if IsVoting then
call GiveToStack(null,this,DIALOG_TYPE_VOTE)
return
endif
set IsVoting = true
set TempVoting = this
set Voted = 0
loop
set i = i + 1
exitwhen i > .OptionCount
set Result[i] = 0
endloop
set i = 0
loop
exitwhen index > Highest_ID
if CurrentOption[index] != 0 then
call GiveToStack(Player(index),CurrentOption[index],DIALOG_TYPE_OPTION)
set CurrentOption[index] = 0
endif
call .InternalShow(Player(index))
set index = index + 1
endloop
call TimerStart(Voting,.Time,false,function EndVoting)
endmethod
method StartVoteClickReaction takes AfterCode onClick returns nothing
call .StartVote()
set .onVoteClick = onClick
endmethod
method GetVote takes player p returns integer
return .Vote[GetPlayerId(p)]
endmethod
method AddSpecialOption takes string option, integer value, integer place, string Hotkey returns nothing
if StringLength(.Options[place]) > 0 then
call Debug(this,"You must use the 'AddSpecialOption' method for '"+option+"', before you add other options.")
return
endif
call StringContainsString(HOTKEY_CHARMAP,SubString(Hotkey,0,1))
loop
exitwhen place > MAX_OPTIONS_PER_DIALOG
// Place already filled: We have to push all buttons.
// That costs performance, but makes place for the new button.
set .Options[place] = option
set .Values[place] = value
set .Hotkeys[place] = FoundAt
set place = place + MAX_OPTIONS_PER_PAGE
endloop
endmethod
method AddOption takes string option, integer value returns nothing
if .OptionCount > MAX_OPTIONS_PER_DIALOG then
call Debug(this,"Too many options added. Increase MAX_OPTIONS_PER_DIALOG!")
return
endif
set .OptionCount = .OptionCount + 1
// If this is true, a special button stole the place.
// We simply increase optioncount.
if StringLength(.Options[.OptionCount]) > 0 then
loop
set .OptionCount = .OptionCount + 1
exitwhen StringLength(.Options[.OptionCount]) < 1
endloop
endif
set .Options[.OptionCount] = option
set .Values[.OptionCount] = value
endmethod
method AddValueOptions takes string before, string after, integer End, real Start, real m returns nothing
local integer i = 0
loop
set i = i + 1
exitwhen i > End
call .AddOption(before+I2S(R2I(i*m+Start))+after,R2I((i*m+Start)*10))
endloop
endmethod
method AddTextOptions takes string whichOptions returns nothing
local integer i = 0
local integer Length
local integer lastfound = 0
local integer count = 0
local integer newLength = StringLength(NEW_OPTION)-1
set whichOptions = whichOptions+NEW_OPTION
set Length = StringLength(whichOptions)
loop
set i = i + 1
exitwhen i > Length
if SubString(whichOptions,i-1,i+newLength) == NEW_OPTION then
set count = count + 1
if lastfound != 0 then
call .AddOption(SubString(whichOptions,lastfound+newLength,i-1),count)
else
call .AddOption(SubString(whichOptions,0,i-1),count)
endif
set lastfound = i
endif
endloop
endmethod
method ChangeName takes string s returns nothing
if SET_LINEBREAKS then
// If this is true, the player set linebreaks by hand - we don't have to make
// them artifically.
set s = ParseDialogText(s)
endif
set .Name = s
call .Update()
endmethod
method ChangeEndCode takes AfterCode b returns nothing
set .EndVote = b
endmethod
static method create takes string Name, AfterCode endvotewith, real Time returns Dialog
local Dialog a = Dialog.allocate()
if SET_LINEBREAKS then
// If this is true, the player set linebreaks by hand - we don't have to make
// them artifically.
set Name = ParseDialogText(Name)
endif
set a.Name = Name
set a.EndVote = endvotewith
set a.Time = Time
set a.HotkeySearchMethod = HOTKEY_SEARCH_STANDARD
return a
endmethod
static method StopVote takes nothing returns nothing
if IsVoting then
call PauseTimer(Voting)
call ExecuteVoting()
call TempVoting.HideAll()
debug else
debug if EXPLICIT_DEBUG then
debug call Debug(0,"Tried to End Voting, although no vote is running.")
debug endif
endif
endmethod
static method DoDebug takes nothing returns nothing
local integer i = 0
call Debug(0,"Votes in stack: "+I2S(VoteStackNumber))
loop
exitwhen i > 11
if StackNumber[i] != 0 then
call Debug(0,"Dialogs in Stack["+I2S(i+1)+"]: "+I2S(StackNumber[i]))
endif
set i = i + 1
endloop
if IsVoting then
call Debug(0,"Currently running Vote: "+TempVoting.Name)
else
call Debug(0,"Currently no Vote running.")
endif
endmethod
endstruct
private function InitLetterSize takes nothing returns nothing
set LetterSize = StringTable.create()
set LetterSize["a"] = R2I(BasicSize)
set LetterSize["b"] = R2I(BasicSize)
set LetterSize["c"] = R2I(BasicSize)
set LetterSize["d"] = R2I(BasicSize)
set LetterSize["e"] = R2I(BasicSize)
set LetterSize["f"] = R2I(BasicSize * 0.35)
set LetterSize["g"] = R2I(BasicSize)
set LetterSize["h"] = R2I(BasicSize)
set LetterSize["i"] = R2I(BasicSize * 0.3)
set LetterSize["j"] = R2I(BasicSize * 0.3)
set LetterSize["k"] = R2I(BasicSize)
set LetterSize["l"] = R2I(BasicSize * 0.3)
set LetterSize["m"] = R2I(BasicSize * 1.3)
set LetterSize["n"] = R2I(BasicSize)
set LetterSize["o"] = R2I(BasicSize)
set LetterSize["p"] = R2I(BasicSize)
set LetterSize["q"] = R2I(BasicSize)
set LetterSize["r"] = R2I(BasicSize * 0.35)
set LetterSize["s"] = R2I(BasicSize)
set LetterSize["t"] = R2I(BasicSize * 0.35)
set LetterSize["u"] = R2I(BasicSize)
set LetterSize["v"] = R2I(BasicSize)
set LetterSize["w"] = R2I(BasicSize * 1.3)
set LetterSize["x"] = R2I(BasicSize * 1.04)
set LetterSize["y"] = R2I(BasicSize)
set LetterSize["z"] = R2I(BasicSize)
set LetterSize["A"] = R2I(BasicSizeBIG)
set LetterSize["B"] = R2I(BasicSizeBIG)
set LetterSize["C"] = R2I(BasicSizeBIG * 1.2)
set LetterSize["D"] = R2I(BasicSizeBIG * 1.2)
set LetterSize["E"] = R2I(BasicSizeBIG)
set LetterSize["F"] = R2I(BasicSizeBIG)
set LetterSize["G"] = R2I(BasicSizeBIG * 1.17)
set LetterSize["H"] = R2I(BasicSizeBIG * 1.31)
set LetterSize["I"] = R2I(BasicSizeBIG)
set LetterSize["J"] = R2I(BasicSizeBIG)
set LetterSize["K"] = R2I(BasicSizeBIG)
set LetterSize["L"] = R2I(BasicSizeBIG)
set LetterSize["M"] = R2I(BasicSizeBIG)
set LetterSize["N"] = R2I(BasicSizeBIG)
set LetterSize["O"] = R2I(BasicSizeBIG * 1.2)
set LetterSize["P"] = R2I(BasicSizeBIG)
set LetterSize["Q"] = R2I(BasicSizeBIG * 1.35)
set LetterSize["R"] = R2I(BasicSizeBIG)
set LetterSize["S"] = R2I(BasicSizeBIG)
set LetterSize["T"] = R2I(BasicSizeBIG)
set LetterSize["U"] = R2I(BasicSizeBIG)
set LetterSize["V"] = R2I(BasicSizeBIG)
set LetterSize["W"] = R2I(BasicSizeBIG)
set LetterSize["X"] = R2I(BasicSizeBIG)
set LetterSize["Y"] = R2I(BasicSizeBIG)
set LetterSize["Z"] = R2I(BasicSizeBIG)
set LetterSize["1"] = R2I(BasicSize)
set LetterSize["2"] = R2I(BasicSize)
set LetterSize["3"] = R2I(BasicSize)
set LetterSize["4"] = R2I(BasicSize)
set LetterSize["5"] = R2I(BasicSize)
set LetterSize["6"] = R2I(BasicSize)
set LetterSize["7"] = R2I(BasicSize)
set LetterSize["8"] = R2I(BasicSize)
set LetterSize["9"] = R2I(BasicSize * 1.1 )
set LetterSize["0"] = R2I(BasicSize)
set LetterSize[" "] = R2I(BasicSize)
set LetterSize["-"] = R2I(BasicSize * 0.8)
set LetterSize["_"] = R2I(BasicSize * 1.08)
set LetterSize[":"] = R2I(BasicSize * 0.1)
set LetterSize[";"] = R2I(BasicSize * 0.11)
set LetterSize["."] = R2I(BasicSize * 0.1 )
set LetterSize[","] = R2I(BasicSize * 0.105)
set LetterSize["<"] = R2I(BasicSize * 1.08)
set LetterSize[">"] = R2I(BasicSize * 1.08)
set LetterSize["^"] = R2I(BasicSize * 0.97)
set LetterSize["§"] = R2I(BasicSizeBIG)
set LetterSize["$"] = R2I(BasicSizeBIG)
set LetterSize["%"] = R2I(BasicSizeBIG)
set LetterSize["&"] = R2I(BasicSize)
set LetterSize["/"] = R2I(BasicSize)
set LetterSize["("] = R2I(BasicSize * 0.4)
set LetterSize[")"] = R2I(BasicSize * 0.4)
set LetterSize["="] = R2I(BasicSize)
set LetterSize["?"] = R2I(BasicSizeBIG)
set LetterSize["`"] = R2I(BasicSize)
set LetterSize["{"] = R2I(BasicSize * 0.4)
set LetterSize["["] = R2I(BasicSize * 0.4)
set LetterSize["]"] = R2I(BasicSize * 0.4)
set LetterSize["}"] = R2I(BasicSize * 0.4)
//set LetterSize["\"] = R2I(BasicSize)
set LetterSize["´"] = R2I(BasicSize * 0.15)
set LetterSize["'"] = R2I(BasicSize * 0.13)
set LetterSize["#"] = R2I(BasicSize * 1.2)
set LetterSize["*"] = R2I(BasicSize)
set LetterSize["+"] = R2I(BasicSize)
set LetterSize["~"] = R2I(BasicSize * 0.7)
endfunction
private function Init2 takes nothing returns nothing
local integer i = 0
set Leave = CreateTrigger()
set Playing = CreateForce()
call TriggerAddAction(Leave, function DecreasePlaying)
loop
if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set Main = Main + 1
call TriggerRegisterPlayerEvent(Leave, Player(i), EVENT_PLAYER_LEAVE)
call ForceAddPlayer(Playing,Player(i))
set Highest_ID = i
endif
set i = i + 1
exitwhen i == 13
endloop
endfunction
private function Init takes nothing returns nothing
local integer index = 0
call Init2()
set ClickChecker = CreateTrigger()
call TriggerAddAction(ClickChecker,function CheckClicks)
loop
set DS[index] = DialogCreate()
set CurrentPage[index] = 0
call TriggerRegisterDialogEventBJ(ClickChecker,DS[index])
exitwhen index == GetHID()
set index = index + 1
endloop
if SET_LINEBREAKS then
call InitLetterSize()
endif
endfunction
endlibrary
//TESH.scrollpos=15
//TESH.alwaysfold=0
scope Start
globals
private timerdialog dddd
Dialog LanguageDialog
endglobals
function Language takes integer value, Dialog vote returns nothing
if value == 0 then
set German[GetPlayerId(GetClickingPlayer())] = true
else
set German[GetPlayerId(GetClickingPlayer())] = false
endif
endfunction
function Difficulty takes integer value, Dialog vote returns nothing
set udg_Basis_Handycap = I2R(value)
call LanguageDialog.ShowAll()
endfunction
private function StartGame takes nothing returns nothing
call DestroyTimer(GetExpiredTimer())
call ConditionalTriggerExecute( gg_trg_Init )
call DestroyTimerDialog(dddd)
endfunction
function Trig_Dialog_Actions takes nothing returns nothing
local integer i = 0
local timer T = CreateTimer()
local Dialog d = Dialog.create("Welcome to 'Stampede Surviver'. Please choose your language.",Language,45.)
local Dialog d2 = Dialog.create("Choose the difficulty",Difficulty,20.)
call d.AddOption("English",1)
call d.AddOption("Deutsch",0)
call d.MakeFirstLetterHotkeyMap()
set LanguageDialog = d
loop
exitwhen i > 15
set German[i] = false
set i = i + 1
endloop
call d2.AddOption("Easy",125)
call d2.AddOption("Normal",100)
call d2.AddOption("Hard",80)
call d2.AddOption("Insane",50)
call d2.MakeFirstLetterHotkeyMap()
call d2.StartVote()
//call SetDialogTime(d,30.,true)
call TimerStart(T,30.,false,function StartGame)
set dddd = CreateTimerDialog(T)
call TimerDialogSetTitle(dddd,"Gamestart")
call TimerDialogDisplay(dddd,true)
endfunction
//===========================================================================
function InitTrig_Dialog takes nothing returns nothing
set gg_trg_Dialog = CreateTrigger( )
call TriggerRegisterTimerEventSingle( gg_trg_Dialog, 1.00 )
call TriggerAddAction( gg_trg_Dialog, function Trig_Dialog_Actions )
endfunction
endscope
function Trig_Unbezeichneter_Ausl__ser_002_Actions takes nothing returns nothing
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Ldro', -1, 1, 0 )
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Bdsd', -1, 1, 0 )
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Bdrh', -1, 1, 0 )
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Bdrg', -1, 1, 0 )
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Bflr', -1, 1, 0 )
---
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Idki', -1, 1, 0 )
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Kdkt', -1, 1, 0 )
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Crck', -1, 1, 0 )
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Gbrk', -1, 1, 0 )
call SetTerrainTypeBJ( GetRectCenter(GetPlayableMapRect()), 'Gdkr', -1, 1, 0 )
endfunction
//===========================================================================
function InitTrig_Unbezeichneter_Ausl__ser_002 takes nothing returns nothing
set gg_trg_Unbezeichneter_Ausl__ser_002 = CreateTrigger( )
call TriggerAddAction( gg_trg_Unbezeichneter_Ausl__ser_002, function Trig_Unbezeichneter_Ausl__ser_002_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Votekick initializer Init requires DialogSystem, Embasic
globals
private constant integer FREE_VOTEKICKS = 1
private integer array VotekicksLeft
private trigger Starter = CreateTrigger()
private player array P
endglobals
private function Eval takes integer value, Dialog vote returns nothing
if value == 1 then
call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(P[vote.GetId()])+" was kicked.")
if GetLocalPlayer() == P[vote.GetId()] then
call EndGame(false)
endif
else
call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(P[vote.GetId()])+" was not kicked.")
endif
call vote.destroy()
endfunction
function VotekickPlayer takes player p returns nothing
local Dialog d
if VotekicksLeft[GetPlayerId(p)] < 1 then
call DisplayTextToPlayer(p,0,0,"You already used all your votekicks.")
else
set VotekicksLeft[GetPlayerId(p)] = VotekicksLeft[GetPlayerId(p)] - 1
endif
set d = Dialog.create("Shall "+ColorPlayer(p)+" be kicked?",Eval,45.)
call d.AddTextOptions("Yes;No")
call d.StartVote()
call d.MakeFirstLetterHotkeyMap()
set P[d.GetId()] = p
// No problem if sb. starts a votekick during another one.
// Attach the player that shall be kicked to the dialog.
endfunction
private function Init takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 11
set VotekicksLeft[i] = FREE_VOTEKICKS
set i = i + 1
endloop
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Votesell initializer Init requires DialogSystem, Embasic, SellUnit
globals
private constant integer FREE_VOTESELLS = 25
private integer array VotekicksLeft
private trigger Starter = CreateTrigger()
private player array P
private unit array U
endglobals
private function Eval takes integer value, Dialog vote returns nothing
if value == 1 then
call SellUnit(U[vote.GetId()],0.5)
else
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Vote failed")
endif
call vote.destroy()
endfunction
function VotesellUnit takes unit u returns nothing
local Dialog d
if VotekicksLeft[GetPlayerId(GetOwningPlayer(u))] < 1 then
call DisplayTextToPlayer(GetOwningPlayer(u),0,0,"You already used all your votesells.")
else
set VotekicksLeft[GetPlayerId(GetOwningPlayer(u))] = VotekicksLeft[GetPlayerId(GetOwningPlayer(u))] - 1
endif
set d = Dialog.create("Shall "+GetUnitName(u)+" be sold?",Eval,10.)
call d.AddTextOptions("Yes;No")
call d.StartVote()
call d.MakeFirstLetterHotkeyMap()
set U[d.GetId()] = u
endfunction
private function Init takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 11
set VotekicksLeft[i] = FREE_VOTESELLS
set i = i + 1
endloop
endfunction
endlibrary
//TESH.scrollpos=3
//TESH.alwaysfold=0
library I2H initializer Init
// ========================
// This allows you to convert the handle ID of a type to the type itself
// as long, as you add an 'ID' to the end of the create function you'd usually use.
globals
private hashtable data
endglobals
function I2I takes integer i returns item
return LoadItemHandle(data,i,0)
endfunction
function I2U takes integer i returns unit
return LoadUnitHandle(data,i,0)
endfunction
function I2E takes integer i returns effect
return LoadEffectHandle(data,i,0)
endfunction
// Unit
function CreateUnitID takes player id, integer unitid, real x, real y, real face returns unit
local unit d = CreateUnit(id,unitid,x,y,face)
call SaveUnitHandle(data,GetHandleId(d),0,d)
return d
endfunction
// Effect
function AddSpecialEffectID takes string modelName, real x, real y returns effect
local effect d = AddSpecialEffect(modelName,x,y)
call SaveEffectHandle(data,GetHandleId(d),0,d)
return d
endfunction
// Item
function CreateItemID takes integer itemid, real x, real y returns item
local item d = CreateItem(itemid,x,y)
call SaveItemHandle(data,GetHandleId(d),0,d)
return d
endfunction
private function Init takes nothing returns nothing
set data = InitHashtable()
endfunction
endlibrary
//TESH.scrollpos=149
//TESH.alwaysfold=0
library Embasic requires HandleIndexing
//*********************************************************************
//* Embasic
//* ----------
//! [Attachment] [Recycling] [Coloring] [H2I] [GameTime]
//*
//*
//* To implement it , create a custom text trigger called Embasic
//* and paste the contents of this script there.
//* If you want to use it, don't forget to call InitEmbasic() at the map start.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3campaigns.net
//*
//! TimerUtils [by Vesxorian]
//! HandleIndexing [by Mr.Malte]
//! AID [by Mr.Malt]
//! GroupUtils [by Rising_Dusk]
//! ColorFunctions [by Mr.Malte]
// ======= What is Embasic ? =======
// Embasic is a collection of useful stuff that should go into any map.
// Embasic inclues mainly HandleAttachment functions.
// There are many attachment systems, but these are the two which I
// recommend.
// ======= Functions of Embasic =======
// NewTimer() : Recycles an old timer, to keep the HandleID size small.
// ReleaseTimer(timer) : Timers created with NewTimer() must be deleten like this.
// SetTimerData(timer,integer) : Attach Data to a timer created with NewTimer()
// GetTimerData(timer) : Get the attached Data
// Index(handle) : Creates a unique integer between 1 and 8190 for a handle.
// ReleaseIndex(integer) : Release the index of a unit. Very important! Call this, when you don't need the Index anymore, like if a unit dies.
// GameTimeString() : Returns in a string the elapsed game time.
// NewGroup() : Simliar to NewTimer(), just with groups. Create a new group with this.
// ReleaseGroup(group) : Use this instead of DestroyGroup(g), but ONLY on groups created with NewGroup()
// GroupRefresh(group) : Removes for example dead units from a group. Destroys 'Shadow References'
// PrintAID() : Prints the number of handles that will probably be created in your game.
// GameTimeString() : Returns the gametime as a string ( when GameTimeWanted is true ). Example: 01:05:36 => 1 hour, 5 minutes, 36 seconds.
// GetElapsedGameTime(string) : Returns the elapsed game time in a device (hours, minutes, seconds)
// ColorPlayer(player) : Returns the name of a player coloured.
// H2I, h2i, i2e, i2u, i2t : Basic returnbug functions. You don't have to create tons of private h2i() functions then.
// ======= Constants of Embasic =======
// Pi : The thing you need to handle with circles. Maybe Useful.
// ColorBlue/Green/Red[PlayerId]: The Color of players in integers between 0 and 255
// ======= What else should I know? =======
// This supports AID. MAX_HANDLE_ID_COUNT is very important for attachment systems.
// If you create more handles than this value is big, attachment systems fail.
// AID stores the number of created handles and the biggest Handle ID.
// Then it calculates this value up to MAX_GAME_DURATION.
// Example: After 10 minutes, 5000 handles were created.
// MAX_GAME_DURATION is 40.
// So it calculates how many handles might be created after 40 minutes.
// This needs performance! To disabled AID, set AID to false
// ======= About the Systems =======
//! [HandleIndexing]
// Fast, save, doesn't need Unit User Data.
// This is not the fastest! But it doesn't use UnitUserData.
//! [TimerUtils]
// Fast, save, recycles timers
//! [AID]
// Slow system. Should be disabled for final games.
//! [GroupUtils]
// Recycles groups in order to keep the Handle ID size small.
// ======= For speed Freaks =======
// To increase the speed of embasic:
// [x] Replace TimerUtils(Red) with TimerUtils(DarkRed)
// [x] Replace HandleIndexing with UnitIndexing
// [x] Disable AID
// [x] Disable GameTimeWanted
//*
//********************************************************************
globals
private constant integer MAX_HANDLE_ID_COUNT = 70000 //: Very important. Tip: Play a whole game with AID enabled and if AID recommends a higher value, increase it.
private constant integer tosub = 0x100000 //: Subtracts this integer from handles. Keep it!
private constant integer QUANTITY = 256 //: The number of timers you can use at the same time created with NewTimer()
private constant integer ARRAY_SIZE = 8191 //: Increase this; Make safer, cripple performance
private constant integer HELD = 0x28829022 //: Use a totally random number. The best: Don't change it.
private boolean GameTimeWanted = true //: Starts a timer that counts the Game Time.
private constant integer MAX_GAME_DURATION = 60 //: What do you think, how long will your game last? In minutes, please
constant boolean AID = true //: Disable AID?
private constant boolean ColorsWanted = true //: Color Codes for players. false will disable 'ColorPlayer' and PlayerColorConstants
constant real Pi = 3.1415926535897
endglobals
function Display takes string English, string german returns nothing
local integer i = 0
loop
exitwhen i > GetHID()
if German[i] then
call DisplayTextToPlayer(Player(i),0,0,german)
else
call DisplayTextToPlayer(Player(i),0,0,English)
endif
set i = i + 1
endloop
endfunction
function h2i takes handle h returns integer
return GetHandleId(h)
endfunction
function H2I takes handle h returns integer
return GetHandleId(h)
endfunction
function Debug takes string s returns nothing
call DisplayTextToForce(GetPlayersAll(),s)
endfunction
globals
integer BIGGEST = 0
integer SMALLEST = 0
//integer HandlesNeeded = 0
integer seconds = 0
integer hours = 0
integer minutes = 0
integer ElapsedMinutes = 0
integer GameTime = 0
endglobals
function startAID takes handle h returns nothing
local integer i = h2i(h)-tosub
if ( i > BIGGEST ) then
set BIGGEST = i
endif
endfunction
function Gametime takes nothing returns nothing
set seconds = seconds + 1
set GameTime = GameTime + 1
if ( seconds == 60 ) then
set seconds = 0
set minutes = minutes + 1
set ElapsedMinutes = ElapsedMinutes + 1
if ( minutes == 60 ) then
set hours = hours + 1
set minutes = 0
endif
endif
endfunction
function GetElapsedGameTime takes string device returns integer
if ( device == "minutes" ) then
return ElapsedMinutes
elseif ( device == "seconds" ) then
return ElapsedMinutes*60
elseif ( device == "hours" ) then
return R2I(I2R(ElapsedMinutes/60))
endif
return -1
endfunction
function GameTimeString takes nothing returns string
local string toreturn = ""
if ( hours < 10 ) then
set toreturn = toreturn + "0" + I2S(hours)
else
set toreturn = toreturn + I2S(hours)
endif
if ( minutes < 10 ) then
set toreturn = toreturn + ":"+"0"+I2S(minutes)
else
set toreturn = toreturn + ":"+I2S(minutes)
endif
if ( seconds < 10 ) then
set toreturn = toreturn + ":"+"0"+I2S(seconds)
else
set toreturn = toreturn + ":"+I2S(seconds)
endif
return toreturn
endfunction
function PrintAID takes nothing returns nothing
local real HandlesNeeded = GameTime/(BIGGEST-SMALLEST)*(MAX_GAME_DURATION*60)+SMALLEST+5000
call DisplayTextToForce(GetPlayersAll(),I2S(R2I(HandlesNeeded))+" is probably gonna be the biggest handle Index in your map. Now "+I2S(BIGGEST) +" was the biggest Index.")
endfunction
function HAID takes nothing returns nothing
local unit t = CreateUnit(Player(13),'hpea',0.,0.,0.)
call startAID(t)
call RemoveUnit(t)
endfunction
// ***************************************
//! S T A R T O F C O L O R F U N C T I O N S
// ***************************************
globals
integer array ColorRed
integer array ColorGreen
integer array ColorBlue
string array ColorString
endglobals
function ColorPlayer takes player p returns string
if ( ColorsWanted ) then
return ColorString[GetPlayerId(p)]+GetPlayerName(p)+"|r"
endif
return "Embasic: Enable ColorsWanted!"
endfunction
function InitColor takes nothing returns nothing
local integer nIndex = 0
set ColorRed[nIndex] = 255
set ColorGreen[nIndex] = 0
set ColorBlue[nIndex] = 0
set ColorString[nIndex] = "|cffff0000" //red
set nIndex = nIndex + 1
set ColorRed[nIndex] = 0
set ColorGreen[nIndex] = 0
set ColorBlue[nIndex] = 255
set ColorString[nIndex] = "|cff0000ff" //blue
set nIndex = nIndex + 1
set ColorRed[nIndex] = 0
set ColorGreen[nIndex] = 245
set ColorBlue[nIndex] = 255
set ColorString[nIndex] = "|cff00f5ff" //Teal
set nIndex = nIndex + 1
set ColorRed[nIndex] = 85
set ColorGreen[nIndex] = 26
set ColorBlue[nIndex] = 139
set ColorString[nIndex] = "|cff551A8B" //Purple
set nIndex = nIndex + 1
set ColorRed[nIndex] = 255
set ColorGreen[nIndex] = 255
set ColorBlue[nIndex] = 0
set ColorString[nIndex] = "|cffffff00" //Yellow
set nIndex = nIndex + 1
set ColorRed[nIndex] = 248
set ColorGreen[nIndex] = 154
set ColorBlue[nIndex] = 0
set ColorString[nIndex] = "|cffEE9A00" //Orange
set nIndex = nIndex + 1
set ColorRed[nIndex] = 0
set ColorGreen[nIndex] = 255
set ColorBlue[nIndex] = 0
set ColorString[nIndex] = "|cff00CD00" //Green
set nIndex = nIndex + 1
set ColorRed[nIndex] = 255
set ColorGreen[nIndex] = 105
set ColorBlue[nIndex] = 180
set ColorString[nIndex] = "|cffFF69B4" //Pink
set nIndex = nIndex + 1
set ColorRed[nIndex] = 192
set ColorGreen[nIndex] = 192
set ColorBlue[nIndex] = 192
set ColorString[nIndex] = "|cffC0C0C0" //Gray
set nIndex = nIndex + 1
set ColorRed[nIndex] = 176
set ColorGreen[nIndex] = 226
set ColorBlue[nIndex] = 255
set ColorString[nIndex] = "|cffB0E2FF" //Light Blue
set nIndex = nIndex + 1
set ColorRed[nIndex] = 0
set ColorGreen[nIndex] = 100
set ColorBlue[nIndex] = 0
set ColorString[nIndex] = "|cff006400" //Dark Green
set nIndex = nIndex + 1
set ColorRed[nIndex] = 139
set ColorGreen[nIndex] = 69
set ColorBlue[nIndex] = 19
set ColorString[nIndex] = "|cff8B4513" //Brown
endfunction
// ***************************************
//! S T A R T O F T I M E R U T I L S
// ***************************************
globals
private integer array data[ARRAY_SIZE]
private integer OFFSET = 0
endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
debug if(H2I(t)-OFFSET<0) then
debug call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
debug endif
set data[H2I(t)-OFFSET]=value
endfunction
function GetTimerData takes timer t returns integer
debug if(H2I(t)-OFFSET<0) then
debug call BJDebugMsg("GetTimerData: Wrong handle id, only use GetTimerData on timers created by NewTimer")
debug endif
return data[H2I(t)-OFFSET]
endfunction
//==========================================================================================
globals
private timer array tT
private integer tN = 0
endglobals
//==========================================================================================
function NewTimer takes nothing returns timer
if (tN==0) then
debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, please increase it for your map, fix your map's timer leaks or switch to blue flavor when applicable")
set tT[0]=CreateTimer()
if (H2I(tT[0])-OFFSET<0) or (H2I(tT[0])-OFFSET>=ARRAY_SIZE) then
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably switch to the blue flavor or fix timer leaks.")
return null
endif
else
set tN=tN-1
endif
call SetTimerData(tT[tN],0)
return tT[tN]
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==8191) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
call DestroyTimer(t)
else
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
private function redInit takes nothing returns nothing
local integer i
local integer last
local boolean correct
loop
set tT[0] = CreateTimer()
set OFFSET=H2I(tT[0] )
set i=1
set correct=true
loop
exitwhen (i==QUANTITY)
set tT[i] = CreateTimer()
if(H2I(tT[i])-OFFSET<0) or (H2I(tT[i])-OFFSET>=ARRAY_SIZE) then
debug call BJDebugMsg("TimerUtils_redInit: Failed a initializing attempt")
set correct=false
exitwhen true
endif
set i=i+1
endloop
exitwhen correct
endloop
set tN=QUANTITY
endfunction
// ***************************************
//! S T A R T O F I N I T I A L I Z E R
// ***************************************
function InitEmbasic takes nothing returns nothing
local timer t
call Debug("Embasic initalized")
//call Debug(" Featuring:")
//call Debug("-- HandleIndexing")
//call Debug("-- Recycling")
//call Debug("-- PlayerColoring")
//call Debug("-- Getting Game Time as Text")
//call Debug("-- Attaching.")
//call Debug("-- Returnbug")
//call Debug("-- AID")
if ( AID ) then
set GameTimeWanted = true
set t = CreateTimer()
set SMALLEST = h2i(t)-tosub
call TimerStart(CreateTimer(),10.,true,function HAID)
call DestroyTimer(t)
endif
if ( GameTimeWanted ) then
call TimerStart(CreateTimer(),1.,true,function Gametime)
endif
call redInit()
if ( ColorsWanted ) then
call InitColor()
endif
endfunction
endlibrary
library EmbasicChild initializer AutoAID requires Embasic
globals
private constant real TIMEOUT = 200.
private constant boolean PERIODIC = false
endglobals
function AutoAID takes nothing returns nothing
return
if ( AID ) then
call TimerStart(CreateTimer(),TIMEOUT,PERIODIC,function PrintAID)
endif
endfunction
endlibrary
//TESH.scrollpos=29
//TESH.alwaysfold=0
//********************************************************************
// textmacro Recycling takes NAME, TYPE, IDENTIFIER, AMOUNT, ERASELIKE
// NAME = Enter the name you want to Recycle with. Example: Enter Bottle to create NewBottle() and ReleaseBottle().
// TYPE = Enter the handle type you want to recycle. timer will create timers to recycle.
// IDENTIFIER = How is that handle created? Preloaded? If TYPE is timer, this has to be NewTimer().
// AMOUNT = How big shall the stack be? The bigger the safer. But this preloads AMOUNT types of the Handle
// You want at the map Init, so it lacks all the time some memory.
// ERASELIKE = How is the handle simulated to be dead? For Timers Write PauseTimer.
// Dont add the parameters here. They are added automatically. If you don't want simulate death, or it is impossible,
// set this to Foo.
// ======= Examples =======
// Are found below
// ======= Functions =======
// New$NAME$() : Recycles an old timer, to keep the HandleID size small.
// Release$NAME$($TYPE$) : Timers created with NewTimer() must be deleten like this.
//! textmacro Recycling takes NAME, TYPE, IDENTIFIER, AMOUNT, ERASELIKE
library $NAME$Recycling initializer $NAME$Preload
globals
integer $NAME$Wanted = $AMOUNT$
$TYPE$ array $NAME$Handle
endglobals
function New$NAME$ takes nothing returns $TYPE$
//call Debug( "New$NAME$: Nr."+I2S($NAME$Wanted))
if ( $NAME$Wanted<1 ) then
call BJDebugMsg("$NAME$Recycling: Stack is empty.")
endif
set $NAME$Wanted = $NAME$Wanted - 1
return $NAME$Handle[$NAME$Wanted]
endfunction
function Release$NAME$ takes $TYPE$ which returns nothing
call $ERASELIKE$(which)
set $NAME$Handle[$NAME$Wanted] = which
set $NAME$Wanted = $NAME$Wanted + 1
endfunction
function $NAME$Preload takes nothing returns nothing
local integer i = 0
loop
set i = i + 1
exitwhen i > $NAME$Wanted
set $NAME$Handle[i] = $IDENTIFIER$
endloop
endfunction
endlibrary
//! endtextmacro
//! runtextmacro Recycling( "Group", "group", "CreateGroup()" , "10", "DestroyGroup")
// runtextmacro Recycling( "Rect", "rect", "Rect(0.,0.,0.,0.)" , "10", "Foo")
//! runtextmacro Recycling( "Location", "location", "null", "10","RemoveLocation")
//! runtextmacro Recycling( "Force", "force", "CreateForce()", "3", "ForceClear")
//TESH.scrollpos=25
//TESH.alwaysfold=0
// ***************************************
//! S T A R T O F H A N D L E I N D E X I N G
// ***************************************
//*********************************************************************
//* HandleIndexing
//* ----------
//*
//* To implement it , create a custom text trigger called HandleIndexing
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3campaigns.net
//*
//* For your needs:
//* * Get unique integers between 1 and 8190 for handles.
//*
//* set index = Index(handle) : Gets a unique number that fits into arrays for a handle.
//* FlushIndex(handle) : Tells the recycler that this Index can be recycles. Call this, when youre don with the Index.
//* FlushIndexSafe(handle) : Flushs an Index using the system itself;
//* PassIndex(handle,handle) : Passes ALL the data attached with this system from a handle to another handle.
//* Features
//* - Doesn't use UnitUserData
//* - You Don't have to run textmacros
//* - Attaching 15 Data to a unit is almost as fast as attaching 1 Date to a unit.
//* - This is safe! If you Release an Index from a unit, that isn't create, the index will instantly be moved to the RecycleBin
//* - This is fast! HSAS for example or PUI is faster, but; HSAS needs to run a textmacro for each usage. And it uses extended arrays. That are about 30 globals per macro. PUI uses UnitUserData and I don't like PUIs way to recycle Indexes.
//* - If you combinate this with Recycling textmacros, it is perfect to recycle indexes and add Data to them.
//*
//********************************************************************
//! I M P O R T A N T
//* If it is possible, that your handle is used in more than one system (like units), Flush the Handle
//* Only, when the Handle is destroyed!
//================================================================
library HandleIndexing
globals
private constant boolean Plugin = false
private constant integer MAX_HANDLE_ID = 8190 // Should be a Multiply of 8190. But only, if Plugin is true.
private constant integer tosub = 0x100000
private integer array StoredIDs[MAX_HANDLE_ID]
private integer IDs = 0
private integer gaps = 0
private integer array Gaps
endglobals
private function h2i takes handle h returns integer
return GetHandleId(h)
endfunction
function ReleaseIndex takes integer index returns nothing
//! Tell the recycler which gap can be recycled. This will not remove the fitting Index from a unit. ==> lacks memory
set gaps = gaps + 1
set Gaps[gaps] = index
endfunction
function HasHandleIndex takes integer H2Ivalue returns boolean
return StoredIDs[H2Ivalue] != 0
endfunction
function FlushIndex takes handle h returns integer
local integer num = h2i(h)-tosub
local integer re = 0
if ( StoredIDs[num] != 0 ) then
call ReleaseIndex(StoredIDs[num])
set re = StoredIDs[num]
set StoredIDs[num] = 0
endif
return re
endfunction
function CreateIndex takes integer num returns integer
//! Recycle Indexes
if ( gaps > 0 ) then
set StoredIDs[num] = Gaps[gaps]
set gaps = gaps - 1
return StoredIDs[num]
else
//! Create new Index
set IDs = IDs + 1
set StoredIDs[num] = IDs
if IDs > 8190 then
debug call BJDebugMsg("Handle Indexing; Created too many Indexes! Don't forget to call ReleaseIndex(handle). Trying to fix Issue. May cause Errors or bugs!")
return GetRandomInt(1,8190)
endif
return IDs
endif
endfunction
function Index takes handle h returns integer
local integer hashnum = h2i(h)-tosub
if ( StoredIDs[hashnum] == 0 ) then
return CreateIndex(hashnum)
else
return StoredIDs[hashnum]
endif
endfunction
function PassIndex takes handle a, handle b returns nothing
local integer index = Index(a)
local integer num = h2i(b)-tosub
set StoredIDs[num] = index
call FlushIndex(a)
endfunction
endlibrary
//TESH.scrollpos=5
//TESH.alwaysfold=0
library SimError initializer init
//**************************************************************************************************
//*
//* SimError
//*
//* Mimic an interface error message
//* call SimError(ForPlayer, msg)
//* ForPlayer : The player to show the error
//* msg : The error
//*
//* To implement this function, copy this trigger and paste it in your map.
//* Unless of course you are actually reading the library from wc3c's scripts section, then just
//* paste the contents into some custom text trigger in your map.
//*
//**************************************************************************************************
//==================================================================================================
globals
private sound error
endglobals
//====================================================================================================
function SimError takes player ForPlayer, string msg returns nothing
set msg="\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00"+msg+"|r"
if (GetLocalPlayer() == ForPlayer) then
call ClearTextMessages()
call DisplayTimedTextToPlayer( ForPlayer, 0.52, 0.96, 2.00, msg )
call StartSound( error )
endif
endfunction
private function init takes nothing returns nothing
set error=CreateSoundFromLabel("InterfaceError",false,false,false,10,10)
//call StartSound( error ) //apparently the bug in which you play a sound for the first time
//and it doesn't work is not there anymore in patch 1.22
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//* set t=Table.create() - instanceates a new table object
//* call t.destroy() - destroys it
//* t[1234567] - Get value for key 1234567
//* (zero if not assigned previously)
//* set t[12341]=32 - Assigning it.
//* call t.flush(12341) - Flushes the stored value, so it
//* doesn't use any more memory
//* t.exists(32) - Was key 32 assigned? Notice
//* that flush() unassigns values.
//* call t.reset() - Flushes the whole contents of the
//* Table.
//*
//* call t.destroy() - Does reset() and also recycles the id.
//*
//* If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//* You can use Table on structs' onInit if the struct is
//* placed in a library that requires Table or outside a library.
//*
//* You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//* set Table["thisstring"][ 7 ] = 2
//* set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************
//=============================================================
globals
private constant integer MAX_INSTANCES=8100 //400000
//Feel free to change max instances if necessary, it will only affect allocation
//speed which shouldn't matter that much.
//=========================================================
private hashtable ht
endglobals
private struct GTable[MAX_INSTANCES]
method reset takes nothing returns nothing
call FlushChildHashtable(ht, integer(this) )
endmethod
private method onDestroy takes nothing returns nothing
call this.reset()
endmethod
//=============================================================
// initialize it all.
//
private static method onInit takes nothing returns nothing
set ht = InitHashtable()
endmethod
endstruct
//Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
//! textmacro Table__make takes name, type, key
struct $name$ extends GTable
method operator [] takes $type$ key returns integer
return LoadInteger(ht, integer(this), $key$)
endmethod
method operator []= takes $type$ key, integer value returns nothing
call SaveInteger(ht, integer(this) ,$key$, value)
endmethod
method flush takes $type$ key returns nothing
call RemoveSavedInteger(ht, integer(this), $key$)
endmethod
method exists takes $type$ key returns boolean
return HaveSavedInteger( ht, integer(this) ,$key$)
endmethod
static method flush2D takes string firstkey returns nothing
call $name$(- StringHash(firstkey)).reset()
endmethod
static method operator [] takes string firstkey returns $name$
return $name$(- StringHash(firstkey) )
endmethod
endstruct
//! endtextmacro
//! runtextmacro Table__make("Table","integer","key" )
//! runtextmacro Table__make("StringTable","string", "StringHash(key)" )
//! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )
endlibrary
//TESH.scrollpos=3
//TESH.alwaysfold=0
library Playercount initializer Init
globals
public integer Main = 0
public integer Highest_ID = 0
private trigger Leave
private force Playing
private integer highest = 0
endglobals
private function Debug takes string s returns nothing
call DisplayTextToForce(GetPlayersAll(),s)
endfunction
private function CompareID takes nothing returns nothing
if GetPlayerId(GetEnumPlayer()) > highest then
set highest = GetPlayerId(GetEnumPlayer())
endif
endfunction
private function GetHighestIDPlayer takes nothing returns integer
call ForForce(Playing, function CompareID)
return highest
endfunction
private function DecreasePlaying takes nothing returns nothing
set Main = Main - 1
if GetPlayerId(GetTriggerPlayer()) == Highest_ID then
set highest = 0
call ForceRemovePlayer(Playing,GetTriggerPlayer())
set Highest_ID = GetHighestIDPlayer()
endif
endfunction
function GetHID takes nothing returns integer
return Highest_ID
endfunction
private function Init takes nothing returns nothing
local integer i = 0
set Leave = CreateTrigger()
set Playing = CreateForce()
call TriggerAddAction(Leave, function DecreasePlaying)
loop
if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set Main = Main + 1
call TriggerRegisterPlayerEvent(Leave, Player(i), EVENT_PLAYER_LEAVE)
call ForceAddPlayer(Playing,Player(i))
set Highest_ID = i
endif
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
endfunction
endlibrary