Всем доброго времени суток! Возник следующий вопрос: как я могу в jass или с помощью триггеров получить номер игрока по его цвету? Пытаюсь решить следующую задачу: На карте первый игрок назначается своеобразным администратором игры, он может прописать команду в чат, где укажет цвет игрока, например green, после чего все сооружения и юниты, подконтрольные зеленому игроку будут убиты. Проблема заключается в том, что если игроки выберут себе цвета по вкусу, то может получится неразбериха, например админ введет green пытаясь, образно говоря, "кикнуть" игрока, выбравшего себе зеленый цвет, а пострадает игрок, который занял при присоединении к игре 7 слот. В голову приходит только такое решение: при выборе всех юнитов, подконтрольных игроку, как то получать номер этого игрока по цвету. Прошу помощи.

Слишком сложно.
Вот так попроще будет.
Код
function StringToPlayerColor takes string color returns playercolor
    set color = StringCase(color, false)
	
    if color == "red" then
        return PLAYER_COLOR_RED
    elseif color == "blue" then
        return PLAYER_COLOR_BLUE
    elseif color == "teal" then
        return PLAYER_COLOR_CYAN
    elseif color == "purple" then
        return PLAYER_COLOR_PURPLE
    elseif color == "yellow" then
        return PLAYER_COLOR_YELLOW
    elseif color == "orange" then
        return PLAYER_COLOR_ORANGE
    elseif color == "green" then
        return PLAYER_COLOR_GREEN
    elseif color == "pink" then
        return PLAYER_COLOR_PINK
    elseif color == "gray" then
        return PLAYER_COLOR_LIGHT_GRAY
    elseif color == "light blue" then
        return PLAYER_COLOR_LIGHT_BLUE
    elseif color == "dark green" then
        return PLAYER_COLOR_AQUA
    elseif color == "brown" then
        return PLAYER_COLOR_BROWN
    elseif color == "maroon" then
        return PLAYER_COLOR_MAROON
    elseif color == "navy" then
        return PLAYER_COLOR_NAVY
    elseif color == "turquoise" then
        return PLAYER_COLOR_TURQUOISE
    elseif color == "violet" then
        return PLAYER_COLOR_VIOLET
    elseif color == "wheat" then
        return PLAYER_COLOR_WHEAT
    elseif color == "peach" then
        return PLAYER_COLOR_PEACH
    elseif color == "mint" then
        return PLAYER_COLOR_MINT
    elseif color == "lavender" then
        return PLAYER_COLOR_LAVENDER
    elseif color == "coal" then
        return PLAYER_COLOR_COAL
    elseif color == "snow" then
        return PLAYER_COLOR_SNOW
    elseif color == "emerald" then
        return PLAYER_COLOR_EMERALD
    elseif color == "peanut" then
        return PLAYER_COLOR_PEANUT
    endif
	
    return null
endfunction

function StringToPlayer takes string color returns player
    local integer i
    set bj_setPlayerTargetColor = StringToPlayerColor(color)
	
    if bj_setPlayerTargetColor != null then
        set i = 1
        loop
            set bj_forceRandomCurrentPick = Player(i)
			if GetPlayerSlotState(bj_forceRandomCurrentPick) == PLAYER_SLOT_STATE_PLAYING and /*
            */ GetPlayerColor(bj_forceRandomCurrentPick) == bj_setPlayerTargetColor then
				return bj_forceRandomCurrentPick
			endif
			
            set i = i + 1
			
            exitwhen i == bj_MAX_PLAYERS
        endloop
    endif
	
    return null
endfunction

function KickPlayer takes nothing returns boolean
    call KillUnit(GetFilterUnit())
    return false
endfunction

function MyTrig_Actions takes nothing returns nothing
    local string color = GetEventPlayerChatString()
    local player p = StringToPlayer(SubString(color, 3, StringLength(color)))
    if p != null then
        call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, p, Filter(function KickPlayer))
        set p = null
    endif
endfunction

function InitMyTrig takes nothing returns nothing
    set gg_trg_My = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_My, Player(0), "gg", false )
    call TriggerAddAction( gg_trg_My, function MyTrig_Actions )
