//TESH.scrollpos=0
//TESH.alwaysfold=0
/* THX
Cohadar -> ABC, Dialogs
Romek -> ExplodeString
*/
/* ##RUBY CODE FOR CARD CREATION
c = [ "RED", "GREEN", "BLUE" ]
s = [ "SWING", "DIAMOND", "CIRCLE" ]
n = [ "ONE", "TWO", "THREE" ]
f = [ "LIGHT", "MID", "DARK" ]
i = 0
f.each do |fill|
s.each do |shp|
n.each do |num|
c.each do |col|
puts " set Card[ %2d ] = card.create( %-14s %-14s %-14s %-14s )" % [ i, "COLOR_" + col + ",", "FILL_" +fill+ ",", "COUNT_"+num+ ",", "SHAPE_"+shp ]
i+=1
end
end
end
end
*/
Name | Type | is_array | initial_value |
//TESH.scrollpos=489
//TESH.alwaysfold=0
scope Model initializer INIT_DATA
globals
key COLOR_RED
key COLOR_BLUE
key COLOR_GREEN
key FILL_LIGHT
key FILL_MID
key FILL_DARK
key COUNT_ONE
key COUNT_TWO
key COUNT_THREE
key SHAPE_SWING
key SHAPE_DIAMOND
key SHAPE_CIRCLE
key TYPE_CARD
key TYPE_SYMBOL
key TYPE_HIGHLIGHT
constant integer MAX_CARDS = 21
constant integer PILE_MAX_CARDS = 81 // 3 * 3 * 3 * 3
constant integer CARD_X = 512
constant integer CARD_Y = 256
constant integer SYMBOL_X = 128
constant integer SYMBOL_Y = 256
constant integer SYMBOL_SPACING = 175 - SYMBOL_X
constant real DELTA_X = 768
constant real DELTA_Y = 512
constant string CARD_PATH = "Card\\"
constant string PATH_SYMBOL = CARD_PATH + "FG\\"
constant string PATH_CARD = CARD_PATH + "BG\\"
constant string CardColorString = "color"
constant string CardFillString = "stripe"
constant string CardCountString = "symbol"
constant string CardShapeString = "shape"
string array CardColorPath
string array CardFillPath
string array CardCountPath
string array CardShapePath
string array CardColorName
string array CardFillName
string array CardCountName
string array CardShapeName
integer array ColorRedValue
integer array ColorGreenValue
integer array ColorBlueValue
integer array SymbolNumber
cardboard MainBoard
cardboard PracticeBoard
key MODE_CARDS_ALL
key MODE_ENDLESS_GAME
integer GameState
key GAME_STATE_RUN
key GAME_STATE_INIT
key GAME_STATE_END
card array Card
constant integer SELECTOR = 'h002'
constant integer SELECT_CIRCLE = 'h001'
constant integer SELECTOR_MAIN = 'h000'
constant integer SELECTOR_PRACT = SELECTOR
constant integer ABIL_SWAP_MAIN = 'A000'
constant integer ABIL_SWAP_PRACT = 'A004'
constant integer ABIL_SHOW = 'A001'
constant integer ABIL_HELP = 'A002'
constant integer ABIL_TELL = 'A003'
unit array Selector
endglobals
struct Mode extends array
private static hashtable table = InitHashtable()
method operator [] takes integer mode returns boolean
return LoadBoolean( .table, this, mode )
endmethod
method operator []= takes integer mode, boolean val returns nothing
call SaveBoolean( .table, this, mode, val )
endmethod
endstruct
globals // GAME DATA
boolean FormedSet = false
gamecard SetA = 0
gamecard SetB = 0
gamecard SetC = 0
integer array LastPoints
endglobals
function GetSymbolModelPath takes integer shape returns string
return PATH_SYMBOL + CardShapePath[ shape ] + ".blp"
endfunction
function GetBackgroundModelPath takes integer fill, integer color returns string
return PATH_CARD + CardColorPath[ color ] + CardFillPath[ fill ] + ".blp"
endfunction
function DoFormSet_Local takes card a, card b, card c returns boolean
local boolean cardMatch = ( a!=b and b!=c and a!=c ) and ( a != 0 and b!= 0 and c != 0 )
//! runtextmacro PERFORM_MATCH( "color" )
//! runtextmacro PERFORM_MATCH( "fill" )
//! runtextmacro PERFORM_MATCH( "count" )
//! runtextmacro PERFORM_MATCH( "shape" )
return ( cardMatch and colorMatch and fillMatch and countMatch and shapeMatch )
endfunction
function DoFormSet takes card a, card b, card c returns boolean
local boolean cardMatch = ( a!=b and b!=c and a!=c ) and ( a != 0 and b!= 0 and c != 0 )
//! runtextmacro PERFORM_MATCH( "color" )
//! runtextmacro PERFORM_MATCH( "fill" )
//! runtextmacro PERFORM_MATCH( "count" )
//! runtextmacro PERFORM_MATCH( "shape" )
set FormedSet = ( cardMatch and colorMatch and fillMatch and countMatch and shapeMatch )
return FormedSet
endfunction
function GetSetMessage takes card a, card b, card c returns string
local boolean cardMatch = ( a!=b and b!=c and a!=c ) and ( a != 0 and b!= 0 and c != 0 )
local string msg = "These cards don't form a set because: "
local integer count = 1
local card soleCard
local card twinCard
local string soleString
local string twinString
//! runtextmacro PERFORM_MATCH( "color" )
//! runtextmacro PERFORM_MATCH( "fill" )
//! runtextmacro PERFORM_MATCH( "count" )
//! runtextmacro PERFORM_MATCH( "shape" )
if cardMatch then
//! runtextmacro MATCH_MESSAGE( "color", "Color" )
//! runtextmacro MATCH_MESSAGE( "fill", "Fill" )
//! runtextmacro MATCH_MESSAGE( "count", "Count" )
//! runtextmacro MATCH_MESSAGE( "shape", "Shape" )
else
set msg = msg + "\n " + I2S( count ) + " At least one of the cards is invalid!"
endif
set FormedSet = ( cardMatch and colorMatch and fillMatch and countMatch and shapeMatch )
if FormedSet then
set msg = "The cards form a set."
endif
return msg
endfunction
function SavePointsToRank takes player p returns nothing
local integer i = GetPlayerId( p )
call PlayerAddRank( p, MainBoard.points[ i ] - LastPoints[ i ] )
call SavePlayerRank( p )
set LastPoints[ i ] = MainBoard.points[ i ]
endfunction
function MapEnd takes nothing returns nothing
local integer i = 0
set GameState = GAME_STATE_END
loop
exitwhen i > MAX_USER_SLOT
call SavePointsToRank.execute( Player( i ) )
set i = i + 1
endloop
call DisplayText( LOCAL_PLAYER, GREEN + "Game will restart in 30 seconds!" )
set GameState = GAME_STATE_INIT
call PolledWait(30)
set GameState = GAME_STATE_RUN
call FillMainBoard.execute()
call MainBoard.dealUntilSet()
endfunction
struct pileofcards
card array pile[PILE_MAX_CARDS]
boolean array hasCard[100]
integer cards
method drawCard takes nothing returns card
local card drawn_card
local integer index
if .cards == 0 then
set drawn_card = 0
else
set index = GetRandomInt(1, .cards )
set drawn_card = .pile[ index ]
if .hasCard[ drawn_card ] then
set .hasCard[ drawn_card ] = false
set .pile[ index ] = .pile[ .cards ]
set .cards = .cards - 1
endif
endif
return drawn_card
endmethod
method pushCard takes card new returns nothing
if .cards == PILE_MAX_CARDS or .hasCard[ new ] then
else
set .hasCard[ new ] = true
set .cards = .cards +1
set .pile[ .cards ] = new
endif
endmethod
static method create takes nothing returns thistype
local thistype new = .allocate()
set new.cards = 0
return new
endmethod
endstruct
function CardIndex takes integer x, integer y returns integer
local integer res = 3*x + y
if res >= MAX_CARDS then
set res = MAX_CARDS
endif
return res
endfunction
struct cardboard
gamecard array board [MAX_CARDS]
rect array field [MAX_CARDS]
real oX
real oY
real cX
real cY
integer cards = 1
private integer lastPos
delegate pileofcards drawpile
gamecard array selectedCard[36]
integer array cardsSelected[12]
integer array points[12]
unit array selCircle[36]
thistype next
private static thistype last = 0
static method create takes real x, real y returns thistype
local thistype new = .allocate()
set new.drawpile = pileofcards.create()
set new.oX = x
set new.oY = y
set new.cX = x + 3 * DELTA_X
set new.cY = y + 1 * DELTA_Y
set .last.next = new
set .last = new
return new
endmethod
method bindCamera takes player p returns nothing
call SetCameraBounds( .cX - DELTA_X, .cY, .cX + DELTA_X, .cY, .cX - DELTA_X, .cY, .cX + DELTA_X, .cY )
endmethod
method putCard takes card which returns nothing
local integer x
local integer y
if .cards < MAX_CARDS and .drawpile.cards > 0 then
loop
exitwhen .lastPos == MAX_CARDS
if .board[ .lastPos ] == 0 then
debug call BJDebugMsg( "Could put card." )
set x = .lastPos / 3
set y = .lastPos - ( x * 3 )
set .board[ .lastPos ] = gamecard.create( which, this, x, y )
set .cards = .cards + 1
exitwhen true
endif
set .lastPos = .lastPos + 1
endloop
debug if .lastPos == MAX_CARDS then
debug call BJDebugMsg( "Max Cards reached!" )
debug endif
debug else
debug call BJDebugMsg( "Board is full or no cards in drawpile!" )
endif
endmethod
method deal takes nothing returns nothing
if .drawpile.cards > 0 then
debug call BJDebugMsg( "Dealing..." )
call .putCard( .drawCard() )
call .putCard( .drawCard() )
call .putCard( .drawCard() )
debug else
debug call BJDebugMsg( "No cards in drawpile!" )
endif
endmethod
method hasSet takes nothing returns boolean
local integer i = 0
local integer j = 0
local integer k = 0
local boolean result = .cards >= MAX_CARDS
loop
exitwhen i >= MAX_CARDS - 2 or result
call TriggerSleepAction( 0.0 )
set j = i + 1
loop
exitwhen j >= MAX_CARDS - 1 or result
set k = j + 1
loop
exitwhen k >= MAX_CARDS or result
set SetA = .board[ i ]
set SetB = .board[ j ]
set SetC = .board[ k ]
set result = DoFormSet_Local( SetA.self, SetB.self, SetC.self )
set k = k + 1
endloop
set j = j + 1
endloop
set i = i + 1
endloop
return result
endmethod
method dealUntilSet takes nothing returns nothing
if .drawpile.cards == 0 then
debug call BJDebugMsg( "No Cards" )
if .hasSet() then
else
call DisplayText( LOCAL_PLAYER, GREEN + "The game is over! There are no sets on the table anymore, and all cards have been given." )
call MapEnd( )
endif
else
loop
debug call BJDebugMsg( "Checking for Deal" )
exitwhen .cards > 12 and .hasSet()
call TriggerSleepAction( 0.0 )
call .deal()
endloop
endif
endmethod
method removeCard takes gamecard which returns nothing
if which.board == this then
set .board[ which.index ] = 0
set .cards = .cards - 1
if .lastPos > which.index then
set .lastPos = which.index
endif
if Mode[ this ][ MODE_ENDLESS_GAME ] then
call .pushCard( which.self )
endif
call which.destroy()
debug else
debug call BJDebugMsg( "Trying to remove card from wrong board!" )
endif
endmethod
method getCard takes integer x, integer y returns gamecard
local gamecard result = 0
local integer index = CardIndex( x, y )
if index == MAX_CARDS then
elseif .board[ index ] == 0 then
else
set result = .board[ index ]
endif
return result
endmethod
method getField takes integer x, integer y returns rect
return .field[ CardIndex( x, y ) ]
endmethod
method getImageX takes integer x returns real
return DELTA_X * x + .oX // iX = .oX + x * DELTA_X <=> x = ( iX - .oX ) / DELTA_X
endmethod
method getImageY takes integer y returns real
return DELTA_Y * y + .oY
endmethod
static method selIndex takes integer pid, integer slot returns integer
local integer res = 3 * pid + slot
if res < 0 or res > 36 then
set res = -1
endif
return res
endmethod
method isWithinBoard takes real x, real y returns boolean
set x = x + DELTA_X / 2 - .oX
set y = y + DELTA_Y / 2 - .oY
return x >= 0 and x <= DELTA_X * 7 and y >= 0 and y <= DELTA_Y * 7
endmethod
endstruct
struct gamecard
delegate card self
cardboard board
integer index
boolean drawn
cardimage cImage
real x
real y
integer array selId[12]
method ping takes nothing returns nothing
call PingMinimap( .x, .y, 5 )
endmethod
static method create takes card self, cardboard board, integer x, integer y returns thistype
local thistype new = .allocate()
local integer i = 0
set new.board = board
set new.self = self
set new.index = CardIndex( x, y )
set new.drawn = false
call new.createImage( new.board.getImageX( x ), new.board.getImageY( y ) )
loop
exitwhen i > MAX_USER_SLOT
set new.selId[ i ] = -1
set i = i + 1
endloop
return new
endmethod
method createImage takes real x, real y returns nothing
if not .drawn then
set .x = x
set .y = y
set .drawn = true
set .cImage = cardimage.create_type( .color, .fill, .count, .shape, .x, .y )
debug else
debug call BJDebugMsg( "Trying to repaint card!" )
endif
endmethod
method destroyImage takes nothing returns nothing
call .cImage.destroy()
endmethod
method operator selfRect takes nothing returns rect
return .board.field[ .index ]
endmethod
method selected takes player p returns boolean
return .selId[ GetPlayerId( p ) ] != -1
endmethod
method select takes player p returns nothing
local integer i = GetPlayerId( p )
local string msg
local integer selIndex = .board.selIndex( i, .board.cardsSelected[ i ] )
local gamecard a
local gamecard b
local gamecard c
local unit circle
if selIndex == -1 then
else
if .selected( p ) then
else
set .board.selectedCard[ selIndex ] = this
set .selId[ i ] = selIndex
set circle = .board.selCircle[ selIndex ]
if circle == null then
set .board.selCircle[ selIndex ] = CreateUnit( p, SELECT_CIRCLE, .x, .y, 270 )
set circle =.board.selCircle[ selIndex ]
else
call SetUnitX( circle, .x )
call SetUnitY( circle, .y )
endif
call SetUnitVertexColor( circle, 255, 255, 255, IntegerTertiaryOp( LOCAL_PLAYER == p, 255, 0 ) )
set .board.cardsSelected[ i ] = .board.cardsSelected[ i ] + 1
if .board.cardsSelected[ i ] == 3 then
set a = .board.selectedCard[ .board.selIndex( i, 0 ) ]
set b = .board.selectedCard[ .board.selIndex( i, 1 ) ]
set c = .board.selectedCard[ .board.selIndex( i, 2 ) ]
set msg =GetSetMessage(a.self, b.self, c.self )
if FormedSet then
call .board.removeCard( a )
call .board.removeCard( b )
call .board.removeCard( c )
call DisplayText( LOCAL_PLAYER, PlayerName[ i ] + GREEN + " has found a set!" )
set .board.points[ i ] = .board.points[ i ] + TotalPlayers+1
debug call BJDebugMsg( "Points Given" )
call PolledWait( 1 )
debug call BJDebugMsg( "Refill Board" )
call .board.dealUntilSet()
else
call a.deselect( p )
call b.deselect( p )
call c.deselect( p )
set .board.points[ i ] = .board.points[ i ] - 1
if .board == PracticeBoard then
call DisplayText( p, RED + msg )
endif
endif
endif
endif
endif
//circle never gets destroyed...
endmethod
method deselect takes player p returns nothing
local integer i = GetPlayerId( p )
local integer selIndex = .board.selIndex( i, .board.cardsSelected[ i ] )
local unit circle
if selIndex == -1 then
else
if .selected( p ) then
set circle = .board.selCircle[ .selId[ i ] ]
call SetUnitVertexColor( circle, 255, 255, 255, 0 )
set .board.selectedCard[ .selId[ i ] ] = .board.selectedCard[ selIndex ]
set .selId[ i ] = -1
set .board.cardsSelected[ i ] = .board.cardsSelected[ i ] - 1
else
endif
endif
endmethod
method onDestroy takes nothing returns nothing
local integer i = 0
call .destroyImage()
call .ping()
loop
exitwhen i > MAX_USER_SLOT
call .deselect( Player( i ) )
set i = i + 1
endloop
endmethod
method highlight takes boolean highlight returns nothing
call .cImage.highlight( highlight )
endmethod
endstruct
struct card
integer color
integer fill
integer count
integer shape
private static string array abbrevString
static method create takes integer color, integer fill, integer count, integer shape returns thistype
local thistype new = .allocate()
set new.color = color
set new.fill = fill
set new.count = count
set new.shape = shape
return new
endmethod
method operator suffix takes nothing returns string
local string result = ""
if .count == COUNT_ONE then
else
set result = "s"
endif
return result
endmethod
method operator abbrev takes nothing returns string
local string res = "|cff000000" + .abbrevString[ .fill ] + "|cff" + .abbrevString[ .color ]
local integer i =0
loop
exitwhen i == SymbolNumber[.count]
set res = res + .abbrevString[ .shape ]
set i = i + 1
endloop
set res = res + "|cff000000" + .abbrevString[ .fill ]
return res
endmethod
static method onInit takes nothing returns nothing
set .abbrevString[ COLOR_RED ] = "FF0000"
set .abbrevString[ COLOR_BLUE ] = "0000FF"
set .abbrevString[ COLOR_GREEN ] = "00FF00"
set .abbrevString[ FILL_LIGHT ] = " "
set .abbrevString[ FILL_MID ] = " | "
set .abbrevString[ FILL_DARK ] = "="
set .abbrevString[ SHAPE_SWING ] = "S"
set .abbrevString[ SHAPE_DIAMOND ] = "D"
set .abbrevString[ SHAPE_CIRCLE ] = "C"
endmethod
endstruct
//! textmacro PERFORM_MATCH takes TYPE
local boolean $TYPE$Match = ( a.$TYPE$ == b.$TYPE$ and b.$TYPE$ == c.$TYPE$ ) or ( a.$TYPE$ != b.$TYPE$ and b.$TYPE$ != c.$TYPE$ and c.$TYPE$ != a.$TYPE$ )
//! endtextmacro
//! textmacro MATCH_MESSAGE takes TYPE, TYPE_CAP
if not $TYPE$Match then
if a.$TYPE$ == b.$TYPE$ then
set soleCard = c
set twinCard = a
elseif b.$TYPE$ == c.$TYPE$ then
set soleCard = a
set twinCard = b
else
set soleCard = b
set twinCard = c
endif
set soleString = Card$TYPE_CAP$Name[ soleCard.$TYPE$ ] + " " + Card$TYPE_CAP$String + soleCard.suffix
set twinString = Card$TYPE_CAP$Name[ twinCard.$TYPE$ ] + " " + Card$TYPE_CAP$String + "s"
set msg = msg + "\n " + I2S( count ) + ". Two cards share " + twinString + ", while only one has " + soleString
set count = count + 1
endif
//! endtextmacro
function SetColorValues takes integer color, integer r, integer g, integer b returns nothing
set ColorRedValue [ color ] = r
set ColorGreenValue [ color ] = g
set ColorBlueValue [ color ] = b
endfunction
private function INIT_DATA takes nothing returns nothing
set CardColorPath[ COLOR_RED ] = "BG"
set CardColorPath[ COLOR_BLUE ] = "BG"
set CardColorPath[ COLOR_GREEN ] = "BG"
set CardFillPath [ FILL_LIGHT ] = "None"
set CardFillPath [ FILL_MID ] = "Single"
set CardFillPath [ FILL_DARK ] = "Double"
set CardCountPath[ COUNT_ONE ] = "One"
set CardCountPath[ COUNT_TWO ] = "Two"
set CardCountPath[ COUNT_THREE ] = "Three"
set CardShapePath[ SHAPE_SWING ] = "Swing"
set CardShapePath[ SHAPE_DIAMOND ] = "Diamond"
set CardShapePath[ SHAPE_CIRCLE ] = "Circle"
call SetColorValues( COLOR_RED, 200, 35, 20 )
call SetColorValues( COLOR_GREEN, 25,180, 45 )
call SetColorValues( COLOR_BLUE, 25, 40,180 )
set CardColorName[ COLOR_RED ] = "red"
set CardColorName[ COLOR_BLUE ] = "blue"
set CardColorName[ COLOR_GREEN ] = "green"
set CardFillName [ FILL_LIGHT ] = "no"
set CardFillName [ FILL_MID ] = "horizontal"
set CardFillName [ FILL_DARK ] = "vertical"
set CardCountName[ COUNT_ONE ] = "one"
set CardCountName[ COUNT_TWO ] = "two"
set CardCountName[ COUNT_THREE ] = "three"
set CardShapeName[ SHAPE_SWING ] = "Swing"
set CardShapeName[ SHAPE_DIAMOND ] = "Diamond"
set CardShapeName[ SHAPE_CIRCLE ] = "Circle"
set SymbolNumber [ COUNT_ONE ] = 1
set SymbolNumber [ COUNT_TWO ] = 2
set SymbolNumber [ COUNT_THREE ] = 3
set MainBoard = cardboard.create( -2816, -768 )
set PracticeBoard = cardboard.create( -2816, -4608 )
set Card[ 0 ] = card.create( COLOR_RED, FILL_LIGHT, COUNT_ONE, SHAPE_SWING )
set Card[ 1 ] = card.create( COLOR_GREEN, FILL_LIGHT, COUNT_ONE, SHAPE_SWING )
set Card[ 2 ] = card.create( COLOR_BLUE, FILL_LIGHT, COUNT_ONE, SHAPE_SWING )
set Card[ 3 ] = card.create( COLOR_RED, FILL_LIGHT, COUNT_TWO, SHAPE_SWING )
set Card[ 4 ] = card.create( COLOR_GREEN, FILL_LIGHT, COUNT_TWO, SHAPE_SWING )
set Card[ 5 ] = card.create( COLOR_BLUE, FILL_LIGHT, COUNT_TWO, SHAPE_SWING )
set Card[ 6 ] = card.create( COLOR_RED, FILL_LIGHT, COUNT_THREE, SHAPE_SWING )
set Card[ 7 ] = card.create( COLOR_GREEN, FILL_LIGHT, COUNT_THREE, SHAPE_SWING )
set Card[ 8 ] = card.create( COLOR_BLUE, FILL_LIGHT, COUNT_THREE, SHAPE_SWING )
set Card[ 9 ] = card.create( COLOR_RED, FILL_LIGHT, COUNT_ONE, SHAPE_DIAMOND )
set Card[ 10 ] = card.create( COLOR_GREEN, FILL_LIGHT, COUNT_ONE, SHAPE_DIAMOND )
set Card[ 11 ] = card.create( COLOR_BLUE, FILL_LIGHT, COUNT_ONE, SHAPE_DIAMOND )
set Card[ 12 ] = card.create( COLOR_RED, FILL_LIGHT, COUNT_TWO, SHAPE_DIAMOND )
set Card[ 13 ] = card.create( COLOR_GREEN, FILL_LIGHT, COUNT_TWO, SHAPE_DIAMOND )
set Card[ 14 ] = card.create( COLOR_BLUE, FILL_LIGHT, COUNT_TWO, SHAPE_DIAMOND )
set Card[ 15 ] = card.create( COLOR_RED, FILL_LIGHT, COUNT_THREE, SHAPE_DIAMOND )
set Card[ 16 ] = card.create( COLOR_GREEN, FILL_LIGHT, COUNT_THREE, SHAPE_DIAMOND )
set Card[ 17 ] = card.create( COLOR_BLUE, FILL_LIGHT, COUNT_THREE, SHAPE_DIAMOND )
set Card[ 18 ] = card.create( COLOR_RED, FILL_LIGHT, COUNT_ONE, SHAPE_CIRCLE )
set Card[ 19 ] = card.create( COLOR_GREEN, FILL_LIGHT, COUNT_ONE, SHAPE_CIRCLE )
set Card[ 20 ] = card.create( COLOR_BLUE, FILL_LIGHT, COUNT_ONE, SHAPE_CIRCLE )
set Card[ 21 ] = card.create( COLOR_RED, FILL_LIGHT, COUNT_TWO, SHAPE_CIRCLE )
set Card[ 22 ] = card.create( COLOR_GREEN, FILL_LIGHT, COUNT_TWO, SHAPE_CIRCLE )
set Card[ 23 ] = card.create( COLOR_BLUE, FILL_LIGHT, COUNT_TWO, SHAPE_CIRCLE )
set Card[ 24 ] = card.create( COLOR_RED, FILL_LIGHT, COUNT_THREE, SHAPE_CIRCLE )
set Card[ 25 ] = card.create( COLOR_GREEN, FILL_LIGHT, COUNT_THREE, SHAPE_CIRCLE )
set Card[ 26 ] = card.create( COLOR_BLUE, FILL_LIGHT, COUNT_THREE, SHAPE_CIRCLE )
set Card[ 27 ] = card.create( COLOR_RED, FILL_MID, COUNT_ONE, SHAPE_SWING )
set Card[ 28 ] = card.create( COLOR_GREEN, FILL_MID, COUNT_ONE, SHAPE_SWING )
set Card[ 29 ] = card.create( COLOR_BLUE, FILL_MID, COUNT_ONE, SHAPE_SWING )
set Card[ 30 ] = card.create( COLOR_RED, FILL_MID, COUNT_TWO, SHAPE_SWING )
set Card[ 31 ] = card.create( COLOR_GREEN, FILL_MID, COUNT_TWO, SHAPE_SWING )
set Card[ 32 ] = card.create( COLOR_BLUE, FILL_MID, COUNT_TWO, SHAPE_SWING )
set Card[ 33 ] = card.create( COLOR_RED, FILL_MID, COUNT_THREE, SHAPE_SWING )
set Card[ 34 ] = card.create( COLOR_GREEN, FILL_MID, COUNT_THREE, SHAPE_SWING )
set Card[ 35 ] = card.create( COLOR_BLUE, FILL_MID, COUNT_THREE, SHAPE_SWING )
set Card[ 36 ] = card.create( COLOR_RED, FILL_MID, COUNT_ONE, SHAPE_DIAMOND )
set Card[ 37 ] = card.create( COLOR_GREEN, FILL_MID, COUNT_ONE, SHAPE_DIAMOND )
set Card[ 38 ] = card.create( COLOR_BLUE, FILL_MID, COUNT_ONE, SHAPE_DIAMOND )
set Card[ 39 ] = card.create( COLOR_RED, FILL_MID, COUNT_TWO, SHAPE_DIAMOND )
set Card[ 40 ] = card.create( COLOR_GREEN, FILL_MID, COUNT_TWO, SHAPE_DIAMOND )
set Card[ 41 ] = card.create( COLOR_BLUE, FILL_MID, COUNT_TWO, SHAPE_DIAMOND )
set Card[ 42 ] = card.create( COLOR_RED, FILL_MID, COUNT_THREE, SHAPE_DIAMOND )
set Card[ 43 ] = card.create( COLOR_GREEN, FILL_MID, COUNT_THREE, SHAPE_DIAMOND )
set Card[ 44 ] = card.create( COLOR_BLUE, FILL_MID, COUNT_THREE, SHAPE_DIAMOND )
set Card[ 45 ] = card.create( COLOR_RED, FILL_MID, COUNT_ONE, SHAPE_CIRCLE )
set Card[ 46 ] = card.create( COLOR_GREEN, FILL_MID, COUNT_ONE, SHAPE_CIRCLE )
set Card[ 47 ] = card.create( COLOR_BLUE, FILL_MID, COUNT_ONE, SHAPE_CIRCLE )
set Card[ 48 ] = card.create( COLOR_RED, FILL_MID, COUNT_TWO, SHAPE_CIRCLE )
set Card[ 49 ] = card.create( COLOR_GREEN, FILL_MID, COUNT_TWO, SHAPE_CIRCLE )
set Card[ 50 ] = card.create( COLOR_BLUE, FILL_MID, COUNT_TWO, SHAPE_CIRCLE )
set Card[ 51 ] = card.create( COLOR_RED, FILL_MID, COUNT_THREE, SHAPE_CIRCLE )
set Card[ 52 ] = card.create( COLOR_GREEN, FILL_MID, COUNT_THREE, SHAPE_CIRCLE )
set Card[ 53 ] = card.create( COLOR_BLUE, FILL_MID, COUNT_THREE, SHAPE_CIRCLE )
set Card[ 54 ] = card.create( COLOR_RED, FILL_DARK, COUNT_ONE, SHAPE_SWING )
set Card[ 55 ] = card.create( COLOR_GREEN, FILL_DARK, COUNT_ONE, SHAPE_SWING )
set Card[ 56 ] = card.create( COLOR_BLUE, FILL_DARK, COUNT_ONE, SHAPE_SWING )
set Card[ 57 ] = card.create( COLOR_RED, FILL_DARK, COUNT_TWO, SHAPE_SWING )
set Card[ 58 ] = card.create( COLOR_GREEN, FILL_DARK, COUNT_TWO, SHAPE_SWING )
set Card[ 59 ] = card.create( COLOR_BLUE, FILL_DARK, COUNT_TWO, SHAPE_SWING )
set Card[ 60 ] = card.create( COLOR_RED, FILL_DARK, COUNT_THREE, SHAPE_SWING )
set Card[ 61 ] = card.create( COLOR_GREEN, FILL_DARK, COUNT_THREE, SHAPE_SWING )
set Card[ 62 ] = card.create( COLOR_BLUE, FILL_DARK, COUNT_THREE, SHAPE_SWING )
set Card[ 63 ] = card.create( COLOR_RED, FILL_DARK, COUNT_ONE, SHAPE_DIAMOND )
set Card[ 64 ] = card.create( COLOR_GREEN, FILL_DARK, COUNT_ONE, SHAPE_DIAMOND )
set Card[ 65 ] = card.create( COLOR_BLUE, FILL_DARK, COUNT_ONE, SHAPE_DIAMOND )
set Card[ 66 ] = card.create( COLOR_RED, FILL_DARK, COUNT_TWO, SHAPE_DIAMOND )
set Card[ 67 ] = card.create( COLOR_GREEN, FILL_DARK, COUNT_TWO, SHAPE_DIAMOND )
set Card[ 68 ] = card.create( COLOR_BLUE, FILL_DARK, COUNT_TWO, SHAPE_DIAMOND )
set Card[ 69 ] = card.create( COLOR_RED, FILL_DARK, COUNT_THREE, SHAPE_DIAMOND )
set Card[ 70 ] = card.create( COLOR_GREEN, FILL_DARK, COUNT_THREE, SHAPE_DIAMOND )
set Card[ 71 ] = card.create( COLOR_BLUE, FILL_DARK, COUNT_THREE, SHAPE_DIAMOND )
set Card[ 72 ] = card.create( COLOR_RED, FILL_DARK, COUNT_ONE, SHAPE_CIRCLE )
set Card[ 73 ] = card.create( COLOR_GREEN, FILL_DARK, COUNT_ONE, SHAPE_CIRCLE )
set Card[ 74 ] = card.create( COLOR_BLUE, FILL_DARK, COUNT_ONE, SHAPE_CIRCLE )
set Card[ 75 ] = card.create( COLOR_RED, FILL_DARK, COUNT_TWO, SHAPE_CIRCLE )
set Card[ 76 ] = card.create( COLOR_GREEN, FILL_DARK, COUNT_TWO, SHAPE_CIRCLE )
set Card[ 77 ] = card.create( COLOR_BLUE, FILL_DARK, COUNT_TWO, SHAPE_CIRCLE )
set Card[ 78 ] = card.create( COLOR_RED, FILL_DARK, COUNT_THREE, SHAPE_CIRCLE )
set Card[ 79 ] = card.create( COLOR_GREEN, FILL_DARK, COUNT_THREE, SHAPE_CIRCLE )
set Card[ 80 ] = card.create( COLOR_BLUE, FILL_DARK, COUNT_THREE, SHAPE_CIRCLE )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope View initializer INIT
globals
multiboard Stats
real array CardHeight
real array CardWidth
endglobals
function CreateImageEx takes string imagePath, real sizeX, real sizeY, real x, real y, real z, boolean showImage returns image
local image i = CreateImage(imagePath, sizeX, sizeY, 0, x - (sizeX / 2), y - (sizeY / 2), z, 0, 0, 0, 2)
call SetImageRenderAlways(i, true)
call ShowImage(i, showImage)
return i
endfunction
function RealTertiaryOp takes boolean flag, real valueA, real valueB returns real
if flag then
return valueA
else
return valueB
endif
endfunction
function CreateCardImage takes string imagePath, real x, real y, integer cardType returns image
return CreateImageEx(imagePath, CardWidth[ cardType ], CardHeight[ cardType ], x, y, 0, true)
endfunction
struct cardimage
image bg
image array fg [3]
image hl
integer count
real x
real y
static method create takes integer count, string fgModel, string bgModel, real x, real y, integer r, integer g, integer b returns cardimage
local thistype new = .allocate()
local real dX = SYMBOL_X + SYMBOL_SPACING // 'X_'
local real lenX = dX * count - SYMBOL_SPACING // 'X_X_X_' - '_' -> 'X_X_X'
local real curX = x - ( lenX - SYMBOL_X ) / 2 // 'x_X_x' -> 'X_x_x' leftMost position
set new.x = x
set new.y = y
set new.count = 0
set new.bg = CreateCardImage( bgModel, x, y, TYPE_CARD )
call SetImageColor( new.bg, r, g, b, 255 )
loop
exitwhen new.count == count
set new.fg[ new.count ] = CreateCardImage( fgModel, curX, y, TYPE_SYMBOL )
set curX = curX + dX
set new.count = new.count + 1
endloop
set new.hl = CreateCardImage( GetBackgroundModelPath( FILL_LIGHT, COLOR_RED ), x, y, TYPE_HIGHLIGHT )
call SetImageColor( new.hl, 51, 204, 255, 128 )
call ShowImage( new.hl, false )
return new
endmethod
static method create_type takes integer color, integer fill, integer count, integer shape, real x, real y returns cardimage
return .create( SymbolNumber[ count ], GetSymbolModelPath( shape ), GetBackgroundModelPath( fill, color ), x, y, ColorRedValue[ color ], ColorGreenValue[ color ], ColorBlueValue[ color ] )
endmethod
method onDestroy takes nothing returns nothing
call DestroyImage( .bg )
call DestroyImage( .hl )
loop
exitwhen .count == 0
set .count = .count - 1
call DestroyImage( .fg[ .count ] )
endloop
endmethod
method highlight takes boolean highlight returns nothing
call ShowImage( .hl, highlight )
endmethod
endstruct
function UpdateStatsMB takes nothing returns nothing
local integer i = 0
call SetMultiboardItemValue( Stats, 8, 1, I2S( MainBoard.drawpile.cards ), "", 0, null )
loop
exitwhen i > 5
call SetMultiboardItemValue( Stats, i+1, 1, PlayerName[i], "", 0, null )
if PlayerActive[ i ] then
call SetMultiboardItemValue( Stats, i+1, 0, LIGHTGREY + GetPlayerRankText( Player( i ) ), "", 0, null )
call SetMultiboardItemValue( Stats, i+1, 2, LIGHTGREY + I2S( MainBoard.points[ i ] ), "", 0, null )
call SetMultiboardItemValue( Stats, i+1, 3, LIGHTGREY + I2S( GetPlayerRank( Player( i ) ) ) , "", 0, null )
else
call SetMultiboardItemValue( Stats, i+1, 0, GREY + "N/A", "", 0, null )
call SetMultiboardItemValue( Stats, i+1, 2, GREY + "N/A", "", 0, null )
call SetMultiboardItemValue( Stats, i+1, 3, GREY + "N/A", "", 0, null )
endif
set i = i + 1
endloop
endfunction
function SetCardSize takes integer cardType, real x, real y returns nothing
set CardWidth[ cardType ] = x
set CardHeight[ cardType ] = y
endfunction
private function INIT_VIEW takes nothing returns nothing
local integer i = 0
call TriggerSleepAction( 0.0 )
set Stats = CreateMultiboardBJ( 4, 9, "Stats" )
call SetMultiboardItemValue( Stats, -1, 0, "", "", 0.08, null )
call SetMultiboardItemValue( Stats, 0, 0, GOLD + "Player", "", 0, null )
call SetMultiboardItemValue( Stats, -1, 1, GOLD + "", "", 0.1, null )
call SetMultiboardItemValue( Stats, 0, 1, GOLD + "", "", 0, null )
call SetMultiboardItemValue( Stats, -1, 2, "", "", 0.04, null )
call SetMultiboardItemValue( Stats, 0, 2, GOLD + "Points", "", 0, null )
call SetMultiboardItemValue( Stats, -1, 3, GOLD + "", "", 0.04, null )
call SetMultiboardItemValue( Stats, 0, 3, GOLD + "Rank", "", 0, null )
call SetMultiboardItemValue( Stats, 8, 0, GOLD + "Cards in drawpile", "", 0, null )
call UpdateStatsMB()
call TimerStart( CreateTimer(), .5, true, function UpdateStatsMB )
call MultiboardDisplaySJ( Stats, true, null )
//multiboard mb, integer row, integer col, string value, string iconfilename, real width, player whichplayer
call SetFogStateRect( LOCAL_PLAYER, FOG_OF_WAR_VISIBLE, GetWorldBounds(), true )
call FogEnable( false )
endfunction
private function INIT takes nothing returns nothing
call SetCardSize( TYPE_SYMBOL, SYMBOL_X, SYMBOL_Y )
call SetCardSize( TYPE_CARD, CARD_X, CARD_Y )
call SetCardSize( TYPE_HIGHLIGHT, CARD_X + 64, CARD_Y + 64 )
call INIT_VIEW.execute()
endfunction
endscope
//TESH.scrollpos=5
//TESH.alwaysfold=0
scope Controller initializer INIT
globals
cardboard array CurrentBoard
endglobals
function DebugInit takes nothing returns nothing
set Mode[ MainBoard ][ MODE_CARDS_ALL ] = false
call TriggerSleepAction( 2 )
call SetPlayerRank( Player( 0 ), 9999 )
call SavePlayerRank( Player( 0 ) )
endfunction
function FillMainBoard takes nothing returns nothing
local integer i = 0
loop
exitwhen i == 81
call MainBoard.pushCard( Card[ i ] )
set i = i + 1
endloop
call MainBoard.dealUntilSet.execute()
endfunction
function FillPracticeBoard takes nothing returns nothing
local integer i = 0
loop
exitwhen i == 27
call PracticeBoard.pushCard( Card[ i ] )
set i = i + 1
endloop
call PracticeBoard.dealUntilSet.execute()
endfunction
function SelectCard takes nothing returns nothing
local real x = GetOrderPointX()
local real y = GetOrderPointY()
local integer i = GetPlayerId( GetTriggerPlayer() )
local integer boardX
local integer boardY
local gamecard selected
local cardboard board = MainBoard
loop
exitwhen board == 0
exitwhen board.isWithinBoard( x, y )
set board = board.next
endloop
if board == 0 then
else
set boardX = R2I( ( x - board.oX ) / DELTA_X +0.5 )
set boardY = R2I( ( y - board.oY ) / DELTA_Y +0.5 )
set selected = board.getCard( boardX, boardY )
if selected == 0 then
else
if selected.selected( GetTriggerPlayer() ) then
call selected.deselect( GetTriggerPlayer() )
else
call selected.select( GetTriggerPlayer() )
endif
endif
endif
endfunction
function HighlightCards takes nothing returns nothing
call PracticeBoard.hasSet()
call SetA.highlight( true )
call SetB.highlight( true )
call SetC.highlight( true )
endfunction
//! textmacro SET_SHOW_SETTEXT takes VAL, NAME
if SetA.$VAL$ == SetB.$VAL$ then
set msg = msg + share + "$NAME$"
else
set msg = msg + differ + "$NAME$"
endif
//! endtextmacro
function TellWhySet takes player p returns nothing
local string share = LIGHTGREY+ "\n They all have the same "
local string differ = LIGHTGREY+ "\n They all have a different "
local string msg = ""
call HighlightCards()
call DisplayText( p, LIGHTGREY+ "These cards form a set because:" )
//! runtextmacro SET_SHOW_SETTEXT( "color", "color" )
//! runtextmacro SET_SHOW_SETTEXT( "shape", "shape" )
//! runtextmacro SET_SHOW_SETTEXT( "count", "number" )
call DisplayText( p, msg )
endfunction
function SwapBoard takes player p, boolean toMain returns nothing
local integer i = GetPlayerId( p )
if ( CurrentBoard[ i ] == MainBoard ) == toMain then
else
if toMain then
set CurrentBoard[ i ] = MainBoard
set Selector[ i ] = ReplaceUnitBJ( Selector[ i ], SELECTOR_MAIN, 0 )
else
set CurrentBoard[ i ] = PracticeBoard
set Selector[ i ] = ReplaceUnitBJ( Selector[ i ], SELECTOR_PRACT, 0 )
endif
call SetShowAbility.execute( p )
call SetTellAbility.execute( p )
endif
endfunction
private function Explain takes nothing returns nothing
call TellWhySet( GetTriggerPlayer() )
endfunction
private function TrigSwapBoard takes nothing returns nothing
call SwapBoard( GetOwningPlayer( GetTriggerUnit() ), GetSpellAbilityId() == ABIL_SWAP_PRACT )
endfunction
private function INIT takes nothing returns nothing
local integer i = 0
local timer selector = CreateTimer()
local unit lastUnit
local trigger t
call TimerStart( CreateTimer(), 15.0, false, function FillMainBoard )
call TimerStart( CreateTimer(), 1.0, false, function FillPracticeBoard )
set Mode[ MainBoard ][ MODE_CARDS_ALL ] = true
set Mode[ PracticeBoard ][ MODE_ENDLESS_GAME ] = true
loop
exitwhen i > MAX_PLAYER_SLOT
set CurrentBoard[ i ] = PracticeBoard
if PlayerActive[ i ] then
set Selector[ i ] = CreateUnit( Player( i ), SELECTOR, StartLocX[ i ], StartLocY[ i ], 0 )
endif
set i = i + 1
endloop
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerAddAction( t, function SelectCard )
set t = CreateTrigger()
call TriggerRegisterAnyPlayerChatEvent(t, "-show", false )
call TriggerAddAction( t, function HighlightCards )
set t = CreateTrigger()
call TriggerRegisterAnyPlayerChatEvent(t, "-explain", false )
call TriggerAddAction( t, function Explain )
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( t, function TrigSwapBoard )
set GameState = GAME_STATE_RUN
call EnableSelect( false, false )
debug call DebugInit.execute()
endfunction
endscope
//TESH.scrollpos=255
//TESH.alwaysfold=0
library EasyCode initializer INIT
globals
constant integer EASY_DEFAULT_SAFETY = 3
constant string EASY_ALPHABET = "1234567890abcdefghijklmnopqrstuvwxyz"
constant integer EASY_MODIFIER = 40 // Change this to something greater than 1. Make sure to use something random and not to change it anymore.
constant integer EASY_MAX_ENTRIES = 10 // The maximum number of items that can be saved in one go…
constant integer EASY_MAX_CODES = 40 // The maximum number of codes that can be saved in one map…
constant integer EASY_NONE = -1
integer EASY_CUR_INDEX = 0
constant boolean EASY_CASE = false
string array EASY_Letter
integer EASY_Letters
integer EASY_ID
endglobals
function EASY_HashValue takes integer key, integer safety, integer value returns integer
local integer a = ModuloInteger( value * key, key + EASY_MODIFIER * value )
local integer b = ModuloInteger( value + EASY_MODIFIER - key, key * EASY_MODIFIER )
if safety < 1 then
set safety = 1
endif
return ModuloInteger( value * ( a - b ), R2I( Pow( 36, safety ) ) - 1 )
endfunction
function EASY_S2I takes string s returns integer
local integer index
local integer stringPos = StringLength( s ) - 1
local integer stringValue = 1
local integer returnValue = 0
local string curChar
set s = StringCase( s, EASY_CASE )
loop
exitwhen stringPos < 0
set index = 0
set curChar = SubString( s, stringPos, stringPos + 1 )
loop
exitwhen index == EASY_Letters
if curChar == EASY_Letter[ index ] then
set returnValue = returnValue + index * stringValue
exitwhen true
endif
set index = index + 1
endloop
set stringValue = stringValue * EASY_Letters
set stringPos = stringPos - 1
endloop
return returnValue
endfunction
function EASY_I2S takes integer i returns string
local string returnString = ""
local integer quot
loop
set quot = i /EASY_Letters
set returnString = EASY_Letter[ i - quot * EASY_Letters ] + returnString
set i = quot
exitwhen i == 0
endloop
return returnString
endfunction
private function INIT takes nothing returns nothing
local integer i = 0
set EASY_Letters = StringLength( EASY_ALPHABET )
set EASY_Letter[ EASY_Letters ] = StringCase( EASY_ALPHABET, EASY_CASE )
loop
exitwhen i == EASY_Letters
set EASY_Letter[ i ] = SubString( EASY_Letter[ EASY_Letters ], i, i + 1 )
set i = i + 1
endloop
endfunction
endlibrary
// EASYSAVE
// The lightweight saver component
library EasySave needs EasyCode
globals
string sj_lastCreatedSaveCode = null
private integer array Value
private integer array Pos
private integer array Indicies
private integer array Size[EASY_MAX_CODES][EASY_MAX_ENTRIES]
private integer array CodeSafety[EASY_MAX_CODES]
private boolean array Initialized[EASY_MAX_CODES]
private integer inUse = EASY_NONE
private integer FreeCoder = 0
endglobals
// Accessors:
function InitializeCoderEx takes integer id, integer safety returns integer
if id == EASY_NONE then
loop
if FreeCoder >= EASY_MAX_CODES then
debug call BJDebugMsg( SCOPE_PREFIX + ": No free Coder available!" )
return EASY_NONE
endif
set EASY_ID = FreeCoder
exitwhen not Initialized[ FreeCoder ]
set FreeCoder = FreeCoder + 1
endloop
else
set EASY_ID = ModuloInteger( id, EASY_MAX_CODES )
endif
if not Initialized[ EASY_ID ] then
set Initialized[ EASY_ID ] = true
set Indicies[ EASY_ID ] = 0
set Pos [ EASY_ID ] = 1
set Value[ EASY_ID ] = 0
else
debug call BJDebugMsg( SCOPE_PREFIX + ": Initializing allready used Coder!" )
endif
set CodeSafety[ EASY_ID ] = safety
return EASY_ID
endfunction
function InitializeCoder takes integer id returns integer
return InitializeCoderEx( id, EASY_DEFAULT_SAFETY )
endfunction
function CoderAddSlot takes integer slotSize returns integer
set Size [ EASY_ID ][ Indicies[ EASY_ID ] ] = slotSize
set Indicies[ EASY_ID ] = Indicies[ EASY_ID ] + 1
return Indicies[ EASY_ID ] - 1
endfunction
function SetCoderSlotSize takes integer slot, integer slotSize returns nothing
set Size [ slot ][ Indicies[ slot ] ] = slotSize
endfunction
function GetCodeSize takes integer id, integer index returns integer
return Size[ id ][ index ]
endfunction
function GetCoderSafety takes integer id returns integer
return CodeSafety[ id ]
endfunction
function GetCoderEntries takes integer id returns integer
return Indicies[ id ]
endfunction
function ActivateCoder takes integer id returns nothing
if inUse != EASY_NONE then
debug call BJDebugMsg( SCOPE_PREFIX + ": Trying to overwrite active coder!" )
call TriggerSleepAction(0.0)
call InitializeCoder( id )
elseif Initialized[ EASY_ID ] then
set inUse = EASY_ID
set EASY_ID = ModuloInteger( id, EASY_MAX_CODES )
set EASY_CUR_INDEX = 0
set Pos [ EASY_ID ] = 1
set Value[ EASY_ID ] = 0
else
debug call BJDebugMsg( SCOPE_PREFIX + ": Accessing uninitialised Coder!" )
endif
endfunction
function CoderAddEntry takes integer entry returns integer
local integer size = Size[ EASY_ID ][ EASY_CUR_INDEX ]
if EASY_CUR_INDEX >= Indicies[ EASY_ID ] then
debug call BJDebugMsg( SCOPE_PREFIX + ": Accessing uninitialised Slot!" )
elseif entry > size then
debug call BJDebugMsg( SCOPE_PREFIX + ": Trying to push too big value to slot " + I2S( EASY_CUR_INDEX ) + "!" )
else
set Value[ EASY_ID ] = Value[ EASY_ID ] + entry * Pos[ EASY_ID ]
set Pos [ EASY_ID ] = Pos [ EASY_ID ] * IntegerTertiaryOp( size == 0, 1, size )
set EASY_CUR_INDEX = EASY_CUR_INDEX + 1
endif
return EASY_CUR_INDEX
endfunction
function CoderGetHashString takes integer key returns string
if CodeSafety[ EASY_ID ] < 1 then
set CodeSafety[ EASY_ID ] = 1
endif
return EASY_I2S( EASY_ID ) + "-" + StringCase( EASY_I2S( EASY_HashValue( key, CodeSafety[ EASY_ID ], Value[ EASY_ID ] ) ), true )
endfunction
function CoderExecute takes integer key returns string
local string value = EASY_I2S( Value[ EASY_ID ] ) + "-" + CoderGetHashString( key )
set inUse = EASY_NONE
set sj_lastCreatedSaveCode = value
return value
endfunction
function GetLastCreatedSaveCodeSJ takes nothing returns string
return sj_lastCreatedSaveCode
endfunction
endlibrary
// EASYLOAD
// The lightweight loader component
library EasyLoad needs EasySave, ExplodeString
globals
boolean sj_wasLastLoadSuccessful = false
private integer array Value[ EASY_MAX_ENTRIES ]
endglobals
// Accessors:
function GetLoaderEntries takes integer id returns integer
return GetCoderEntries( id )
endfunction
function SetLoaderEntry takes integer index, integer entry returns nothing
set Value[ index ] = entry
endfunction
function LoaderGetEntry takes integer index returns integer
return Value[ index ]
endfunction
function LoaderExecute takes string coded, integer key returns boolean
local ExpString exploded = ExplodeString( coded, "-", 4 )
local string value = exploded[ 0 ]
local string id = exploded[ 1 ]
local string hash = exploded[ 2 ]
local integer totalValue = EASY_S2I ( value )
local integer index = 0
local integer curPos = 1
local integer maxIndex = GetCoderEntries( EASY_ID )
local integer restValue = totalValue
local integer safety
local integer quot
local boolean isHashCorrect
set EASY_ID = EASY_S2I ( id )
set safety = GetCoderSafety( EASY_ID )
set isHashCorrect = StringCase( hash, false ) == EASY_I2S( EASY_HashValue( key, safety, totalValue ) )
call exploded.destroy()
if isHashCorrect then
loop
exitwhen index >= maxIndex
set curPos = GetCodeSize( EASY_ID, index )
set quot = restValue / curPos
set Value[ index ] = restValue - quot * curPos
set restValue = quot
set index = index + 1
endloop
else
loop
exitwhen index >= maxIndex
set Value[ index ] = EASY_NONE
set index = index + 1
endloop
debug call BJDebugMsg( SCOPE_PREFIX + ": Bad hash value!" )
endif
set sj_wasLastLoadSuccessful = isHashCorrect
return isHashCorrect
endfunction
function WasLoadSuccessfulSJ takes nothing returns boolean
return sj_wasLastLoadSuccessful
endfunction
endlibrary
//TESH.scrollpos=56
//TESH.alwaysfold=0
library SaveRanking initializer INIT needs Ranking, PasswordSaver
globals
private integer CODER_SLOT = -1
private integer array MinRank
endglobals
function SavePlayerRank takes player p returns nothing
local integer index = GetPlayerId( p )
local integer key
local string savecode
local integer rank = GetPlayerRank( p )
if not HasPlayerEnteredPassword( p ) then
call AskPlayerPassword( p )
endif
set key = GetPlayerPassword( p )
set rank = IMaxBJ( MinRank[ index ], rank )
call ActivateCoder( CODER_SLOT )
call CoderAddEntry( rank )
call CoderExecute ( key )
set savecode = GetLastCreatedSaveCodeSJ()
call DisplayTimedTextToPlayer( p, 0, 0, 30, LIGHTGREY + "Please write down the following rank code:" )
call DisplayTimedTextToPlayer( p, 0, 0, 30, GOLD + "\n " + savecode + "\n\n" )
call DisplayTimedTextToPlayer( p, 0, 0, 30, LIGHTGREY + "Enter " + GOLD + "'-load " + savecode + "'" + LIGHTGREY + " to load your rank!" )
endfunction
function LoadPlayerRank takes player p, string savecode returns nothing
local integer index = GetPlayerId( p )
local integer key
local integer rank
local boolean correctCode
if not HasPlayerEnteredPassword( p ) then
call AskPlayerPassword( p )
endif
set key = GetPlayerPassword( p )
call LoaderExecute ( savecode, key )
if WasLoadSuccessfulSJ() then
set rank = LoaderGetEntry( 0 )
if GameState == GAME_STATE_INIT or GetPolledPlayerFeedback( p, "Load " + I2S( rank ) + " Rank?", 30 ) then
call SetPlayerRank( p, rank )
call DisplayText( p, LIGHTGREY + "Restored " + GOLD + I2S( rank ) + LIGHTGREY + " Rank." )
call DisplayText( LOCAL_PLAYER, LIGHTGREY + "A " + GetPlayerRankText(p) + LIGHTGREY + " has entered the Battlefield!" )
set MinRank[ index ] = rank
endif
else
call DisplayText( p, RED + "Invalid code entered!" + LIGHTGREY + " Try to retype your password or retype the code." )
endif
endfunction
private function SaveRank takes nothing returns nothing
call SavePlayerRank( GetTriggerPlayer() )
endfunction
private function LoadRank takes nothing returns nothing
if GameState == GAME_STATE_INIT then
call LoadPlayerRank( GetTriggerPlayer(), GetEventPlayerChatStringUnmatched() )
else
call DisplayText( GetTriggerPlayer(), RED + "You cannot load codes anymore!" )
endif
endfunction
private function INIT takes nothing returns nothing
local trigger t
set t = CreateTrigger()
call TriggerRegisterAnyPlayerChatEvent( t, "-save", true )
call TriggerAddAction( t, function SaveRank )
set t = CreateTrigger()
call TriggerRegisterAnyPlayerChatEvent( t, "-load ", false)
call TriggerAddAction( t, function LoadRank )
set CODER_SLOT = InitializeCoder( CODER_SLOT )
call CoderAddSlot( MAX_RANK )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Ranking initializer INIT needs Utilities
scope RankFactors
globals
real array PlayerRankingFactor
real GlobalRankFactor = 1.0
constant integer MAX_RANK = 10000
constant integer START_RANK = 10
endglobals
function SetPlayerRankingFactor takes player p, real factor returns nothing
set PlayerRankingFactor[ GetPlayerId( p ) ] = factor
endfunction
function GetPlayerRankingFactor takes player p returns real
return PlayerRankingFactor[ GetPlayerId( p ) ]
endfunction
function GetPlayerRankFactor takes player p returns real
return GetPlayerRankingFactor( p ) * GlobalRankFactor
endfunction
function SetGlobalRankFactor takes real r returns nothing
set GlobalRankFactor = r
endfunction
function GetGlobalRankFactor takes nothing returns real
return GlobalRankFactor
endfunction
endscope
scope Rank
globals
integer array Rank
endglobals
function PlayerAddRank takes player p, integer amount returns nothing
local integer index = GetPlayerId( p )
set Rank[ index ] = Rank[ index ] + R2I( amount * PlayerRankingFactor[ index ] * GlobalRankFactor + 0.9 )
if Rank[ index ] > MAX_RANK then
set Rank[ index ] = MAX_RANK
endif
endfunction
function SetPlayerRank takes player p, integer amount returns nothing
set Rank[ GetPlayerId( p ) ] = amount
endfunction
function GetPlayerRank takes player p returns integer
return Rank[ GetPlayerId( p ) ]
endfunction
endscope
scope RankText
struct rankstate
static integer count = 0
static rankstate array self
integer state
string text
rankstate next
static method create takes string text, real state returns thistype
local thistype new = .allocate()
local integer i = .count
local integer nextI = i - 1
set new.text = text
set new.state = R2I( state * MAX_RANK )
set .count = .count + 1
loop
exitwhen i <= 0
exitwhen new.state >= .self[ nextI ]
set .self[ i ] = .self[ nextI ]
set i = nextI
set nextI = nextI - 1
endloop
set .self[ i ] = new
set new.next = .self[ i + 1 ]
set .self[ i - 1 ].next = new
return new
endmethod
endstruct
function SetRankStateText takes string text, real state returns nothing
call rankstate.create( text, state )
endfunction
function GetRankState takes integer state returns rankstate
local integer index = 0
loop
if rankstate.self[index].state >= state then
if index != 0 then
set index = index - 1
endif
exitwhen true
endif
exitwhen index >= rankstate.count - 1
set index = index + 1
endloop
return rankstate.self[ index ]
endfunction
function GetRankStateText takes integer state returns string
return GetRankState( state ).text
endfunction
function GetPlayerRankText takes player p returns string
local rankstate r = GetRankState( GetPlayerRank( p ) )
local real finished = I2R( GetPlayerRank( p ) - r.state ) / ( r.next.state - r.state )
return State2Color( finished ) + r.text + "|r"
endfunction
endscope
private function INIT takes nothing returns nothing
local integer i = 0
loop
exitwhen i > MAX_USER_SLOT
set PlayerRankingFactor[ i ] = 1.0
set Rank[ i ] = START_RANK
set i = i + 1
endloop
// Rank in % of RANK_MAX
call SetRankStateText( "Slave", 0.00 )
call SetRankStateText( "Pawn", 0.01 )
call SetRankStateText( "Bandit", 0.02 )
call SetRankStateText( "Footman", 0.03 )
call SetRankStateText( "Rider", 0.05 )
call SetRankStateText( "Knight", 0.08 )
call SetRankStateText( "Commander", 0.12 )
call SetRankStateText( "Elder", 0.16 )
call SetRankStateText( "Lord", 0.22 )
call SetRankStateText( "Mage", 0.30 )
call SetRankStateText( "King", 0.38 )
call SetRankStateText( "Angel", 0.48 )
call SetRankStateText( "Avatar", 0.58 )
call SetRankStateText( "Demigod", 0.70 )
call SetRankStateText( "Master of All", 0.99 )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library ExplodeString
// ________________________________________
// +----------------------------------------+
// | E X P L O D E S T R I N G |
// | v3 |
// +----------------------------------------+
// | SerraAvenger |
// | Separation algorithm coded by Romek |
// |________________________________________|
// +----------------------------------------+
struct ExpString
// Change the [10] to the maximum amount of substrings
private string array S [10]
readonly integer size
method operator [] takes integer i returns string
if i < .size and i >= 0 then
return .S[i]
endif
return null
endmethod
static method create takes string source, string separator, integer maxamount returns ExpString
local ExpString this = ExpString.allocate()
local integer i = 0
local integer last = 0
local integer first = 0
local integer length
local boolean insep = true
if maxamount < 1 then
set maxamount = 1
endif
set maxamount = maxamount - 1
if separator == "" or separator == null then
set separator = " "
else
set separator = SubString(separator, 0, 1)
endif
set .size = 0
set source = separator + source
set length = StringLength(source)
loop
exitwhen i > length
if SubString(source, i, i + 1) == separator or i == length then
if not insep then
set last = i + 1
set insep = true
if .size == maxamount then
set .S[.size ] = SubString(source, first, length)
exitwhen true
endif
set .S[.size ] = SubString(source, first, last - 1)
set .size = .size + 1
endif
elseif insep then
set insep = false
set first = i
endif
set i = i + 1
endloop
return this
endmethod
method onDestroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i > .size
set .S[ i ] = null
set i = i + 1
endloop
endmethod
endstruct
function ExplodeString takes string source, string separator, integer maxamount returns ExpString
return ExpString.create(source, separator, maxamount)
endfunction
endlibrary
//TESH.scrollpos=32
//TESH.alwaysfold=0
////! runtextmacro Attach( "DialogOwnerId", "Dialog", "integer", "0" )
library GetPlayerFeedback initializer INIT needs Utilities, Dialogs
globals
public boolean array ReturnVal
private boolean array HasClicked
private Dialog array FeedbackDialog
private integer array OwnerId
endglobals
private function NULL_FUNC takes nothing returns nothing
endfunction
function AskPlayerFeedback takes player whichPlayer, string question, code execute returns nothing
local integer i = GetPlayerId( whichPlayer )
call FeedbackDialog[i].SetMessage( GOLD + question )
call FeedbackDialog[i].AddAction( execute )
call FeedbackDialog[i].Show( whichPlayer )
set ReturnVal [i] = false
set HasClicked[i] = false
endfunction
private function Feedback_Check takes nothing returns boolean
local Dialog id = GetTriggerDialog()
local integer i = OwnerId[ integer( id ) ]
set ReturnVal[i] = id.GetResult() == HK_A
set HasClicked[i] = true
return true
endfunction
function GetPlayerFeedback takes player whichPlayer returns boolean
return ReturnVal[ GetPlayerId( whichPlayer ) ]
endfunction
function GetPolledPlayerFeedback takes player whichplayer, string question, real maxWait returns boolean
local integer i = GetPlayerId( whichplayer )
call AskPlayerFeedback( whichplayer, question, function NULL_FUNC )
loop
exitwhen HasClicked[i]
exitwhen maxWait <= 0
call TriggerSleepAction( 0.1 )
set maxWait = maxWait - 0.1
endloop
return GetPlayerFeedback( whichplayer )
endfunction
private function INIT takes nothing returns nothing
local integer i = 0
local boolexpr condFunc = Condition( function Feedback_Check )
loop
exitwhen i > MAX_USER_SLOT
set FeedbackDialog[i] = Dialog.create()
set OwnerId[ integer( FeedbackDialog[i] ) ] = i
call FeedbackDialog[i].AddButton( GOLD + "A" + GREEN + "ccept", HK_A )
call FeedbackDialog[i].AddButton( GOLD + "C" + RED + "ancel", HK_C )
call FeedbackDialog[i].AddCondition( condFunc)
set i = i + 1
endloop
endfunction
endlibrary
//TESH.scrollpos=137
//TESH.alwaysfold=0
library Dialogs needs ABC
globals
// Dialog button hotkey constants
constant integer HK_ESC = 512
constant integer HK_0 = 48
constant integer HK_1 = 49
constant integer HK_2 = 50
constant integer HK_3 = 51
constant integer HK_4 = 52
constant integer HK_5 = 53
constant integer HK_6 = 54
constant integer HK_7 = 55
constant integer HK_8 = 56
constant integer HK_9 = 57
constant integer HK_A = 65
constant integer HK_B = 66
constant integer HK_C = 67
constant integer HK_D = 68
constant integer HK_E = 69
constant integer HK_F = 70
constant integer HK_G = 71
constant integer HK_H = 72
constant integer HK_I = 73
constant integer HK_J = 74
constant integer HK_K = 75
constant integer HK_L = 76
constant integer HK_M = 77
constant integer HK_N = 78
constant integer HK_O = 79
constant integer HK_P = 80
constant integer HK_Q = 81
constant integer HK_R = 82
constant integer HK_S = 83
constant integer HK_T = 84
constant integer HK_U = 85
constant integer HK_V = 86
constant integer HK_W = 87
constant integer HK_X = 88
constant integer HK_Y = 89
constant integer HK_Z = 90
endglobals
globals
private constant integer MAX_BUTTONS = 16 // maximum of buttons on dialog
endglobals
//===========================================================================
// Use this inside dialog action function
//===========================================================================
function GetTriggerDialog takes nothing returns Dialog
return GetDialogStructA( GetClickedDialog() )
endfunction
//===========================================================================
struct Dialog
private trigger t = CreateTrigger()
private dialog d = DialogCreate()
private boolean isActionSet = false
private string messageText = ""
private integer button_count = 0
private button array buttons[MAX_BUTTONS]
private integer array hotkeys[MAX_BUTTONS]
static method create takes nothing returns Dialog
local Dialog this = .allocate()
call TriggerRegisterDialogEvent( .t, .d )
call SetDialogStructA( .d, this )
return this
endmethod
method onDestroy takes nothing returns nothing
call DestroyTrigger(.t)
call DialogDestroy(.d)
endmethod
method GetResult takes nothing returns integer
local button b = GetClickedButton()
local integer i = 0
local integer result = -1
loop
exitwhen i >= MAX_BUTTONS
exitwhen result != -1
if b == this.buttons[i] then
set result = this.hotkeys[i]
endif
set i = i + 1
endloop
return result
endmethod
method SetMessage takes string messageText returns nothing
set .messageText = messageText
endmethod
method AddButton takes string buttonText, integer hotkey returns nothing
local button b
if this.button_count >= MAX_BUTTONS then
debug call BJDebugMsg("|c00FF0000ERROR: Maximum number of dialog buttons is " + I2S(MAX_BUTTONS))
else
set b = DialogAddButton( this.d, buttonText , hotkey )
set this.buttons[this.button_count] = b
set this.hotkeys[this.button_count] = hotkey
set this.button_count = this.button_count + 1
endif
endmethod
method AddCondition takes boolexpr condFunc returns nothing
call TriggerAddCondition( this.t, condFunc )
endmethod
method AddAction takes code actionFunc returns nothing
if this.isActionSet == true then
call TriggerClearActions( this.t )
endif
set this.isActionSet = true
call TriggerAddAction( this.t, actionFunc )
endmethod
method Show takes player whichPlayer returns nothing
if this.isActionSet == false then
debug call BJDebugMsg("|c00FF0000WARNING: You forgot to set a dialog action")
endif
if this.button_count == 0 then
debug call BJDebugMsg("|c00FF0000ERROR: You cannot show dialog with no buttons")
else
// message must be set before every display because of some bug.
call DialogSetMessage( this.d, this.messageText )
call DialogDisplay(whichPlayer, this.d, true)
endif
endmethod
method ShowAll takes nothing returns nothing
local integer i = 0
loop
exitwhen i>=12 // maximum of human players is 12
if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
call this.Show(Player(i))
endif
set i = i + 1
endloop
endmethod
method Hide takes player whichPlayer returns nothing
call DialogDisplay(whichPlayer, this.d, false)
endmethod
method HideAll takes nothing returns nothing
local integer i = 0
loop
exitwhen i>=12 // maximum of human players is 12
call this.Hide(Player(i))
set i = i + 1
endloop
endmethod
endstruct
endlibrary
//TESH.scrollpos=526
//TESH.alwaysfold=0
//==============================================================================
// ABC -- STRUCT ATTACHMENT SYSTEM BY COHADAR -- v6.1
//==============================================================================
//==============================================================================
// Quick function index:
//==============================================================================
//
// ----------------------------------------------------------------------
// Set Functions - these functions attach struct to a handle
// ----------------------------------------------------------------------
// SetTimerStructA(timer, struct)
// SetTimerStructB(timer, struct)
// SetTimerStructC(timer, struct)
//
// SetTriggerStructA(trigger, struct)
// SetTriggerStructB(trigger, struct)
// SetTriggerStructC(trigger, struct)
//
// SetDialogStructA(dialog, struct)
// SetDialogStructB(dialog, struct)
// SetDialogStructC(dialog, struct)
//
// SetRegionStructA(region, struct)
// SetRegionStructB(region, struct)
// SetRegionStructC(region, struct)
//
// ----------------------------------------------------------------------
// Get Functions - these functions retrieve attached structs
// ----------------------------------------------------------------------
// GetTimerStructA(timer) -> struct
// GetTimerStructB(timer) -> struct
// GetTimerStructC(timer) -> struct
//
// GetTriggerStructA(trigger) -> struct
// GetTriggerStructB(trigger) -> struct
// GetTriggerStructC(trigger) -> struct
//
// GetDialogStructA(dialog) -> struct
// GetDialogStructB(dialog) -> struct
// GetDialogStructC(dialog) -> struct
//
// GetRegionStructA(region) -> struct
// GetRegionStructB(region) -> struct
// GetRegionStructC(region) -> struct
//
// ----------------------------------------------------------------------
// Clear Functions - these functions clear and return attached value
// ----------------------------------------------------------------------
// ClearTimerStructA(timer) -> struct
// ClearTimerStructB(timer) -> struct
// ClearTimerStructC(timer) -> struct
//
// ClearTriggerStructA(trigger) -> struct
// ClearTriggerStructB(trigger) -> struct
// ClearTriggerStructC(trigger) -> struct
//
// ClearDialogStructA(dialog) -> struct
// ClearDialogStructB(dialog) -> struct
// ClearDialogStructC(dialog) -> struct
//
// ClearRegionStructA(region) -> struct
// ClearRegionStructB(region) -> struct
// ClearRegionStructC(region) -> struct
//
//==============================================================================
//==============================================================================
// DOCUMENTATION:
//==============================================================================
//
// PURPOUSE OF ABC:
// * Type safe handle attaching.
//
// * Currently supported handle types are timer, trigger, dialog and region
//
// PROS:
// * ABC is faster than gamecache based systems.
//
// * You can attach up to 3 structs on the same handle
//
// * System reports collision, and clearing of non-existent value.
//
// * This system will work even if your map leaks
// and will NOT slow down because of it.
//
// CONS:
// * you must manually clear the stored value - REMEMBER THIS RULE!!!
// Don't forget to use Clear functions
//
// DETAILS:
// * You can use Get to check if struct is attached to handle
// It will return 0 if it is not.
//
// * ABC will not interfere with other attachment systems
// You can freely use any other system alongside ABC
//
// * For unit attaching I recommend using PUI
//
// SPECIAL THANKS TO:
// * NagelBagel - for finding errors in versions 4.3 and 4.4
// * Here-b-Trollz - for testing ABC and for making cool spells with it.
// * Toadcop - for being pain in the ass and for pushing me to improve ABC.
// * emjlr3 - for pointing out the need for non-generic trigger attachments
// * PandaMine - I found a bug in ABC by examining his HSAS vs ABC test
// * All those people out there who use and support my systems
// Thank you guys.
//
// HOW TO IMPORT:
// * Just create a trigger named ABC
// * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
//==============================================================================
// Macro function cores
//==============================================================================
//------------------------------------------------------------------------------
//! textmacro ABC_Set takes X, NAME, TYPE
local integer i = GetHandleId(key)
set i = i - (i / HASH) * HASH
if $NAME$Key$X$[i] == null then
set $NAME$Key$X$[i] = key
set $NAME$Value$X$[i] = value
else
debug set $NAME$Collision$X$[i] = $NAME$Collision$X$[i] + 1
debug if $NAME$MaxCollision$X$ < $NAME$Collision$X$[i] then
debug set $NAME$MaxCollision$X$ = $NAME$Collision$X$[i]
debug call BJDebugMsg("|cFFFF00FFWarning: Set$NAME$Struct$X$("+I2S(GetHandleId(key))+", "+I2S(value)+") - index: "+I2S(i)+", collision: "+I2S($NAME$MaxCollision$X$))
debug endif
call SaveInteger($NAME$Hash, '$X$', GetHandleId(key), value)
endif
//! endtextmacro
//------------------------------------------------------------------------------
//! textmacro ABC_Get takes X, NAME, TYPE
local integer i = GetHandleId(key)
set i = i - (i / HASH) * HASH
if $NAME$Key$X$[i] == key then
return $NAME$Value$X$[i]
else
return LoadInteger($NAME$Hash, '$X$', GetHandleId(key))
endif
//! endtextmacro
//------------------------------------------------------------------------------
//! textmacro ABC_Clear takes X, NAME, TYPE
local integer ret
local integer i = GetHandleId(key)
set i = i - (i / HASH) * HASH
if $NAME$Key$X$[i] == key then
set ret = $NAME$Value$X$[i]
set $NAME$Key$X$[i] = null
set $NAME$Value$X$[i] = 0
else
if HaveSavedInteger($NAME$Hash, '$X$', GetHandleId(key)) then
debug set $NAME$Collision$X$[i] = $NAME$Collision$X$[i] - 1
set ret = LoadInteger($NAME$Hash, '$X$', GetHandleId(key))
call RemoveSavedInteger($NAME$Hash, '$X$', GetHandleId(key))
else
call BJDebugMsg("|cFFFF0000ERROR: Clear$NAME$Struct$X$("+I2S(GetHandleId(key))+") - clear attempt on bad key")
set ret = 0
endif
endif
return ret
//! endtextmacro
//==============================================================================
library ABC initializer Init
globals
private constant integer HASH = 8191
private timer array TimerKeyA
private timer array TimerKeyB
private timer array TimerKeyC
private trigger array TriggerKeyA
private trigger array TriggerKeyB
private trigger array TriggerKeyC
private dialog array DialogKeyA
private dialog array DialogKeyB
private dialog array DialogKeyC
private region array RegionKeyA
private region array RegionKeyB
private region array RegionKeyC
private integer array TimerValueA
private integer array TimerValueB
private integer array TimerValueC
private integer array TriggerValueA
private integer array TriggerValueB
private integer array TriggerValueC
private integer array DialogValueA
private integer array DialogValueB
private integer array DialogValueC
private integer array RegionValueA
private integer array RegionValueB
private integer array RegionValueC
private integer array TimerCollisionA
private integer array TimerCollisionB
private integer array TimerCollisionC
private integer array TriggerCollisionA
private integer array TriggerCollisionB
private integer array TriggerCollisionC
private integer array DialogCollisionA
private integer array DialogCollisionB
private integer array DialogCollisionC
private integer array RegionCollisionA
private integer array RegionCollisionB
private integer array RegionCollisionC
private integer TimerMaxCollisionA = 0
private integer TimerMaxCollisionB = 0
private integer TimerMaxCollisionC = 0
private integer TriggerMaxCollisionA = 0
private integer TriggerMaxCollisionB = 0
private integer TriggerMaxCollisionC = 0
private integer DialogMaxCollisionA = 0
private integer DialogMaxCollisionB = 0
private integer DialogMaxCollisionC = 0
private integer RegionMaxCollisionA = 0
private integer RegionMaxCollisionB = 0
private integer RegionMaxCollisionC = 0
private hashtable TimerHash
private hashtable TriggerHash
private hashtable DialogHash
private hashtable RegionHash
endglobals
//==============================================================================
// Collision check functions
//==============================================================================
//------------------------------------------------------------------------------
function GetTimerCollisionA takes nothing returns integer
return TimerMaxCollisionA
endfunction
//------------------------------------------------------------------------------
function GetTimerCollisionB takes nothing returns integer
return TimerMaxCollisionB
endfunction
//------------------------------------------------------------------------------
function GetTimerCollisionC takes nothing returns integer
return TimerMaxCollisionC
endfunction
//------------------------------------------------------------------------------
function GetTriggerCollisionA takes nothing returns integer
return TriggerMaxCollisionA
endfunction
//------------------------------------------------------------------------------
function GetTriggerCollisionB takes nothing returns integer
return TriggerMaxCollisionB
endfunction
//------------------------------------------------------------------------------
function GetTriggerCollisionC takes nothing returns integer
return TriggerMaxCollisionC
endfunction
//------------------------------------------------------------------------------
function GetDialogCollisionA takes nothing returns integer
return DialogMaxCollisionA
endfunction
//------------------------------------------------------------------------------
function GetDialogCollisionB takes nothing returns integer
return DialogMaxCollisionB
endfunction
//------------------------------------------------------------------------------
function GetDialogCollisionC takes nothing returns integer
return DialogMaxCollisionC
endfunction
//------------------------------------------------------------------------------
function GetRegionCollisionA takes nothing returns integer
return RegionMaxCollisionA
endfunction
//------------------------------------------------------------------------------
function GetRegionCollisionB takes nothing returns integer
return RegionMaxCollisionB
endfunction
//------------------------------------------------------------------------------
function GetRegionCollisionC takes nothing returns integer
return RegionMaxCollisionC
endfunction
//==============================================================================
// Set functions
//==============================================================================
//------------------------------------------------------------------------------
function SetTimerStructA takes timer key, integer value returns nothing
//! runtextmacro ABC_Set("A", "Timer", "timer")
endfunction
//------------------------------------------------------------------------------
function SetTimerStructB takes timer key, integer value returns nothing
//! runtextmacro ABC_Set("B", "Timer", "timer")
endfunction
//------------------------------------------------------------------------------
function SetTimerStructC takes timer key, integer value returns nothing
//! runtextmacro ABC_Set("C", "Timer", "timer")
endfunction
//------------------------------------------------------------------------------
function SetTriggerStructA takes trigger key, integer value returns nothing
//! runtextmacro ABC_Set("A", "Trigger", "trigger")
endfunction
//------------------------------------------------------------------------------
function SetTriggerStructB takes trigger key, integer value returns nothing
//! runtextmacro ABC_Set("B", "Trigger", "trigger")
endfunction
//------------------------------------------------------------------------------
function SetTriggerStructC takes trigger key, integer value returns nothing
//! runtextmacro ABC_Set("C", "Trigger", "trigger")
endfunction
//------------------------------------------------------------------------------
function SetDialogStructA takes dialog key, integer value returns nothing
//! runtextmacro ABC_Set("A", "Dialog", "dialog")
endfunction
//------------------------------------------------------------------------------
function SetDialogStructB takes dialog key, integer value returns nothing
//! runtextmacro ABC_Set("B", "Dialog", "dialog")
endfunction
//------------------------------------------------------------------------------
function SetDialogStructC takes dialog key, integer value returns nothing
//! runtextmacro ABC_Set("C", "Dialog", "dialog")
endfunction
//------------------------------------------------------------------------------
function SetRegionStructA takes region key, integer value returns nothing
//! runtextmacro ABC_Set("A", "Region", "region")
endfunction
//------------------------------------------------------------------------------
function SetRegionStructB takes region key, integer value returns nothing
//! runtextmacro ABC_Set("B", "Region", "region")
endfunction
//------------------------------------------------------------------------------
function SetRegionStructC takes region key, integer value returns nothing
//! runtextmacro ABC_Set("C", "Region", "region")
endfunction
//==============================================================================
// Get functions
//==============================================================================
//------------------------------------------------------------------------------
function GetTimerStructA takes timer key returns integer
//! runtextmacro ABC_Get("A", "Timer", "timer")
endfunction
//------------------------------------------------------------------------------
function GetTimerStructB takes timer key returns integer
//! runtextmacro ABC_Get("B", "Timer", "timer")
endfunction
//------------------------------------------------------------------------------
function GetTimerStructC takes timer key returns integer
//! runtextmacro ABC_Get("C", "Timer", "timer")
endfunction
//------------------------------------------------------------------------------
function GetTriggerStructA takes trigger key returns integer
//! runtextmacro ABC_Get("A", "Trigger", "trigger")
endfunction
//------------------------------------------------------------------------------
function GetTriggerStructB takes trigger key returns integer
//! runtextmacro ABC_Get("B", "Trigger", "trigger")
endfunction
//------------------------------------------------------------------------------
function GetTriggerStructC takes trigger key returns integer
//! runtextmacro ABC_Get("C", "Trigger", "trigger")
endfunction
//------------------------------------------------------------------------------
function GetDialogStructA takes dialog key returns integer
//! runtextmacro ABC_Get("A", "Dialog", "dialog")
endfunction
//------------------------------------------------------------------------------
function GetDialogStructB takes dialog key returns integer
//! runtextmacro ABC_Get("B", "Dialog", "dialog")
endfunction
//------------------------------------------------------------------------------
function GetDialogStructC takes dialog key returns integer
//! runtextmacro ABC_Get("C", "Dialog", "dialog")
endfunction
//------------------------------------------------------------------------------
function GetRegionStructA takes region key returns integer
//! runtextmacro ABC_Get("A", "Region", "region")
endfunction
//------------------------------------------------------------------------------
function GetRegionStructB takes region key returns integer
//! runtextmacro ABC_Get("B", "Region", "region")
endfunction
//------------------------------------------------------------------------------
function GetRegionStructC takes region key returns integer
//! runtextmacro ABC_Get("C", "Region", "region")
endfunction
//==============================================================================
// Clear functions
//==============================================================================
//------------------------------------------------------------------------------
function ClearTimerStructA takes timer key returns integer
//! runtextmacro ABC_Clear("A", "Timer", "timer")
endfunction
//------------------------------------------------------------------------------
function ClearTimerStructB takes timer key returns integer
//! runtextmacro ABC_Clear("B", "Timer", "timer")
endfunction
//------------------------------------------------------------------------------
function ClearTimerStructC takes timer key returns integer
//! runtextmacro ABC_Clear("C", "Timer", "timer")
endfunction
//------------------------------------------------------------------------------
function ClearTriggerStructA takes trigger key returns integer
//! runtextmacro ABC_Clear("A", "Trigger", "trigger")
endfunction
//------------------------------------------------------------------------------
function ClearTriggerStructB takes trigger key returns integer
//! runtextmacro ABC_Clear("B", "Trigger", "trigger")
endfunction
//------------------------------------------------------------------------------
function ClearTriggerStructC takes trigger key returns integer
//! runtextmacro ABC_Clear("C", "Trigger", "trigger")
endfunction
//------------------------------------------------------------------------------
function ClearDialogStructA takes dialog key returns integer
//! runtextmacro ABC_Clear("A", "Dialog", "dialog")
endfunction
//------------------------------------------------------------------------------
function ClearDialogStructB takes dialog key returns integer
//! runtextmacro ABC_Clear("B", "Dialog", "dialog")
endfunction
//------------------------------------------------------------------------------
function ClearDialogStructC takes dialog key returns integer
//! runtextmacro ABC_Clear("C", "Dialog", "dialog")
endfunction
//------------------------------------------------------------------------------
function ClearRegionStructA takes region key returns integer
//! runtextmacro ABC_Clear("A", "Region", "region")
endfunction
//------------------------------------------------------------------------------
function ClearRegionStructB takes region key returns integer
//! runtextmacro ABC_Clear("B", "Region", "region")
endfunction
//------------------------------------------------------------------------------
function ClearRegionStructC takes region key returns integer
//! runtextmacro ABC_Clear("C", "Region", "region")
endfunction
//==============================================================================
// Initialization
//==============================================================================
private function Init takes nothing returns nothing
set TimerKeyA[HASH-1] = null
set TimerKeyB[HASH-1] = null
set TimerKeyC[HASH-1] = null
set TriggerKeyA[HASH-1] = null
set TriggerKeyB[HASH-1] = null
set TriggerKeyC[HASH-1] = null
set DialogKeyA[HASH-1] = null
set DialogKeyB[HASH-1] = null
set DialogKeyC[HASH-1] = null
set RegionKeyA[HASH-1] = null
set RegionKeyB[HASH-1] = null
set RegionKeyC[HASH-1] = null
set TimerValueA[HASH-1] = 0
set TimerValueB[HASH-1] = 0
set TimerValueC[HASH-1] = 0
set TriggerValueA[HASH-1] = 0
set TriggerValueB[HASH-1] = 0
set TriggerValueC[HASH-1] = 0
set DialogValueA[HASH-1] = 0
set DialogValueB[HASH-1] = 0
set DialogValueC[HASH-1] = 0
set RegionValueA[HASH-1] = 0
set RegionValueB[HASH-1] = 0
set RegionValueC[HASH-1] = 0
set TimerCollisionA[HASH-1] = 0
set TimerCollisionB[HASH-1] = 0
set TimerCollisionC[HASH-1] = 0
set TriggerCollisionA[HASH-1] = 0
set TriggerCollisionB[HASH-1] = 0
set TriggerCollisionC[HASH-1] = 0
set DialogCollisionA[HASH-1] = 0
set DialogCollisionB[HASH-1] = 0
set DialogCollisionC[HASH-1] = 0
set RegionCollisionA[HASH-1] = 0
set RegionCollisionB[HASH-1] = 0
set RegionCollisionC[HASH-1] = 0
set TimerHash = InitHashtable()
set TriggerHash = InitHashtable()
set DialogHash = InitHashtable()
set RegionHash = InitHashtable()
endfunction
endlibrary
//==============================================================================
// END OF ABC STRUCT ATTACHMENT SYSTEM
//==============================================================================
//TESH.scrollpos=0
//TESH.alwaysfold=0
///// VER 00
library Zoomer initializer InitZoom needs Utilities
globals
private real array Distance
private constant real NearDistance = 3500
private constant trigger BackZoomer = CreateTrigger()
private constant real sj_DISTTOFARZ = 3
private integer PlayerId
private cardboard lastBoard
endglobals
function SelectSelector takes integer i, boolean sel returns nothing
if i == PlayerId then
call SelectUnit( Selector[ i ], sel )
endif
endfunction
private function BackZoomer_Actions takes nothing returns nothing
call SetCameraField( CAMERA_FIELD_FARZ, sj_DISTTOFARZ * Distance[ PlayerId ], 0 )
call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE, Distance[ PlayerId ], 0 )
call SetCameraField( CAMERA_FIELD_ANGLE_OF_ATTACK, -90, 0 )
if lastBoard == CurrentBoard[ PlayerId ] then
else
call SelectSelector( PlayerId, true )
call CurrentBoard[ PlayerId ].bindCamera( LOCAL_PLAYER )
set lastBoard = CurrentBoard[ PlayerId ]
endif
endfunction
private function InitZoom takes nothing returns nothing
local integer playerId = 0
loop
exitwhen playerId > NUMPLAYERS
set Distance[ playerId ] = NearDistance
set playerId = playerId + 1
endloop
call SetTimeOfDay( 8 )
call SuspendTimeOfDay( true )
call TriggerRegisterTimerEvent( BackZoomer, 0.2, true )
call TriggerAddAction ( BackZoomer, function BackZoomer_Actions )
set PlayerId = GetPlayerId( LOCAL_PLAYER )
set lastBoard = CurrentBoard[ PlayerId ]
endfunction
endlibrary
//TESH.scrollpos=98
//TESH.alwaysfold=0
library PasswordSaver initializer INIT needs ExplodeString, EasySave, EasyLoad, Dialogs
globals
private integer PASSWORD_LENGTH = 4
private integer array Len
private integer array Pwd
private boolean array HasPwd
private Dialog PwdPanel
private Dialog ResetPanel
endglobals
private function PlayerResetPassword takes player p returns nothing
local integer trigId = GetPlayerId( p )
call DisplayText( p, LIGHTGREY + "Password resetted." )
set Pwd[ trigId ] = 0
set Len[ trigId ] = 0
set HasPwd[ trigId ] = false
endfunction
private function SavePassword takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local boolean save = GetPlayerFeedback( trigPlayer )
local integer trigId = GetPlayerId( trigPlayer )
if save then
set HasPwd[ trigId ] = true
call DisplayText( trigPlayer, LIGHTGREY + "Password saved." )
else
call PlayerResetPassword( trigPlayer )
call PwdPanel.Show( trigPlayer )
endif
endfunction
private function SetPassword_enum takes nothing returns nothing
local Dialog clicked = GetTriggerDialog()
local player trigPlayer = GetTriggerPlayer()
local integer letter = clicked.GetResult() - HK_0
local integer trigId = GetPlayerId( trigPlayer )
set Pwd[ trigId ] = Pwd[ trigId ] * 10 + letter
set Len[ trigId ] = Len[ trigId ] + 1
if Len[ trigId ] == PASSWORD_LENGTH then
if Pwd[ trigId ] != 0 then
call AskPlayerFeedback( trigPlayer, "Save " + I2S( Pwd[ trigId ] ) + " as your password?", function SavePassword )
else
call DisplayText( trigPlayer, RED + "Bad password entered!" )
call PlayerResetPassword( trigPlayer )
endif
else
call clicked.Show( trigPlayer )
endif
endfunction
private function ChatCommandPassword takes nothing returns nothing
local ExpString command = ExplodeString( StringCase( GetEventPlayerChatString(), false ), " ", 3 )
local player trigPlayer = GetTriggerPlayer()
local integer trigId = GetPlayerId ( trigPlayer )
if command[ 1 ] == "reset" then
call PlayerResetPassword( trigPlayer )
elseif command[ 1 ] == "show" then
call DisplayText( trigPlayer, LIGHTGREY + "For security reasons, we may not show you your password. Use " + GOLD + "'-password new'" + LIGHTGREY + " to reset your password, then get a new password." )
elseif command[ 1 ] == "new" or command[ 1 ] == "set" then
call PlayerResetPassword( trigPlayer )
call PwdPanel.Show( trigPlayer )
elseif command[ 1 ] == "" or command[ 1 ] == null then
if HasPwd[ trigId ] then
call DisplayText( trigPlayer, RED + "You already have a password!" )
else
call PwdPanel.Show( trigPlayer )
endif
else
call DisplayText( trigPlayer, RED + "Unknown command: " + LIGHTGREY + command[ 1 ] + RED + "!" )
endif
call command.destroy()
endfunction
private function INIT takes nothing returns nothing
local trigger t
set t = CreateTrigger()
call TriggerRegisterAnyPlayerChatEvent( t, "-password", false )
call TriggerAddAction( t, function ChatCommandPassword )
set PwdPanel = Dialog.create()
call PwdPanel.SetMessage( "Choose your password" )
call PwdPanel.AddButton ( "0" , HK_0 )
call PwdPanel.AddButton ( "1" , HK_1 )
call PwdPanel.AddButton ( "2" , HK_2 )
call PwdPanel.AddButton ( "3" , HK_3 )
call PwdPanel.AddButton ( "4" , HK_4 )
call PwdPanel.AddButton ( "5" , HK_5 )
call PwdPanel.AddButton ( "6" , HK_6 )
call PwdPanel.AddButton ( "7" , HK_7 )
call PwdPanel.AddButton ( "8" , HK_8 )
call PwdPanel.AddButton ( "9" , HK_9 )
call PwdPanel.AddAction ( function SetPassword_enum )
endfunction
// Accessors:
function AskPlayerPassword takes player p returns nothing
local integer trigId = GetPlayerId( p )
call PwdPanel.Show( p )
loop
call TriggerSleepAction(0.1)
exitwhen HasPwd[ trigId ]
endloop
endfunction
function HasPlayerEnteredPassword takes player p returns boolean
return HasPwd[ GetPlayerId( p ) ]
endfunction
function GetPlayerPassword takes player p returns integer
if HasPlayerEnteredPassword( p ) then
return Pwd[ GetPlayerId( p ) ]
endif
return 0
endfunction
endlibrary
//TESH.scrollpos=497
//TESH.alwaysfold=0
//----------------------------\\
// VER B5 \\
//----------------------------\\
// Special thanks: Tom_Kazansky for his incredible wisdom concerning the creation of texttags ; )
// PurplePoot for his countless tips on what to improve!
library UtilityParameters
globals
// parameters
// for parameter coloring
// GOLD will be used as the display color for positive bounty created with CreateBountyText()
// RED will be used as the display color for negative bounty created with CreateBountyText()
constant string NegativeTag = "|cffff3333"
constant string PositiveTag = "|cff33cf33"
constant string NeutralTag = "|cffffcc00"
constant string InactiveTag = "|cff808080"
constant string EndTag = "|r"
constant string RED = "|cffff3333"
constant string GREEN = "|cff33cf33"
constant string GOLD = "|cffffcc00"
constant string GREY = "|cff808080"
constant string LIGHTGREY = "|cffC0C0C0"
constant string TURQUOISE = "|cff33BBBB"
constant string WHITE = "|r"
// use %p for the name of the player that has left.
constant string LEAVER_MESSAGE = RED + "%p has left the game!"
endglobals
endlibrary
library Utilities initializer UtilityInit needs UtilityParameters
//! textmacro ChangePlayerState takes PLAYER, STATE, AMOUNT
call SetPlayerState( $PLAYER$, PLAYER_STATE_$STATE$, GetPlayerState( $PLAYER$, PLAYER_STATE_$STATE$ ) + $AMOUNT$ )
//! endtextmacro
//! textmacro State2Text takes STATE
globals
integer $STATE$s = 0
string array $STATE$Name
real array $STATE$State
endglobals
function Text2$STATE$ takes string text, real state returns nothing
local real curKey = state
local string parKey = text
local integer index = $STATE$s
local integer curdex = index - 1
set $STATE$s = $STATE$s + 1
loop
exitwhen index < 1
exitwhen curKey >= $STATE$State[ curdex ]
set $STATE$State[ index ] = $STATE$State[ curdex ]
set $STATE$Name[ index ] = $STATE$Name[ curdex ]
set index = curdex
set curdex = index - 1
endloop
set $STATE$State[ index ] = curKey
set $STATE$Name[ index ] = parKey
endfunction
function $STATE$2Text takes real state returns string
local integer index = 0
loop
if $STATE$State[ index ] >= state then
set index = index - 1
if index < 0 then
set index = 0
endif
exitwhen true
endif
exitwhen index >= $STATE$s - 1
set index = index + 1
endloop
return $STATE$Name[ index ]
endfunction
//! endtextmacro
globals
// Do not change these!
player array Players
integer TotalPlayers = 0
constant integer NUMPLAYERS = 15
constant integer MAX_PLAYER_SLOT = 15
constant integer NUMUSERS = 11
constant integer MAX_USER_SLOT = 11
constant integer NUMSLOTS = 5
constant integer MAX_INV_SLOT = 5
integer LETTERS = 0
real array StartLocX
real array StartLocY
string array PlayerName
string array PlayerNameUncolored
string array PlayerStartName
string array PlayerColor
boolean array PlayerActive
playercolor array DefaultPlayerColor
private string array NormalPlayerColor
constant group GLOBAL_GROUP = CreateGroup()
constant integer HexBase = 16
string array Hex
string array LETTER
constant string BountyEffectString = "UI\\Feedback\\GoldCredit\\GoldCredit.mdl"
string BountyColoring = GOLD + "+"
constant real BountySpeed = 0.71 / 24
constant real BountyTextSize = 0.023
constant trigger LEAVER_HANDLER = CreateTrigger()
handle ReturnHandle
unit ReturnUnit
group ReturnGroup
force ReturnForce
item ReturnItem
boolean array PLAYER_ALLIANCE_STATE_PASSIVE
boolean array PLAYER_ALLIANCE_STATE_HELP_REQUEST
boolean array PLAYER_ALLIANCE_STATE_HELP_RESPONSE
boolean array PLAYER_ALLIANCE_STATE_SHARED_XP
boolean array PLAYER_ALLIANCE_STATE_SHARED_SPELLS
boolean array PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_VISION
boolean array PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL
boolean array PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_ADVANCED_CONTROL
constant boolean AUTOCOLOR_NAMES = true
string LEAVER_MESSAGE_A
string LEAVER_MESSAGE_B
boolean DISPLAY_LEAVER_NAME = false
player LOCAL_PLAYER
private multiboardchain array MBChain
endglobals
function DisplayText takes player whichplayer, string text returns nothing
call DisplayTimedTextToPlayer( whichplayer, 0, .1, 15, text )
endfunction
function Hex2S takes integer hex, integer digits returns string
local string hexstring = ""
local integer curDigit
loop
exitwhen digits <= 0
set curDigit = ModuloInteger( hex, HexBase )
set hex = hex / HexBase
set hexstring = Hex[ curDigit ] + hexstring
set digits = digits - 1
endloop
return hexstring
endfunction
function S2Hex takes string hex returns integer
local integer hexint = 0
local integer digits = StringLength( hex )
local integer curDigit = 0
local integer i
local string curChar
loop
exitwhen curDigit > digits
set i = 0
set hexint = hexint * HexBase
set curChar = SubString( hex, curDigit, curDigit + 1)
loop
exitwhen i >= HexBase
if curChar == Hex[ i ] then
set hexint = hexint + i
exitwhen true
endif
set i = i + 1
endloop
set curDigit = curDigit + 1
endloop
return hexint
endfunction
function DistanceBetweenUnits takes unit a, unit b returns real
local real deltaX = GetUnitX( a ) - GetUnitX( b )
local real deltaY = GetUnitY( a ) - GetUnitY( b )
set a = null
set b = null
return SquareRoot( deltaX * deltaX + deltaY * deltaY )
endfunction
function Value2Gradient takes real state, integer r1, integer g1, integer b1, integer r2, integer g2, integer b2 returns string
if state > 1 then
set state = 1
elseif state < 0 then
set state = 0
endif
return "|cff" + Hex2S( R2I( r1 + state * ( r2 - r1 ) ), 2 ) + Hex2S( R2I( g1 + state * ( g2 - g1 ) ), 2 ) + Hex2S( R2I( b1 + state * ( b2 - b1 ) ), 2 )
endfunction
function State2Color takes real state returns string
return Value2Gradient( state, 255, 51, 20, 51, 255, 20 )
endfunction
function SetPlayerNameSJ takes player whichplayer, string name returns nothing
local integer playerId = GetPlayerId( whichplayer )
set PlayerName[ playerId ] = PlayerColor[ playerId ] + name
set PlayerNameUncolored[ playerId ] = name
call SetPlayerName( whichplayer, name )
endfunction
function SetPlayerColors takes integer playerid, integer red, integer green, integer blue returns nothing
set PlayerColor[ playerid ] = "|cff" + Hex2S( red, 2 ) + Hex2S( green, 2 ) + Hex2S( blue, 2 )
set PlayerName[ playerid ] = PlayerColor[ playerid ] + PlayerNameUncolored[ playerid ]
endfunction
function SetPlayerColorsOld takes integer playerid, integer red, integer green, integer blue returns nothing
set NormalPlayerColor[ playerid ] = "|cff" + Hex2S( red, 2 ) + Hex2S( green, 2 ) + Hex2S( blue, 2 )
endfunction
private function LeaverHandlerNoName_Actions takes nothing returns nothing
local player leaver = GetTriggerPlayer( )
local integer leaverId = GetPlayerId ( leaver )
local string leaverName = GREY + PlayerName[ leaverId ] + " (LEFT)" + EndTag
call SetPlayerNameSJ( leaver, leaverName )
set PlayerActive [ leaverId ] = false
set PlayerName [ leaverId ] = leaverName
set TotalPlayers = TotalPlayers - 1
call DisplayText( LOCAL_PLAYER, LEAVER_MESSAGE )
endfunction
private function LeaverHandlerName_Actions takes nothing returns nothing
local player leaver = GetTriggerPlayer( )
local integer leaverId = GetPlayerId ( leaver )
local string leaverName = InactiveTag + PlayerName[ leaverId ] + " (LEFT)" + EndTag
call SetPlayerNameSJ( leaver, leaverName )
set PlayerActive [ leaverId ] = false
set PlayerName [ leaverId ] = leaverName
set TotalPlayers = TotalPlayers - 1
call DisplayText( LOCAL_PLAYER, LEAVER_MESSAGE_A + PlayerStartName[ leaverId ] + LEAVER_MESSAGE_B )
endfunction
function SetAllianceState takes integer alliancestate, boolean passive, boolean helprequest, boolean helpresponse, boolean sharedxp, boolean sharedspells, boolean sharedvision, boolean sharedcontrol, boolean sharedadvancedcontrol returns nothing
if alliancestate >= 0 and alliancestate <= 8 then
set PLAYER_ALLIANCE_STATE_PASSIVE[ alliancestate ] = passive
set PLAYER_ALLIANCE_STATE_HELP_REQUEST[ alliancestate ] = helprequest
set PLAYER_ALLIANCE_STATE_HELP_RESPONSE[ alliancestate ] = helpresponse
set PLAYER_ALLIANCE_STATE_SHARED_XP[ alliancestate ] = sharedxp
set PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ alliancestate ] = sharedspells
set PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_VISION[ alliancestate ] = sharedvision
set PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ alliancestate ] = sharedcontrol
set PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_ADVANCED_CONTROL[ alliancestate ] = sharedadvancedcontrol
endif
endfunction
private function AddLetter takes string char returns nothing
set LETTER[ LETTERS ] = char
set LETTERS = LETTERS + 1
endfunction
struct multiboardchain
player owner
multiboardchain_member first
multiboardchain_member last
static method create takes player owner returns multiboardchain
local multiboardchain this = .allocate()
set .owner = owner
set .first = 0
set .last = 0
return this
endmethod
endstruct
struct multiboardchain_member
multiboard mb
multiboardchain parent
multiboardchain_member next
multiboardchain_member last
static method create takes multiboard mb, multiboardchain parent returns multiboardchain_member
local multiboardchain_member this
local multiboardchain_member curChild = parent.first
if parent.first == 0 then
set this = .allocate()
set parent.first = this
else
loop
exitwhen curChild == 0
if curChild.mb == mb then
call curChild.reAppend()
return curChild
endif
set curChild = curChild.next
endloop
set this = .allocate()
endif
set .mb = mb
set .parent = parent
set .last = .parent.last
set .parent.last = this
if .last != 0 then
set .last.next = this
endif
set .next = 0
if LOCAL_PLAYER == .parent.owner then
if .last != 0 then
call MultiboardDisplay( .last.mb, false )
endif
call MultiboardDisplay( mb, true )
endif
return this
endmethod
// drops the chain member from the chain and fixes the chain
method drop takes nothing returns nothing
local boolean isLast = .next == 0
local boolean isFirst = .last == 0
if isLast and isFirst then
set .parent.last = 0
set .parent.first = 0
elseif isLast then
set .parent.last = .last
set .last.next = 0
elseif isFirst then
set .parent.first = .next
set .next.last = 0
else
set .next.last = .last
set .last.next = .next
endif
endmethod
method reAppend takes nothing returns nothing
// fix chain
call .drop()
// append self
set .last = .parent.last
set .parent.last = this
set .last.next = this
if LOCAL_PLAYER == .parent.owner then
if .last != 0 then
call MultiboardDisplay( .last.mb, false )
endif
call MultiboardDisplay( .mb, true )
endif
endmethod
method onDestroy takes nothing returns nothing
local boolean view = LOCAL_PLAYER == .parent.owner
if view and .next == 0 then
call MultiboardDisplay( .mb, false )
if .last != 0 then
call MultiboardDisplay( .last.mb, true )
endif
endif
call .drop()
set .mb = null
endmethod
endstruct
function GetEventPlayerChatStringUnmatched takes nothing returns string
return SubString( GetEventPlayerChatString(), StringLength( GetEventPlayerChatStringMatched() ), StringLength( GetEventPlayerChatString() ) )
endfunction
function MultiboardDisplaySJ takes multiboard mb, boolean display, player viewer returns nothing
local multiboardchain parent
local multiboardchain_member curChild
local boolean view
if viewer == null then
set viewer = LOCAL_PLAYER
endif
set view = viewer == LOCAL_PLAYER
set parent = MBChain[ GetPlayerId( viewer ) ]
if display then
call multiboardchain_member.create( mb, parent )
else
set curChild = parent.last
loop
exitwhen curChild == 0
if curChild.mb == mb then
call curChild.destroy()
set view = false
exitwhen true
endif
set curChild = curChild.last
endloop
if view then
call MultiboardDisplay( mb, false )
endif
endif
endfunction
private function UtilityInit takes nothing returns nothing
local integer playerId = 0
local integer innerIndex = 0
local integer stringIndex = 0
local integer stringLen = StringLength( LEAVER_MESSAGE )
local integer startLocation
local playercolor curColor
set LOCAL_PLAYER = GetLocalPlayer()
set Hex[ 0 ] = "0"
set Hex[ 1 ] = "1"
set Hex[ 2 ] = "2"
set Hex[ 3 ] = "3"
set Hex[ 4 ] = "4"
set Hex[ 5 ] = "5"
set Hex[ 6 ] = "6"
set Hex[ 7 ] = "7"
set Hex[ 8 ] = "8"
set Hex[ 9 ] = "9"
set Hex[ 10 ] = "a"
set Hex[ 11 ] = "b"
set Hex[ 12 ] = "c"
set Hex[ 13 ] = "e"
set Hex[ 14 ] = "d"
set Hex[ 15 ] = "f"
call AddLetter( RED + "UNDEF CHAR" )
call AddLetter( "0" )
call AddLetter( "1" )
call AddLetter( "2" )
call AddLetter( "3" )
call AddLetter( "4" )
call AddLetter( "5" )
call AddLetter( "6" )
call AddLetter( "7" )
call AddLetter( "8" )
call AddLetter( "9" )
call AddLetter( "a" )
call AddLetter( "b" )
call AddLetter( "c" )
call AddLetter( "d" )
call AddLetter( "e" )
call AddLetter( "f" )
call AddLetter( "g" )
call AddLetter( "h" )
call AddLetter( "i" )
call AddLetter( "j" )
call AddLetter( "k" )
call AddLetter( "l" )
call AddLetter( "m" )
call AddLetter( "n" )
call AddLetter( "o" )
call AddLetter( "p" )
call AddLetter( "q" )
call AddLetter( "r" )
call AddLetter( "s" )
call AddLetter( "t" )
call AddLetter( "u" )
call AddLetter( "v" )
call AddLetter( "w" )
call AddLetter( "x" )
call AddLetter( "y" )
call AddLetter( "z" )
set BountyColoring = GOLD + "+"
call SetPlayerColorsOld( 0, 255, 3, 3 )
call SetPlayerColorsOld( 1, 0, 66, 255 )
call SetPlayerColorsOld( 2, 28, 230, 185 )
call SetPlayerColorsOld( 3, 84, 0, 129 )
call SetPlayerColorsOld( 4, 255, 252, 1 )
call SetPlayerColorsOld( 5, 254, 186, 14 )
call SetPlayerColorsOld( 6, 32, 192, 0 )
call SetPlayerColorsOld( 7, 229, 91, 176 )
call SetPlayerColorsOld( 8, 149, 150, 151 )
call SetPlayerColorsOld( 9, 126, 191, 241 )
call SetPlayerColorsOld( 10, 16, 98, 70 )
call SetPlayerColorsOld( 11, 78, 42, 4 )
call SetAllianceState( bj_ALLIANCE_ALLIED_ADVUNITS, true, true, true, true, true, true, true, true )
call SetAllianceState( bj_ALLIANCE_ALLIED_UNITS, true, true, true, true, true, true, true, false )
call SetAllianceState( bj_ALLIANCE_ALLIED_VISION, true, true, true, true, true, true, false, false )
call SetAllianceState( bj_ALLIANCE_ALLIED, true, true, true, true, true, false, false, false )
call SetAllianceState( bj_ALLIANCE_NEUTRAL_VISION, true, false, false, false, false, true, false, false )
call SetAllianceState( bj_ALLIANCE_NEUTRAL, false, false, false, false, false, false, false, false )
call SetAllianceState( bj_ALLIANCE_UNALLIED_VISION, false, false, false, false, false, true, false, false )
call SetAllianceState( bj_ALLIANCE_UNALLIED, false, false, false, false, false, false, false, false )
loop
exitwhen stringIndex >= stringLen
if SubString( LEAVER_MESSAGE, stringIndex, stringIndex +2 ) == "%p" then
set LEAVER_MESSAGE_A = SubString( LEAVER_MESSAGE, 0, stringIndex )
set LEAVER_MESSAGE_B = SubString( LEAVER_MESSAGE, stringIndex+2, stringLen )
set DISPLAY_LEAVER_NAME = true
exitwhen true
endif
set stringIndex = stringIndex + 1
endloop
set playerId = 0
loop
exitwhen playerId > NUMPLAYERS
set Players [ playerId ] = Player( playerId )
set PlayerActive [ playerId ] = GetPlayerSlotState( Players[ playerId ] ) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController( Players[ playerId ] ) == MAP_CONTROL_USER
set PlayerStartName[ playerId ] = GetPlayerName( Players[ playerId ] )
set curColor = GetPlayerColor( Player( playerId ) )
set PlayerColor[ playerId ] = NormalPlayerColor[ GetHandleId( curColor ) ]
set startLocation = GetPlayerStartLocation( Players[ playerId ] )
set StartLocX [ playerId ] = GetStartLocationX( startLocation )
set StartLocY [ playerId ] = GetStartLocationY( startLocation )
set MBChain[ playerId ] = multiboardchain.create( Players[ playerId ] )
if PlayerActive[ playerId ] then
set TotalPlayers = TotalPlayers + 1
set PlayerName[ playerId ] = PlayerColor[ playerId ] + PlayerStartName[ playerId ]
call TriggerRegisterPlayerEvent( LEAVER_HANDLER, Players[ playerId ], EVENT_PLAYER_LEAVE )
else
set PlayerName[ playerId ] = LIGHTGREY + "Player " + I2S( playerId + 1 ) + GREY + " (N/A)" + WHITE
endif
set PlayerNameUncolored[ playerId ] = PlayerStartName[ playerId ]
set playerId = playerId + 1
endloop
if DISPLAY_LEAVER_NAME then
call TriggerAddAction( LEAVER_HANDLER, function LeaverHandlerName_Actions )
else
call TriggerAddAction( LEAVER_HANDLER, function LeaverHandlerNoName_Actions )
endif
call SetPlayerNameSJ( Players[ PLAYER_NEUTRAL_AGGRESSIVE ], "Neutral aggressive" )
call SetPlayerNameSJ( Players[ PLAYER_NEUTRAL_PASSIVE ], "Neutral passive" )
call SetPlayerNameSJ( Players[ bj_PLAYER_NEUTRAL_EXTRA ], "Neutral extra" )
call SetPlayerNameSJ( Players[ bj_PLAYER_NEUTRAL_VICTIM ], "Neutral victim" )
set ReturnGroup = CreateGroup()
endfunction
function CreateColoredBountyText takes string color, integer bounty, unit target, player getter returns nothing
local texttag bountyText = CreateTextTag()
local effect bountyArt
if bounty > 0 then
call SetTextTagText ( bountyText, color + "+" + I2S( bounty ) + "|r", BountyTextSize )
elseif bounty < 0 then
call SetTextTagText ( bountyText, color + I2S( bounty ) + "|r", BountyTextSize )
else
call SetTextTagText ( bountyText, "", BountyTextSize )
endif
set bountyArt = AddSpecialEffectTarget( BountyEffectString, target, "overhead" )
call SetTextTagVelocity ( bountyText, 0, BountySpeed )
call SetTextTagPermanent( bountyText, false )
call SetTextTagAge ( bountyText, 0 )
call SetTextTagFadepoint( bountyText, 2 )
call SetTextTagLifespan ( bountyText, 3 )
call SetTextTagPosUnit ( bountyText, target, 0 )
if LOCAL_PLAYER != getter then
call SetTextTagVisibility( bountyText, false )
endif
call DestroyEffect( bountyArt )
set bountyText = null
set bountyArt = null
endfunction
function CreateBountyText takes integer bounty, unit target, player getter returns nothing
local texttag bountyText = CreateTextTag()
local effect bountyArt
if bounty > 0 then
call SetTextTagText ( bountyText, BountyColoring + I2S( bounty ) + "|r", BountyTextSize )
elseif bounty < 0 then
call SetTextTagText ( bountyText, RED + I2S( bounty ) + "|r", BountyTextSize )
else
call SetTextTagText ( bountyText, "", BountyTextSize )
endif
set bountyArt = AddSpecialEffectTarget( BountyEffectString, target, "overhead" )
call SetTextTagVelocity ( bountyText, 0, BountySpeed )
call SetTextTagPermanent( bountyText, false )
call SetTextTagAge ( bountyText, 0 )
call SetTextTagFadepoint( bountyText, 2 )
call SetTextTagLifespan ( bountyText, 3 )
call SetTextTagPosUnit ( bountyText, target, 0 )
if LOCAL_PLAYER != getter then
call SetTextTagVisibility( bountyText, false )
endif
call DestroyEffect( bountyArt )
set bountyText = null
set bountyArt = null
endfunction
function TriggerRegisterAnyPlayerChatEvent takes trigger whichtrigger, string chatmessagetodetect, boolean exactmatchonly returns nothing
local integer playerId = 0
loop
exitwhen playerId > NUMPLAYERS
call TriggerRegisterPlayerChatEvent( whichtrigger, Players[ playerId ], chatmessagetodetect, exactmatchonly )
set playerId = playerId + 1
endloop
endfunction
function CreateNUnits takes player owner, integer unittypeid, real x, real y, integer n returns group
call GroupClear( ReturnGroup )
loop
exitwhen n <= 0
call GroupAddUnit( ReturnGroup, CreateUnit( owner, unittypeid, x, y, GetRandomReal( 0, 360 ) ) )
set n = n - 1
endloop
return ReturnGroup
endfunction
function CreateNUnitsAngle takes player owner, integer unittypeid, real x, real y, real angle, integer n returns group
call GroupClear( ReturnGroup )
loop
exitwhen n <= 0
call GroupAddUnit( ReturnGroup, CreateUnit( owner, unittypeid, x, y, angle ) )
set n = n - 1
endloop
return ReturnGroup
endfunction
function CreateNUnitsOrder takes player owner, integer unittypeid, real x, real y, integer n, string order, real targetx, real targety returns group
local real angle = Atan2( y-targety, x-targetx )
local unit loopUnit
call GroupClear( ReturnGroup )
loop
exitwhen n <= 0
set loopUnit = CreateUnit( owner, unittypeid, x, y, angle )
call GroupAddUnit( ReturnGroup, loopUnit )
call IssuePointOrder( loopUnit, order, targetx, targety )
set n = n - 1
endloop
set loopUnit = null
return ReturnGroup
endfunction
function SetPlayerAllianceStateSJ takes player sourcePlayer, player otherPlayer, integer allianceState returns nothing
if (sourcePlayer == otherPlayer) then
return
endif
//this works like the normal BJ, just that it allies in both ways
if allianceState >= 0 and allianceState <= 8 then
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_PASSIVE, PLAYER_ALLIANCE_STATE_PASSIVE[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_HELP_REQUEST, PLAYER_ALLIANCE_STATE_HELP_REQUEST[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_HELP_RESPONSE, PLAYER_ALLIANCE_STATE_HELP_RESPONSE[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_XP, PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_SPELLS, PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_VISION, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_CONTROL, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ allianceState ] )
call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_ADVANCED_CONTROL[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_PASSIVE, PLAYER_ALLIANCE_STATE_PASSIVE[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_HELP_REQUEST, PLAYER_ALLIANCE_STATE_HELP_REQUEST[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_HELP_RESPONSE, PLAYER_ALLIANCE_STATE_HELP_RESPONSE[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_XP, PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_SPELLS, PLAYER_ALLIANCE_STATE_SHARED_SPELLS[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_VISION, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_CONTROL, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_CONTROL[ allianceState ] )
call SetPlayerAlliance( otherPlayer, sourcePlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, PLAYER_ALLIANCE_STATE_ALLIANCE_SHARED_ADVANCED_CONTROL[ allianceState ] )
endif
endfunction
/*
function GetClosestUnitInRange takes real x, real y, real radius, boolean closest, boolexpr filter returns unit
local group g = ReturnGroup
local unit curUnit = null
local unit loopUnit
local real curDist
local real dX
local real dY
local real loopDist
call GroupClear( g )
call GroupEnumUnitsInRange( g, x, y, radius, filter )
if closest then
set curDist = radius + 1
else
set curDist = 0
endif
loop
set loopUnit = FirstOfGroup( g )
exitwhen loopUnit == null
set dX = x - GetUnitX( loopUnit )
set dY = y - GetUnitY( loopUnit )
set loopDist = SquareRoot( dX * dX + dY * dY )
if loopDist < curDist == closest then
set curDist = loopDist
set curUnit = loopUnit
endif
call GroupRemoveUnit( g, loopUnit )
endloop
set ReturnUnit = curUnit
set filter = null
set loopUnit = null
set curUnit = null
return ReturnUnit
endfunction
*/
function EndMap takes nothing returns nothing
call EndGame( true )
endfunction
function WinGame takes player whichPlayer, boolean win, string message returns nothing
local trigger t = CreateTrigger()
local dialog d = DialogCreate ()
local player localPlayer = LOCAL_PLAYER
if win then
call RemovePlayer ( whichPlayer, PLAYER_GAME_RESULT_VICTORY )
else
call RemovePlayer ( whichPlayer, PLAYER_GAME_RESULT_DEFEAT )
endif
call DialogSetMessage ( d, message )
call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, "Ok", GetLocalizedHotkey("GAMEOVER_CONTINUE") ) )
call TriggerAddAction ( t, function EndMap )
if localPlayer == whichPlayer then
call EnableUserControl( true )
call EnableUserUI ( false )
endif
call DialogDisplay( whichPlayer, d, true )
endfunction
function SetMultiboardItemValue takes multiboard mb, integer row, integer col, string value, string iconfilename, real width, player whichplayer returns nothing
local multiboarditem curItem
local boolean showIcon = iconfilename != ""
local boolean showValue = value != ""
local boolean changeWidth = width > 0
local integer minCol
local integer maxCol
local integer minRow
local integer maxRow
local integer i
local integer j
if col == - 1 then
set minCol = 0
set maxCol = MultiboardGetColumnCount( mb )
else
set minCol = col
set maxCol = col + 1
endif
if row == -1 then
set minRow = 0
set maxRow = MultiboardGetRowCount( mb )
else
set minRow = row
set maxRow = row + 1
endif
set col = minCol
loop
exitwhen col >= maxCol
set row = minRow
loop
exitwhen row >= maxRow
set curItem = MultiboardGetItem( mb, row, col )
if whichplayer == null or whichplayer == LOCAL_PLAYER then
call MultiboardSetItemStyle( curItem, showValue, showIcon )
if showIcon then
call MultiboardSetItemIcon( curItem, iconfilename )
endif
if showValue then
call MultiboardSetItemValue( curItem, value )
endif
if changeWidth then
call MultiboardSetItemWidth( curItem, width )
endif
endif
call MultiboardReleaseItem( curItem )
set row = row + 1
endloop
set col = col + 1
endloop
endfunction
function Char2I takes string char, integer min, integer max returns integer
local integer index
local string toInt = SubString( char, min, max )
local integer stringPos = StringLength( toInt ) - 1
local integer stringValue = 1
local string curChar
local integer returnValue = 0
set char = StringCase( toInt, false )
loop
exitwhen stringPos < 0
set index = 0
set curChar = SubString( char, stringPos, stringPos + 1 )
loop
exitwhen index == LETTERS
if curChar == LETTER[ index ] then
set returnValue = returnValue + index * stringValue
exitwhen true
endif
set index = index + 1
endloop
set stringValue = stringValue * LETTERS
set stringPos = stringPos - 1
endloop
return returnValue
endfunction
function I2Char takes integer i returns string
local string returnString = ""
local integer curValue
loop
exitwhen i == 0
set curValue = ModuloInteger( i, LETTERS )
if curValue != 0 then
set returnString = LETTER[ curValue ] + returnString
endif
set i = i / LETTERS
endloop
return returnString
endfunction
//! textmacro RandomString takes SCOPE, NAME
globals
private string array $NAME$
private integer $NAME$s = -1
endglobals
$SCOPE$ function Get$NAME$String takes nothing returns string
return $NAME$[GetRandomInt( 0, $NAME$s )]
endfunction
$SCOPE$ function Add$NAME$String takes string toadd returns nothing
set $NAME$s = $NAME$s + 1
set $NAME$[ $NAME$s ] = toadd
endfunction
//! endtextmacro
endlibrary
//TESH.scrollpos=36
//TESH.alwaysfold=0
scope AntiCP initializer Init
//****************************************************************************************
//
// | Anti-CheatPack System v1.00 by saw792 |
//
// Using this system will report any modification to the map script. Combined with map
// optimisation it will effectively stop people from using a modified version of your
// map, as it disables all GUI trigger functionality and all JASS triggers (with the
// exception of libraries, for technical reasons) on detection of modification.
//
// It is recommended that all functioning vJASS code is writeen within scopes (with the
// exception of systems) in order for them to be disabled on modification detection.
//
//
// Implementation Instructions:
//
// 1. Create a blank disabled trigger named AntiCPConfig, convert to custom text
// 2. Copy/Paste the AntiCPConfig library into the blank trigger
// 3. Click the name of your map in the left-hand panel in the trigger editor
// 4. Copy/Paste the AntiCP scope into the Custom Text section
// NB: The scope MUST be at the VERY top of the custom text section, and
// NOT in a blank trigger
// 5. Follow the instructions in the AntiCPConfig library
// 6. Set the HANDLE_COUNT variable below to the output of the library
// 7. Configure other constants below
// 8. Set ENABLED = true
// 9. Save your map and enjoy
//
// NB: Every time you save a final version run the AntiCPConfig library again
// as the handle count has probably changed
// NB: When modifying your map set ENABLED = false, and set it to true again
// when a final version is saved
//
//****************************************************************************************
globals
//Output of AntiCPConfig library
private constant integer HANDLE_COUNT = 0
//System enabled or disabled
private constant boolean ENABLED = false
//Disable triggers initializers on detection?
private constant boolean TRIGGER_DISABLE = false
//Show a message to players if modification is detected?
private constant boolean SHOW_TEXT = true
//Text to display when SHOW_TEXT = true
//If SHOW_TEXT = false it is recommended that this string be emptied (i.e. = "")
private constant string DISP_TEXT = "This map has been modified. Please delete it and redownload from a trusted source."
private gamecache g = InitGameCache( "Lock.w3v" )
endglobals
//! inject main
call StoreInteger(g, "", "", GetStoredInteger(g,"","") + 1 )
//! dovjassinit
call StoreInteger(g, "", "", GetStoredInteger(g,"","") + 1 )
//! endinject
private function Init takes nothing returns nothing
local integer i
local trigger t = CreateTrigger()
call StoreInteger(g, "", "", GetStoredInteger(g,"","") + 1 )
if (GetHandleId(t) - 1048584) != HANDLE_COUNT and ENABLED and GetStoredInteger(g,"","")==4then
if SHOW_TEXT then
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, DISP_TEXT)
endif
if TRIGGER_DISABLE then
set i = i
endif
endif
call DestroyTrigger(t)
set t = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
library AntiCPConfig initializer Init //requires
//****************************************************************************
//
// | Anti-CheatPack Configuration Functions by saw792 |
//
// Configuration Instructions:
//
// 1. Uncomment the 'requires' line above these instructions
// 2. Add in the name of every library in your map separated by ,
// NB: If you have no vJASS libraries in your map ignore these two steps
// 3. Enable this trigger
// 4. Save your map
// 5. Click 'Test Map' and write down the number that is displayed
// once the game starts (Handle Count: ...)
// 6. Exit the game
// 7. Disable this library
// 8. Keep this library within your map
// 9. Repeat these instruction every time you save a final version
//
//****************************************************************************
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call BJDebugMsg("Handle Count: " + I2S(GetHandleId(t) - 1048584))
call DestroyTrigger(t)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
globals
gamecache g = InitGameCache("Lock.w3v")
endglobals
function PreloadFiles takes nothing returns nothing
call StoreInteger(g, "", "", GetStoredInteger(g,"","") + 1 )
endfunction
//TESH.scrollpos=89
//TESH.alwaysfold=0
scope InitTutorial initializer INIT
globals
private string DEFAULT = GREY
boolean array MaySwapBoard
endglobals
private function Key takes string msg returns string
return " |cffcc5555" + StringCase( msg, true ) + DEFAULT
endfunction
private function Target takes string msg returns string
return " |cffc8a000" + msg + DEFAULT
endfunction
private function String takes string msg returns string
return " '|cff7777aa" + msg + DEFAULT + "'"
endfunction
private function F takes string msg returns string
return msg + DEFAULT
endfunction
function SetPlayerAbilityAvailableSJ takes player whichPlayer, integer abilid, boolean avail returns nothing
local integer i = GetPlayerId( whichPlayer )
//call SelectSelector( i, false )
call SetPlayerAbilityAvailable( whichPlayer, abilid, avail )
//call SelectSelector( i, true )
endfunction
private function SetTutorialState takes player p returns nothing
local integer i = GetPlayerId( p )
set MaySwapBoard[ i ] = not WatchesTutorial[ i ]
call SwapBoard( p, false )
if WatchesTutorial[ i ] then
call SetPlayerAbilityAvailableSJ( p, ABIL_SHOW, false )
call SetPlayerAbilityAvailableSJ( p, ABIL_TELL, false )
call SetPlayerAbilityAvailableSJ( p, ABIL_SWAP_MAIN, false )
call SetPlayerAbilityAvailableSJ( p, ABIL_SWAP_PRACT, false )
else
call SetPlayerAbilityAvailableSJ( p, ABIL_SHOW, true )
call SetPlayerAbilityAvailableSJ( p, ABIL_TELL, true )
call SetPlayerAbilityAvailableSJ( p, ABIL_HELP, true )
call SetPlayerAbilityAvailableSJ( p, ABIL_SWAP_MAIN, true )
call SetPlayerAbilityAvailableSJ( p, ABIL_SWAP_PRACT, true )
endif
endfunction
function SetTutorialAbility takes player p returns nothing
call SetPlayerAbilityAvailableSJ( p, ABIL_HELP, true )
endfunction
function SetShowAbility takes player p returns nothing
call SetPlayerAbilityAvailableSJ( p, ABIL_SHOW, CurrentBoard[ GetPlayerId( p ) ] == PracticeBoard )
endfunction
function SetTellAbility takes player p returns nothing
call SetPlayerAbilityAvailableSJ( p, ABIL_TELL, CurrentBoard[ GetPlayerId( p ) ] == PracticeBoard )
endfunction
private function AskTutorial takes integer i returns nothing
local player p = Player( i )
call SetPlayerWatchState( i, GetPolledPlayerFeedback( p, "Show Tutorial?", 30 ) )
if WatchesTutorial[ i ] then
call SetPlayerAbilityAvailableSJ( p, ABIL_HELP, false )
else
call SetPlayerAbilityAvailableSJ( p, ABIL_SWAP_MAIN, true )
call SetPlayerAbilityAvailableSJ( p, ABIL_SWAP_PRACT, true )
call SetPlayerAbilityAvailableSJ( p, ABIL_SHOW, true )
call SetPlayerAbilityAvailableSJ( p, ABIL_TELL, true )
call SetPlayerAbilityAvailableSJ( p, ABIL_HELP, true )
endif
endfunction
private function HelpActions takes nothing returns nothing
local integer id = GetSpellAbilityId()
local player p = GetOwningPlayer( GetTriggerUnit() )
if id == ABIL_HELP then
call SetPlayerWatchState( GetPlayerId( p ), not WatchesTutorial[ GetPlayerId( p ) ] )
elseif id == ABIL_SHOW then
call HighlightCards()
elseif id == ABIL_TELL then
call TellWhySet( p )
endif
endfunction
private function INIT_REALLY takes nothing returns nothing
local integer i = 0
local quest h
local trigger t
//Commands
//call AddTutorialMessage( "" )
set DEFAULT = LIGHTGREY
call TriggerSleepAction(0)
call AddTutorialMessage( "Welcome to the Tutorial. " + Key( "Please read these messages if you're new." ) + " Take your time!", TUT_FUNC_NOTHING )
call AddTutorialMessage( "The board you're on is the " + Key( "Practice Board" ) + ". It is simpler, and you can't get or loose points.", TUT_FUNC_NOTHING )
call AddTutorialMessage( "There also is the " + Key( "Main Board" ) + ". It is much harder, and you'll get points for every set you find, but loose points when you click on three cards that don't form a set.", TUT_FUNC_NOTHING )
call AddTutorialMessage( "If you want to see a set in the practice board, type " + String("-show") + ", and the cards will be highlighted. You also have a 'Show' ability, which does the same [Blue Eye] (Hotkey: " + GOLD + "S" + LIGHTGREY + " ).", SetShowAbility )
call AddTutorialMessage( "You want to know why these cards form a set? Type " + String("-explain") + ". You can also use your ability [Yellow Scroll] (Hotkey: " + GOLD + "E" + DEFAULT+ " ).", SetTellAbility )
call AddTutorialMessage( "In order to select a card, " + Key("RIGHT-CLICK") + " it (as if you were issuing a move command).", TUT_FUNC_NOTHING )
call AddTutorialMessage( "Selected the wrong card? Just " + Key("RIGHT-CLICK") + " again!", TUT_FUNC_NOTHING )
call AddTutorialMessage( "If you still don't know what a set is, there is a little help in the quest log (F9). Also play arround a little bit with the show and explain abilities.", TUT_FUNC_NOTHING )
call AddTutorialMessage( "You can turn this tutorial on/off with " + String("-help") + ", "+ String("-start tut") + " or " + String("-tutorial") + ". You also have a tutorial button that will disable / enable it [Question Mark] (Hotkey: " + GOLD + "H" + LIGHTGREY + " ).", SetTutorialAbility )
call AddTutorialMessage( "If you want to leave the practicing grounds and joing the real game, just disable the tutorial and use your " + Key( "Swap Board" ) + " ability [Violet Arrow] (Hotkey: " + GOLD + "M" + LIGHTGREY + " ).", TUT_FUNC_NOTHING )
call AddTutorialMessage( "For going back to practice mode, use the " + Key( "Swap Board" ) + " ability again.", TUT_FUNC_NOTHING )
call AddTutorialMessage( "Once there are no cards left, you are asked to enter a password if you haven't done so before. Depending on the password, you'll get a save/load code to save your rank", TUT_FUNC_NOTHING )
call AddTutorialMessage( "In order to load your rank, just type " + String("-load CODE") + " in the chat. Then enter the password you had chosen into the dialog.", TUT_FUNC_NOTHING )
call AddTutorialMessage( "You can use your keyboard for typing your password, just don't type too fast.", TUT_FUNC_NOTHING )
set AT_TUT_START = SetTutorialState
set AT_TUT_END = SetTutorialState
set h = CreateQuestBJ( bj_QUESTTYPE_REQ_DISCOVERED, "What is a 'Set'?", "Examples:
- | |cffFF0000DDD|r |, =|cffFF0000DD|r=, |cffFF0000D|r -> |cff00FF00Set |r(Same Color, Same Shape, different Number, different Card)
- |cff0000FFSSS|r, |cff00FF00DD|r, |cffFF0000C|r -> |cff00FF00Set |r(Different Color, different Shape, different Number, different Card)
- |cffFF0000DDD|r, |cffFF0000SSS|r, |cffFF0000CCC|r -> |cff00FF00Set |r(Same Color, different Shape, Same Number, Same Card)
- | |cff00FF00DDD|r |, =|cffFF0000DD|r=, |cffFF0000D|r -> |cffFF0000No Set |r(Two are Red, one isn't)
- | |cff00FF00DDD|r |, =|cffFF0000SS|r=, |cffFF0000D|r -> |cffFF0000No Set |r(Two are Diamonds, one isn't)
- | |cff0000FFDDD|r |, =|cff0000FFDD|r=, |cffFF0000DDD|r -> |cffFF0000No Set |r(Two are Three, one isn't, Two are Blue, one isn't)
", "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOff.blp" )
call CreateQuestItemBJ( h, "A Set is three cards that (for all the four features) either all have..." )
call CreateQuestItemBJ( h, "a) the same attribute or b) different attributes." )
call CreateQuestItemBJ( h, "In other words, If two cards have an attribute, and one has not, it is no set." )
set h = CreateQuestBJ( bj_QUESTTYPE_OPT_DISCOVERED, "Set abbrev.", "Examples:
- | |cffFF0000DDD|r | -> Three Diamonds with Vertical Stripes on a Red card
- =|cff0000FFCC|r= -> Two Circles with Horizontal Stripes on a Blue card
", "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOff.blp" )
call CreateQuestItemBJ( h, "The letter identifies the Shape (Diamond, Circle, Swing)" )
call CreateQuestItemBJ( h, "The Number of Letters identifies the Number of Symbols (One, Two, Three)" )
call CreateQuestItemBJ( h, "The Color identifies the Color of the Card (Red, Green, Blue)" )
call CreateQuestItemBJ( h, "The Stripes idetify the Direction of the Stripes (None, Vertical, Horizontal)")
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( t, function HelpActions )
loop
exitwhen i > MAX_USER_SLOT
call AskTutorial.execute( i )
set i = i + 1
endloop
call ForceQuestDialogUpdate()
call FlashQuestDialogButton()
endfunction
//===========================================================================
private function INIT takes nothing returns nothing
call ExecuteFunc( SCOPE_PRIVATE + "INIT_REALLY" )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Tutorial initializer INIT needs GetPlayerFeedback
function interface TutFunc takes player p returns nothing
private function NoFunc takes player p returns nothing
endfunction
globals
private constant trigger TutTrigger = CreateTrigger()
boolean array WatchesTutorial
private integer array CurHelpMessage
private string array HelpMessage
private TutFunc array HelpAction
private integer HelpMessages = 0
private integer Watchers = 0
private constant integer REVEAL_TIME = 10
private constant timer REVEAL_TIMER = CreateTimer()
TutFunc TUT_FUNC_NOTHING
TutFunc AT_TUT_START
TutFunc AT_TUT_END
endglobals
private function TutorialMessage takes player whichplayer, string msg returns nothing
call DisplayTimedTextToPlayer( whichplayer, 0, .1, REVEAL_TIME, LIGHTGREY + msg )
endfunction
function AddTutorialMessage takes string msg, TutFunc func returns nothing
set HelpAction [ HelpMessages ] = func
set HelpMessage[ HelpMessages ] = msg
set HelpMessages = HelpMessages + 1
endfunction
private function ShowNextMessage takes nothing returns nothing
local integer i = 0
loop
exitwhen i > MAX_USER_SLOT
if WatchesTutorial[ i ] then
if CurHelpMessage[ i ] == HelpMessages then
set CurHelpMessage[ i ] = 0
call SetPlayerWatchState.execute( i, false )
else
call TutorialMessage( Players[ i ], HelpMessage[ CurHelpMessage[ i ] ] )
call HelpAction[ CurHelpMessage[ i ] ].execute( Player(i) )
set CurHelpMessage[ i ] = CurHelpMessage[ i ] + 1
endif
endif
set i = i + 1
endloop
endfunction
function SetPlayerWatchState takes integer playerId, boolean watches returns nothing
if watches == WatchesTutorial[ playerId ] then
else
set WatchesTutorial[ playerId ] = watches
if watches then
call AT_TUT_START.execute( Player( playerId ) )
if Watchers == 0 then
call ShowNextMessage()
call TimerStart( REVEAL_TIMER, REVEAL_TIME, true, function ShowNextMessage )
endif
set Watchers = Watchers + 1
else
call AT_TUT_END.execute( Player( playerId ) )
set Watchers = Watchers - 1
if Watchers == 0 then
call PauseTimer( REVEAL_TIMER )
endif
endif
endif
endfunction
private function Tutorial_Index takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local integer trigId = GetPlayerId( trigPlayer )
local boolean reset = GetPlayerFeedback( trigPlayer )
if reset then
set CurHelpMessage[trigId] = 0
endif
endfunction
private function Actions takes nothing returns nothing
local player trigPlayer = GetTriggerPlayer()
local integer trigId = GetPlayerId( trigPlayer )
call SetPlayerWatchState( trigId, not WatchesTutorial[ trigId ] )
if WatchesTutorial[ trigId ] then
call TutorialMessage( trigPlayer, "Tutorial started. You can turn it off with the command you used to turn it on." )
else
call TutorialMessage( trigPlayer, "Tutorial stopped." )
call AskPlayerFeedback( trigPlayer, "Reset tutorial index?", function Tutorial_Index )
endif
endfunction
private function INIT takes nothing returns nothing
call TriggerRegisterAnyPlayerChatEvent( TutTrigger, "-start tut", false )
call TriggerRegisterAnyPlayerChatEvent( TutTrigger, "-tutorial", true )
call TriggerRegisterAnyPlayerChatEvent( TutTrigger, "-help", true )
call TriggerAddAction( TutTrigger, function Actions )
set TUT_FUNC_NOTHING = TutFunc.NoFunc
set AT_TUT_START = TUT_FUNC_NOTHING
set AT_TUT_END = TUT_FUNC_NOTHING
endfunction
endlibrary