endfunction
Должно работать.
Чутка подправил.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
15
PT153, да. Он там есть. Он у тебя и был же в твоей функции изначально.
Ну у админа id 0, так как он первый слот занимает всегда. Не работает именно тот момент, когда красный цвет у кого-нибудь из игроков, например пусть у нас Игрок 1 - админ, будет синего цвета, а Игрок 2 - обычный игрок себе поставит красный цвет. В этот случае вот не работает.
8gabriel8, хм, это не плохая идея кстати. Я подумаю над этим. Спасибо. Но тогда надо как то сделать "включатель" этого диалога, чтобы он появлялся, когда админ захочет, в принципе, можно просто по команде в чат сделать...
28
А как насчёт создания диалога, кого кикнуть?
Тут обратная ситуация: нужно по id игрока узнать его цвет, ведь в диалоге должны быть только те игроки, что ещё играют.
Meddin:
Он у тебя и был же в твоей функции изначально.
Так а что не работает-то?
15
PT153, я отредактировал свое сообщение выше, там написал.
28
Убедись, что используешь GetPlayerColor(), а не ConvertPlayerColor().
Я также уверен, что код отсюда будет работать.
28
Вообще, было бы лучше, если бы кинул сюда свой код и триггер заодно.
15
Как сейчас есть:
function StringToPlayerColor takes string color returns playercolor
    set color = StringCase(color, false)
	
    if color == "red" then
        return PLAYER_COLOR_RED
    elseif color == "blue" then
        return PLAYER_COLOR_BLUE
    elseif color == "teal" then
        return PLAYER_COLOR_CYAN
    elseif color == "purple" then
        return PLAYER_COLOR_PURPLE
    elseif color == "yellow" then
        return PLAYER_COLOR_YELLOW
    elseif color == "orange" then
        return PLAYER_COLOR_ORANGE
    elseif color == "green" then
        return PLAYER_COLOR_GREEN
    elseif color == "pink" then
        return PLAYER_COLOR_PINK
    elseif color == "gray" then
        return PLAYER_COLOR_LIGHT_GRAY
    elseif color == "light blue" then
        return PLAYER_COLOR_LIGHT_BLUE
    elseif color == "dark green" then
        return PLAYER_COLOR_AQUA
    elseif color == "brown" then
        return PLAYER_COLOR_BROWN
    elseif color == "maroon" then
        return PLAYER_COLOR_MAROON
    elseif color == "navy" then
        return PLAYER_COLOR_NAVY
    elseif color == "turquoise" then
        return PLAYER_COLOR_TURQUOISE
    elseif color == "violet" then
        return PLAYER_COLOR_VIOLET
    elseif color == "wheat" then
        return PLAYER_COLOR_WHEAT
    elseif color == "peach" then
        return PLAYER_COLOR_PEACH
    elseif color == "mint" then
        return PLAYER_COLOR_MINT
    elseif color == "lavender" then
        return PLAYER_COLOR_LAVENDER
    elseif color == "coal" then
        return PLAYER_COLOR_COAL
    elseif color == "snow" then
        return PLAYER_COLOR_SNOW
    elseif color == "emerald" then
        return PLAYER_COLOR_EMERALD
    elseif color == "peanut" then
        return PLAYER_COLOR_PEANUT
    endif
	
    return null
endfunction

function StringToPlayerId takes string color returns integer
    local integer i
    set bj_setPlayerTargetColor = StringToPlayerColor(color)
	
    if bj_setPlayerTargetColor != null then
        set i = 1
        loop
			if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
				if GetPlayerColor(Player(i)) == bj_setPlayerTargetColor then
					return i
				endif
			endif
			
            set i = i + 1
			
            exitwhen i == bj_MAX_PLAYERS
        endloop
    endif
	
    return -1
endfunction

function KickPlayer takes nothing returns nothing
    call KillUnit( GetEnumUnit() )
endfunction

function CompareChatMessage takes nothing returns nothing
    if GetEventPlayerChatString() == "gg red" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("red"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg blue" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("blue"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg teal" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("teal"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg purple" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("purple"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg yellow" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("yellow"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg orange" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("orange"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg green" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("green"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg pink" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("pink"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg gray" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("gray"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg light blue" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("light blue"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg dark green" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("dark green"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg brown" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("brown"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg maroon" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("maroon"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg navy" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("navy"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg turquoise" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("turquoise"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg violet" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("violet"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg wheat" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("wheat"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg peach" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("peach"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg mint" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("mint"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg lavender" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("lavender"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg coal" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("coal"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg snow" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("snow"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg emerald" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("emerald"))), function KickPlayer )
    elseif GetEventPlayerChatString() == "gg peanut" then
		call ForGroupBJ( GetUnitsOfPlayerAll(Player(StringToPlayerId("peanut"))), function KickPlayer )
    endif
endfunction

function MyTrig_Actions takes nothing returns nothing
    call CompareChatMessage()
endfunction

//===========================================================================
function InitMyTrig takes nothing returns nothing
    set gg_trg_My = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_My, Player(0), "gg", false )
    call TriggerAddAction( gg_trg_My, function MyTrig_Actions )
endfunction
28
Слишком сложно.
Вот так попроще будет.
Код
function StringToPlayerColor takes string color returns playercolor
    set color = StringCase(color, false)
	
    if color == "red" then
        return PLAYER_COLOR_RED
    elseif color == "blue" then
        return PLAYER_COLOR_BLUE
    elseif color == "teal" then
        return PLAYER_COLOR_CYAN
    elseif color == "purple" then
        return PLAYER_COLOR_PURPLE
    elseif color == "yellow" then
        return PLAYER_COLOR_YELLOW
    elseif color == "orange" then
        return PLAYER_COLOR_ORANGE
    elseif color == "green" then
        return PLAYER_COLOR_GREEN
    elseif color == "pink" then
        return PLAYER_COLOR_PINK
    elseif color == "gray" then
        return PLAYER_COLOR_LIGHT_GRAY
    elseif color == "light blue" then
        return PLAYER_COLOR_LIGHT_BLUE
    elseif color == "dark green" then
        return PLAYER_COLOR_AQUA
    elseif color == "brown" then
        return PLAYER_COLOR_BROWN
    elseif color == "maroon" then
        return PLAYER_COLOR_MAROON
    elseif color == "navy" then
        return PLAYER_COLOR_NAVY
    elseif color == "turquoise" then
        return PLAYER_COLOR_TURQUOISE
    elseif color == "violet" then
        return PLAYER_COLOR_VIOLET
    elseif color == "wheat" then
        return PLAYER_COLOR_WHEAT
    elseif color == "peach" then
        return PLAYER_COLOR_PEACH
    elseif color == "mint" then
        return PLAYER_COLOR_MINT
    elseif color == "lavender" then
        return PLAYER_COLOR_LAVENDER
    elseif color == "coal" then
        return PLAYER_COLOR_COAL
    elseif color == "snow" then
        return PLAYER_COLOR_SNOW
    elseif color == "emerald" then
        return PLAYER_COLOR_EMERALD
    elseif color == "peanut" then
        return PLAYER_COLOR_PEANUT
    endif
	
    return null
endfunction

function StringToPlayer takes string color returns player
    local integer i
    set bj_setPlayerTargetColor = StringToPlayerColor(color)
	
    if bj_setPlayerTargetColor != null then
        set i = 1
        loop
            set bj_forceRandomCurrentPick = Player(i)
			if GetPlayerSlotState(bj_forceRandomCurrentPick) == PLAYER_SLOT_STATE_PLAYING and /*
            */ GetPlayerColor(bj_forceRandomCurrentPick) == bj_setPlayerTargetColor then
				return bj_forceRandomCurrentPick
			endif
			
            set i = i + 1
			
            exitwhen i == bj_MAX_PLAYERS
        endloop
    endif
	
    return null
endfunction

function KickPlayer takes nothing returns boolean
    call KillUnit(GetFilterUnit())
    return false
endfunction

function MyTrig_Actions takes nothing returns nothing
    local string color = GetEventPlayerChatString()
    local player p = StringToPlayer(SubString(color, 3, StringLength(color)))
    if p != null then
        call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, p, Filter(function KickPlayer))
        set p = null
    endif
endfunction

function InitMyTrig takes nothing returns nothing
    set gg_trg_My = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_My, Player(0), "gg", false )
    call TriggerAddAction( gg_trg_My, function MyTrig_Actions )
endfunction
Должно работать.
Чутка подправил.
Принятый ответ
15
PT153, благодарю, сейчас разберусь.
Хех честно говоря не особо вкурил, с подстрокой вот понял, даже стало стыдно, что сам не подумал поискать в jass подобные вещи, но вот всякие bj_lastCreatedGroup и bj_forceRandomCurrentPick. Просто сказывается отсутствие опыта, как никак в первый раз плотно соприкоснулся с jass, раньше только с AI баловался немного. Но тем не менее потестил твой вариант, к сожалению с красным цветом так проблема и осталась. Когда у какого-либо из игроков красный цвет, а не у админа - не работает.
C bj_forceRandomCurrentPick понял. Ты просто юзаешь ее как переменную в которую запоминаешь игрока. Окей.
28
Когда у какого-либо из игроков красный цвет, а не у админа - не работает.
Я просто грешил на bj, сейчас их глянул, там всё хорошо, буду думать, что же не так.
bj_lastCreatedGroup и bj_forceRandomCurrentPick.
Да я просто открыл Blizzard.j в поисках глобалок, чтобы свои не создавать. Так-то можно и свои сделать, кто мешает.
bj_lastCreatedGroup вообще нужно в качестве прокси, туда ничего не добавляется, и там обязательно должна быть созданная группа! Если стоит null или удалённая группа, то ничего не произойдёт. Если использовать другие bj, связанные с группой или юнитами, то стоит сделать свою глобалку и использовать её как прокси.
globals
    constant group EmptyGroup = CreateGroup()
endglobals

Вообще не работает или не работает только кик игрока с красным цветом?
Добавь функции ниже и замени StringToPlayer на вариант, что там. В настройках vJass должен быть включён Debug Mode.
Все функции net safe.
Функции
function DebugMsg takes string s returns nothing
    debug call DisplayTimedTextToPlayer(LocalPlayer, 0., 0., 5., s)
endfunction

function DebugMsgIf takes boolean bool, string s returns nothing
    static if DEBUG_MODE then
        if bool then
            call DebugMsg(s)
        endif
    endif
endfunction

function DebugMsgIfElse takes boolean bool, string s1, string s2 returns nothing
    static if DEBUG_MODE then
        if bool then
            call DebugMsg(s1)
        else
            call DebugMsg(s2)
        endif
    endif
endfunction

function PlayerColorToString takes playercolor color returns string	
    if color == PLAYER_COLOR_RED then
        return "red"
    elseif color == PLAYER_COLOR_BLUE then
        return "blue"
    elseif color == PLAYER_COLOR_CYAN then
        return "teal"
    elseif color == PLAYER_COLOR_PURPLE then
        return "purple"
    elseif color == PLAYER_COLOR_YELLOW then
        return "yellow"
    elseif color == PLAYER_COLOR_ORANGE then
        return "orange"
    elseif color == PLAYER_COLOR_GREEN then
        return "green"
    elseif color == PLAYER_COLOR_PINK then
        return "pink"
    elseif color == PLAYER_COLOR_LIGHT_GRAY then
        return "gray"
    elseif color == PLAYER_COLOR_LIGHT_BLUE then
        return "light blue"
    elseif color == PLAYER_COLOR_AQUA then
        return "dark green"
    elseif color == PLAYER_COLOR_BROWN then
        return "brown"
    elseif color == PLAYER_COLOR_MAROON then
        return "maroon"
    elseif color == PLAYER_COLOR_NAVY then
        return "navy"
    elseif color == PLAYER_COLOR_TURQUOISE then
        return "turquoise"
    elseif color == PLAYER_COLOR_VIOLET then
        return "violet"
    elseif color == PLAYER_COLOR_WHEAT then
        return "wheat"
    elseif color == PLAYER_COLOR_PEACH then
        return "peach"
    elseif color == PLAYER_COLOR_MINT then
        return "mint"
    elseif color == PLAYER_COLOR_LAVENDER then
        return "lavender"
    elseif color == PLAYER_COLOR_COAL then
        return "coal"
    elseif color == PLAYER_COLOR_SNOW then
        return "snow"
    elseif color == PLAYER_COLOR_EMERALD then
        return "emerald"
    elseif color == PLAYER_COLOR_PEANUT then
        return "peanut"
    endif
	
    return null
endfunction

function StringToPlayer takes string color returns player
    local integer i
    set bj_setPlayerTargetColor = StringToPlayerColor(color)
	
    if bj_setPlayerTargetColor != null then
        set i = 1
        loop
            set bj_forceRandomCurrentPick = Player(i)
            call DebugMsg("Current player is " + GetPlayerName(bj_forceRandomCurrentPick))
			if GetPlayerSlotState(bj_forceRandomCurrentPick) == PLAYER_SLOT_STATE_PLAYING then
                call DebugMsg("Color of " + GetPlayerName(bj_forceRandomCurrentPick) + " is " + PlayerColorToString(GetPlayerColor(bj_forceRandomCurrentPick)))
                if GetPlayerColor(bj_forceRandomCurrentPick) == bj_setPlayerTargetColor then
				    return bj_forceRandomCurrentPick
				endif
			endif
            call DebugMsg("No match!")
            set i = i + 1
			
            exitwhen i == bj_MAX_PLAYERS
        endloop
    endif
	call DebugMsg("Invalid string! String is " + color)
    return null
endfunction
После этого протестируй и скажи результат.

А вообще, чего мы возимся, лол, у тебя же последняя версия. Вот патч, тут есть вшитый кик игрока по имени или слоту.
15
PT153, не работает только с игроком, который имеет красный цвет. Хорошо, я попробую добавить эти функции, но давай оставим это уже до завтра, а то очень поздно, уже пора и спать отправляться. Завтра я поищу, где настройки vJass находятся. Вообще говоря они же вроде в JPNG были, если я не ошибаюсь, а не в стандартном редакторе...
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.